python-openstackclient 7.0.0__py3-none-any.whl → 7.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openstackclient/common/clientmanager.py +22 -30
- openstackclient/common/limits.py +3 -4
- openstackclient/common/quota.py +28 -23
- openstackclient/compute/v2/aggregate.py +29 -23
- openstackclient/compute/v2/hypervisor.py +5 -3
- openstackclient/compute/v2/server.py +5 -4
- openstackclient/identity/v3/application_credential.py +17 -17
- openstackclient/identity/v3/service.py +5 -5
- openstackclient/releasenotes/notes/volume-backup-created-at-list-b49ec893ae1f6b0d.yaml +4 -0
- openstackclient/tests/functional/identity/v3/common.py +2 -2
- openstackclient/tests/functional/identity/v3/test_application_credential.py +7 -7
- openstackclient/tests/functional/identity/v3/test_limit.py +2 -2
- openstackclient/tests/functional/identity/v3/test_registered_limit.py +1 -1
- openstackclient/tests/functional/identity/v3/test_service.py +3 -3
- openstackclient/tests/unit/compute/v2/test_aggregate.py +70 -42
- openstackclient/tests/unit/compute/v2/test_hypervisor.py +29 -3
- openstackclient/tests/unit/compute/v2/test_server.py +23 -62
- openstackclient/tests/unit/fakes.py +1 -1
- openstackclient/tests/unit/identity/v3/test_application_credential.py +17 -17
- openstackclient/tests/unit/identity/v3/test_service.py +6 -6
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +3 -0
- openstackclient/volume/v2/volume_backup.py +2 -0
- {python_openstackclient-7.0.0.dist-info → python_openstackclient-7.1.1.dist-info}/AUTHORS +2 -0
- {python_openstackclient-7.0.0.dist-info → python_openstackclient-7.1.1.dist-info}/METADATA +3 -2
- {python_openstackclient-7.0.0.dist-info → python_openstackclient-7.1.1.dist-info}/RECORD +30 -29
- python_openstackclient-7.1.1.dist-info/pbr.json +1 -0
- python_openstackclient-7.0.0.dist-info/pbr.json +0 -1
- {python_openstackclient-7.0.0.dist-info → python_openstackclient-7.1.1.dist-info}/LICENSE +0 -0
- {python_openstackclient-7.0.0.dist-info → python_openstackclient-7.1.1.dist-info}/WHEEL +0 -0
- {python_openstackclient-7.0.0.dist-info → python_openstackclient-7.1.1.dist-info}/entry_points.txt +0 -0
- {python_openstackclient-7.0.0.dist-info → python_openstackclient-7.1.1.dist-info}/top_level.txt +0 -0
|
@@ -116,7 +116,6 @@ class ClientManager(clientmanager.ClientManager):
|
|
|
116
116
|
|
|
117
117
|
def is_network_endpoint_enabled(self):
|
|
118
118
|
"""Check if the network endpoint is enabled"""
|
|
119
|
-
|
|
120
119
|
# NOTE(dtroyer): is_service_available() can also return None if
|
|
121
120
|
# there is no Service Catalog, callers here are
|
|
122
121
|
# not expecting that so fold None into True to
|
|
@@ -125,43 +124,37 @@ class ClientManager(clientmanager.ClientManager):
|
|
|
125
124
|
|
|
126
125
|
def is_compute_endpoint_enabled(self):
|
|
127
126
|
"""Check if Compute endpoint is enabled"""
|
|
128
|
-
|
|
129
127
|
return self.is_service_available('compute') is not False
|
|
130
128
|
|
|
131
|
-
|
|
129
|
+
# TODO(stephenfin): Drop volume_client argument in OSC 8.0 or later.
|
|
130
|
+
def is_volume_endpoint_enabled(self, volume_client=None):
|
|
132
131
|
"""Check if volume endpoint is enabled"""
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
# for v3 it is a tuple (3, 0)
|
|
139
|
-
if endpoint_data.api_version and isinstance(
|
|
140
|
-
endpoint_data.api_version, tuple
|
|
141
|
-
):
|
|
142
|
-
volume_version = endpoint_data.api_version[0]
|
|
143
|
-
else:
|
|
144
|
-
# Setting volume_version as 2 here if it doesn't satisfy the
|
|
145
|
-
# conditions for version 3
|
|
146
|
-
volume_version = 2
|
|
147
|
-
if (
|
|
148
|
-
self.is_service_available("volumev%s" % volume_version)
|
|
149
|
-
is not False
|
|
150
|
-
):
|
|
151
|
-
return True
|
|
152
|
-
elif self.is_service_available('volume') is not False:
|
|
153
|
-
return True
|
|
154
|
-
else:
|
|
155
|
-
return False
|
|
132
|
+
return (
|
|
133
|
+
self.is_service_available('volume') is not False
|
|
134
|
+
or self.is_service_available('volumev3') is not False
|
|
135
|
+
or self.is_service_available('volumev2') is not False
|
|
136
|
+
)
|
|
156
137
|
|
|
157
138
|
|
|
158
139
|
# Plugin Support
|
|
159
140
|
|
|
160
141
|
|
|
142
|
+
def _on_load_failure_callback(
|
|
143
|
+
manager: stevedore.ExtensionManager,
|
|
144
|
+
ep: importlib.metadata.EntryPoint,
|
|
145
|
+
err: Exception,
|
|
146
|
+
) -> None:
|
|
147
|
+
sys.stderr.write(
|
|
148
|
+
f"WARNING: Failed to import plugin {ep.group}:{ep.name}: {err}.\n"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
161
152
|
def get_plugin_modules(group):
|
|
162
153
|
"""Find plugin entry points"""
|
|
163
154
|
mod_list = []
|
|
164
|
-
mgr = stevedore.ExtensionManager(
|
|
155
|
+
mgr = stevedore.ExtensionManager(
|
|
156
|
+
group, on_load_failure_callback=_on_load_failure_callback
|
|
157
|
+
)
|
|
165
158
|
for ep in mgr:
|
|
166
159
|
LOG.debug('Found plugin %s', ep.name)
|
|
167
160
|
|
|
@@ -180,9 +173,8 @@ def get_plugin_modules(group):
|
|
|
180
173
|
module = importlib.import_module(module_name)
|
|
181
174
|
except Exception as err:
|
|
182
175
|
sys.stderr.write(
|
|
183
|
-
"WARNING: Failed to import plugin {}:
|
|
184
|
-
|
|
185
|
-
)
|
|
176
|
+
f"WARNING: Failed to import plugin {ep.group}:{ep.name}: "
|
|
177
|
+
f"{err}.\n"
|
|
186
178
|
)
|
|
187
179
|
continue
|
|
188
180
|
|
openstackclient/common/limits.py
CHANGED
|
@@ -101,9 +101,6 @@ class ShowLimits(command.Lister):
|
|
|
101
101
|
return parser
|
|
102
102
|
|
|
103
103
|
def take_action(self, parsed_args):
|
|
104
|
-
compute_client = self.app.client_manager.sdk_connection.compute
|
|
105
|
-
volume_client = self.app.client_manager.sdk_connection.volume
|
|
106
|
-
|
|
107
104
|
project_id = None
|
|
108
105
|
if parsed_args.project is not None:
|
|
109
106
|
identity_client = self.app.client_manager.identity
|
|
@@ -125,11 +122,13 @@ class ShowLimits(command.Lister):
|
|
|
125
122
|
volume_limits = None
|
|
126
123
|
|
|
127
124
|
if self.app.client_manager.is_compute_endpoint_enabled():
|
|
125
|
+
compute_client = self.app.client_manager.sdk_connection.compute
|
|
128
126
|
compute_limits = compute_client.get_limits(
|
|
129
127
|
reserved=parsed_args.is_reserved, tenant_id=project_id
|
|
130
128
|
)
|
|
131
129
|
|
|
132
|
-
if self.app.client_manager.is_volume_endpoint_enabled(
|
|
130
|
+
if self.app.client_manager.is_volume_endpoint_enabled():
|
|
131
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
133
132
|
volume_limits = volume_client.get_limits(
|
|
134
133
|
project_id=project_id,
|
|
135
134
|
)
|
openstackclient/common/quota.py
CHANGED
|
@@ -565,33 +565,42 @@ class SetQuota(common.NetDetectionMixin, command.Command):
|
|
|
565
565
|
msg = _('--force cannot be used with --class or --default')
|
|
566
566
|
raise exceptions.CommandError(msg)
|
|
567
567
|
|
|
568
|
-
compute_client = self.app.client_manager.sdk_connection.compute
|
|
569
|
-
volume_client = self.app.client_manager.sdk_connection.volume
|
|
570
|
-
|
|
571
568
|
compute_kwargs = {}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
if value is not None:
|
|
575
|
-
compute_kwargs[k] = value
|
|
569
|
+
volume_kwargs = {}
|
|
570
|
+
network_kwargs = {}
|
|
576
571
|
|
|
577
|
-
if
|
|
578
|
-
|
|
572
|
+
if self.app.client_manager.is_compute_endpoint_enabled():
|
|
573
|
+
compute_client = self.app.client_manager.sdk_connection.compute
|
|
579
574
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
575
|
+
for k, v in COMPUTE_QUOTAS.items():
|
|
576
|
+
value = getattr(parsed_args, k, None)
|
|
577
|
+
if value is not None:
|
|
578
|
+
compute_kwargs[k] = value
|
|
579
|
+
|
|
580
|
+
if compute_kwargs and parsed_args.force is True:
|
|
581
|
+
compute_kwargs['force'] = parsed_args.force
|
|
582
|
+
|
|
583
|
+
if self.app.client_manager.is_volume_endpoint_enabled():
|
|
584
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
585
|
+
|
|
586
|
+
for k, v in VOLUME_QUOTAS.items():
|
|
587
|
+
value = getattr(parsed_args, k, None)
|
|
588
|
+
if value is not None:
|
|
589
|
+
if (
|
|
590
|
+
parsed_args.volume_type
|
|
591
|
+
and k in IMPACT_VOLUME_TYPE_QUOTAS
|
|
592
|
+
):
|
|
593
|
+
k = k + '_%s' % parsed_args.volume_type
|
|
594
|
+
volume_kwargs[k] = value
|
|
587
595
|
|
|
588
|
-
network_kwargs = {}
|
|
589
596
|
if self.app.client_manager.is_network_endpoint_enabled():
|
|
597
|
+
network_client = self.app.client_manager.network
|
|
598
|
+
|
|
590
599
|
for k, v in NETWORK_QUOTAS.items():
|
|
591
600
|
value = getattr(parsed_args, k, None)
|
|
592
601
|
if value is not None:
|
|
593
602
|
network_kwargs[k] = value
|
|
594
|
-
|
|
603
|
+
elif self.app.client_manager.is_compute_endpoint_enabled():
|
|
595
604
|
for k, v in NOVA_NETWORK_QUOTAS.items():
|
|
596
605
|
value = getattr(parsed_args, k, None)
|
|
597
606
|
if value is not None:
|
|
@@ -632,11 +641,7 @@ class SetQuota(common.NetDetectionMixin, command.Command):
|
|
|
632
641
|
compute_client.update_quota_set(project, **compute_kwargs)
|
|
633
642
|
if volume_kwargs:
|
|
634
643
|
volume_client.update_quota_set(project, **volume_kwargs)
|
|
635
|
-
if
|
|
636
|
-
network_kwargs
|
|
637
|
-
and self.app.client_manager.is_network_endpoint_enabled()
|
|
638
|
-
):
|
|
639
|
-
network_client = self.app.client_manager.network
|
|
644
|
+
if network_kwargs:
|
|
640
645
|
network_client.update_quota(project, **network_kwargs)
|
|
641
646
|
|
|
642
647
|
|
|
@@ -192,40 +192,46 @@ class ListAggregate(command.Lister):
|
|
|
192
192
|
|
|
193
193
|
aggregates = list(compute_client.aggregates())
|
|
194
194
|
|
|
195
|
+
if sdk_utils.supports_microversion(compute_client, '2.41'):
|
|
196
|
+
column_headers = ("ID", "UUID")
|
|
197
|
+
columns = ("id", "uuid")
|
|
198
|
+
else:
|
|
199
|
+
column_headers = ("ID",)
|
|
200
|
+
columns = ("id",)
|
|
201
|
+
|
|
202
|
+
column_headers += (
|
|
203
|
+
"Name",
|
|
204
|
+
"Availability Zone",
|
|
205
|
+
)
|
|
206
|
+
columns += (
|
|
207
|
+
"name",
|
|
208
|
+
"availability_zone",
|
|
209
|
+
)
|
|
210
|
+
|
|
195
211
|
if parsed_args.long:
|
|
196
212
|
# Remove availability_zone from metadata because Nova doesn't
|
|
197
213
|
for aggregate in aggregates:
|
|
198
214
|
if 'availability_zone' in aggregate.metadata:
|
|
199
215
|
aggregate.metadata.pop('availability_zone')
|
|
200
|
-
|
|
201
|
-
column_headers
|
|
202
|
-
"ID",
|
|
203
|
-
"Name",
|
|
204
|
-
"Availability Zone",
|
|
216
|
+
|
|
217
|
+
column_headers += (
|
|
205
218
|
"Properties",
|
|
206
219
|
"Hosts",
|
|
207
220
|
)
|
|
208
|
-
columns
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"Availability Zone",
|
|
212
|
-
"Metadata",
|
|
213
|
-
"Hosts",
|
|
214
|
-
)
|
|
215
|
-
else:
|
|
216
|
-
column_headers = columns = (
|
|
217
|
-
"ID",
|
|
218
|
-
"Name",
|
|
219
|
-
"Availability Zone",
|
|
221
|
+
columns += (
|
|
222
|
+
"metadata",
|
|
223
|
+
"hosts",
|
|
220
224
|
)
|
|
221
225
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
226
|
+
return (
|
|
227
|
+
column_headers,
|
|
228
|
+
(
|
|
229
|
+
utils.get_item_properties(
|
|
230
|
+
s, columns, formatters=_aggregate_formatters
|
|
231
|
+
)
|
|
232
|
+
for s in aggregates
|
|
233
|
+
),
|
|
227
234
|
)
|
|
228
|
-
return (column_headers, data)
|
|
229
235
|
|
|
230
236
|
|
|
231
237
|
class RemoveAggregateHost(command.ShowOne):
|
|
@@ -165,9 +165,11 @@ class ShowHypervisor(command.ShowOne):
|
|
|
165
165
|
|
|
166
166
|
def take_action(self, parsed_args):
|
|
167
167
|
compute_client = self.app.client_manager.sdk_connection.compute
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
|
|
169
|
+
hypervisor_id = compute_client.find_hypervisor(
|
|
170
|
+
parsed_args.hypervisor, ignore_missing=False, details=False
|
|
171
|
+
).id
|
|
172
|
+
hypervisor = compute_client.get_hypervisor(hypervisor_id).copy()
|
|
171
173
|
|
|
172
174
|
# Some of the properties in the hypervisor object need to be processed
|
|
173
175
|
# before they get reported to the user. We spend this section
|
|
@@ -3587,6 +3587,9 @@ class RebuildServer(command.ShowOne):
|
|
|
3587
3587
|
if parsed_args.name is not None:
|
|
3588
3588
|
kwargs['name'] = parsed_args.name
|
|
3589
3589
|
|
|
3590
|
+
if parsed_args.password is not None:
|
|
3591
|
+
kwargs['admin_password'] = parsed_args.password
|
|
3592
|
+
|
|
3590
3593
|
if parsed_args.preserve_ephemeral is not None:
|
|
3591
3594
|
kwargs['preserve_ephemeral'] = parsed_args.preserve_ephemeral
|
|
3592
3595
|
|
|
@@ -3725,9 +3728,7 @@ class RebuildServer(command.ShowOne):
|
|
|
3725
3728
|
msg = _("The server status is not ACTIVE, SHUTOFF or ERROR.")
|
|
3726
3729
|
raise exceptions.CommandError(msg)
|
|
3727
3730
|
|
|
3728
|
-
server = compute_client.rebuild_server(
|
|
3729
|
-
server, image, admin_password=parsed_args.password, **kwargs
|
|
3730
|
-
)
|
|
3731
|
+
server = compute_client.rebuild_server(server, image, **kwargs)
|
|
3731
3732
|
|
|
3732
3733
|
if parsed_args.wait:
|
|
3733
3734
|
if utils.wait_for_status(
|
|
@@ -3839,7 +3840,7 @@ host."""
|
|
|
3839
3840
|
|
|
3840
3841
|
kwargs = {
|
|
3841
3842
|
'host': parsed_args.host,
|
|
3842
|
-
'
|
|
3843
|
+
'admin_password': parsed_args.password,
|
|
3843
3844
|
}
|
|
3844
3845
|
|
|
3845
3846
|
if not sdk_utils.supports_microversion(compute_client, '2.14'):
|
|
@@ -186,15 +186,15 @@ class CreateApplicationCredential(command.ShowOne):
|
|
|
186
186
|
application_credential['roles'] = msg
|
|
187
187
|
|
|
188
188
|
columns = (
|
|
189
|
-
'
|
|
190
|
-
'
|
|
191
|
-
'
|
|
192
|
-
'
|
|
193
|
-
'
|
|
194
|
-
'
|
|
195
|
-
'
|
|
196
|
-
'
|
|
197
|
-
'
|
|
189
|
+
'id',
|
|
190
|
+
'name',
|
|
191
|
+
'description',
|
|
192
|
+
'project_id',
|
|
193
|
+
'roles',
|
|
194
|
+
'unrestricted',
|
|
195
|
+
'access_rules',
|
|
196
|
+
'expires_at',
|
|
197
|
+
'secret',
|
|
198
198
|
)
|
|
199
199
|
return (
|
|
200
200
|
columns,
|
|
@@ -337,14 +337,14 @@ class ShowApplicationCredential(command.ShowOne):
|
|
|
337
337
|
app_cred['roles'] = msg
|
|
338
338
|
|
|
339
339
|
columns = (
|
|
340
|
-
'
|
|
341
|
-
'
|
|
342
|
-
'
|
|
343
|
-
'
|
|
344
|
-
'
|
|
345
|
-
'
|
|
346
|
-
'
|
|
347
|
-
'
|
|
340
|
+
'id',
|
|
341
|
+
'name',
|
|
342
|
+
'description',
|
|
343
|
+
'project_id',
|
|
344
|
+
'roles',
|
|
345
|
+
'unrestricted',
|
|
346
|
+
'access_rules',
|
|
347
|
+
'expires_at',
|
|
348
348
|
)
|
|
349
349
|
return (
|
|
350
350
|
columns,
|
|
@@ -48,7 +48,7 @@ class IdentityTests(base.TestCase):
|
|
|
48
48
|
'parent_id',
|
|
49
49
|
]
|
|
50
50
|
ROLE_FIELDS = ['id', 'name', 'domain_id', 'description']
|
|
51
|
-
SERVICE_FIELDS = ['
|
|
51
|
+
SERVICE_FIELDS = ['id', 'enabled', 'name', 'type', 'description']
|
|
52
52
|
REGION_FIELDS = ['description', 'enabled', 'parent_region', 'region']
|
|
53
53
|
ENDPOINT_FIELDS = [
|
|
54
54
|
'id',
|
|
@@ -376,7 +376,7 @@ class IdentityTests(base.TestCase):
|
|
|
376
376
|
if add_clean_up:
|
|
377
377
|
service = self.parse_show_as_object(raw_output)
|
|
378
378
|
self.addCleanup(
|
|
379
|
-
self.openstack, 'service delete %s' % service['
|
|
379
|
+
self.openstack, 'service delete %s' % service['id']
|
|
380
380
|
)
|
|
381
381
|
items = self.parse_show(raw_output)
|
|
382
382
|
self.assert_show_fields(items, self.SERVICE_FIELDS)
|
|
@@ -21,13 +21,13 @@ from openstackclient.tests.functional.identity.v3 import common
|
|
|
21
21
|
|
|
22
22
|
class ApplicationCredentialTests(common.IdentityTests):
|
|
23
23
|
APPLICATION_CREDENTIAL_FIELDS = [
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'
|
|
24
|
+
'id',
|
|
25
|
+
'name',
|
|
26
|
+
'project_id',
|
|
27
|
+
'description',
|
|
28
|
+
'roles',
|
|
29
|
+
'expires_at',
|
|
30
|
+
'unrestricted',
|
|
31
31
|
]
|
|
32
32
|
APPLICATION_CREDENTIAL_LIST_HEADERS = [
|
|
33
33
|
'ID',
|
|
@@ -32,7 +32,7 @@ class LimitTestCase(common.IdentityTests):
|
|
|
32
32
|
|
|
33
33
|
raw_output = self.openstack('service show %s' % service_id)
|
|
34
34
|
items = self.parse_show(raw_output)
|
|
35
|
-
service_name = self._extract_value_from_items('
|
|
35
|
+
service_name = self._extract_value_from_items('name', items)
|
|
36
36
|
|
|
37
37
|
project_name = self._create_dummy_project()
|
|
38
38
|
raw_output = self.openstack('project show %s' % project_name)
|
|
@@ -73,7 +73,7 @@ class LimitTestCase(common.IdentityTests):
|
|
|
73
73
|
|
|
74
74
|
raw_output = self.openstack('service show %s' % service_id)
|
|
75
75
|
items = self.parse_show(raw_output)
|
|
76
|
-
service_name = self._extract_value_from_items('
|
|
76
|
+
service_name = self._extract_value_from_items('name', items)
|
|
77
77
|
|
|
78
78
|
project_name = self._create_dummy_project()
|
|
79
79
|
|
|
@@ -29,7 +29,7 @@ class RegisteredLimitTestCase(common.IdentityTests):
|
|
|
29
29
|
'service show' ' %(service_name)s' % {'service_name': service_name}
|
|
30
30
|
)
|
|
31
31
|
service_items = self.parse_show(raw_output)
|
|
32
|
-
service_id = self._extract_value_from_items('
|
|
32
|
+
service_id = self._extract_value_from_items('id', service_items)
|
|
33
33
|
|
|
34
34
|
raw_output = self.openstack(
|
|
35
35
|
'registered limit create'
|
|
@@ -61,9 +61,9 @@ class ServiceTests(common.IdentityTests):
|
|
|
61
61
|
raw_output = self.openstack('service show %s' % new_service_name)
|
|
62
62
|
# assert service details
|
|
63
63
|
service = self.parse_show_as_object(raw_output)
|
|
64
|
-
self.assertEqual(new_service_type, service['
|
|
65
|
-
self.assertEqual(new_service_name, service['
|
|
66
|
-
self.assertEqual(new_service_description, service['
|
|
64
|
+
self.assertEqual(new_service_type, service['type'])
|
|
65
|
+
self.assertEqual(new_service_name, service['name'])
|
|
66
|
+
self.assertEqual(new_service_description, service['description'])
|
|
67
67
|
|
|
68
68
|
def test_service_show(self):
|
|
69
69
|
service_name = self._create_dummy_service()
|
|
@@ -227,44 +227,6 @@ class TestAggregateDelete(TestAggregate):
|
|
|
227
227
|
|
|
228
228
|
|
|
229
229
|
class TestAggregateList(TestAggregate):
|
|
230
|
-
list_columns = (
|
|
231
|
-
"ID",
|
|
232
|
-
"Name",
|
|
233
|
-
"Availability Zone",
|
|
234
|
-
)
|
|
235
|
-
|
|
236
|
-
list_columns_long = (
|
|
237
|
-
"ID",
|
|
238
|
-
"Name",
|
|
239
|
-
"Availability Zone",
|
|
240
|
-
"Properties",
|
|
241
|
-
"Hosts",
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
list_data = (
|
|
245
|
-
(
|
|
246
|
-
TestAggregate.fake_ag.id,
|
|
247
|
-
TestAggregate.fake_ag.name,
|
|
248
|
-
TestAggregate.fake_ag.availability_zone,
|
|
249
|
-
),
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
list_data_long = (
|
|
253
|
-
(
|
|
254
|
-
TestAggregate.fake_ag.id,
|
|
255
|
-
TestAggregate.fake_ag.name,
|
|
256
|
-
TestAggregate.fake_ag.availability_zone,
|
|
257
|
-
format_columns.DictColumn(
|
|
258
|
-
{
|
|
259
|
-
key: value
|
|
260
|
-
for key, value in TestAggregate.fake_ag.metadata.items()
|
|
261
|
-
if key != 'availability_zone'
|
|
262
|
-
}
|
|
263
|
-
),
|
|
264
|
-
format_columns.ListColumn(TestAggregate.fake_ag.hosts),
|
|
265
|
-
),
|
|
266
|
-
)
|
|
267
|
-
|
|
268
230
|
def setUp(self):
|
|
269
231
|
super().setUp()
|
|
270
232
|
|
|
@@ -272,13 +234,54 @@ class TestAggregateList(TestAggregate):
|
|
|
272
234
|
self.cmd = aggregate.ListAggregate(self.app, None)
|
|
273
235
|
|
|
274
236
|
def test_aggregate_list(self):
|
|
237
|
+
self.set_compute_api_version('2.41')
|
|
238
|
+
|
|
239
|
+
parsed_args = self.check_parser(self.cmd, [], [])
|
|
240
|
+
columns, data = self.cmd.take_action(parsed_args)
|
|
241
|
+
|
|
242
|
+
expected_columns = (
|
|
243
|
+
"ID",
|
|
244
|
+
"UUID",
|
|
245
|
+
"Name",
|
|
246
|
+
"Availability Zone",
|
|
247
|
+
)
|
|
248
|
+
expected_data = (
|
|
249
|
+
(
|
|
250
|
+
self.fake_ag.id,
|
|
251
|
+
self.fake_ag.uuid,
|
|
252
|
+
self.fake_ag.name,
|
|
253
|
+
self.fake_ag.availability_zone,
|
|
254
|
+
),
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
self.assertEqual(expected_columns, columns)
|
|
258
|
+
self.assertCountEqual(expected_data, tuple(data))
|
|
259
|
+
|
|
260
|
+
def test_aggregate_list_pre_v241(self):
|
|
261
|
+
self.set_compute_api_version('2.40')
|
|
262
|
+
|
|
275
263
|
parsed_args = self.check_parser(self.cmd, [], [])
|
|
276
264
|
columns, data = self.cmd.take_action(parsed_args)
|
|
277
265
|
|
|
278
|
-
|
|
279
|
-
|
|
266
|
+
expected_columns = (
|
|
267
|
+
"ID",
|
|
268
|
+
"Name",
|
|
269
|
+
"Availability Zone",
|
|
270
|
+
)
|
|
271
|
+
expected_data = (
|
|
272
|
+
(
|
|
273
|
+
self.fake_ag.id,
|
|
274
|
+
self.fake_ag.name,
|
|
275
|
+
self.fake_ag.availability_zone,
|
|
276
|
+
),
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
self.assertEqual(expected_columns, columns)
|
|
280
|
+
self.assertCountEqual(expected_data, tuple(data))
|
|
280
281
|
|
|
281
282
|
def test_aggregate_list_with_long(self):
|
|
283
|
+
self.set_compute_api_version('2.41')
|
|
284
|
+
|
|
282
285
|
arglist = [
|
|
283
286
|
'--long',
|
|
284
287
|
]
|
|
@@ -288,8 +291,33 @@ class TestAggregateList(TestAggregate):
|
|
|
288
291
|
parsed_args = self.check_parser(self.cmd, arglist, vertifylist)
|
|
289
292
|
columns, data = self.cmd.take_action(parsed_args)
|
|
290
293
|
|
|
291
|
-
|
|
292
|
-
|
|
294
|
+
expected_columns = (
|
|
295
|
+
"ID",
|
|
296
|
+
"UUID",
|
|
297
|
+
"Name",
|
|
298
|
+
"Availability Zone",
|
|
299
|
+
"Properties",
|
|
300
|
+
"Hosts",
|
|
301
|
+
)
|
|
302
|
+
expected_data = (
|
|
303
|
+
(
|
|
304
|
+
self.fake_ag.id,
|
|
305
|
+
self.fake_ag.uuid,
|
|
306
|
+
self.fake_ag.name,
|
|
307
|
+
self.fake_ag.availability_zone,
|
|
308
|
+
format_columns.DictColumn(
|
|
309
|
+
{
|
|
310
|
+
key: value
|
|
311
|
+
for key, value in self.fake_ag.metadata.items()
|
|
312
|
+
if key != 'availability_zone'
|
|
313
|
+
}
|
|
314
|
+
),
|
|
315
|
+
format_columns.ListColumn(self.fake_ag.hosts),
|
|
316
|
+
),
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
self.assertEqual(expected_columns, columns)
|
|
320
|
+
self.assertCountEqual(expected_data, tuple(data))
|
|
293
321
|
|
|
294
322
|
|
|
295
323
|
class TestAggregateRemoveHost(TestAggregate):
|
|
@@ -296,13 +296,11 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
|
|
|
296
296
|
}
|
|
297
297
|
)
|
|
298
298
|
|
|
299
|
-
# Return value of compute_client.find_hypervisor
|
|
300
299
|
self.compute_sdk_client.find_hypervisor.return_value = self.hypervisor
|
|
300
|
+
self.compute_sdk_client.get_hypervisor.return_value = self.hypervisor
|
|
301
301
|
|
|
302
|
-
# Return value of compute_client.aggregates()
|
|
303
302
|
self.compute_sdk_client.aggregates.return_value = []
|
|
304
303
|
|
|
305
|
-
# Return value of compute_client.get_hypervisor_uptime()
|
|
306
304
|
uptime_info = {
|
|
307
305
|
'status': self.hypervisor.status,
|
|
308
306
|
'state': self.hypervisor.state,
|
|
@@ -429,6 +427,13 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
|
|
|
429
427
|
self.assertEqual(self.columns_v288, columns)
|
|
430
428
|
self.assertCountEqual(self.data_v288, data)
|
|
431
429
|
|
|
430
|
+
self.compute_sdk_client.find_hypervisor.assert_called_once_with(
|
|
431
|
+
self.hypervisor.name, ignore_missing=False, details=False
|
|
432
|
+
)
|
|
433
|
+
self.compute_sdk_client.get_hypervisor.assert_called_once_with(
|
|
434
|
+
self.hypervisor.id
|
|
435
|
+
)
|
|
436
|
+
|
|
432
437
|
def test_hypervisor_show_pre_v288(self):
|
|
433
438
|
self.set_compute_api_version('2.87')
|
|
434
439
|
|
|
@@ -448,6 +453,13 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
|
|
|
448
453
|
self.assertEqual(self.columns, columns)
|
|
449
454
|
self.assertCountEqual(self.data, data)
|
|
450
455
|
|
|
456
|
+
self.compute_sdk_client.find_hypervisor.assert_called_once_with(
|
|
457
|
+
self.hypervisor.name, ignore_missing=False, details=False
|
|
458
|
+
)
|
|
459
|
+
self.compute_sdk_client.get_hypervisor.assert_called_once_with(
|
|
460
|
+
self.hypervisor.id
|
|
461
|
+
)
|
|
462
|
+
|
|
451
463
|
def test_hypervisor_show_pre_v228(self):
|
|
452
464
|
self.set_compute_api_version('2.27')
|
|
453
465
|
|
|
@@ -472,6 +484,13 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
|
|
|
472
484
|
self.assertEqual(self.columns, columns)
|
|
473
485
|
self.assertCountEqual(self.data, data)
|
|
474
486
|
|
|
487
|
+
self.compute_sdk_client.find_hypervisor.assert_called_once_with(
|
|
488
|
+
self.hypervisor.name, ignore_missing=False, details=False
|
|
489
|
+
)
|
|
490
|
+
self.compute_sdk_client.get_hypervisor.assert_called_once_with(
|
|
491
|
+
self.hypervisor.id
|
|
492
|
+
)
|
|
493
|
+
|
|
475
494
|
def test_hypervisor_show_uptime_not_implemented(self):
|
|
476
495
|
self.set_compute_api_version('2.87')
|
|
477
496
|
|
|
@@ -543,3 +562,10 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
|
|
|
543
562
|
|
|
544
563
|
self.assertEqual(expected_columns, columns)
|
|
545
564
|
self.assertCountEqual(expected_data, data)
|
|
565
|
+
|
|
566
|
+
self.compute_sdk_client.find_hypervisor.assert_called_once_with(
|
|
567
|
+
self.hypervisor.name, ignore_missing=False, details=False
|
|
568
|
+
)
|
|
569
|
+
self.compute_sdk_client.get_hypervisor.assert_called_once_with(
|
|
570
|
+
self.hypervisor.id
|
|
571
|
+
)
|