python-openstackclient 7.1.2__py3-none-any.whl → 7.2.0__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/api/api.py +2 -1
- openstackclient/api/image_v2.py +1 -1
- openstackclient/api/object_store_v1.py +12 -20
- openstackclient/common/clientmanager.py +1 -1
- openstackclient/common/module.py +2 -2
- openstackclient/common/quota.py +4 -4
- openstackclient/compute/v2/flavor.py +1 -1
- openstackclient/compute/v2/server.py +123 -60
- openstackclient/compute/v2/server_backup.py +1 -1
- openstackclient/compute/v2/server_image.py +1 -1
- openstackclient/compute/v2/server_migration.py +11 -2
- openstackclient/compute/v2/usage.py +3 -3
- openstackclient/identity/common.py +4 -1
- openstackclient/identity/v2_0/project.py +1 -1
- openstackclient/identity/v2_0/role_assignment.py +1 -1
- openstackclient/identity/v2_0/user.py +2 -2
- openstackclient/identity/v3/access_rule.py +26 -14
- openstackclient/identity/v3/identity_provider.py +1 -1
- openstackclient/identity/v3/project.py +1 -1
- openstackclient/identity/v3/role_assignment.py +24 -3
- openstackclient/identity/v3/service.py +2 -1
- openstackclient/identity/v3/user.py +35 -15
- openstackclient/image/v2/image.py +13 -13
- openstackclient/image/v2/metadef_objects.py +6 -4
- openstackclient/network/common.py +8 -7
- openstackclient/network/v2/floating_ip.py +6 -2
- openstackclient/network/v2/floating_ip_port_forwarding.py +2 -2
- openstackclient/network/v2/l3_conntrack_helper.py +1 -1
- openstackclient/network/v2/ndp_proxy.py +1 -0
- openstackclient/network/v2/network_agent.py +2 -6
- openstackclient/network/v2/network_qos_rule.py +2 -5
- openstackclient/network/v2/network_trunk.py +5 -4
- openstackclient/network/v2/port.py +18 -3
- openstackclient/network/v2/router.py +7 -4
- openstackclient/network/v2/subnet_pool.py +2 -2
- openstackclient/shell.py +3 -2
- openstackclient/tests/functional/common/test_help.py +3 -9
- openstackclient/tests/functional/common/test_module.py +1 -1
- openstackclient/tests/functional/common/test_quota.py +2 -4
- openstackclient/tests/functional/compute/v2/common.py +1 -3
- openstackclient/tests/functional/compute/v2/test_hypervisor.py +3 -3
- openstackclient/tests/functional/compute/v2/test_keypair.py +2 -2
- openstackclient/tests/functional/compute/v2/test_server.py +1 -1
- openstackclient/tests/functional/identity/v2/common.py +31 -48
- openstackclient/tests/functional/identity/v2/test_catalog.py +1 -1
- openstackclient/tests/functional/identity/v2/test_ec2_credentials.py +2 -2
- openstackclient/tests/functional/identity/v2/test_endpoint.py +2 -2
- openstackclient/tests/functional/identity/v2/test_project.py +8 -8
- openstackclient/tests/functional/identity/v2/test_role.py +14 -34
- openstackclient/tests/functional/identity/v2/test_service.py +2 -2
- openstackclient/tests/functional/identity/v2/test_token.py +1 -1
- openstackclient/tests/functional/identity/v2/test_user.py +7 -9
- openstackclient/tests/functional/identity/v3/common.py +69 -110
- openstackclient/tests/functional/identity/v3/test_access_rule.py +86 -0
- openstackclient/tests/functional/identity/v3/test_application_credential.py +18 -44
- openstackclient/tests/functional/identity/v3/test_catalog.py +1 -1
- openstackclient/tests/functional/identity/v3/test_domain.py +9 -11
- openstackclient/tests/functional/identity/v3/test_endpoint.py +15 -27
- openstackclient/tests/functional/identity/v3/test_group.py +32 -93
- openstackclient/tests/functional/identity/v3/test_idp.py +3 -3
- openstackclient/tests/functional/identity/v3/test_limit.py +32 -32
- openstackclient/tests/functional/identity/v3/test_project.py +17 -26
- openstackclient/tests/functional/identity/v3/test_region.py +6 -7
- openstackclient/tests/functional/identity/v3/test_registered_limit.py +27 -36
- openstackclient/tests/functional/identity/v3/test_role.py +30 -60
- openstackclient/tests/functional/identity/v3/test_role_assignment.py +33 -80
- openstackclient/tests/functional/identity/v3/test_service.py +7 -13
- openstackclient/tests/functional/identity/v3/test_service_provider.py +3 -3
- openstackclient/tests/functional/identity/v3/test_user.py +17 -34
- openstackclient/tests/functional/image/v2/test_image.py +1 -3
- openstackclient/tests/functional/network/v2/common.py +1 -3
- openstackclient/tests/functional/network/v2/test_default_security_group_rule.py +3 -8
- openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py +27 -31
- openstackclient/tests/functional/network/v2/test_network.py +9 -12
- openstackclient/tests/functional/network/v2/test_network_agent.py +15 -20
- openstackclient/tests/functional/network/v2/test_network_flavor.py +2 -2
- openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py +17 -39
- openstackclient/tests/functional/network/v2/test_network_qos_rule.py +48 -63
- openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py +1 -1
- openstackclient/tests/functional/network/v2/test_network_segment_range.py +2 -2
- openstackclient/tests/functional/network/v2/test_network_trunk.py +15 -25
- openstackclient/tests/functional/network/v2/test_port.py +28 -34
- openstackclient/tests/functional/network/v2/test_router.py +13 -19
- openstackclient/tests/functional/object/v1/test_object.py +4 -7
- openstackclient/tests/functional/volume/base.py +5 -17
- openstackclient/tests/functional/volume/v1/test_volume_type.py +11 -11
- openstackclient/tests/functional/volume/v2/test_volume_backup.py +1 -1
- openstackclient/tests/functional/volume/v2/test_volume_type.py +13 -15
- openstackclient/tests/functional/volume/v3/test_volume_type.py +13 -15
- openstackclient/tests/unit/api/test_compute_v2.py +0 -5
- openstackclient/tests/unit/api/test_object_store_v1.py +6 -4
- openstackclient/tests/unit/common/test_extension.py +24 -31
- openstackclient/tests/unit/compute/v2/test_host.py +0 -1
- openstackclient/tests/unit/compute/v2/test_server.py +124 -116
- openstackclient/tests/unit/identity/v3/test_access_rule.py +65 -64
- openstackclient/tests/unit/identity/v3/test_group.py +4 -10
- openstackclient/tests/unit/identity/v3/test_limit.py +2 -2
- openstackclient/tests/unit/identity/v3/test_service.py +0 -3
- openstackclient/tests/unit/identity/v3/test_user.py +4 -90
- openstackclient/tests/unit/image/v2/test_metadef_objects.py +1 -2
- openstackclient/tests/unit/image/v2/test_metadef_resource_type_association.py +2 -6
- openstackclient/tests/unit/integ/base.py +1 -1
- openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +3 -3
- openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +4 -4
- openstackclient/tests/unit/network/v2/test_local_ip_association.py +2 -2
- openstackclient/tests/unit/network/v2/test_network_qos_rule.py +12 -13
- openstackclient/tests/unit/network/v2/test_network_trunk.py +31 -35
- openstackclient/tests/unit/network/v2/test_port.py +40 -17
- openstackclient/tests/unit/network/v2/test_subnet_pool.py +1 -1
- openstackclient/tests/unit/object/v1/test_object.py +1 -1
- openstackclient/tests/unit/utils.py +2 -2
- openstackclient/volume/client.py +1 -1
- openstackclient/volume/v1/volume.py +2 -2
- openstackclient/volume/v1/volume_backup.py +2 -2
- openstackclient/volume/v1/volume_snapshot.py +2 -2
- openstackclient/volume/v2/volume.py +2 -2
- openstackclient/volume/v2/volume_backup.py +2 -2
- openstackclient/volume/v2/volume_snapshot.py +2 -2
- openstackclient/volume/v2/volume_type.py +4 -4
- openstackclient/volume/v3/service.py +0 -1
- openstackclient/volume/v3/volume.py +3 -3
- openstackclient/volume/v3/volume_backup.py +2 -2
- openstackclient/volume/v3/volume_group.py +3 -7
- openstackclient/volume/v3/volume_type.py +6 -6
- {python_openstackclient-7.1.2.dist-info → python_openstackclient-7.2.0.dist-info}/AUTHORS +3 -0
- {python_openstackclient-7.1.2.dist-info → python_openstackclient-7.2.0.dist-info}/METADATA +2 -3
- {python_openstackclient-7.1.2.dist-info → python_openstackclient-7.2.0.dist-info}/RECORD +132 -131
- python_openstackclient-7.2.0.dist-info/pbr.json +1 -0
- python_openstackclient-7.1.2.dist-info/pbr.json +0 -1
- {python_openstackclient-7.1.2.dist-info → python_openstackclient-7.2.0.dist-info}/LICENSE +0 -0
- {python_openstackclient-7.1.2.dist-info → python_openstackclient-7.2.0.dist-info}/WHEEL +0 -0
- {python_openstackclient-7.1.2.dist-info → python_openstackclient-7.2.0.dist-info}/entry_points.txt +0 -0
- {python_openstackclient-7.1.2.dist-info → python_openstackclient-7.2.0.dist-info}/top_level.txt +0 -0
|
@@ -250,9 +250,9 @@ class ListUser(command.Lister):
|
|
|
250
250
|
try:
|
|
251
251
|
for p in identity_client.tenants.list():
|
|
252
252
|
project_cache[p.id] = p
|
|
253
|
-
except Exception:
|
|
253
|
+
except Exception: # noqa: S110
|
|
254
254
|
# Just forget it if there's any trouble
|
|
255
|
-
pass
|
|
255
|
+
pass
|
|
256
256
|
formatters['tenantId'] = functools.partial(
|
|
257
257
|
ProjectColumn, project_cache=project_cache
|
|
258
258
|
)
|
|
@@ -42,15 +42,15 @@ class DeleteAccessRule(command.Command):
|
|
|
42
42
|
return parser
|
|
43
43
|
|
|
44
44
|
def take_action(self, parsed_args):
|
|
45
|
-
identity_client = self.app.client_manager.identity
|
|
45
|
+
identity_client = self.app.client_manager.sdk_connection.identity
|
|
46
|
+
conn = self.app.client_manager.sdk_connection
|
|
47
|
+
user_id = conn.config.get_auth().get_user_id(conn.identity)
|
|
46
48
|
|
|
47
49
|
errors = 0
|
|
48
50
|
for ac in parsed_args.access_rule:
|
|
49
51
|
try:
|
|
50
|
-
access_rule =
|
|
51
|
-
|
|
52
|
-
)
|
|
53
|
-
identity_client.access_rules.delete(access_rule.id)
|
|
52
|
+
access_rule = identity_client.get_access_rule(user_id, ac)
|
|
53
|
+
identity_client.delete_access_rule(user_id, access_rule.id)
|
|
54
54
|
except Exception as e:
|
|
55
55
|
errors += 1
|
|
56
56
|
LOG.error(
|
|
@@ -83,16 +83,17 @@ class ListAccessRule(command.Lister):
|
|
|
83
83
|
return parser
|
|
84
84
|
|
|
85
85
|
def take_action(self, parsed_args):
|
|
86
|
-
identity_client = self.app.client_manager.identity
|
|
86
|
+
identity_client = self.app.client_manager.sdk_connection.identity
|
|
87
87
|
if parsed_args.user:
|
|
88
88
|
user_id = common.find_user(
|
|
89
89
|
identity_client, parsed_args.user, parsed_args.user_domain
|
|
90
90
|
).id
|
|
91
91
|
else:
|
|
92
|
-
|
|
92
|
+
conn = self.app.client_manager.sdk_connection
|
|
93
|
+
user_id = conn.config.get_auth().get_user_id(conn.identity)
|
|
93
94
|
|
|
94
95
|
columns = ('ID', 'Service', 'Method', 'Path')
|
|
95
|
-
data = identity_client.access_rules
|
|
96
|
+
data = identity_client.access_rules(user=user_id)
|
|
96
97
|
return (
|
|
97
98
|
columns,
|
|
98
99
|
(
|
|
@@ -119,11 +120,22 @@ class ShowAccessRule(command.ShowOne):
|
|
|
119
120
|
return parser
|
|
120
121
|
|
|
121
122
|
def take_action(self, parsed_args):
|
|
122
|
-
identity_client = self.app.client_manager.identity
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
)
|
|
123
|
+
identity_client = self.app.client_manager.sdk_connection.identity
|
|
124
|
+
conn = self.app.client_manager.sdk_connection
|
|
125
|
+
user_id = conn.config.get_auth().get_user_id(conn.identity)
|
|
126
126
|
|
|
127
|
-
access_rule.
|
|
127
|
+
access_rule = identity_client.get_access_rule(
|
|
128
|
+
user_id, parsed_args.access_rule
|
|
129
|
+
)
|
|
128
130
|
|
|
129
|
-
|
|
131
|
+
columns = ('ID', 'Method', 'Path', 'Service')
|
|
132
|
+
return (
|
|
133
|
+
columns,
|
|
134
|
+
(
|
|
135
|
+
utils.get_item_properties(
|
|
136
|
+
access_rule,
|
|
137
|
+
columns,
|
|
138
|
+
formatters={},
|
|
139
|
+
)
|
|
140
|
+
),
|
|
141
|
+
)
|
|
@@ -146,12 +146,19 @@ class ListRoleAssignment(command.Lister):
|
|
|
146
146
|
domain_id=role_domain_id,
|
|
147
147
|
)
|
|
148
148
|
|
|
149
|
+
user_domain_id = None
|
|
150
|
+
if parsed_args.user_domain:
|
|
151
|
+
project_domain_id = _find_sdk_id(
|
|
152
|
+
identity_client.find_domain,
|
|
153
|
+
name_or_id=parsed_args.user_domain,
|
|
154
|
+
)
|
|
155
|
+
|
|
149
156
|
user_id = None
|
|
150
157
|
if parsed_args.user:
|
|
151
158
|
user_id = _find_sdk_id(
|
|
152
159
|
identity_client.find_user,
|
|
153
160
|
name_or_id=parsed_args.user,
|
|
154
|
-
domain_id=
|
|
161
|
+
domain_id=user_domain_id,
|
|
155
162
|
)
|
|
156
163
|
elif parsed_args.authuser:
|
|
157
164
|
if auth_ref:
|
|
@@ -171,6 +178,13 @@ class ListRoleAssignment(command.Lister):
|
|
|
171
178
|
name_or_id=parsed_args.domain,
|
|
172
179
|
)
|
|
173
180
|
|
|
181
|
+
project_domain_id = None
|
|
182
|
+
if parsed_args.project_domain:
|
|
183
|
+
project_domain_id = _find_sdk_id(
|
|
184
|
+
identity_client.find_domain,
|
|
185
|
+
name_or_id=parsed_args.project_domain,
|
|
186
|
+
)
|
|
187
|
+
|
|
174
188
|
project_id = None
|
|
175
189
|
if parsed_args.project:
|
|
176
190
|
project_id = _find_sdk_id(
|
|
@@ -178,7 +192,7 @@ class ListRoleAssignment(command.Lister):
|
|
|
178
192
|
name_or_id=common._get_token_resource(
|
|
179
193
|
identity_client, 'project', parsed_args.project
|
|
180
194
|
),
|
|
181
|
-
domain_id=
|
|
195
|
+
domain_id=project_domain_id,
|
|
182
196
|
)
|
|
183
197
|
elif parsed_args.authproject:
|
|
184
198
|
if auth_ref:
|
|
@@ -187,12 +201,19 @@ class ListRoleAssignment(command.Lister):
|
|
|
187
201
|
name_or_id=auth_ref.project_id,
|
|
188
202
|
)
|
|
189
203
|
|
|
204
|
+
group_domain_id = None
|
|
205
|
+
if parsed_args.group_domain:
|
|
206
|
+
group_domain_id = _find_sdk_id(
|
|
207
|
+
identity_client.find_domain,
|
|
208
|
+
name_or_id=parsed_args.group_domain,
|
|
209
|
+
)
|
|
210
|
+
|
|
190
211
|
group_id = None
|
|
191
212
|
if parsed_args.group:
|
|
192
213
|
group_id = _find_sdk_id(
|
|
193
214
|
identity_client.find_group,
|
|
194
215
|
name_or_id=parsed_args.group,
|
|
195
|
-
domain_id=
|
|
216
|
+
domain_id=group_domain_id,
|
|
196
217
|
)
|
|
197
218
|
|
|
198
219
|
include_names = True if parsed_args.names else None
|
|
@@ -225,7 +225,8 @@ class SetService(command.Command):
|
|
|
225
225
|
kwargs['name'] = parsed_args.name
|
|
226
226
|
if parsed_args.description:
|
|
227
227
|
kwargs['description'] = parsed_args.description
|
|
228
|
-
|
|
228
|
+
if parsed_args.is_enabled is not None:
|
|
229
|
+
kwargs['is_enabled'] = parsed_args.is_enabled
|
|
229
230
|
|
|
230
231
|
identity_client.update_service(service.id, **kwargs)
|
|
231
232
|
|
|
@@ -249,26 +249,44 @@ class CreateUser(command.ShowOne):
|
|
|
249
249
|
def take_action(self, parsed_args):
|
|
250
250
|
identity_client = self.app.client_manager.sdk_connection.identity
|
|
251
251
|
|
|
252
|
+
kwargs = {}
|
|
253
|
+
|
|
252
254
|
domain_id = None
|
|
253
255
|
if parsed_args.domain:
|
|
254
256
|
domain_id = identity_client.find_domain(
|
|
255
|
-
|
|
257
|
+
parsed_args.domain,
|
|
256
258
|
ignore_missing=False,
|
|
257
259
|
).id
|
|
260
|
+
kwargs['domain_id'] = domain_id
|
|
258
261
|
|
|
259
|
-
project_id = None
|
|
260
262
|
if parsed_args.project:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
+
project_domain_id = None
|
|
264
|
+
if parsed_args.project_domain:
|
|
265
|
+
project_domain_id = identity_client.find_domain(
|
|
266
|
+
parsed_args.project_domain,
|
|
267
|
+
ignore_missing=False,
|
|
268
|
+
).id
|
|
269
|
+
kwargs['default_project_id'] = identity_client.find_project(
|
|
270
|
+
parsed_args.project,
|
|
263
271
|
ignore_missing=False,
|
|
264
|
-
domain_id=
|
|
272
|
+
domain_id=project_domain_id,
|
|
265
273
|
).id
|
|
266
274
|
|
|
275
|
+
if parsed_args.description:
|
|
276
|
+
kwargs['description'] = parsed_args.description
|
|
277
|
+
|
|
278
|
+
if parsed_args.email:
|
|
279
|
+
kwargs['email'] = parsed_args.email
|
|
280
|
+
|
|
267
281
|
is_enabled = True
|
|
268
282
|
if parsed_args.disable:
|
|
269
283
|
is_enabled = False
|
|
270
|
-
|
|
271
|
-
|
|
284
|
+
|
|
285
|
+
password = None
|
|
286
|
+
if parsed_args.password:
|
|
287
|
+
password = parsed_args.password
|
|
288
|
+
elif parsed_args.password_prompt:
|
|
289
|
+
password = utils.get_password(self.app.stdin)
|
|
272
290
|
|
|
273
291
|
if not parsed_args.password:
|
|
274
292
|
LOG.warning(
|
|
@@ -278,24 +296,26 @@ class CreateUser(command.ShowOne):
|
|
|
278
296
|
)
|
|
279
297
|
)
|
|
280
298
|
options = _get_options_for_user(identity_client, parsed_args)
|
|
299
|
+
if options:
|
|
300
|
+
kwargs['options'] = options
|
|
281
301
|
|
|
282
302
|
try:
|
|
283
303
|
user = identity_client.create_user(
|
|
284
|
-
default_project_id=project_id,
|
|
285
|
-
description=parsed_args.description,
|
|
286
|
-
domain_id=domain_id,
|
|
287
|
-
email=parsed_args.email,
|
|
288
304
|
is_enabled=is_enabled,
|
|
289
305
|
name=parsed_args.name,
|
|
290
|
-
password=
|
|
291
|
-
|
|
306
|
+
password=password,
|
|
307
|
+
**kwargs,
|
|
292
308
|
)
|
|
293
309
|
except sdk_exc.ConflictException:
|
|
294
310
|
if parsed_args.or_show:
|
|
311
|
+
kwargs = {}
|
|
312
|
+
if domain_id:
|
|
313
|
+
kwargs['domain_id'] = domain_id
|
|
314
|
+
|
|
295
315
|
user = identity_client.find_user(
|
|
296
|
-
|
|
297
|
-
domain_id=domain_id,
|
|
316
|
+
parsed_args.name,
|
|
298
317
|
ignore_missing=False,
|
|
318
|
+
**kwargs,
|
|
299
319
|
)
|
|
300
320
|
LOG.info(_('Returning existing user %s'), user.name)
|
|
301
321
|
else:
|
|
@@ -421,8 +421,8 @@ class CreateImage(command.ShowOne):
|
|
|
421
421
|
identity_common.add_project_domain_option_to_parser(parser)
|
|
422
422
|
for deadopt in self.deadopts:
|
|
423
423
|
parser.add_argument(
|
|
424
|
-
"
|
|
425
|
-
metavar="
|
|
424
|
+
f"--{deadopt}",
|
|
425
|
+
metavar=f"<{deadopt}>",
|
|
426
426
|
dest=deadopt.replace('-', '_'),
|
|
427
427
|
help=argparse.SUPPRESS,
|
|
428
428
|
)
|
|
@@ -488,7 +488,7 @@ class CreateImage(command.ShowOne):
|
|
|
488
488
|
fp = open(parsed_args.filename, 'rb')
|
|
489
489
|
except FileNotFoundError:
|
|
490
490
|
raise exceptions.CommandError(
|
|
491
|
-
'
|
|
491
|
+
f'{parsed_args.filename!r} is not a valid file',
|
|
492
492
|
)
|
|
493
493
|
else:
|
|
494
494
|
fp = get_data_from_stdin()
|
|
@@ -1209,8 +1209,8 @@ class SetImage(command.Command):
|
|
|
1209
1209
|
identity_common.add_project_domain_option_to_parser(parser)
|
|
1210
1210
|
for deadopt in self.deadopts:
|
|
1211
1211
|
parser.add_argument(
|
|
1212
|
-
"
|
|
1213
|
-
metavar="
|
|
1212
|
+
f"--{deadopt}",
|
|
1213
|
+
metavar=f"<{deadopt}>",
|
|
1214
1214
|
dest=f"dead_{deadopt.replace('-', '_')}",
|
|
1215
1215
|
help=argparse.SUPPRESS,
|
|
1216
1216
|
)
|
|
@@ -1575,7 +1575,7 @@ class StageImage(command.Command):
|
|
|
1575
1575
|
fp = open(parsed_args.filename, 'rb')
|
|
1576
1576
|
except FileNotFoundError:
|
|
1577
1577
|
raise exceptions.CommandError(
|
|
1578
|
-
'
|
|
1578
|
+
f'{parsed_args.filename!r} is not a valid file',
|
|
1579
1579
|
)
|
|
1580
1580
|
else:
|
|
1581
1581
|
fp = get_data_from_stdin()
|
|
@@ -1614,8 +1614,6 @@ class ImportImage(command.ShowOne):
|
|
|
1614
1614
|
metavar='<image>',
|
|
1615
1615
|
help=_('Image to initiate import process for (name or ID)'),
|
|
1616
1616
|
)
|
|
1617
|
-
# TODO(stephenfin): Uncomment help text when we have this command
|
|
1618
|
-
# implemented
|
|
1619
1617
|
parser.add_argument(
|
|
1620
1618
|
'--method',
|
|
1621
1619
|
metavar='<method>',
|
|
@@ -1630,8 +1628,6 @@ class ImportImage(command.ShowOne):
|
|
|
1630
1628
|
help=_(
|
|
1631
1629
|
"Import method used for image import process. "
|
|
1632
1630
|
"Not all deployments will support all methods. "
|
|
1633
|
-
# "Valid values can be retrieved with the 'image import "
|
|
1634
|
-
# "methods' command. "
|
|
1635
1631
|
"The 'glance-direct' method (default) requires images be "
|
|
1636
1632
|
"first staged using the 'image-stage' command."
|
|
1637
1633
|
),
|
|
@@ -1734,11 +1730,15 @@ class ImportImage(command.ShowOne):
|
|
|
1734
1730
|
|
|
1735
1731
|
if parsed_args.import_method not in import_methods:
|
|
1736
1732
|
msg = _(
|
|
1737
|
-
"The '%s' import method is not supported by this
|
|
1738
|
-
"Supported: %s"
|
|
1733
|
+
"The '%(method)s' import method is not supported by this "
|
|
1734
|
+
"deployment. Supported: %(supported)s"
|
|
1739
1735
|
)
|
|
1740
1736
|
raise exceptions.CommandError(
|
|
1741
|
-
msg
|
|
1737
|
+
msg
|
|
1738
|
+
% {
|
|
1739
|
+
'method': parsed_args.import_method,
|
|
1740
|
+
'supported': ', '.join(import_methods),
|
|
1741
|
+
},
|
|
1742
1742
|
)
|
|
1743
1743
|
|
|
1744
1744
|
if parsed_args.import_method == 'web-download':
|
|
@@ -260,10 +260,12 @@ class ShowMetadefObjectProperty(command.ShowOne):
|
|
|
260
260
|
prop['name'] = parsed_args.property
|
|
261
261
|
|
|
262
262
|
except KeyError:
|
|
263
|
-
msg = _(
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
263
|
+
msg = _(
|
|
264
|
+
'Property %(property)s not found in object %(object)s.'
|
|
265
|
+
) % {
|
|
266
|
+
'property': parsed_args.property,
|
|
267
|
+
'object': parsed_args.object,
|
|
268
|
+
}
|
|
267
269
|
raise exceptions.CommandError(msg)
|
|
268
270
|
|
|
269
271
|
return zip(*sorted(prop.items()))
|
|
@@ -120,13 +120,14 @@ class NetDetectionMixin(metaclass=abc.ABCMeta):
|
|
|
120
120
|
@staticmethod
|
|
121
121
|
def split_help(network_help, compute_help):
|
|
122
122
|
return (
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
123
|
+
"*{network_qualifier}:*\n {network_help}\n\n"
|
|
124
|
+
"*{compute_qualifier}:*\n {compute_help}".format(
|
|
125
|
+
**dict(
|
|
126
|
+
network_qualifier=_("Network version 2"),
|
|
127
|
+
network_help=network_help,
|
|
128
|
+
compute_qualifier=_("Compute version 2"),
|
|
129
|
+
compute_help=compute_help,
|
|
130
|
+
)
|
|
130
131
|
)
|
|
131
132
|
)
|
|
132
133
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
"""IP Floating action implementations"""
|
|
14
14
|
|
|
15
|
+
from openstack import exceptions as sdk_exceptions
|
|
15
16
|
from osc_lib import utils
|
|
16
17
|
from osc_lib.utils import tags as _tag
|
|
17
18
|
|
|
@@ -390,7 +391,10 @@ class ListFloatingIP(common.NetworkAndComputeLister):
|
|
|
390
391
|
|
|
391
392
|
_tag.get_tag_filtering_args(parsed_args, query)
|
|
392
393
|
|
|
393
|
-
|
|
394
|
+
try:
|
|
395
|
+
data = list(client.ips(**query))
|
|
396
|
+
except sdk_exceptions.NotFoundException:
|
|
397
|
+
data = []
|
|
394
398
|
|
|
395
399
|
return (
|
|
396
400
|
headers,
|
|
@@ -448,7 +452,7 @@ class SetFloatingIP(common.NeutronCommandWithExtraArgs):
|
|
|
448
452
|
'--port',
|
|
449
453
|
metavar='<port>',
|
|
450
454
|
help=_("Associate the floating IP with port (name or ID)"),
|
|
451
|
-
)
|
|
455
|
+
)
|
|
452
456
|
parser.add_argument(
|
|
453
457
|
'--fixed-ip-address',
|
|
454
458
|
metavar='<ip-address>',
|
|
@@ -144,7 +144,7 @@ class CreateFloatingIPPortForwarding(
|
|
|
144
144
|
"The protocol used in the floating IP "
|
|
145
145
|
"port forwarding, for instance: TCP, UDP"
|
|
146
146
|
),
|
|
147
|
-
)
|
|
147
|
+
)
|
|
148
148
|
parser.add_argument(
|
|
149
149
|
'--description',
|
|
150
150
|
metavar='<description>',
|
|
@@ -404,7 +404,7 @@ class SetFloatingIPPortForwarding(common.NeutronCommandWithExtraArgs):
|
|
|
404
404
|
metavar='<protocol>',
|
|
405
405
|
choices=['tcp', 'udp'],
|
|
406
406
|
help=_("The IP protocol used in the floating IP port forwarding"),
|
|
407
|
-
)
|
|
407
|
+
)
|
|
408
408
|
parser.add_argument(
|
|
409
409
|
'--description',
|
|
410
410
|
metavar='<description>',
|
|
@@ -89,9 +89,7 @@ class AddNetworkToAgent(command.Command):
|
|
|
89
89
|
try:
|
|
90
90
|
client.add_dhcp_agent_to_network(agent, network)
|
|
91
91
|
except Exception:
|
|
92
|
-
msg = 'Failed to add {} to {}'
|
|
93
|
-
network.name, agent.agent_type
|
|
94
|
-
)
|
|
92
|
+
msg = f'Failed to add {network.name} to {agent.agent_type}'
|
|
95
93
|
exceptions.CommandError(msg)
|
|
96
94
|
|
|
97
95
|
|
|
@@ -321,9 +319,7 @@ class RemoveNetworkFromAgent(command.Command):
|
|
|
321
319
|
try:
|
|
322
320
|
client.remove_dhcp_agent_from_network(agent, network)
|
|
323
321
|
except Exception:
|
|
324
|
-
msg = 'Failed to remove {} to {}'
|
|
325
|
-
network.name, agent.agent_type
|
|
326
|
-
)
|
|
322
|
+
msg = f'Failed to remove {network.name} to {agent.agent_type}'
|
|
327
323
|
exceptions.CommandError(msg)
|
|
328
324
|
|
|
329
325
|
|
|
@@ -159,10 +159,7 @@ def _get_item_properties(item, fields):
|
|
|
159
159
|
|
|
160
160
|
def _rule_action_call(client, action, rule_type):
|
|
161
161
|
rule_type = rule_type.replace('-', '_')
|
|
162
|
-
func_name = '{action}_qos_{rule_type}_rule'
|
|
163
|
-
action=action,
|
|
164
|
-
rule_type=rule_type,
|
|
165
|
-
)
|
|
162
|
+
func_name = f'{action}_qos_{rule_type}_rule'
|
|
166
163
|
return getattr(client, func_name)
|
|
167
164
|
|
|
168
165
|
|
|
@@ -311,7 +308,7 @@ class DeleteNetworkQosRule(command.Command):
|
|
|
311
308
|
)
|
|
312
309
|
rule_type = _find_rule_type(qos, rule_id)
|
|
313
310
|
if not rule_type:
|
|
314
|
-
raise Exception('Rule
|
|
311
|
+
raise Exception(f'Rule {rule_id} not found')
|
|
315
312
|
_rule_action_call(network_client, ACTION_DELETE, rule_type)(
|
|
316
313
|
rule_id, qos.id
|
|
317
314
|
)
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#
|
|
16
16
|
|
|
17
17
|
"""Network trunk and subports action implementations"""
|
|
18
|
+
|
|
18
19
|
import logging
|
|
19
20
|
|
|
20
21
|
from cliff import columns as cliff_columns
|
|
@@ -67,8 +68,8 @@ class CreateNetworkTrunk(command.ShowOne):
|
|
|
67
68
|
required_keys=['port'],
|
|
68
69
|
help=_(
|
|
69
70
|
"Subport to add. Subport is of form "
|
|
70
|
-
"
|
|
71
|
-
"segmentation-id=<segmentation-ID
|
|
71
|
+
"'port=<name or ID>,segmentation-type=<segmentation-type>,"
|
|
72
|
+
"segmentation-id=<segmentation-ID>' (--subport) option "
|
|
72
73
|
"can be repeated"
|
|
73
74
|
),
|
|
74
75
|
)
|
|
@@ -198,8 +199,8 @@ class SetNetworkTrunk(command.Command):
|
|
|
198
199
|
required_keys=['port'],
|
|
199
200
|
help=_(
|
|
200
201
|
"Subport to add. Subport is of form "
|
|
201
|
-
"
|
|
202
|
-
",segmentation-id=<segmentation-ID
|
|
202
|
+
"'port=<name or ID>,segmentation-type=<segmentation-type>"
|
|
203
|
+
",segmentation-id=<segmentation-ID>' (--subport) option "
|
|
203
204
|
"can be repeated"
|
|
204
205
|
),
|
|
205
206
|
)
|
|
@@ -274,13 +274,13 @@ def _prepare_filter_fixed_ips(client_manager, parsed_args):
|
|
|
274
274
|
_subnet = client.find_subnet(
|
|
275
275
|
subnet_name_id, ignore_missing=False
|
|
276
276
|
)
|
|
277
|
-
ips.append('subnet_id
|
|
277
|
+
ips.append(f'subnet_id={_subnet.id}')
|
|
278
278
|
|
|
279
279
|
if 'ip-address' in ip_spec:
|
|
280
|
-
ips.append('ip_address
|
|
280
|
+
ips.append('ip_address={}'.format(ip_spec['ip-address']))
|
|
281
281
|
|
|
282
282
|
if 'ip-substring' in ip_spec:
|
|
283
|
-
ips.append('ip_address_substr
|
|
283
|
+
ips.append('ip_address_substr={}'.format(ip_spec['ip-substring']))
|
|
284
284
|
return ips
|
|
285
285
|
|
|
286
286
|
|
|
@@ -792,6 +792,19 @@ class ListPort(command.Lister):
|
|
|
792
792
|
metavar='<security-group>',
|
|
793
793
|
help=_("List only ports associated with this security group"),
|
|
794
794
|
)
|
|
795
|
+
# the API sadly reports these in upper case and while it would be
|
|
796
|
+
# wonderful to plaster over this ugliness client-side, there are
|
|
797
|
+
# already users in the wild doing this in upper case that we need to
|
|
798
|
+
# support
|
|
799
|
+
parser.add_argument(
|
|
800
|
+
'--status',
|
|
801
|
+
metavar='<status>',
|
|
802
|
+
choices=('ACTIVE', 'BUILD', 'DOWN', 'ERROR'),
|
|
803
|
+
help=_(
|
|
804
|
+
"List ports according to their status "
|
|
805
|
+
"('ACTIVE', 'BUILD', 'DOWN', 'ERROR')"
|
|
806
|
+
),
|
|
807
|
+
)
|
|
795
808
|
identity_common.add_project_domain_option_to_parser(parser)
|
|
796
809
|
parser.add_argument(
|
|
797
810
|
'--fixed-ip',
|
|
@@ -859,6 +872,8 @@ class ListPort(command.Lister):
|
|
|
859
872
|
filters['network_id'] = network.id
|
|
860
873
|
if parsed_args.mac_address:
|
|
861
874
|
filters['mac_address'] = parsed_args.mac_address
|
|
875
|
+
if parsed_args.status:
|
|
876
|
+
filters['status'] = parsed_args.status
|
|
862
877
|
if parsed_args.project:
|
|
863
878
|
project_id = identity_common.find_project(
|
|
864
879
|
identity_client,
|
|
@@ -164,10 +164,13 @@ def _get_external_gateway_attrs(client_manager, parsed_args):
|
|
|
164
164
|
'subnet_id' in ip_spec
|
|
165
165
|
and ip_net_id not in external_gateways
|
|
166
166
|
):
|
|
167
|
-
msg =
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
msg = (
|
|
168
|
+
_(
|
|
169
|
+
'Subnet %s does not belong to any of the networks '
|
|
170
|
+
'provided for --external-gateway.'
|
|
171
|
+
)
|
|
172
|
+
% (ip_spec['subnet_id'])
|
|
173
|
+
)
|
|
171
174
|
raise exceptions.CommandError(msg)
|
|
172
175
|
for gw_info in external_gateways[ip_net_id]:
|
|
173
176
|
if 'external_fixed_ips' not in gw_info:
|
|
@@ -201,7 +201,7 @@ class CreateSubnetPool(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
|
|
201
201
|
"as the number of IP addresses that can be allocated "
|
|
202
202
|
"from the subnet pool"
|
|
203
203
|
),
|
|
204
|
-
)
|
|
204
|
+
)
|
|
205
205
|
_tag.add_tag_option_to_parser_for_create(parser, _('subnet pool'))
|
|
206
206
|
return parser
|
|
207
207
|
|
|
@@ -433,7 +433,7 @@ class SetSubnetPool(common.NeutronCommandWithExtraArgs):
|
|
|
433
433
|
"as the number of IP addresses that can be allocated "
|
|
434
434
|
"from the subnet pool"
|
|
435
435
|
),
|
|
436
|
-
)
|
|
436
|
+
)
|
|
437
437
|
_tag.add_tag_option_to_parser_for_set(parser, _('subnet pool'))
|
|
438
438
|
|
|
439
439
|
return parser
|
openstackclient/shell.py
CHANGED
|
@@ -96,8 +96,9 @@ class OpenStackShell(shell.OpenStackShell):
|
|
|
96
96
|
key=lambda s: list(map(int, s.split('.'))),
|
|
97
97
|
)
|
|
98
98
|
self.log.warning(
|
|
99
|
-
"
|
|
100
|
-
|
|
99
|
+
"{} version {} is not in supported versions: {}".format(
|
|
100
|
+
api, version_opt, ', '.join(sorted_versions)
|
|
101
|
+
)
|
|
101
102
|
)
|
|
102
103
|
|
|
103
104
|
# Command groups deal only with major versions
|
|
@@ -21,7 +21,7 @@ class HelpTests(base.TestCase):
|
|
|
21
21
|
"""Functional tests for openstackclient help output."""
|
|
22
22
|
|
|
23
23
|
SERVER_COMMANDS = [
|
|
24
|
-
('server add security group', 'Add security group to server'),
|
|
24
|
+
('server add security group', 'Add security group(s) to server'),
|
|
25
25
|
('server add volume', 'Add volume to server'),
|
|
26
26
|
('server backup create', 'Create a server backup image'),
|
|
27
27
|
('server create', 'Create a new server'),
|
|
@@ -60,15 +60,9 @@ class HelpTests(base.TestCase):
|
|
|
60
60
|
"""Check server commands in main help message."""
|
|
61
61
|
raw_output = self.openstack('help')
|
|
62
62
|
for command, description in self.SERVER_COMMANDS:
|
|
63
|
-
msg = 'Command: {} not found in help output:\n{}'
|
|
64
|
-
command,
|
|
65
|
-
raw_output,
|
|
66
|
-
)
|
|
63
|
+
msg = f'Command: {command} not found in help output:\n{raw_output}'
|
|
67
64
|
self.assertIn(command, raw_output, msg)
|
|
68
|
-
msg = 'Description: {} not found in help output:\n{}'
|
|
69
|
-
description,
|
|
70
|
-
raw_output,
|
|
71
|
-
)
|
|
65
|
+
msg = f'Description: {description} not found in help output:\n{raw_output}'
|
|
72
66
|
self.assertIn(description, raw_output, msg)
|
|
73
67
|
|
|
74
68
|
def test_server_only_help(self):
|