Add MKS protocol for remote consoles

MKS is the native protocol for VMware consoles and this patch is adding
API support for it. For now there is only one console type for this
protocol and this is 'webmks'. A new microversion is introduced which
adds protocol 'mks' and type 'webmks' for requesting a remote console.

Example request:

POST /servers/<uuid>/remote-consoles
{
  "remote_console": {
    "protocol": "mks",
    "type": "webmks"
  }
}

Example response:

{
  "remote_console": {
    "protocol": "mks",
    "type": "webmks",
    "url": "http://example.com:6090/mks.html?token=XYZ"
  }
}

APIImpact
Implements: blueprint vmware-webmks-console

Change-Id: I7217b999fb8d64a5646d8f20d7426c26553871d7
This commit is contained in:
Radoslav Gerganov 2015-07-07 17:17:09 +03:00
parent 50c8f93e51
commit 14ca7c37ba
13 changed files with 111 additions and 7 deletions

View File

@ -22,7 +22,7 @@
}
],
"status": "CURRENT",
"version": "2.7",
"version": "2.8",
"min_version": "2.1",
"updated": "2013-07-23T11:33:21Z"
}

View File

@ -0,0 +1,6 @@
{
"remote_console": {
"protocol": "mks",
"type": "webmks"
}
}

View File

@ -0,0 +1,7 @@
{
"remote_console": {
"protocol": "mks",
"type": "webmks",
"url": "http://example.com:6090/mks.html?token=b60bcfc3-5fd4-4d21-986c-e83379107819"
}
}

View File

@ -46,6 +46,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
* 2.5 - Allow server search option ip6 for non-admin
* 2.6 - Consolidate the APIs for getting remote consoles
* 2.7 - Check flavor type before add tenant access.
* 2.8 - Add new protocol for VM console (mks)
"""
# The minimum and maximum versions of the API supported
@ -54,7 +55,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
# Note(cyeoh): This only applies for the v2.1 API once microversions
# support is fully merged. It does not affect the V2 API.
_MIN_API_VERSION = "2.1"
_MAX_API_VERSION = "2.7"
_MAX_API_VERSION = "2.8"
DEFAULT_API_VERSION = _MIN_API_VERSION

View File

@ -33,7 +33,8 @@ class RemoteConsolesController(wsgi.Controller):
self.handlers = {'vnc': self.compute_api.get_vnc_console,
'spice': self.compute_api.get_spice_console,
'rdp': self.compute_api.get_rdp_console,
'serial': self.compute_api.get_serial_console}
'serial': self.compute_api.get_serial_console,
'mks': self.compute_api.get_mks_console}
super(RemoteConsolesController, self).__init__(*args, **kwargs)
@wsgi.Controller.api_version("2.1", "2.5")
@ -154,7 +155,8 @@ class RemoteConsolesController(wsgi.Controller):
@wsgi.Controller.api_version("2.6")
@extensions.expected_errors((400, 404, 409, 501))
@validation.schema(remote_consoles.create_v26)
@validation.schema(remote_consoles.create_v26, "2.6", "2.7")
@validation.schema(remote_consoles.create_v28, "2.8")
def create(self, req, server_id, body):
context = req.environ['nova.context']
authorize(context)

View File

@ -109,3 +109,25 @@ create_v26 = {
'required': ['remote_console'],
'additionalProperties': False,
}
create_v28 = {
'type': 'object',
'properties': {
'remote_console': {
'type': 'object',
'properties': {
'protocol': {
'enum': ['vnc', 'spice', 'rdp', 'serial', 'mks'],
},
'type': {
'enum': ['novnc', 'xvpvnc', 'rdp-html5',
'spice-html5', 'serial', 'webmks'],
},
},
'required': ['protocol', 'type'],
'additionalProperties': False,
},
},
'required': ['remote_console'],
'additionalProperties': False,
}

View File

@ -96,3 +96,7 @@ user documentation.
Check the ``is_public`` attribute of a flavor before adding tenant access
to it. Reject the request with HTTPConflict error.
2.8
---
Add 'mks' protocol and 'webmks' type for remote consoles.

View File

@ -22,7 +22,7 @@
}
],
"status": "CURRENT",
"version": "2.7",
"version": "2.8",
"min_version": "2.1",
"updated": "2013-07-23T11:33:21Z"
}

View File

@ -0,0 +1,6 @@
{
"remote_console": {
"protocol": "mks",
"type": "webmks"
}
}

View File

@ -0,0 +1,7 @@
{
"remote_console": {
"protocol": "mks",
"type": "webmks",
"url": "%(url)s"
}
}

View File

@ -107,3 +107,28 @@ class ConsolesV26SampleJsonTests(test_servers.ServersSampleBase):
subs = self._get_regexes()
subs["url"] = self.http_regex
self._verify_response('create-vnc-console-resp', subs, response, 200)
class ConsolesV28SampleJsonTests(test_servers.ServersSampleBase):
extension_name = "os-remote-consoles"
_api_version = 'v3'
def setUp(self):
super(ConsolesV28SampleJsonTests, self).setUp()
self.http_regex = "(https?://)([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*"
self.flags(enabled=True, group='mks')
def test_create_mks_console(self):
# NOTE(rgerganov): set temporary to None to avoid duplicating server
# templates in the v2.8 folder
ConsolesV28SampleJsonTests.request_api_version = None
uuid = self._post_server()
ConsolesV28SampleJsonTests.request_api_version = '2.8'
body = {'protocol': 'mks', 'type': 'webmks'}
response = self._do_post('servers/%s/remote-consoles' % uuid,
'create-mks-console-req', body,
api_version='2.8')
subs = self._get_regexes()
subs["url"] = self.http_regex
self._verify_response('create-mks-console-resp', subs, response, 200)

View File

@ -573,6 +573,30 @@ class ConsolesExtensionTestV26(test.NoDBTestCase):
self.req, fakes.FAKE_UUID, body=body)
class ConsolesExtensionTestV28(ConsolesExtensionTestV26):
def setUp(self):
super(ConsolesExtensionTestV28, self).setUp()
self.req = fakes.HTTPRequest.blank('')
self.context = self.req.environ['nova.context']
self.req.api_version_request = api_version_request.APIVersionRequest(
'2.8')
self.controller = console_v21.RemoteConsolesController()
@mock.patch.object(compute_api.API, 'get', return_value='fake_instance')
def test_create_mks_console(self, mock_get):
mock_handler = mock.MagicMock()
mock_handler.return_value = {'url': "http://fake"}
self.controller.handlers['mks'] = mock_handler
body = {'remote_console': {'protocol': 'mks', 'type': 'webmks'}}
output = self.controller.create(self.req, fakes.FAKE_UUID, body=body)
self.assertEqual({'remote_console': {'protocol': 'mks',
'type': 'webmks',
'url': 'http://fake'}}, output)
mock_handler.assert_called_once_with(self.context, 'fake_instance',
'webmks')
class ConsolesExtensionTestV2(ConsolesExtensionTestV21):
controller_class = console_v2.ConsolesController
validation_error = webob.exc.HTTPBadRequest

View File

@ -65,7 +65,7 @@ EXP_VERSIONS = {
"v2.1": {
"id": "v2.1",
"status": "CURRENT",
"version": "2.7",
"version": "2.8",
"min_version": "2.1",
"updated": "2013-07-23T11:33:21Z",
"links": [
@ -114,7 +114,7 @@ class VersionsTestV20(test.NoDBTestCase):
{
"id": "v2.1",
"status": "CURRENT",
"version": "2.7",
"version": "2.8",
"min_version": "2.1",
"updated": "2013-07-23T11:33:21Z",
"links": [