Skip to content

Commit dbddbf9

Browse files
committed
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>
1 parent 34f431b commit dbddbf9

File tree

2 files changed

+168
-20
lines changed

2 files changed

+168
-20
lines changed

openstackclient/compute/v2/server.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,13 @@ def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
183183
'updated_at': 'updated',
184184
'user_data': 'OS-EXT-SRV-ATTR:user_data',
185185
'vm_state': 'OS-EXT-STS:vm_state',
186-
'pinned_availability_zone': 'pinned_availability_zone',
187186
'scheduler_hints': 'scheduler_hints',
188187
}
188+
# NOTE(ratailor): microversion 2.96 introduces
189+
# pinned_availability_zone support
190+
if sdk_utils.supports_microversion(compute_client, '2.96'):
191+
column_map['pinned_availability_zone'] = 'pinned_availability_zone'
192+
189193
# Some columns returned by openstacksdk should not be shown because they're
190194
# either irrelevant or duplicates
191195
ignored_columns = {
@@ -240,6 +244,11 @@ def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
240244
if not sdk_utils.supports_microversion(compute_client, '2.100'):
241245
info.pop('scheduler_hints', None)
242246

247+
# NOTE(ratailor): microversion 2.96 introduces
248+
# pinned_availability_zone support
249+
if not sdk_utils.supports_microversion(compute_client, '2.96'):
250+
info.pop('pinned_availability_zone', None)
251+
243252
# Convert the image blob to a name
244253
image_info = info.get('image', {})
245254
if image_info and any(image_info.values()):
@@ -2838,18 +2847,19 @@ def take_action(self, parsed_args):
28382847
if parsed_args.long:
28392848
columns += (
28402849
'availability_zone',
2841-
'pinned_availability_zone',
28422850
'hypervisor_hostname',
28432851
'metadata',
28442852
'scheduler_hints',
28452853
)
28462854
column_headers += (
28472855
'Availability Zone',
2848-
'Pinned Availability Zone',
28492856
'Host',
28502857
'Properties',
28512858
'Scheduler Hints',
28522859
)
2860+
if sdk_utils.supports_microversion(compute_client, '2.96'):
2861+
columns += ('pinned_availability_zone',)
2862+
column_headers += ('Pinned Availability Zone',)
28532863

28542864
if parsed_args.all_projects:
28552865
columns += ('project_id',)
@@ -2887,10 +2897,11 @@ def take_action(self, parsed_args):
28872897
column_headers += ('Availability Zone',)
28882898
if c in (
28892899
'pinned_availability_zone',
2890-
"Pinned Availability Zone",
2900+
'Pinned Availability Zone',
28912901
):
2892-
columns += ('Pinned Availability Zone',)
2893-
column_headers += ('Pinned Availability Zone',)
2902+
if sdk_utils.supports_microversion(compute_client, '2.96'):
2903+
columns += ('pinned_availability_zone',)
2904+
column_headers += ('Pinned Availability Zone',)
28942905
if c in ('Host', "host"):
28952906
columns += ('hypervisor_hostname',)
28962907
column_headers += ('Host',)

openstackclient/tests/unit/compute/v2/test_server.py

Lines changed: 151 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,6 @@ class TestServerCreate(TestServer):
12121212
'locked',
12131213
'locked_reason',
12141214
'name',
1215-
'pinned_availability_zone',
12161215
'progress',
12171216
'project_id',
12181217
'properties',
@@ -1261,7 +1260,6 @@ def datalist(self):
12611260
None, # locked
12621261
None, # locked_reason
12631262
self.server.name,
1264-
None, # pinned_availability_zone
12651263
None, # progress
12661264
None, # project_id
12671265
format_columns.DictColumn({}), # properties
@@ -4583,7 +4581,6 @@ class _TestServerList(TestServer):
45834581
'Flavor Name',
45844582
'Flavor ID',
45854583
'Availability Zone',
4586-
'Pinned Availability Zone',
45874584
'Host',
45884585
'Properties',
45894586
'Scheduler Hints',
@@ -4732,7 +4729,6 @@ def test_server_list_long_option(self):
47324729
self.flavor.name,
47334730
s.flavor['id'],
47344731
getattr(s, 'availability_zone'),
4735-
getattr(s, 'pinned_availability_zone', ''),
47364732
server.HostColumn(getattr(s, 'hypervisor_hostname')),
47374733
format_columns.DictColumn(s.metadata),
47384734
format_columns.DictListColumn(None),
@@ -4809,8 +4805,6 @@ def test_server_list_column_option(self):
48094805
'-c',
48104806
'Availability Zone',
48114807
'-c',
4812-
'Pinned Availability Zone',
4813-
'-c',
48144808
'Host',
48154809
'-c',
48164810
'Properties',
@@ -4835,7 +4829,6 @@ def test_server_list_column_option(self):
48354829
self.assertIn('Image ID', columns)
48364830
self.assertIn('Flavor ID', columns)
48374831
self.assertIn('Availability Zone', columns)
4838-
self.assertIn('Pinned Availability Zone', columns)
48394832
self.assertIn('Host', columns)
48404833
self.assertIn('Properties', columns)
48414834
self.assertIn('Scheduler Hints', columns)
@@ -5249,7 +5242,6 @@ def test_server_list_long_with_host_status_v216(self):
52495242
self.flavor.name,
52505243
s.flavor['id'],
52515244
getattr(s, 'availability_zone'),
5252-
getattr(s, 'pinned_availability_zone', ''),
52535245
server.HostColumn(getattr(s, 'hypervisor_hostname')),
52545246
format_columns.DictColumn(s.metadata),
52555247
format_columns.DictListColumn(s.scheduler_hints),
@@ -5305,7 +5297,6 @@ def test_server_list_long_with_host_status_v216(self):
53055297
self.flavor.name,
53065298
s.flavor['id'],
53075299
getattr(s, 'availability_zone'),
5308-
getattr(s, 'pinned_availability_zone', ''),
53095300
server.HostColumn(getattr(s, 'hypervisor_hostname')),
53105301
format_columns.DictColumn(s.metadata),
53115302
format_columns.DictListColumn(s.scheduler_hints),
@@ -5343,7 +5334,6 @@ class TestServerListV273(_TestServerList):
53435334
'Image ID',
53445335
'Flavor',
53455336
'Availability Zone',
5346-
'Pinned Availability Zone',
53475337
'Host',
53485338
'Properties',
53495339
'Scheduler Hints',
@@ -5541,6 +5531,157 @@ def test_server_list_v269_with_partial_constructs(self):
55415531
self.assertEqual(expected_row, partial_server)
55425532

55435533

5534+
class TestServerListV296(_TestServerList):
5535+
columns = (
5536+
'ID',
5537+
'Name',
5538+
'Status',
5539+
'Networks',
5540+
'Image',
5541+
'Flavor',
5542+
)
5543+
columns_long = (
5544+
'ID',
5545+
'Name',
5546+
'Status',
5547+
'Task State',
5548+
'Power State',
5549+
'Networks',
5550+
'Image Name',
5551+
'Image ID',
5552+
'Flavor',
5553+
'Availability Zone',
5554+
'Host',
5555+
'Properties',
5556+
'Scheduler Hints',
5557+
'Pinned Availability Zone',
5558+
)
5559+
5560+
def setUp(self):
5561+
super().setUp()
5562+
self.set_compute_api_version('2.96')
5563+
5564+
Image = collections.namedtuple('Image', 'id name')
5565+
self.image_client.images.return_value = [
5566+
Image(id=s.image['id'], name=self.image.name)
5567+
# Image will be an empty string if boot-from-volume
5568+
for s in self.servers
5569+
if s.image
5570+
]
5571+
5572+
Flavor = collections.namedtuple('Flavor', 'id name')
5573+
self.compute_client.flavors.return_value = [
5574+
Flavor(id=s.flavor['id'], name=self.flavor.name)
5575+
for s in self.servers
5576+
]
5577+
5578+
self.data = tuple(
5579+
(
5580+
s.id,
5581+
s.name,
5582+
s.status,
5583+
server.AddressesColumn(s.addresses),
5584+
# Image will be an empty string if boot-from-volume
5585+
self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
5586+
self.flavor.name,
5587+
)
5588+
for s in self.servers
5589+
)
5590+
5591+
def test_server_list_long_option(self):
5592+
self.data = tuple(
5593+
(
5594+
s.id,
5595+
s.name,
5596+
s.status,
5597+
getattr(s, 'task_state'),
5598+
server.PowerStateColumn(getattr(s, 'power_state')),
5599+
server.AddressesColumn(s.addresses),
5600+
# Image will be an empty string if boot-from-volume
5601+
self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
5602+
s.image['id'] if s.image else server.IMAGE_STRING_FOR_BFV,
5603+
self.flavor.name,
5604+
getattr(s, 'availability_zone'),
5605+
server.HostColumn(getattr(s, 'hypervisor_hostname')),
5606+
format_columns.DictColumn(s.metadata),
5607+
format_columns.DictListColumn(None),
5608+
getattr(s, 'pinned_availability_zone', ''),
5609+
)
5610+
for s in self.servers
5611+
)
5612+
arglist = [
5613+
'--long',
5614+
]
5615+
verifylist = [
5616+
('all_projects', False),
5617+
('long', True),
5618+
]
5619+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
5620+
5621+
columns, data = self.cmd.take_action(parsed_args)
5622+
self.compute_client.servers.assert_called_with(**self.kwargs)
5623+
image_ids = {s.image['id'] for s in self.servers if s.image}
5624+
self.image_client.images.assert_called_once_with(
5625+
id=f'in:{",".join(image_ids)}',
5626+
)
5627+
self.compute_client.flavors.assert_called_once_with(is_public=None)
5628+
self.assertEqual(self.columns_long, columns)
5629+
self.assertEqual(self.data, tuple(data))
5630+
5631+
def test_server_list_column_option(self):
5632+
arglist = [
5633+
'-c',
5634+
'Project ID',
5635+
'-c',
5636+
'User ID',
5637+
'-c',
5638+
'Created At',
5639+
'-c',
5640+
'Security Groups',
5641+
'-c',
5642+
'Task State',
5643+
'-c',
5644+
'Power State',
5645+
'-c',
5646+
'Image ID',
5647+
'-c',
5648+
'Flavor ID',
5649+
'-c',
5650+
'Availability Zone',
5651+
'-c',
5652+
'Host',
5653+
'-c',
5654+
'Properties',
5655+
'-c',
5656+
'Scheduler Hints',
5657+
'-c',
5658+
'Pinned Availability Zone',
5659+
'--long',
5660+
]
5661+
verifylist = [
5662+
('long', True),
5663+
]
5664+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
5665+
5666+
columns, data = self.cmd.take_action(parsed_args)
5667+
5668+
self.compute_client.servers.assert_called_with(**self.kwargs)
5669+
self.assertIn('Project ID', columns)
5670+
self.assertIn('User ID', columns)
5671+
self.assertIn('Created At', columns)
5672+
self.assertIn('Security Groups', columns)
5673+
self.assertIn('Task State', columns)
5674+
self.assertIn('Power State', columns)
5675+
self.assertIn('Image ID', columns)
5676+
self.assertIn('Flavor ID', columns)
5677+
self.assertIn('Availability Zone', columns)
5678+
self.assertIn('Pinned Availability Zone', columns)
5679+
self.assertIn('Host', columns)
5680+
self.assertIn('Properties', columns)
5681+
self.assertIn('Scheduler Hints', columns)
5682+
self.assertCountEqual(columns, set(columns))
5683+
5684+
55445685
class TestServerAction(compute_fakes.TestComputev2):
55455686
def run_method_with_sdk_servers(self, method_name, server_count):
55465687
servers = compute_fakes.create_servers(count=server_count)
@@ -8533,7 +8674,6 @@ def setUp(self):
85338674
'locked',
85348675
'locked_reason',
85358676
'name',
8536-
'pinned_availability_zone',
85378677
'progress',
85388678
'project_id',
85398679
'properties',
@@ -8583,7 +8723,6 @@ def setUp(self):
85838723
None, # locked
85848724
None, # locked_reason
85858725
self.server.name,
8586-
None, # pinned_availability_zone
85878726
None, # progress
85888727
'tenant-id-xxx', # project_id
85898728
format_columns.DictColumn({}), # properties
@@ -9522,7 +9661,6 @@ def test_prep_server_detail(self):
95229661
'locked': None,
95239662
'locked_reason': None,
95249663
'name': _server.name,
9525-
'pinned_availability_zone': None,
95269664
'progress': None,
95279665
'project_id': 'tenant-id-xxx',
95289666
'properties': format_columns.DictColumn({}),
@@ -9609,7 +9747,6 @@ def test_prep_server_detail_v247(self):
96099747
'locked': None,
96109748
'locked_reason': None,
96119749
'name': _server.name,
9612-
'pinned_availability_zone': None,
96139750
'progress': None,
96149751
'project_id': 'tenant-id-xxx',
96159752
'properties': format_columns.DictColumn({}),

0 commit comments

Comments
 (0)