python-openstackclient 7.1.3__py3-none-any.whl → 7.2.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/api/api.py +2 -1
- openstackclient/api/image_v2.py +1 -1
- openstackclient/api/object_store_v1.py +12 -20
- openstackclient/common/clientmanager.py +7 -2
- openstackclient/common/module.py +2 -2
- openstackclient/common/quota.py +4 -4
- openstackclient/compute/v2/flavor.py +1 -1
- openstackclient/compute/v2/server.py +122 -59
- 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 +1 -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/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 +123 -115
- 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/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.3.dist-info → python_openstackclient-7.2.1.dist-info}/AUTHORS +3 -0
- {python_openstackclient-7.1.3.dist-info → python_openstackclient-7.2.1.dist-info}/METADATA +2 -3
- {python_openstackclient-7.1.3.dist-info → python_openstackclient-7.2.1.dist-info}/RECORD +127 -126
- python_openstackclient-7.2.1.dist-info/pbr.json +1 -0
- python_openstackclient-7.1.3.dist-info/pbr.json +0 -1
- {python_openstackclient-7.1.3.dist-info → python_openstackclient-7.2.1.dist-info}/LICENSE +0 -0
- {python_openstackclient-7.1.3.dist-info → python_openstackclient-7.2.1.dist-info}/WHEEL +0 -0
- {python_openstackclient-7.1.3.dist-info → python_openstackclient-7.2.1.dist-info}/entry_points.txt +0 -0
- {python_openstackclient-7.1.3.dist-info → python_openstackclient-7.2.1.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
|
+
)
|
|
@@ -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):
|
|
@@ -59,7 +59,7 @@ class CommandTest(base.TestCase):
|
|
|
59
59
|
input_groups = ['volume', 'network', 'image', 'identity', 'compute.v2']
|
|
60
60
|
for each_input in input_groups:
|
|
61
61
|
cmd_output = self.openstack(
|
|
62
|
-
'command list --group
|
|
62
|
+
f'command list --group {each_input}',
|
|
63
63
|
parse_output=True,
|
|
64
64
|
)
|
|
65
65
|
group_names = [each.get('Command Group') for each in cmd_output]
|
|
@@ -165,8 +165,7 @@ class QuotaTests(base.TestCase):
|
|
|
165
165
|
# That will ensure we have at least two networks in the system.
|
|
166
166
|
for _ in range(2):
|
|
167
167
|
self.openstack(
|
|
168
|
-
'network create --project
|
|
169
|
-
% (self.PROJECT_NAME, uuid.uuid4().hex)
|
|
168
|
+
f'network create --project {self.PROJECT_NAME} {uuid.uuid4().hex}'
|
|
170
169
|
)
|
|
171
170
|
|
|
172
171
|
self.assertRaises(
|
|
@@ -211,8 +210,7 @@ class QuotaTests(base.TestCase):
|
|
|
211
210
|
# That will ensure we have at least two networks in the system.
|
|
212
211
|
for _ in range(2):
|
|
213
212
|
self.openstack(
|
|
214
|
-
'network create --project
|
|
215
|
-
% (self.PROJECT_NAME, uuid.uuid4().hex)
|
|
213
|
+
f'network create --project {self.PROJECT_NAME} {uuid.uuid4().hex}'
|
|
216
214
|
)
|
|
217
215
|
|
|
218
216
|
self.openstack('quota set --networks 1 --force ' + self.PROJECT_NAME)
|
|
@@ -132,9 +132,7 @@ class ComputeTestCase(base.TestCase):
|
|
|
132
132
|
print(f'Server {name} now has status {status}')
|
|
133
133
|
break
|
|
134
134
|
print(
|
|
135
|
-
'Server {}: Waiting for {}, current status: {}'
|
|
136
|
-
name, expected_status, status
|
|
137
|
-
)
|
|
135
|
+
f'Server {name}: Waiting for {expected_status}, current status: {status}'
|
|
138
136
|
)
|
|
139
137
|
self.assertNotIn(status, failures)
|
|
140
138
|
time.sleep(interval)
|
|
@@ -37,8 +37,8 @@ class HypervisorTests(base.TestCase):
|
|
|
37
37
|
for i in ids1:
|
|
38
38
|
cmd_output = json.loads(
|
|
39
39
|
self.openstack(
|
|
40
|
-
"hypervisor show
|
|
41
|
-
" --os-compute-api-version 2.1"
|
|
40
|
+
f"hypervisor show {i} -f json "
|
|
41
|
+
" --os-compute-api-version 2.1"
|
|
42
42
|
)
|
|
43
43
|
)
|
|
44
44
|
self.assertIsNotNone(cmd_output)
|
|
@@ -47,6 +47,6 @@ class HypervisorTests(base.TestCase):
|
|
|
47
47
|
# Show test - latest microversion
|
|
48
48
|
for i in ids2:
|
|
49
49
|
cmd_output = json.loads(
|
|
50
|
-
self.openstack("hypervisor show
|
|
50
|
+
self.openstack(f"hypervisor show {i} -f json")
|
|
51
51
|
)
|
|
52
52
|
self.assertIsNotNone(cmd_output)
|
|
@@ -96,7 +96,7 @@ class KeypairTests(KeypairBase):
|
|
|
96
96
|
f.flush()
|
|
97
97
|
|
|
98
98
|
raw_output = self.openstack(
|
|
99
|
-
'keypair create --public-key
|
|
99
|
+
f'keypair create --public-key {f.name} tmpkey',
|
|
100
100
|
)
|
|
101
101
|
self.addCleanup(
|
|
102
102
|
self.openstack,
|
|
@@ -113,7 +113,7 @@ class KeypairTests(KeypairBase):
|
|
|
113
113
|
"""
|
|
114
114
|
with tempfile.NamedTemporaryFile(mode='w+') as f:
|
|
115
115
|
cmd_output = self.openstack(
|
|
116
|
-
'keypair create --private-key
|
|
116
|
+
f'keypair create --private-key {f.name} tmpkey',
|
|
117
117
|
parse_output=True,
|
|
118
118
|
)
|
|
119
119
|
self.addCleanup(self.openstack, 'keypair delete tmpkey')
|
|
@@ -111,7 +111,7 @@ class ServerTests(common.ComputeTestCase):
|
|
|
111
111
|
)
|
|
112
112
|
except exceptions.CommandFailed as e:
|
|
113
113
|
self.assertIn(
|
|
114
|
-
'marker [
|
|
114
|
+
f'marker [{name2}] not found', e.stderr.decode('utf-8')
|
|
115
115
|
)
|
|
116
116
|
|
|
117
117
|
def test_server_list_with_changes_before(self):
|