Fix microversion 2.96
This change fixes missing conditional logic for microversion 2.96 which adds `pinned_availability_zone` field to `openstack server list` output. Change-Id: I1e398bb3379fa6443b0a44db76baaf6241a945e7 Signed-off-by: Rajesh Tailor <ratailor@redhat.com>
This commit is contained in:
@@ -183,9 +183,13 @@ def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
|
||||
'updated_at': 'updated',
|
||||
'user_data': 'OS-EXT-SRV-ATTR:user_data',
|
||||
'vm_state': 'OS-EXT-STS:vm_state',
|
||||
'pinned_availability_zone': 'pinned_availability_zone',
|
||||
'scheduler_hints': 'scheduler_hints',
|
||||
}
|
||||
# NOTE(ratailor): microversion 2.96 introduces
|
||||
# pinned_availability_zone support
|
||||
if sdk_utils.supports_microversion(compute_client, '2.96'):
|
||||
column_map['pinned_availability_zone'] = 'pinned_availability_zone'
|
||||
|
||||
# Some columns returned by openstacksdk should not be shown because they're
|
||||
# either irrelevant or duplicates
|
||||
ignored_columns = {
|
||||
@@ -240,6 +244,11 @@ def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
|
||||
if not sdk_utils.supports_microversion(compute_client, '2.100'):
|
||||
info.pop('scheduler_hints', None)
|
||||
|
||||
# NOTE(ratailor): microversion 2.96 introduces
|
||||
# pinned_availability_zone support
|
||||
if not sdk_utils.supports_microversion(compute_client, '2.96'):
|
||||
info.pop('pinned_availability_zone', None)
|
||||
|
||||
# Convert the image blob to a name
|
||||
image_info = info.get('image', {})
|
||||
if image_info and any(image_info.values()):
|
||||
@@ -2838,18 +2847,19 @@ class ListServer(command.Lister):
|
||||
if parsed_args.long:
|
||||
columns += (
|
||||
'availability_zone',
|
||||
'pinned_availability_zone',
|
||||
'hypervisor_hostname',
|
||||
'metadata',
|
||||
'scheduler_hints',
|
||||
)
|
||||
column_headers += (
|
||||
'Availability Zone',
|
||||
'Pinned Availability Zone',
|
||||
'Host',
|
||||
'Properties',
|
||||
'Scheduler Hints',
|
||||
)
|
||||
if sdk_utils.supports_microversion(compute_client, '2.96'):
|
||||
columns += ('pinned_availability_zone',)
|
||||
column_headers += ('Pinned Availability Zone',)
|
||||
|
||||
if parsed_args.all_projects:
|
||||
columns += ('project_id',)
|
||||
@@ -2887,10 +2897,11 @@ class ListServer(command.Lister):
|
||||
column_headers += ('Availability Zone',)
|
||||
if c in (
|
||||
'pinned_availability_zone',
|
||||
"Pinned Availability Zone",
|
||||
'Pinned Availability Zone',
|
||||
):
|
||||
columns += ('Pinned Availability Zone',)
|
||||
column_headers += ('Pinned Availability Zone',)
|
||||
if sdk_utils.supports_microversion(compute_client, '2.96'):
|
||||
columns += ('pinned_availability_zone',)
|
||||
column_headers += ('Pinned Availability Zone',)
|
||||
if c in ('Host', "host"):
|
||||
columns += ('hypervisor_hostname',)
|
||||
column_headers += ('Host',)
|
||||
|
@@ -1212,7 +1212,6 @@ class TestServerCreate(TestServer):
|
||||
'locked',
|
||||
'locked_reason',
|
||||
'name',
|
||||
'pinned_availability_zone',
|
||||
'progress',
|
||||
'project_id',
|
||||
'properties',
|
||||
@@ -1261,7 +1260,6 @@ class TestServerCreate(TestServer):
|
||||
None, # locked
|
||||
None, # locked_reason
|
||||
self.server.name,
|
||||
None, # pinned_availability_zone
|
||||
None, # progress
|
||||
None, # project_id
|
||||
format_columns.DictColumn({}), # properties
|
||||
@@ -4583,7 +4581,6 @@ class _TestServerList(TestServer):
|
||||
'Flavor Name',
|
||||
'Flavor ID',
|
||||
'Availability Zone',
|
||||
'Pinned Availability Zone',
|
||||
'Host',
|
||||
'Properties',
|
||||
'Scheduler Hints',
|
||||
@@ -4732,7 +4729,6 @@ class TestServerList(_TestServerList):
|
||||
self.flavor.name,
|
||||
s.flavor['id'],
|
||||
getattr(s, 'availability_zone'),
|
||||
getattr(s, 'pinned_availability_zone', ''),
|
||||
server.HostColumn(getattr(s, 'hypervisor_hostname')),
|
||||
format_columns.DictColumn(s.metadata),
|
||||
format_columns.DictListColumn(None),
|
||||
@@ -4809,8 +4805,6 @@ class TestServerList(_TestServerList):
|
||||
'-c',
|
||||
'Availability Zone',
|
||||
'-c',
|
||||
'Pinned Availability Zone',
|
||||
'-c',
|
||||
'Host',
|
||||
'-c',
|
||||
'Properties',
|
||||
@@ -4835,7 +4829,6 @@ class TestServerList(_TestServerList):
|
||||
self.assertIn('Image ID', columns)
|
||||
self.assertIn('Flavor ID', columns)
|
||||
self.assertIn('Availability Zone', columns)
|
||||
self.assertIn('Pinned Availability Zone', columns)
|
||||
self.assertIn('Host', columns)
|
||||
self.assertIn('Properties', columns)
|
||||
self.assertIn('Scheduler Hints', columns)
|
||||
@@ -5249,7 +5242,6 @@ class TestServerList(_TestServerList):
|
||||
self.flavor.name,
|
||||
s.flavor['id'],
|
||||
getattr(s, 'availability_zone'),
|
||||
getattr(s, 'pinned_availability_zone', ''),
|
||||
server.HostColumn(getattr(s, 'hypervisor_hostname')),
|
||||
format_columns.DictColumn(s.metadata),
|
||||
format_columns.DictListColumn(s.scheduler_hints),
|
||||
@@ -5305,7 +5297,6 @@ class TestServerList(_TestServerList):
|
||||
self.flavor.name,
|
||||
s.flavor['id'],
|
||||
getattr(s, 'availability_zone'),
|
||||
getattr(s, 'pinned_availability_zone', ''),
|
||||
server.HostColumn(getattr(s, 'hypervisor_hostname')),
|
||||
format_columns.DictColumn(s.metadata),
|
||||
format_columns.DictListColumn(s.scheduler_hints),
|
||||
@@ -5343,7 +5334,6 @@ class TestServerListV273(_TestServerList):
|
||||
'Image ID',
|
||||
'Flavor',
|
||||
'Availability Zone',
|
||||
'Pinned Availability Zone',
|
||||
'Host',
|
||||
'Properties',
|
||||
'Scheduler Hints',
|
||||
@@ -5541,6 +5531,157 @@ class TestServerListV273(_TestServerList):
|
||||
self.assertEqual(expected_row, partial_server)
|
||||
|
||||
|
||||
class TestServerListV296(_TestServerList):
|
||||
columns = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Status',
|
||||
'Networks',
|
||||
'Image',
|
||||
'Flavor',
|
||||
)
|
||||
columns_long = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Status',
|
||||
'Task State',
|
||||
'Power State',
|
||||
'Networks',
|
||||
'Image Name',
|
||||
'Image ID',
|
||||
'Flavor',
|
||||
'Availability Zone',
|
||||
'Host',
|
||||
'Properties',
|
||||
'Scheduler Hints',
|
||||
'Pinned Availability Zone',
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.set_compute_api_version('2.96')
|
||||
|
||||
Image = collections.namedtuple('Image', 'id name')
|
||||
self.image_client.images.return_value = [
|
||||
Image(id=s.image['id'], name=self.image.name)
|
||||
# Image will be an empty string if boot-from-volume
|
||||
for s in self.servers
|
||||
if s.image
|
||||
]
|
||||
|
||||
Flavor = collections.namedtuple('Flavor', 'id name')
|
||||
self.compute_client.flavors.return_value = [
|
||||
Flavor(id=s.flavor['id'], name=self.flavor.name)
|
||||
for s in self.servers
|
||||
]
|
||||
|
||||
self.data = tuple(
|
||||
(
|
||||
s.id,
|
||||
s.name,
|
||||
s.status,
|
||||
server.AddressesColumn(s.addresses),
|
||||
# Image will be an empty string if boot-from-volume
|
||||
self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
|
||||
self.flavor.name,
|
||||
)
|
||||
for s in self.servers
|
||||
)
|
||||
|
||||
def test_server_list_long_option(self):
|
||||
self.data = tuple(
|
||||
(
|
||||
s.id,
|
||||
s.name,
|
||||
s.status,
|
||||
getattr(s, 'task_state'),
|
||||
server.PowerStateColumn(getattr(s, 'power_state')),
|
||||
server.AddressesColumn(s.addresses),
|
||||
# Image will be an empty string if boot-from-volume
|
||||
self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
|
||||
s.image['id'] if s.image else server.IMAGE_STRING_FOR_BFV,
|
||||
self.flavor.name,
|
||||
getattr(s, 'availability_zone'),
|
||||
server.HostColumn(getattr(s, 'hypervisor_hostname')),
|
||||
format_columns.DictColumn(s.metadata),
|
||||
format_columns.DictListColumn(None),
|
||||
getattr(s, 'pinned_availability_zone', ''),
|
||||
)
|
||||
for s in self.servers
|
||||
)
|
||||
arglist = [
|
||||
'--long',
|
||||
]
|
||||
verifylist = [
|
||||
('all_projects', False),
|
||||
('long', True),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.compute_client.servers.assert_called_with(**self.kwargs)
|
||||
image_ids = {s.image['id'] for s in self.servers if s.image}
|
||||
self.image_client.images.assert_called_once_with(
|
||||
id=f'in:{",".join(image_ids)}',
|
||||
)
|
||||
self.compute_client.flavors.assert_called_once_with(is_public=None)
|
||||
self.assertEqual(self.columns_long, columns)
|
||||
self.assertEqual(self.data, tuple(data))
|
||||
|
||||
def test_server_list_column_option(self):
|
||||
arglist = [
|
||||
'-c',
|
||||
'Project ID',
|
||||
'-c',
|
||||
'User ID',
|
||||
'-c',
|
||||
'Created At',
|
||||
'-c',
|
||||
'Security Groups',
|
||||
'-c',
|
||||
'Task State',
|
||||
'-c',
|
||||
'Power State',
|
||||
'-c',
|
||||
'Image ID',
|
||||
'-c',
|
||||
'Flavor ID',
|
||||
'-c',
|
||||
'Availability Zone',
|
||||
'-c',
|
||||
'Host',
|
||||
'-c',
|
||||
'Properties',
|
||||
'-c',
|
||||
'Scheduler Hints',
|
||||
'-c',
|
||||
'Pinned Availability Zone',
|
||||
'--long',
|
||||
]
|
||||
verifylist = [
|
||||
('long', True),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.compute_client.servers.assert_called_with(**self.kwargs)
|
||||
self.assertIn('Project ID', columns)
|
||||
self.assertIn('User ID', columns)
|
||||
self.assertIn('Created At', columns)
|
||||
self.assertIn('Security Groups', columns)
|
||||
self.assertIn('Task State', columns)
|
||||
self.assertIn('Power State', columns)
|
||||
self.assertIn('Image ID', columns)
|
||||
self.assertIn('Flavor ID', columns)
|
||||
self.assertIn('Availability Zone', columns)
|
||||
self.assertIn('Pinned Availability Zone', columns)
|
||||
self.assertIn('Host', columns)
|
||||
self.assertIn('Properties', columns)
|
||||
self.assertIn('Scheduler Hints', columns)
|
||||
self.assertCountEqual(columns, set(columns))
|
||||
|
||||
|
||||
class TestServerAction(compute_fakes.TestComputev2):
|
||||
def run_method_with_sdk_servers(self, method_name, server_count):
|
||||
servers = compute_fakes.create_servers(count=server_count)
|
||||
@@ -8533,7 +8674,6 @@ class TestServerShow(TestServer):
|
||||
'locked',
|
||||
'locked_reason',
|
||||
'name',
|
||||
'pinned_availability_zone',
|
||||
'progress',
|
||||
'project_id',
|
||||
'properties',
|
||||
@@ -8583,7 +8723,6 @@ class TestServerShow(TestServer):
|
||||
None, # locked
|
||||
None, # locked_reason
|
||||
self.server.name,
|
||||
None, # pinned_availability_zone
|
||||
None, # progress
|
||||
'tenant-id-xxx', # project_id
|
||||
format_columns.DictColumn({}), # properties
|
||||
@@ -9522,7 +9661,6 @@ class TestServerGeneral(TestServer):
|
||||
'locked': None,
|
||||
'locked_reason': None,
|
||||
'name': _server.name,
|
||||
'pinned_availability_zone': None,
|
||||
'progress': None,
|
||||
'project_id': 'tenant-id-xxx',
|
||||
'properties': format_columns.DictColumn({}),
|
||||
@@ -9609,7 +9747,6 @@ class TestServerGeneral(TestServer):
|
||||
'locked': None,
|
||||
'locked_reason': None,
|
||||
'name': _server.name,
|
||||
'pinned_availability_zone': None,
|
||||
'progress': None,
|
||||
'project_id': 'tenant-id-xxx',
|
||||
'properties': format_columns.DictColumn({}),
|
||||
|
Reference in New Issue
Block a user