diff --git a/novaclient/__init__.py b/novaclient/__init__.py index bb0e53d1d..5dc881d07 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.70") +API_MAX_VERSION = api_versions.APIVersion("2.71") diff --git a/novaclient/tests/unit/v2/fakes.py b/novaclient/tests/unit/v2/fakes.py index 0f1857ff3..a32e22582 100644 --- a/novaclient/tests/unit/v2/fakes.py +++ b/novaclient/tests/unit/v2/fakes.py @@ -618,8 +618,11 @@ class FakeSessionClient(base_client.SessionClient): return (202, {}, self.get_servers_9012()[2]) def get_servers_1234(self, **kw): - r = {'server': self.get_servers_detail()[2]['servers'][0]} - return (200, {}, r) + server = self.get_servers_detail()[2]['servers'][0] + if self.api_version >= api_versions.APIVersion('2.71'): + server.update( + {'server_groups': ['a67359fb-d397-4697-88f1-f55e3ee7c499']}) + return (200, {}, {'server': server}) def get_servers_1235(self, **kw): r = {'server': self.get_servers_detail()[2]['servers'][0]} diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py index 778c74ac8..3589ec5c0 100644 --- a/novaclient/tests/unit/v2/test_shell.py +++ b/novaclient/tests/unit/v2/test_shell.py @@ -2028,6 +2028,36 @@ class ShellTest(utils.TestCase): }, pos=3) self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + def test_rebuild_with_server_groups_in_response(self): + out = self.run_command('rebuild sample-server %s' % FAKE_UUID_1, + api_version='2.71')[0] + self.assert_called('GET', '/servers?name=sample-server', pos=0) + self.assert_called('GET', '/servers/1234', pos=1) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': {'imageRef': FAKE_UUID_1, + 'description': None, + } + }, pos=3) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + self.assertIn('server_groups', out) + self.assertIn('a67359fb-d397-4697-88f1-f55e3ee7c499', out) + + def test_rebuild_without_server_groups_in_response(self): + out = self.run_command('rebuild sample-server %s' % FAKE_UUID_1, + api_version='2.70')[0] + self.assert_called('GET', '/servers?name=sample-server', pos=0) + self.assert_called('GET', '/servers/1234', pos=1) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': {'imageRef': FAKE_UUID_1, + 'description': None, + } + }, pos=3) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + self.assertNotIn('server_groups', out) + self.assertNotIn('a67359fb-d397-4697-88f1-f55e3ee7c499', out) + def test_start(self): self.run_command('start sample-server') self.assert_called('POST', '/servers/1234/action', {'os-start': None}) @@ -2180,6 +2210,26 @@ class ShellTest(utils.TestCase): output, _ = self.run_command('show help') self.assert_called('GET', '/servers/9014', pos=-6) + def test_show_with_server_groups_in_response(self): + # Starting microversion 2.71, the 'server_groups' is included + # in the output (the response). + out = self.run_command('show 1234', api_version='2.71')[0] + self.assert_called('GET', '/servers?name=1234', pos=0) + self.assert_called('GET', '/servers?name=1234', pos=1) + self.assert_called('GET', '/servers/1234', pos=2) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=3) + self.assertIn('server_groups', out) + self.assertIn('a67359fb-d397-4697-88f1-f55e3ee7c499', out) + + def test_show_without_server_groups_in_response(self): + out = self.run_command('show 1234', api_version='2.70')[0] + self.assert_called('GET', '/servers?name=1234', pos=0) + self.assert_called('GET', '/servers?name=1234', pos=1) + self.assert_called('GET', '/servers/1234', pos=2) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=3) + self.assertNotIn('server_groups', out) + self.assertNotIn('a67359fb-d397-4697-88f1-f55e3ee7c499', out) + @mock.patch('novaclient.v2.shell.utils.print_dict') def test_print_server(self, mock_print_dict): self.run_command('show 5678') @@ -4081,6 +4131,7 @@ class ShellTest(utils.TestCase): # skipped when forming the detailed lists for embedded # flavor information. 70, # There are no version-wrapped shell method changes for this. + 71, # There are no version-wrapped shell method changes for this. ]) versions_supported = set(range(0, novaclient.API_MAX_VERSION.ver_minor + 1)) diff --git a/releasenotes/notes/microversion-v2_71-a87b4bb4205c46e2.yaml b/releasenotes/notes/microversion-v2_71-a87b4bb4205c46e2.yaml new file mode 100644 index 000000000..7a4bf9609 --- /dev/null +++ b/releasenotes/notes/microversion-v2_71-a87b4bb4205c46e2.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Added support for `microversion 2.71`_ which outputs the `server_groups` + field in the following commands: + + * ``nova show`` + * ``nova rebuild`` + + .. _microversion 2.71: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id64