From 14ca7c37baeb46bc277f5e4e0cfec704b5174d7f Mon Sep 17 00:00:00 2001 From: Radoslav Gerganov Date: Tue, 7 Jul 2015 17:17:09 +0300 Subject: [PATCH] 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//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 --- .../versions/versions-get-resp.json | 2 +- .../v2.8/create-mks-console-req.json | 6 +++++ .../v2.8/create-mks-console-resp.json | 7 ++++++ nova/api/openstack/api_version_request.py | 3 ++- .../compute/plugins/v3/remote_consoles.py | 6 +++-- .../compute/schemas/v3/remote_consoles.py | 22 ++++++++++++++++ .../openstack/rest_api_version_history.rst | 4 +++ .../versions/versions-get-resp.json.tpl | 2 +- .../v2.8/create-mks-console-req.json.tpl | 6 +++++ .../v2.8/create-mks-console-resp.json.tpl | 7 ++++++ .../functional/v3/test_remote_consoles.py | 25 +++++++++++++++++++ .../compute/contrib/test_consoles.py | 24 ++++++++++++++++++ .../api/openstack/compute/test_versions.py | 4 +-- 13 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 doc/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-req.json create mode 100644 doc/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-resp.json create mode 100644 nova/tests/functional/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-req.json.tpl create mode 100644 nova/tests/functional/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-resp.json.tpl diff --git a/doc/api_samples/versions/versions-get-resp.json b/doc/api_samples/versions/versions-get-resp.json index 9f9120a2a7..4b87cfa5d8 100644 --- a/doc/api_samples/versions/versions-get-resp.json +++ b/doc/api_samples/versions/versions-get-resp.json @@ -22,7 +22,7 @@ } ], "status": "CURRENT", - "version": "2.7", + "version": "2.8", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } diff --git a/doc/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-req.json b/doc/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-req.json new file mode 100644 index 0000000000..0289a0a5d0 --- /dev/null +++ b/doc/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-req.json @@ -0,0 +1,6 @@ +{ + "remote_console": { + "protocol": "mks", + "type": "webmks" + } +} diff --git a/doc/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-resp.json b/doc/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-resp.json new file mode 100644 index 0000000000..43eba84fd8 --- /dev/null +++ b/doc/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-resp.json @@ -0,0 +1,7 @@ +{ + "remote_console": { + "protocol": "mks", + "type": "webmks", + "url": "http://example.com:6090/mks.html?token=b60bcfc3-5fd4-4d21-986c-e83379107819" + } +} diff --git a/nova/api/openstack/api_version_request.py b/nova/api/openstack/api_version_request.py index 4160950e19..ccbaa185f6 100644 --- a/nova/api/openstack/api_version_request.py +++ b/nova/api/openstack/api_version_request.py @@ -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 diff --git a/nova/api/openstack/compute/plugins/v3/remote_consoles.py b/nova/api/openstack/compute/plugins/v3/remote_consoles.py index 3428f2654d..8b1fe0a33a 100644 --- a/nova/api/openstack/compute/plugins/v3/remote_consoles.py +++ b/nova/api/openstack/compute/plugins/v3/remote_consoles.py @@ -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) diff --git a/nova/api/openstack/compute/schemas/v3/remote_consoles.py b/nova/api/openstack/compute/schemas/v3/remote_consoles.py index dcacab9515..5369513b3f 100644 --- a/nova/api/openstack/compute/schemas/v3/remote_consoles.py +++ b/nova/api/openstack/compute/schemas/v3/remote_consoles.py @@ -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, +} diff --git a/nova/api/openstack/rest_api_version_history.rst b/nova/api/openstack/rest_api_version_history.rst index 281250217d..e5a5fc0960 100644 --- a/nova/api/openstack/rest_api_version_history.rst +++ b/nova/api/openstack/rest_api_version_history.rst @@ -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. diff --git a/nova/tests/functional/api_samples/versions/versions-get-resp.json.tpl b/nova/tests/functional/api_samples/versions/versions-get-resp.json.tpl index 9f9120a2a7..4b87cfa5d8 100644 --- a/nova/tests/functional/api_samples/versions/versions-get-resp.json.tpl +++ b/nova/tests/functional/api_samples/versions/versions-get-resp.json.tpl @@ -22,7 +22,7 @@ } ], "status": "CURRENT", - "version": "2.7", + "version": "2.8", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } diff --git a/nova/tests/functional/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-req.json.tpl b/nova/tests/functional/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-req.json.tpl new file mode 100644 index 0000000000..0289a0a5d0 --- /dev/null +++ b/nova/tests/functional/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-req.json.tpl @@ -0,0 +1,6 @@ +{ + "remote_console": { + "protocol": "mks", + "type": "webmks" + } +} diff --git a/nova/tests/functional/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-resp.json.tpl b/nova/tests/functional/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-resp.json.tpl new file mode 100644 index 0000000000..fb223e2466 --- /dev/null +++ b/nova/tests/functional/v3/api_samples/os-remote-consoles/v2.8/create-mks-console-resp.json.tpl @@ -0,0 +1,7 @@ +{ + "remote_console": { + "protocol": "mks", + "type": "webmks", + "url": "%(url)s" + } +} diff --git a/nova/tests/functional/v3/test_remote_consoles.py b/nova/tests/functional/v3/test_remote_consoles.py index 6b77827525..6bb0a2215a 100644 --- a/nova/tests/functional/v3/test_remote_consoles.py +++ b/nova/tests/functional/v3/test_remote_consoles.py @@ -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) diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_consoles.py b/nova/tests/unit/api/openstack/compute/contrib/test_consoles.py index fc61ddee18..0ea252840f 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_consoles.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_consoles.py @@ -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 diff --git a/nova/tests/unit/api/openstack/compute/test_versions.py b/nova/tests/unit/api/openstack/compute/test_versions.py index 3bf24f6246..3d4140987b 100644 --- a/nova/tests/unit/api/openstack/compute/test_versions.py +++ b/nova/tests/unit/api/openstack/compute/test_versions.py @@ -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": [