diff options
author | Yongli He <yongli.he@intel.com> | 2019-07-15 16:36:09 +0800 |
---|---|---|
committer | Matt Riedemann <mriedem.os@gmail.com> | 2019-09-06 17:24:17 -0400 |
commit | aae95dcc7a79be019fc304ced76a351c16382ede (patch) | |
tree | bb2fa94b9ff6dab6da11c762060a515e8c8d45ce /novaclient | |
parent | e43596ca5ce076ecbb53a6788349b46f2b3f5c39 (diff) | |
download | python-novaclient-aae95dcc7a79be019fc304ced76a351c16382ede.tar.gz |
Microversion 2.78 - show server topology
Add support microversion 2.78 which adds server topology
information in the output of the following new command:
nova server-topology
Depends-on: https://review.opendev.org/#/c/621476/
Change-Id: I6467d52d2528a37348458baf4842b571a97f3ed2
Implements: blueprint show-server-numa-topology
Diffstat (limited to 'novaclient')
-rw-r--r-- | novaclient/__init__.py | 2 | ||||
-rw-r--r-- | novaclient/tests/unit/fixture_data/servers.py | 4 | ||||
-rw-r--r-- | novaclient/tests/unit/v2/fakes.py | 45 | ||||
-rw-r--r-- | novaclient/tests/unit/v2/test_servers.py | 24 | ||||
-rw-r--r-- | novaclient/tests/unit/v2/test_shell.py | 13 | ||||
-rw-r--r-- | novaclient/v2/servers.py | 18 | ||||
-rw-r--r-- | novaclient/v2/shell.py | 11 |
7 files changed, 116 insertions, 1 deletions
diff --git a/novaclient/__init__.py b/novaclient/__init__.py index 00e0b3e4..3e5daf21 100644 --- a/novaclient/__init__.py +++ b/novaclient/__init__.py @@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1") # when client supported the max version, and bumped sequentially, otherwise # the client may break due to server side new version may include some # backward incompatible change. -API_MAX_VERSION = api_versions.APIVersion("2.77") +API_MAX_VERSION = api_versions.APIVersion("2.78") diff --git a/novaclient/tests/unit/fixture_data/servers.py b/novaclient/tests/unit/fixture_data/servers.py index 9962842a..7e4ee64a 100644 --- a/novaclient/tests/unit/fixture_data/servers.py +++ b/novaclient/tests/unit/fixture_data/servers.py @@ -371,6 +371,10 @@ class V1(Base): self.requests_mock.delete(self.url('1234', 'os-interface', 'port-id'), headers=self.json_headers) + self.requests_mock.get(self.url('1234', 'topology'), + json=v2_fakes.SERVER_TOPOLOGY, + headers=self.json_headers) + # Testing with the following password and key # # Clear password: FooBar123 diff --git a/novaclient/tests/unit/v2/fakes.py b/novaclient/tests/unit/v2/fakes.py index faf5f6f4..d6fbf129 100644 --- a/novaclient/tests/unit/v2/fakes.py +++ b/novaclient/tests/unit/v2/fakes.py @@ -58,6 +58,48 @@ FAKE_RESPONSE_HEADERS = {'x-openstack-request-id': FAKE_REQUEST_ID} FAKE_SERVICE_UUID_1 = '75e9eabc-ed3b-4f11-8bba-add1e7e7e2de' FAKE_SERVICE_UUID_2 = '1f140183-c914-4ddf-8757-6df73028aa86' +SERVER_TOPOLOGY = { + "nodes": [ + { + "cpu_pinning": { + "0": 0, + "1": 5 + }, + "host_node": 0, + "memory_mb": 1024, + "siblings": [ + [ + 0, + 1 + ] + ], + "vcpu_set": [ + 0, + 1 + ] + }, + { + "cpu_pinning": { + "2": 1, + "3": 8 + }, + "host_node": 1, + "memory_mb": 2048, + "siblings": [ + [ + 2, + 3 + ] + ], + "vcpu_set": [ + 2, + 3 + ] + } + ], + "pagesize_kb": 4 +} + class FakeClient(fakes.FakeClient, client.Client): @@ -738,6 +780,9 @@ class FakeSessionClient(base_client.SessionClient): 'rules': []}] }) + def get_servers_1234_topology(self, **kw): + return 200, {}, SERVER_TOPOLOGY + # # Server password # diff --git a/novaclient/tests/unit/v2/test_servers.py b/novaclient/tests/unit/v2/test_servers.py index 5ef987fa..c255cbd7 100644 --- a/novaclient/tests/unit/v2/test_servers.py +++ b/novaclient/tests/unit/v2/test_servers.py @@ -1875,3 +1875,27 @@ class ServersV277Test(ServersV274Test): s, availability_zone='foo-az') self.assertIn("unexpected keyword argument 'availability_zone'", six.text_type(ex)) + + +class ServersV278Test(ServersV273Test): + + api_version = "2.78" + + def test_get_server_topology(self): + s = self.cs.servers.get(1234) + topology = s.topology() + self.assert_request_id(topology, fakes.FAKE_REQUEST_ID_LIST) + self.assertIsNotNone(topology) + self.assert_called('GET', '/servers/1234/topology') + + topology_from_manager = self.cs.servers.topology(1234) + self.assert_request_id(topology, fakes.FAKE_REQUEST_ID_LIST) + self.assertIsNotNone(topology_from_manager) + self.assert_called('GET', '/servers/1234/topology') + + self.assertEqual(topology, topology_from_manager) + + def test_get_server_topology_pre278(self): + self.cs.api_version = api_versions.APIVersion('2.77') + s = self.cs.servers.get(1234) + self.assertRaises(exceptions.VersionNotFoundForAPIMethod, s.topology) diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py index 2dc8a38a..928a9de4 100644 --- a/novaclient/tests/unit/v2/test_shell.py +++ b/novaclient/tests/unit/v2/test_shell.py @@ -2463,6 +2463,19 @@ class ShellTest(utils.TestCase): self.run_command('diagnostics sample-server') self.assert_called('GET', '/servers/1234/diagnostics') + def test_server_topology(self): + self.run_command('server-topology 1234', api_version='2.78') + self.assert_called('GET', '/servers/1234/topology') + self.run_command('server-topology sample-server', api_version='2.78') + self.assert_called('GET', '/servers/1234/topology') + + def test_server_topology_pre278(self): + exp = self.assertRaises(SystemExit, + self.run_command, + 'server-topology 1234', + api_version='2.77') + self.assertIn('2', six.text_type(exp)) + def test_refresh_network(self): self.run_command('refresh-network 1234') self.assert_called('POST', '/os-server-external-events', diff --git a/novaclient/v2/servers.py b/novaclient/v2/servers.py index acef7856..9870be0b 100644 --- a/novaclient/v2/servers.py +++ b/novaclient/v2/servers.py @@ -316,6 +316,11 @@ class Server(base.Resource): """Diagnostics -- Retrieve server diagnostics.""" return self.manager.diagnostics(self) + @api_versions.wraps("2.78") + def topology(self): + """Retrieve server topology.""" + return self.manager.topology(self) + @api_versions.wraps("2.0", "2.55") def migrate(self): """ @@ -1286,6 +1291,19 @@ class ServerManager(base.BootingManagerWithFind): base.getid(server)) return base.TupleWithMeta((resp, body), resp) + @api_versions.wraps("2.78") + def topology(self, server): + """ + Retrieve server topology. + + :param server: The :class:`Server` (or its ID) for which + topology to be returned + :returns: An instance of novaclient.base.DictWithMeta + """ + resp, body = self.api.client.get("/servers/%s/topology" % + base.getid(server)) + return base.DictWithMeta(body, resp) + def _validate_create_nics(self, nics): # nics are required with microversion 2.37+ and can be a string or list if self.api_version > api_versions.APIVersion('2.36'): diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py index a08c8674..acaf1783 100644 --- a/novaclient/v2/shell.py +++ b/novaclient/v2/shell.py @@ -2313,6 +2313,17 @@ def do_diagnostics(cs, args): utils.print_dict(cs.servers.diagnostics(server)[1], wrap=80) +@api_versions.wraps("2.78") +@utils.arg('server', metavar='<server>', help=_('Name or ID of server.')) +def do_server_topology(cs, args): + """Retrieve server topology.""" + server = _find_server(cs, args.server) + # This prints a dict with only two properties: nodes and pagesize_kb + # nodes is a list of dicts so it does not print very well, it's just a + # json blob in the output. + utils.print_dict(cs.servers.topology(server), wrap=80) + + @utils.arg( 'server', metavar='<server>', help=_('Name or ID of a server for which the network cache should ' |