From 7f4a64e0aaa365abfb4b7d6d272851ceb01e9dd2 Mon Sep 17 00:00:00 2001 From: huangtianhua Date: Tue, 14 Feb 2017 17:37:57 +0800 Subject: [PATCH] Support to get webmks console url for server Support 'webmks' console type when get console url for server. Change-Id: I1e46a42ad65bba703015ef7c57aefdc67606e87c Closes-Bug: #1646678 --- heat/engine/clients/os/nova.py | 25 +++++++++---- .../engine/resources/openstack/nova/server.py | 2 +- heat/tests/clients/test_nova_client.py | 36 +++++++++++++------ heat/tests/openstack/nova/test_server.py | 2 +- ...r-webmks-console-url-f7066a9e14429084.yaml | 5 +++ 5 files changed, 51 insertions(+), 19 deletions(-) create mode 100644 releasenotes/notes/get-server-webmks-console-url-f7066a9e14429084.yaml diff --git a/heat/engine/clients/os/nova.py b/heat/engine/clients/os/nova.py index 347b41206..a91e58fc9 100644 --- a/heat/engine/clients/os/nova.py +++ b/heat/engine/clients/os/nova.py @@ -56,12 +56,16 @@ class NovaClientPlugin(client_plugin.ClientPlugin): exceptions_module = exceptions - supported_versions = [ - NOVA_API_VERSION, V2_2, V2_15, V2_26 + NOVA_API_VERSION = '2.1' + + validate_versions = [ + V2_2, V2_15, V2_26, V2_8 ] = [ - '2.1', '2.2', '2.15', '2.26' + '2.2', '2.15', '2.26', '2.8' ] + supported_versions = [NOVA_API_VERSION] + validate_versions + service_types = [COMPUTE] = ['compute'] def _get_service_name(self): @@ -87,7 +91,7 @@ class NovaClientPlugin(client_plugin.ClientPlugin): client = nc.Client(version, **args) # NOTE: check for microversion availability - if version in [self.V2_2, self.V2_15, self.V2_26]: + if version in self.validate_versions: try: client.versions.get_current() except exceptions.NotAcceptable: @@ -590,19 +594,25 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers The actual console url is lazily resolved on access. """ + nc = self.client + mks_version = self.V2_8 class ConsoleUrls(collections.Mapping): def __init__(self, server): self.console_method = server.get_console_url self.support_console_types = ['novnc', 'xvpvnc', 'spice-html5', 'rdp-html5', - 'serial'] + 'serial', 'webmks'] def __getitem__(self, key): try: if key not in self.support_console_types: raise exceptions.UnsupportedConsoleType(key) - data = self.console_method(key) + if key == 'webmks': + data = nc(mks_version).servers.get_console_url( + server, key) + else: + data = self.console_method(key) console_data = data.get( 'remote_console', data.get('console')) url = console_data['url'] @@ -614,6 +624,9 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers url = e.message else: raise + except exception.InvalidServiceVersion: + url = _('Nova service version %s is ' + 'unavailable') % mks_version return url def __len__(self): diff --git a/heat/engine/resources/openstack/nova/server.py b/heat/engine/resources/openstack/nova/server.py index 87024f941..9258e4397 100644 --- a/heat/engine/resources/openstack/nova/server.py +++ b/heat/engine/resources/openstack/nova/server.py @@ -605,7 +605,7 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin, "can be specified as parameter to the get_attr function, " "e.g. get_attr: [ , console_urls, novnc ]. " "Currently supported types are " - "novnc, xvpvnc, spice-html5, rdp-html5, serial."), + "novnc, xvpvnc, spice-html5, rdp-html5, serial and webmks."), support_status=support.SupportStatus(version='2015.1'), type=attributes.Schema.MAP ), diff --git a/heat/tests/clients/test_nova_client.py b/heat/tests/clients/test_nova_client.py index 33f8b3afc..12d0ee6db 100644 --- a/heat/tests/clients/test_nova_client.py +++ b/heat/tests/clients/test_nova_client.py @@ -637,11 +637,12 @@ class KeypairConstraintTest(common.HeatTestCase): class ConsoleUrlsTest(common.HeatTestCase): scenarios = [ - ('novnc', dict(console_type='novnc')), - ('xvpvnc', dict(console_type='xvpvnc')), - ('spice', dict(console_type='spice-html5')), - ('rdp', dict(console_type='rdp-html5')), - ('serial', dict(console_type='serial')), + ('novnc', dict(console_type='novnc', res_obj=True)), + ('xvpvnc', dict(console_type='xvpvnc', res_obj=True)), + ('spice', dict(console_type='spice-html5', res_obj=True)), + ('rdp', dict(console_type='rdp-html5', res_obj=True)), + ('serial', dict(console_type='serial', res_obj=True)), + ('mks', dict(console_type='webmks', res_obj=False)), ] def setUp(self): @@ -650,9 +651,14 @@ class ConsoleUrlsTest(common.HeatTestCase): con = utils.dummy_context() c = con.clients self.nova_plugin = c.client_plugin('nova') - self.nova_plugin.client = lambda: self.nova_client + self.patchobject(self.nova_plugin, 'client', + return_value=self.nova_client) self.server = mock.Mock() - self.console_method = getattr(self.server, 'get_console_url') + if self.res_obj: + self.console_method = getattr(self.server, 'get_console_url') + else: + self.console_method = getattr(self.nova_client.servers, + 'get_console_url') def test_get_console_url(self): console = { @@ -667,13 +673,20 @@ class ConsoleUrlsTest(common.HeatTestCase): self.console_type] self.assertEqual(console['console']['url'], console_url) - self.console_method.assert_called_once_with(self.console_type) + self._assert_console_method_called() + + def _assert_console_method_called(self): + if self.console_type == 'webmks': + self.console_method.assert_called_once_with(self.server, + self.console_type) + else: + self.console_method.assert_called_once_with(self.console_type) def _test_get_console_url_tolerate_exception(self, msg): console_url = self.nova_plugin.get_console_urls(self.server)[ self.console_type] - self.console_method.assert_called_once_with(self.console_type) + self._assert_console_method_called() self.assertEqual(msg, console_url) def test_get_console_url_tolerate_unavailable(self): @@ -698,7 +711,7 @@ class ConsoleUrlsTest(common.HeatTestCase): urls = self.nova_plugin.get_console_urls(self.server) e = self.assertRaises(exc, urls.__getitem__, self.console_type) self.assertIn('spam', encodeutils.exception_to_unicode(e)) - self.console_method.assert_called_once_with(self.console_type) + self._assert_console_method_called() def test_get_console_urls_reraises_other(self): exc = Exception @@ -706,8 +719,9 @@ class ConsoleUrlsTest(common.HeatTestCase): urls = self.nova_plugin.get_console_urls(self.server) e = self.assertRaises(exc, urls.__getitem__, self.console_type) + self.assertIn('spam', e.args) - self.console_method.assert_called_once_with(self.console_type) + self._assert_console_method_called() class NovaClientPluginExtensionsTest(NovaClientPluginTestCase): diff --git a/heat/tests/openstack/nova/test_server.py b/heat/tests/openstack/nova/test_server.py index b24612acf..465df2d06 100644 --- a/heat/tests/openstack/nova/test_server.py +++ b/heat/tests/openstack/nova/test_server.py @@ -3097,7 +3097,7 @@ class ServersTest(common.HeatTestCase): console_urls = ws._resolve_all_attributes('console_urls') self.assertIsInstance(console_urls, collections.Mapping) supported_consoles = ('novnc', 'xvpvnc', 'spice-html5', 'rdp-html5', - 'serial') + 'serial', 'webmks') self.assertEqual(set(supported_consoles), set(console_urls)) diff --git a/releasenotes/notes/get-server-webmks-console-url-f7066a9e14429084.yaml b/releasenotes/notes/get-server-webmks-console-url-f7066a9e14429084.yaml new file mode 100644 index 000000000..69cb7e039 --- /dev/null +++ b/releasenotes/notes/get-server-webmks-console-url-f7066a9e14429084.yaml @@ -0,0 +1,5 @@ +--- +features: + - Supports to get the webmks console url for OS::Nova::Server + resource. And this requires nova api version equal or greater + than 2.8.