python-openstackclient 7.4.0__py3-none-any.whl → 8.1.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/common/availability_zone.py +3 -6
- openstackclient/common/clientmanager.py +2 -1
- openstackclient/common/envvars.py +57 -0
- openstackclient/common/extension.py +3 -11
- openstackclient/common/limits.py +1 -1
- openstackclient/common/project_cleanup.py +3 -2
- openstackclient/common/quota.py +54 -28
- openstackclient/compute/client.py +7 -5
- openstackclient/compute/v2/agent.py +5 -5
- openstackclient/compute/v2/aggregate.py +17 -15
- openstackclient/compute/v2/console.py +10 -4
- openstackclient/compute/v2/console_connection.py +48 -0
- openstackclient/compute/v2/flavor.py +14 -18
- openstackclient/compute/v2/host.py +3 -3
- openstackclient/compute/v2/hypervisor.py +10 -4
- openstackclient/compute/v2/hypervisor_stats.py +1 -1
- openstackclient/compute/v2/keypair.py +18 -13
- openstackclient/compute/v2/server.py +144 -121
- openstackclient/compute/v2/server_backup.py +1 -1
- openstackclient/compute/v2/server_event.py +8 -17
- openstackclient/compute/v2/server_group.py +6 -6
- openstackclient/compute/v2/server_image.py +1 -1
- openstackclient/compute/v2/server_migration.py +6 -6
- openstackclient/compute/v2/server_volume.py +4 -4
- openstackclient/compute/v2/service.py +9 -13
- openstackclient/compute/v2/usage.py +4 -6
- openstackclient/identity/client.py +2 -4
- openstackclient/identity/common.py +95 -17
- openstackclient/identity/v2_0/ec2creds.py +4 -3
- openstackclient/identity/v2_0/endpoint.py +12 -10
- openstackclient/identity/v2_0/project.py +6 -6
- openstackclient/identity/v2_0/role.py +1 -1
- openstackclient/identity/v2_0/service.py +7 -7
- openstackclient/identity/v2_0/user.py +6 -21
- openstackclient/identity/v3/access_rule.py +2 -5
- openstackclient/identity/v3/application_credential.py +2 -2
- openstackclient/identity/v3/consumer.py +4 -3
- openstackclient/identity/v3/credential.py +6 -7
- openstackclient/identity/v3/domain.py +63 -44
- openstackclient/identity/v3/ec2creds.py +4 -3
- openstackclient/identity/v3/endpoint.py +104 -88
- openstackclient/identity/v3/endpoint_group.py +1 -1
- openstackclient/identity/v3/group.py +116 -72
- openstackclient/identity/v3/identity_provider.py +1 -2
- openstackclient/identity/v3/limit.py +4 -9
- openstackclient/identity/v3/mapping.py +4 -3
- openstackclient/identity/v3/policy.py +5 -8
- openstackclient/identity/v3/project.py +23 -6
- openstackclient/identity/v3/region.py +2 -5
- openstackclient/identity/v3/registered_limit.py +4 -8
- openstackclient/identity/v3/role.py +15 -16
- openstackclient/identity/v3/service.py +8 -8
- openstackclient/identity/v3/service_provider.py +3 -6
- openstackclient/identity/v3/tag.py +2 -2
- openstackclient/identity/v3/token.py +1 -2
- openstackclient/identity/v3/trust.py +74 -25
- openstackclient/identity/v3/user.py +47 -11
- openstackclient/image/client.py +7 -5
- openstackclient/image/v1/image.py +11 -15
- openstackclient/image/v2/cache.py +2 -4
- openstackclient/image/v2/image.py +41 -48
- openstackclient/image/v2/metadef_namespaces.py +4 -3
- openstackclient/image/v2/metadef_resource_type_association.py +1 -2
- openstackclient/image/v2/metadef_resource_types.py +1 -2
- openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +9 -1370
- openstackclient/network/client.py +4 -16
- openstackclient/network/common.py +16 -12
- openstackclient/network/utils.py +3 -3
- openstackclient/network/v2/address_group.py +5 -9
- openstackclient/network/v2/address_scope.py +2 -3
- openstackclient/network/v2/default_security_group_rule.py +1 -2
- openstackclient/network/v2/floating_ip.py +69 -47
- openstackclient/network/v2/floating_ip_port_forwarding.py +7 -7
- openstackclient/network/v2/ip_availability.py +1 -2
- openstackclient/network/v2/l3_conntrack_helper.py +8 -12
- openstackclient/network/v2/local_ip.py +24 -26
- openstackclient/network/v2/local_ip_association.py +4 -5
- openstackclient/network/v2/ndp_proxy.py +9 -10
- openstackclient/network/v2/network.py +12 -16
- openstackclient/network/v2/network_agent.py +29 -37
- openstackclient/network/v2/network_auto_allocated_topology.py +4 -5
- openstackclient/network/v2/network_flavor.py +1 -1
- openstackclient/network/v2/network_flavor_profile.py +5 -5
- openstackclient/network/v2/network_meter.py +3 -3
- openstackclient/network/v2/network_meter_rule.py +5 -8
- openstackclient/network/v2/network_qos_policy.py +4 -4
- openstackclient/network/v2/network_qos_rule.py +7 -16
- openstackclient/network/v2/network_rbac.py +4 -4
- openstackclient/network/v2/network_segment.py +6 -7
- openstackclient/network/v2/network_segment_range.py +16 -20
- openstackclient/network/v2/network_trunk.py +24 -16
- openstackclient/network/v2/port.py +28 -29
- openstackclient/network/v2/router.py +53 -42
- openstackclient/network/v2/security_group.py +13 -19
- openstackclient/network/v2/security_group_rule.py +10 -11
- openstackclient/network/v2/subnet.py +31 -30
- openstackclient/network/v2/subnet_pool.py +4 -4
- openstackclient/object/client.py +2 -3
- openstackclient/object/v1/container.py +2 -3
- openstackclient/object/v1/object.py +2 -9
- openstackclient/shell.py +22 -5
- openstackclient/tests/functional/base.py +7 -3
- openstackclient/tests/functional/common/test_quota.py +3 -1
- openstackclient/tests/functional/compute/v2/common.py +12 -6
- openstackclient/tests/functional/compute/v2/test_keypair.py +41 -5
- openstackclient/tests/functional/compute/v2/test_server.py +2 -3
- openstackclient/tests/functional/compute/v2/test_server_event.py +1 -1
- openstackclient/tests/functional/identity/v2/test_user.py +1 -1
- openstackclient/tests/functional/identity/v3/common.py +3 -8
- openstackclient/tests/functional/identity/v3/test_application_credential.py +10 -10
- openstackclient/tests/functional/identity/v3/test_endpoint.py +3 -3
- openstackclient/tests/functional/identity/v3/test_group.py +3 -3
- openstackclient/tests/functional/identity/v3/test_idp.py +3 -7
- openstackclient/tests/functional/identity/v3/test_limit.py +4 -4
- openstackclient/tests/functional/identity/v3/test_project.py +5 -14
- openstackclient/tests/functional/identity/v3/test_region.py +1 -3
- openstackclient/tests/functional/identity/v3/test_registered_limit.py +3 -3
- openstackclient/tests/functional/identity/v3/test_role.py +1 -1
- openstackclient/tests/functional/identity/v3/test_role_assignment.py +13 -31
- openstackclient/tests/functional/identity/v3/test_service_provider.py +3 -7
- openstackclient/tests/functional/identity/v3/test_user.py +8 -8
- openstackclient/tests/functional/network/v2/common.py +7 -3
- openstackclient/tests/functional/network/v2/test_address_group.py +4 -0
- openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py +15 -11
- openstackclient/tests/functional/network/v2/test_local_ip.py +4 -0
- openstackclient/tests/functional/network/v2/test_network_meter_rule.py +2 -2
- openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py +2 -3
- openstackclient/tests/functional/network/v2/test_network_rbac.py +2 -2
- openstackclient/tests/functional/network/v2/test_network_trunk.py +1 -1
- openstackclient/tests/functional/network/v2/test_port.py +17 -7
- openstackclient/tests/functional/network/v2/test_router.py +42 -0
- openstackclient/tests/functional/network/v2/test_subnet_pool.py +4 -0
- openstackclient/tests/unit/api/test_compute_v2.py +67 -87
- openstackclient/tests/unit/common/test_availability_zone.py +6 -14
- openstackclient/tests/unit/common/test_command.py +1 -1
- openstackclient/tests/unit/common/test_extension.py +5 -7
- openstackclient/tests/unit/common/test_limits.py +1 -1
- openstackclient/tests/unit/common/test_project_cleanup.py +5 -6
- openstackclient/tests/unit/common/test_quota.py +51 -28
- openstackclient/tests/unit/compute/v2/fakes.py +85 -315
- openstackclient/tests/unit/compute/v2/test_agent.py +16 -16
- openstackclient/tests/unit/compute/v2/test_aggregate.py +56 -60
- openstackclient/tests/unit/compute/v2/test_console.py +34 -17
- openstackclient/tests/unit/compute/v2/test_console_connection.py +72 -0
- openstackclient/tests/unit/compute/v2/test_flavor.py +72 -72
- openstackclient/tests/unit/compute/v2/test_host.py +8 -8
- openstackclient/tests/unit/compute/v2/test_hypervisor.py +22 -30
- openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -2
- openstackclient/tests/unit/compute/v2/test_keypair.py +36 -29
- openstackclient/tests/unit/compute/v2/test_server.py +693 -606
- openstackclient/tests/unit/compute/v2/test_server_backup.py +36 -77
- openstackclient/tests/unit/compute/v2/test_server_event.py +18 -20
- openstackclient/tests/unit/compute/v2/test_server_group.py +25 -31
- openstackclient/tests/unit/compute/v2/test_server_image.py +37 -78
- openstackclient/tests/unit/compute/v2/test_server_migration.py +41 -41
- openstackclient/tests/unit/compute/v2/test_server_volume.py +12 -12
- openstackclient/tests/unit/compute/v2/test_service.py +39 -45
- openstackclient/tests/unit/compute/v2/test_usage.py +5 -5
- openstackclient/tests/unit/identity/v2_0/fakes.py +1 -1
- openstackclient/tests/unit/identity/v3/test_access_rule.py +1 -3
- openstackclient/tests/unit/identity/v3/test_application_credential.py +48 -26
- openstackclient/tests/unit/identity/v3/test_domain.py +115 -105
- openstackclient/tests/unit/identity/v3/test_endpoint.py +167 -172
- openstackclient/tests/unit/identity/v3/test_group.py +353 -202
- openstackclient/tests/unit/identity/v3/test_mappings.py +2 -2
- openstackclient/tests/unit/identity/v3/test_project.py +16 -0
- openstackclient/tests/unit/identity/v3/test_trust.py +5 -2
- openstackclient/tests/unit/identity/v3/test_user.py +102 -6
- openstackclient/tests/unit/image/v1/fakes.py +2 -2
- openstackclient/tests/unit/image/v1/test_image.py +8 -9
- openstackclient/tests/unit/image/v2/test_image.py +84 -46
- openstackclient/tests/unit/integ/cli/test_shell.py +1 -2
- openstackclient/tests/unit/network/test_common.py +2 -2
- openstackclient/tests/unit/network/v2/fakes.py +405 -485
- openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +8 -14
- openstackclient/tests/unit/network/v2/test_floating_ip_network.py +62 -54
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +1 -1
- openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +2 -2
- openstackclient/tests/unit/network/v2/test_ndp_proxy.py +1 -3
- openstackclient/tests/unit/network/v2/test_network.py +4 -4
- openstackclient/tests/unit/network/v2/test_network_agent.py +15 -29
- openstackclient/tests/unit/network/v2/test_network_compute.py +11 -11
- openstackclient/tests/unit/network/v2/test_network_qos_policy.py +16 -19
- openstackclient/tests/unit/network/v2/test_network_qos_rule.py +79 -152
- openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +4 -6
- openstackclient/tests/unit/network/v2/test_network_rbac.py +2 -2
- openstackclient/tests/unit/network/v2/test_network_trunk.py +2 -2
- openstackclient/tests/unit/network/v2/test_port.py +21 -22
- openstackclient/tests/unit/network/v2/test_router.py +130 -51
- openstackclient/tests/unit/network/v2/test_security_group_compute.py +11 -19
- openstackclient/tests/unit/network/v2/test_security_group_network.py +25 -27
- openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +15 -17
- openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +33 -39
- openstackclient/tests/unit/object/v1/test_object_all.py +4 -3
- openstackclient/tests/unit/test_shell.py +16 -13
- openstackclient/tests/unit/volume/v2/fakes.py +1 -2
- openstackclient/tests/unit/volume/v2/test_service.py +57 -91
- openstackclient/tests/unit/volume/v2/test_volume.py +109 -106
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +141 -148
- openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +293 -283
- openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +1 -1
- openstackclient/tests/unit/volume/v3/fakes.py +2 -8
- openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +61 -71
- openstackclient/tests/unit/volume/v3/test_service.py +221 -141
- openstackclient/tests/unit/volume/v3/test_volume.py +131 -120
- openstackclient/tests/unit/volume/v3/test_volume_attachment.py +4 -4
- openstackclient/tests/unit/volume/v3/test_volume_backup.py +198 -203
- openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +683 -49
- openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py +1 -1
- openstackclient/volume/client.py +1 -3
- openstackclient/volume/v2/consistency_group.py +4 -8
- openstackclient/volume/v2/consistency_group_snapshot.py +1 -2
- openstackclient/volume/v2/qos_specs.py +1 -2
- openstackclient/volume/v2/service.py +41 -38
- openstackclient/volume/v2/volume.py +71 -53
- openstackclient/volume/v2/volume_backup.py +15 -10
- openstackclient/volume/v2/volume_snapshot.py +129 -93
- openstackclient/volume/v2/volume_transfer_request.py +0 -3
- openstackclient/volume/v2/volume_type.py +10 -21
- openstackclient/volume/v3/block_storage_cluster.py +3 -3
- openstackclient/volume/v3/block_storage_log_level.py +22 -28
- openstackclient/volume/v3/block_storage_manage.py +1 -3
- openstackclient/volume/v3/service.py +105 -14
- openstackclient/volume/v3/volume.py +218 -58
- openstackclient/volume/v3/volume_attachment.py +3 -2
- openstackclient/volume/v3/volume_backup.py +31 -27
- openstackclient/volume/v3/volume_group.py +2 -1
- openstackclient/volume/v3/volume_group_snapshot.py +2 -1
- openstackclient/volume/v3/volume_snapshot.py +489 -13
- openstackclient/volume/v3/volume_type.py +10 -21
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/AUTHORS +11 -0
- python_openstackclient-8.1.0.dist-info/METADATA +264 -0
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/RECORD +238 -259
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/WHEEL +1 -1
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/entry_points.txt +7 -47
- python_openstackclient-8.1.0.dist-info/pbr.json +1 -0
- openstackclient/tests/functional/volume/v1/__init__.py +0 -0
- openstackclient/tests/functional/volume/v1/common.py +0 -35
- openstackclient/tests/functional/volume/v1/test_qos.py +0 -100
- openstackclient/tests/functional/volume/v1/test_service.py +0 -76
- openstackclient/tests/functional/volume/v1/test_snapshot.py +0 -232
- openstackclient/tests/functional/volume/v1/test_transfer_request.py +0 -111
- openstackclient/tests/functional/volume/v1/test_volume.py +0 -228
- openstackclient/tests/functional/volume/v1/test_volume_type.py +0 -213
- openstackclient/tests/unit/volume/v1/__init__.py +0 -0
- openstackclient/tests/unit/volume/v1/fakes.py +0 -615
- openstackclient/tests/unit/volume/v1/test_qos_specs.py +0 -471
- openstackclient/tests/unit/volume/v1/test_service.py +0 -295
- openstackclient/tests/unit/volume/v1/test_transfer_request.py +0 -380
- openstackclient/tests/unit/volume/v1/test_type.py +0 -633
- openstackclient/tests/unit/volume/v1/test_volume.py +0 -1447
- openstackclient/tests/unit/volume/v1/test_volume_backup.py +0 -435
- openstackclient/volume/v1/__init__.py +0 -0
- openstackclient/volume/v1/qos_specs.py +0 -377
- openstackclient/volume/v1/service.py +0 -136
- openstackclient/volume/v1/volume.py +0 -734
- openstackclient/volume/v1/volume_backup.py +0 -302
- openstackclient/volume/v1/volume_snapshot.py +0 -433
- openstackclient/volume/v1/volume_transfer_request.py +0 -200
- openstackclient/volume/v1/volume_type.py +0 -520
- python_openstackclient-7.4.0.dist-info/METADATA +0 -172
- python_openstackclient-7.4.0.dist-info/pbr.json +0 -1
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/LICENSE +0 -0
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/top_level.txt +0 -0
|
@@ -136,8 +136,7 @@ class CreateRequestToken(command.ShowOne):
|
|
|
136
136
|
'--project',
|
|
137
137
|
metavar='<project>',
|
|
138
138
|
help=_(
|
|
139
|
-
'Project that consumer wants to access (name or ID)'
|
|
140
|
-
' (required)'
|
|
139
|
+
'Project that consumer wants to access (name or ID) (required)'
|
|
141
140
|
),
|
|
142
141
|
required=True,
|
|
143
142
|
)
|
|
@@ -123,37 +123,67 @@ class CreateTrust(command.ShowOne):
|
|
|
123
123
|
# pointless, and trusts are immutable, so let's enforce it at the
|
|
124
124
|
# client level.
|
|
125
125
|
try:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
if parsed_args.trustor_domain:
|
|
127
|
+
trustor_domain_id = identity_client.find_domain(
|
|
128
|
+
parsed_args.trustor_domain, ignore_missing=False
|
|
129
|
+
).id
|
|
130
|
+
trustor_id = identity_client.find_user(
|
|
131
|
+
parsed_args.trustor,
|
|
132
|
+
ignore_missing=False,
|
|
133
|
+
domain_id=trustor_domain_id,
|
|
134
|
+
).id
|
|
135
|
+
else:
|
|
136
|
+
trustor_id = identity_client.find_user(
|
|
137
|
+
parsed_args.trustor, ignore_missing=False
|
|
138
|
+
).id
|
|
139
|
+
kwargs['trustor_user_id'] = trustor_id
|
|
130
140
|
except sdk_exceptions.ForbiddenException:
|
|
131
|
-
kwargs['
|
|
141
|
+
kwargs['trustor_user_id'] = parsed_args.trustor
|
|
132
142
|
|
|
133
143
|
try:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
144
|
+
if parsed_args.trustee_domain:
|
|
145
|
+
trustee_domain_id = identity_client.find_domain(
|
|
146
|
+
parsed_args.trustee_domain, ignore_missing=False
|
|
147
|
+
).id
|
|
148
|
+
trustee_id = identity_client.find_user(
|
|
149
|
+
parsed_args.trustee,
|
|
150
|
+
ignore_missing=False,
|
|
151
|
+
domain_id=trustee_domain_id,
|
|
152
|
+
).id
|
|
153
|
+
else:
|
|
154
|
+
trustee_id = identity_client.find_user(
|
|
155
|
+
parsed_args.trustee, ignore_missing=False
|
|
156
|
+
).id
|
|
157
|
+
kwargs['trustee_user_id'] = trustee_id
|
|
138
158
|
except sdk_exceptions.ForbiddenException:
|
|
139
|
-
kwargs['
|
|
159
|
+
kwargs['trustee_user_id'] = parsed_args.trustee
|
|
140
160
|
|
|
141
161
|
try:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
162
|
+
if parsed_args.project_domain:
|
|
163
|
+
project_domain_id = identity_client.find_domain(
|
|
164
|
+
parsed_args.project_domain, ignore_missing=False
|
|
165
|
+
).id
|
|
166
|
+
project_id = identity_client.find_project(
|
|
167
|
+
parsed_args.project,
|
|
168
|
+
ignore_missing=False,
|
|
169
|
+
domain_id=project_domain_id,
|
|
170
|
+
).id
|
|
171
|
+
else:
|
|
172
|
+
project_id = identity_client.find_project(
|
|
173
|
+
parsed_args.project, ignore_missing=False
|
|
174
|
+
).id
|
|
145
175
|
kwargs['project_id'] = project_id
|
|
146
176
|
except sdk_exceptions.ForbiddenException:
|
|
147
177
|
kwargs['project_id'] = parsed_args.project
|
|
148
178
|
|
|
149
|
-
|
|
179
|
+
roles = []
|
|
150
180
|
for role in parsed_args.roles:
|
|
151
181
|
try:
|
|
152
182
|
role_id = identity_client.find_role(role).id
|
|
153
183
|
except sdk_exceptions.ForbiddenException:
|
|
154
184
|
role_id = role
|
|
155
|
-
|
|
156
|
-
kwargs['roles'] =
|
|
185
|
+
roles.append({"id": role_id})
|
|
186
|
+
kwargs['roles'] = roles
|
|
157
187
|
|
|
158
188
|
if parsed_args.expiration:
|
|
159
189
|
expires_at = datetime.datetime.strptime(
|
|
@@ -161,8 +191,7 @@ class CreateTrust(command.ShowOne):
|
|
|
161
191
|
)
|
|
162
192
|
kwargs['expires_at'] = expires_at
|
|
163
193
|
|
|
164
|
-
|
|
165
|
-
kwargs['is_impersonation'] = parsed_args.is_impersonation
|
|
194
|
+
kwargs['impersonation'] = bool(parsed_args.is_impersonation)
|
|
166
195
|
|
|
167
196
|
trust = identity_client.create_trust(**kwargs)
|
|
168
197
|
|
|
@@ -204,7 +233,7 @@ class DeleteTrust(command.Command):
|
|
|
204
233
|
|
|
205
234
|
if errors > 0:
|
|
206
235
|
total = len(parsed_args.trust)
|
|
207
|
-
msg = _("%(errors)s of %(total)s trusts failed
|
|
236
|
+
msg = _("%(errors)s of %(total)s trusts failed to delete.") % {
|
|
208
237
|
'errors': errors,
|
|
209
238
|
'total': total,
|
|
210
239
|
}
|
|
@@ -289,9 +318,19 @@ class ListTrust(command.Lister):
|
|
|
289
318
|
trustor = None
|
|
290
319
|
if parsed_args.trustor:
|
|
291
320
|
try:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
321
|
+
if parsed_args.trustor_domain:
|
|
322
|
+
trustor_domain_id = identity_client.find_domain(
|
|
323
|
+
parsed_args.trustor_domain, ignore_missing=False
|
|
324
|
+
).id
|
|
325
|
+
trustor_id = identity_client.find_user(
|
|
326
|
+
parsed_args.trustor,
|
|
327
|
+
ignore_missing=False,
|
|
328
|
+
domain_id=trustor_domain_id,
|
|
329
|
+
).id
|
|
330
|
+
else:
|
|
331
|
+
trustor_id = identity_client.find_user(
|
|
332
|
+
parsed_args.trustor, ignore_missing=False
|
|
333
|
+
).id
|
|
295
334
|
trustor = trustor_id
|
|
296
335
|
except sdk_exceptions.ForbiddenException:
|
|
297
336
|
trustor = parsed_args.trustor
|
|
@@ -299,9 +338,19 @@ class ListTrust(command.Lister):
|
|
|
299
338
|
trustee = None
|
|
300
339
|
if parsed_args.trustee:
|
|
301
340
|
try:
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
341
|
+
if parsed_args.trustee_domain:
|
|
342
|
+
trustee_domain_id = identity_client.find_domain(
|
|
343
|
+
parsed_args.trustee_domain, ignore_missing=False
|
|
344
|
+
).id
|
|
345
|
+
trustee_id = identity_client.find_user(
|
|
346
|
+
parsed_args.trustee,
|
|
347
|
+
ignore_missing=False,
|
|
348
|
+
domain_id=trustee_domain_id,
|
|
349
|
+
).id
|
|
350
|
+
else:
|
|
351
|
+
trustee_id = identity_client.find_user(
|
|
352
|
+
parsed_args.trustee, ignore_missing=False
|
|
353
|
+
).id
|
|
305
354
|
trustee = trustee_id
|
|
306
355
|
except sdk_exceptions.ForbiddenException:
|
|
307
356
|
trustee = parsed_args.trustee
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import copy
|
|
19
19
|
import logging
|
|
20
|
+
import typing as ty
|
|
20
21
|
|
|
21
22
|
from openstack import exceptions as sdk_exc
|
|
22
23
|
from osc_lib.command import command
|
|
@@ -40,6 +41,7 @@ def _format_user(user):
|
|
|
40
41
|
'name',
|
|
41
42
|
'description',
|
|
42
43
|
'password_expires_at',
|
|
44
|
+
'options',
|
|
43
45
|
)
|
|
44
46
|
column_headers = (
|
|
45
47
|
'default_project_id',
|
|
@@ -50,6 +52,7 @@ def _format_user(user):
|
|
|
50
52
|
'name',
|
|
51
53
|
'description',
|
|
52
54
|
'password_expires_at',
|
|
55
|
+
'options',
|
|
53
56
|
)
|
|
54
57
|
return (
|
|
55
58
|
column_headers,
|
|
@@ -58,7 +61,7 @@ def _format_user(user):
|
|
|
58
61
|
|
|
59
62
|
|
|
60
63
|
def _get_options_for_user(identity_client, parsed_args):
|
|
61
|
-
options = {}
|
|
64
|
+
options: dict[str, ty.Any] = {}
|
|
62
65
|
if parsed_args.ignore_lockout_failure_attempts:
|
|
63
66
|
options['ignore_lockout_failure_attempts'] = True
|
|
64
67
|
if parsed_args.no_ignore_lockout_failure_attempts:
|
|
@@ -288,7 +291,7 @@ class CreateUser(command.ShowOne):
|
|
|
288
291
|
elif parsed_args.password_prompt:
|
|
289
292
|
password = utils.get_password(self.app.stdin)
|
|
290
293
|
|
|
291
|
-
if not
|
|
294
|
+
if not password:
|
|
292
295
|
LOG.warning(
|
|
293
296
|
_(
|
|
294
297
|
"No password was supplied, authentication will fail "
|
|
@@ -377,7 +380,7 @@ class DeleteUser(command.Command):
|
|
|
377
380
|
|
|
378
381
|
if errors > 0:
|
|
379
382
|
total = len(parsed_args.users)
|
|
380
|
-
msg = _("%(errors)s of %(total)s users failed
|
|
383
|
+
msg = _("%(errors)s of %(total)s users failed to delete.") % {
|
|
381
384
|
'errors': errors,
|
|
382
385
|
'total': total,
|
|
383
386
|
}
|
|
@@ -411,6 +414,24 @@ class ListUser(command.Lister):
|
|
|
411
414
|
default=False,
|
|
412
415
|
help=_('List additional fields in output'),
|
|
413
416
|
)
|
|
417
|
+
parser.add_argument(
|
|
418
|
+
'--enabled',
|
|
419
|
+
action='store_true',
|
|
420
|
+
dest='is_enabled',
|
|
421
|
+
default=None,
|
|
422
|
+
help=_(
|
|
423
|
+
'List only enabled users, does nothing with --project and --group'
|
|
424
|
+
),
|
|
425
|
+
)
|
|
426
|
+
parser.add_argument(
|
|
427
|
+
'--disabled',
|
|
428
|
+
action='store_false',
|
|
429
|
+
dest='is_enabled',
|
|
430
|
+
default=None,
|
|
431
|
+
help=_(
|
|
432
|
+
'List only disabled users, does nothing with --project and --group'
|
|
433
|
+
),
|
|
434
|
+
)
|
|
414
435
|
return parser
|
|
415
436
|
|
|
416
437
|
def take_action(self, parsed_args):
|
|
@@ -430,6 +451,9 @@ class ListUser(command.Lister):
|
|
|
430
451
|
ignore_missing=False,
|
|
431
452
|
).id
|
|
432
453
|
|
|
454
|
+
if parsed_args.is_enabled is not None:
|
|
455
|
+
enabled = parsed_args.is_enabled
|
|
456
|
+
|
|
433
457
|
if parsed_args.project:
|
|
434
458
|
if domain is not None:
|
|
435
459
|
project = identity_client.find_project(
|
|
@@ -468,9 +492,15 @@ class ListUser(command.Lister):
|
|
|
468
492
|
group=group,
|
|
469
493
|
)
|
|
470
494
|
else:
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
495
|
+
if parsed_args.is_enabled is not None:
|
|
496
|
+
data = identity_client.users(
|
|
497
|
+
domain_id=domain,
|
|
498
|
+
is_enabled=enabled,
|
|
499
|
+
)
|
|
500
|
+
else:
|
|
501
|
+
data = identity_client.users(
|
|
502
|
+
domain_id=domain,
|
|
503
|
+
)
|
|
474
504
|
|
|
475
505
|
# Column handling
|
|
476
506
|
if parsed_args.long:
|
|
@@ -612,10 +642,12 @@ class SetUser(command.Command):
|
|
|
612
642
|
if parsed_args.description:
|
|
613
643
|
kwargs['description'] = parsed_args.description
|
|
614
644
|
if parsed_args.project:
|
|
615
|
-
project_domain_id =
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
645
|
+
project_domain_id = None
|
|
646
|
+
if parsed_args.project_domain:
|
|
647
|
+
project_domain_id = identity_client.find_domain(
|
|
648
|
+
name_or_id=parsed_args.project_domain,
|
|
649
|
+
ignore_missing=False,
|
|
650
|
+
).id
|
|
619
651
|
project_id = identity_client.find_project(
|
|
620
652
|
name_or_id=parsed_args.project,
|
|
621
653
|
ignore_missing=False,
|
|
@@ -656,6 +688,8 @@ class SetPasswordUser(command.Command):
|
|
|
656
688
|
|
|
657
689
|
def take_action(self, parsed_args):
|
|
658
690
|
identity_client = self.app.client_manager.sdk_connection.identity
|
|
691
|
+
conn = self.app.client_manager.sdk_connection
|
|
692
|
+
user_id = conn.config.get_auth().get_user_id(conn.identity)
|
|
659
693
|
|
|
660
694
|
# FIXME(gyee): there are two scenarios:
|
|
661
695
|
#
|
|
@@ -698,7 +732,9 @@ class SetPasswordUser(command.Command):
|
|
|
698
732
|
)
|
|
699
733
|
|
|
700
734
|
identity_client.update_user(
|
|
701
|
-
|
|
735
|
+
user=user_id,
|
|
736
|
+
current_password=current_password,
|
|
737
|
+
password=password,
|
|
702
738
|
)
|
|
703
739
|
|
|
704
740
|
|
openstackclient/image/client.py
CHANGED
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
12
12
|
# License for the specific language governing permissions and limitations
|
|
13
13
|
# under the License.
|
|
14
|
-
#
|
|
15
14
|
|
|
16
15
|
import logging
|
|
17
16
|
|
|
@@ -21,13 +20,11 @@ from openstackclient.i18n import _
|
|
|
21
20
|
|
|
22
21
|
LOG = logging.getLogger(__name__)
|
|
23
22
|
|
|
23
|
+
# global variables used when building the shell
|
|
24
24
|
DEFAULT_API_VERSION = '2'
|
|
25
25
|
API_VERSION_OPTION = 'os_image_api_version'
|
|
26
26
|
API_NAME = 'image'
|
|
27
|
-
API_VERSIONS =
|
|
28
|
-
'1': 'openstack.connection.Connection',
|
|
29
|
-
'2': 'openstack.connection.Connection',
|
|
30
|
-
}
|
|
27
|
+
API_VERSIONS = ('1', '2')
|
|
31
28
|
|
|
32
29
|
|
|
33
30
|
def make_client(instance):
|
|
@@ -49,3 +46,8 @@ def build_option_parser(parser):
|
|
|
49
46
|
% DEFAULT_API_VERSION,
|
|
50
47
|
)
|
|
51
48
|
return parser
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def check_api_version(check_version):
|
|
52
|
+
# SDK supports auto-negotiation for us: always return True
|
|
53
|
+
return True
|
|
@@ -30,12 +30,6 @@ from osc_lib import utils
|
|
|
30
30
|
|
|
31
31
|
from openstackclient.i18n import _
|
|
32
32
|
|
|
33
|
-
if os.name == "nt":
|
|
34
|
-
import msvcrt
|
|
35
|
-
else:
|
|
36
|
-
msvcrt = None
|
|
37
|
-
|
|
38
|
-
|
|
39
33
|
CONTAINER_CHOICES = ["ami", "ari", "aki", "bare", "docker", "ova", "ovf"]
|
|
40
34
|
DEFAULT_CONTAINER_FORMAT = 'bare'
|
|
41
35
|
DEFAULT_DISK_FORMAT = 'raw'
|
|
@@ -53,7 +47,6 @@ DISK_CHOICES = [
|
|
|
53
47
|
"ploop",
|
|
54
48
|
]
|
|
55
49
|
|
|
56
|
-
|
|
57
50
|
LOG = logging.getLogger(__name__)
|
|
58
51
|
|
|
59
52
|
|
|
@@ -323,8 +316,10 @@ class CreateImage(command.ShowOne):
|
|
|
323
316
|
else:
|
|
324
317
|
# Read file from stdin
|
|
325
318
|
if not sys.stdin.isatty():
|
|
326
|
-
if
|
|
327
|
-
msvcrt
|
|
319
|
+
if os.name == "nt":
|
|
320
|
+
import msvcrt
|
|
321
|
+
|
|
322
|
+
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) # type: ignore
|
|
328
323
|
if hasattr(sys.stdin, 'buffer'):
|
|
329
324
|
kwargs['data'] = sys.stdin.buffer
|
|
330
325
|
else:
|
|
@@ -384,8 +379,7 @@ class DeleteImage(command.Command):
|
|
|
384
379
|
except Exception as e:
|
|
385
380
|
result += 1
|
|
386
381
|
msg = _(
|
|
387
|
-
"Failed to delete image with name or "
|
|
388
|
-
"ID '%(image)s': %(e)s"
|
|
382
|
+
"Failed to delete image with name or ID '%(image)s': %(e)s"
|
|
389
383
|
)
|
|
390
384
|
LOG.error(msg, {'image': image, 'e': e})
|
|
391
385
|
|
|
@@ -468,7 +462,7 @@ class ListImage(command.Lister):
|
|
|
468
462
|
kwargs['is_private'] = True
|
|
469
463
|
|
|
470
464
|
if parsed_args.long:
|
|
471
|
-
columns = (
|
|
465
|
+
columns: tuple[str, ...] = (
|
|
472
466
|
'ID',
|
|
473
467
|
'Name',
|
|
474
468
|
'Disk Format',
|
|
@@ -481,7 +475,7 @@ class ListImage(command.Lister):
|
|
|
481
475
|
'owner_id',
|
|
482
476
|
'properties',
|
|
483
477
|
)
|
|
484
|
-
column_headers = (
|
|
478
|
+
column_headers: tuple[str, ...] = (
|
|
485
479
|
'ID',
|
|
486
480
|
'Name',
|
|
487
481
|
'Disk Format',
|
|
@@ -775,8 +769,10 @@ class SetImage(command.Command):
|
|
|
775
769
|
# Read file from stdin
|
|
776
770
|
if sys.stdin.isatty() is not True:
|
|
777
771
|
if parsed_args.stdin:
|
|
778
|
-
if
|
|
779
|
-
msvcrt
|
|
772
|
+
if os.name == "nt":
|
|
773
|
+
import msvcrt
|
|
774
|
+
|
|
775
|
+
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) # type: ignore
|
|
780
776
|
if hasattr(sys.stdin, 'buffer'):
|
|
781
777
|
kwargs['data'] = sys.stdin.buffer
|
|
782
778
|
else:
|
|
@@ -131,8 +131,7 @@ class QueueCachedImage(command.Command):
|
|
|
131
131
|
except Exception as e:
|
|
132
132
|
failures += 1
|
|
133
133
|
msg = _(
|
|
134
|
-
"Failed to queue image with name or "
|
|
135
|
-
"ID '%(image)s': %(e)s"
|
|
134
|
+
"Failed to queue image with name or ID '%(image)s': %(e)s"
|
|
136
135
|
)
|
|
137
136
|
LOG.error(msg, {'image': image, 'e': e})
|
|
138
137
|
|
|
@@ -171,8 +170,7 @@ class DeleteCachedImage(command.Command):
|
|
|
171
170
|
except Exception as e:
|
|
172
171
|
failures += 1
|
|
173
172
|
msg = _(
|
|
174
|
-
"Failed to delete image with name or "
|
|
175
|
-
"ID '%(image)s': %(e)s"
|
|
173
|
+
"Failed to delete image with name or ID '%(image)s': %(e)s"
|
|
176
174
|
)
|
|
177
175
|
LOG.error(msg, {'image': image, 'e': e})
|
|
178
176
|
|
|
@@ -17,13 +17,15 @@
|
|
|
17
17
|
|
|
18
18
|
import argparse
|
|
19
19
|
from base64 import b64encode
|
|
20
|
+
import copy
|
|
20
21
|
import logging
|
|
21
22
|
import os
|
|
22
23
|
import sys
|
|
24
|
+
import typing as ty
|
|
23
25
|
|
|
24
|
-
from cinderclient import api_versions
|
|
25
26
|
from openstack import exceptions as sdk_exceptions
|
|
26
27
|
from openstack.image import image_signer
|
|
28
|
+
from openstack import utils as sdk_utils
|
|
27
29
|
from osc_lib.api import utils as api_utils
|
|
28
30
|
from osc_lib.cli import format_columns
|
|
29
31
|
from osc_lib.cli import parseractions
|
|
@@ -36,12 +38,6 @@ from openstackclient.common import progressbar
|
|
|
36
38
|
from openstackclient.i18n import _
|
|
37
39
|
from openstackclient.identity import common as identity_common
|
|
38
40
|
|
|
39
|
-
if os.name == "nt":
|
|
40
|
-
import msvcrt
|
|
41
|
-
else:
|
|
42
|
-
msvcrt = None
|
|
43
|
-
|
|
44
|
-
|
|
45
41
|
CONTAINER_CHOICES = ["ami", "ari", "aki", "bare", "docker", "ova", "ovf"]
|
|
46
42
|
DEFAULT_CONTAINER_FORMAT = 'bare'
|
|
47
43
|
DEFAULT_DISK_FORMAT = 'raw'
|
|
@@ -60,7 +56,6 @@ DISK_CHOICES = [
|
|
|
60
56
|
]
|
|
61
57
|
MEMBER_STATUS_CHOICES = ["accepted", "pending", "rejected", "all"]
|
|
62
58
|
|
|
63
|
-
|
|
64
59
|
LOG = logging.getLogger(__name__)
|
|
65
60
|
|
|
66
61
|
|
|
@@ -154,8 +149,10 @@ def get_data_from_stdin():
|
|
|
154
149
|
image = sys.stdin
|
|
155
150
|
if hasattr(sys.stdin, 'buffer'):
|
|
156
151
|
image = sys.stdin.buffer
|
|
157
|
-
if
|
|
158
|
-
msvcrt
|
|
152
|
+
if os.name == "nt":
|
|
153
|
+
import msvcrt
|
|
154
|
+
|
|
155
|
+
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) # type: ignore
|
|
159
156
|
|
|
160
157
|
return image
|
|
161
158
|
else:
|
|
@@ -359,8 +356,7 @@ class CreateImage(command.ShowOne):
|
|
|
359
356
|
action="store_true",
|
|
360
357
|
default=False,
|
|
361
358
|
help=_(
|
|
362
|
-
"Show upload progress bar "
|
|
363
|
-
"(ignored if passing data via stdin)"
|
|
359
|
+
"Show upload progress bar (ignored if passing data via stdin)"
|
|
364
360
|
),
|
|
365
361
|
)
|
|
366
362
|
parser.add_argument(
|
|
@@ -401,8 +397,7 @@ class CreateImage(command.ShowOne):
|
|
|
401
397
|
metavar="<tag>",
|
|
402
398
|
action='append',
|
|
403
399
|
help=_(
|
|
404
|
-
"Set a tag on this image "
|
|
405
|
-
"(repeat option to set multiple tags)"
|
|
400
|
+
"Set a tag on this image (repeat option to set multiple tags)"
|
|
406
401
|
),
|
|
407
402
|
)
|
|
408
403
|
parser.add_argument(
|
|
@@ -434,7 +429,7 @@ class CreateImage(command.ShowOne):
|
|
|
434
429
|
|
|
435
430
|
# Build an attribute dict from the parsed args, only include
|
|
436
431
|
# attributes that were actually set on the command line
|
|
437
|
-
kwargs = {'allow_duplicates': True}
|
|
432
|
+
kwargs: dict[str, ty.Any] = {'allow_duplicates': True}
|
|
438
433
|
copy_attrs = (
|
|
439
434
|
'name',
|
|
440
435
|
'id',
|
|
@@ -582,7 +577,7 @@ class CreateImage(command.ShowOne):
|
|
|
582
577
|
return _format_image(image)
|
|
583
578
|
|
|
584
579
|
def _take_action_volume(self, parsed_args):
|
|
585
|
-
volume_client = self.app.client_manager.volume
|
|
580
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
586
581
|
|
|
587
582
|
unsupported_opts = {
|
|
588
583
|
# 'name', # 'name' is a positional argument and will always exist
|
|
@@ -613,12 +608,14 @@ class CreateImage(command.ShowOne):
|
|
|
613
608
|
# version
|
|
614
609
|
LOG.warning(msg % opt_name)
|
|
615
610
|
|
|
616
|
-
source_volume =
|
|
617
|
-
|
|
618
|
-
parsed_args.volume,
|
|
611
|
+
source_volume = volume_client.find_volume(
|
|
612
|
+
parsed_args.volume, ignore_missing=False
|
|
619
613
|
)
|
|
620
|
-
kwargs = {
|
|
621
|
-
|
|
614
|
+
kwargs: dict[str, ty.Any] = {
|
|
615
|
+
'visibility': None,
|
|
616
|
+
'protected': None,
|
|
617
|
+
}
|
|
618
|
+
if not sdk_utils.supports_microversion(volume_client, '3.1'):
|
|
622
619
|
if parsed_args.visibility or parsed_args.is_protected is not None:
|
|
623
620
|
msg = _(
|
|
624
621
|
'--os-volume-api-version 3.1 or greater is required '
|
|
@@ -627,20 +624,18 @@ class CreateImage(command.ShowOne):
|
|
|
627
624
|
)
|
|
628
625
|
raise exceptions.CommandError(msg)
|
|
629
626
|
else:
|
|
630
|
-
kwargs.
|
|
631
|
-
|
|
632
|
-
protected=parsed_args.is_protected or False,
|
|
633
|
-
)
|
|
627
|
+
kwargs['visibility'] = parsed_args.visibility or 'private'
|
|
628
|
+
kwargs['protected'] = parsed_args.is_protected or False
|
|
634
629
|
|
|
635
|
-
response
|
|
630
|
+
response = volume_client.upload_volume_to_image(
|
|
636
631
|
source_volume.id,
|
|
637
|
-
parsed_args.force,
|
|
638
632
|
parsed_args.name,
|
|
639
|
-
parsed_args.
|
|
640
|
-
parsed_args.disk_format,
|
|
633
|
+
force=parsed_args.force,
|
|
634
|
+
disk_format=parsed_args.disk_format,
|
|
635
|
+
container_format=parsed_args.container_format,
|
|
641
636
|
**kwargs,
|
|
642
637
|
)
|
|
643
|
-
info =
|
|
638
|
+
info = copy.deepcopy(response)
|
|
644
639
|
try:
|
|
645
640
|
info['volume_type'] = info['volume_type']['name']
|
|
646
641
|
except TypeError:
|
|
@@ -705,8 +700,7 @@ class DeleteImage(command.Command):
|
|
|
705
700
|
except Exception as e:
|
|
706
701
|
result += 1
|
|
707
702
|
msg = _(
|
|
708
|
-
"Failed to delete image with name or "
|
|
709
|
-
"ID '%(image)s': %(e)s"
|
|
703
|
+
"Failed to delete image with name or ID '%(image)s': %(e)s"
|
|
710
704
|
)
|
|
711
705
|
LOG.error(msg, {'image': image, 'e': e})
|
|
712
706
|
|
|
@@ -884,7 +878,7 @@ class ListImage(command.Lister):
|
|
|
884
878
|
if parsed_args.is_hidden:
|
|
885
879
|
kwargs['is_hidden'] = parsed_args.is_hidden
|
|
886
880
|
if parsed_args.long:
|
|
887
|
-
columns = (
|
|
881
|
+
columns: tuple[str, ...] = (
|
|
888
882
|
'ID',
|
|
889
883
|
'Name',
|
|
890
884
|
'Disk Format',
|
|
@@ -897,7 +891,7 @@ class ListImage(command.Lister):
|
|
|
897
891
|
'owner_id',
|
|
898
892
|
'tags',
|
|
899
893
|
)
|
|
900
|
-
column_headers = (
|
|
894
|
+
column_headers: tuple[str, ...] = (
|
|
901
895
|
'ID',
|
|
902
896
|
'Name',
|
|
903
897
|
'Disk Format',
|
|
@@ -959,7 +953,7 @@ class ListImageProjects(command.Lister):
|
|
|
959
953
|
|
|
960
954
|
def take_action(self, parsed_args):
|
|
961
955
|
image_client = self.app.client_manager.image
|
|
962
|
-
columns = ("Image ID", "Member ID", "Status")
|
|
956
|
+
columns: tuple[str, ...] = ("Image ID", "Member ID", "Status")
|
|
963
957
|
|
|
964
958
|
image_id = image_client.find_image(
|
|
965
959
|
parsed_args.image,
|
|
@@ -1153,8 +1147,7 @@ class SetImage(command.Command):
|
|
|
1153
1147
|
default=None,
|
|
1154
1148
|
action='append',
|
|
1155
1149
|
help=_(
|
|
1156
|
-
"Set a tag on this image "
|
|
1157
|
-
"(repeat option to set multiple tags)"
|
|
1150
|
+
"Set a tag on this image (repeat option to set multiple tags)"
|
|
1158
1151
|
),
|
|
1159
1152
|
)
|
|
1160
1153
|
parser.add_argument(
|
|
@@ -1457,7 +1450,6 @@ class UnsetImage(command.Command):
|
|
|
1457
1450
|
ignore_missing=False,
|
|
1458
1451
|
)
|
|
1459
1452
|
|
|
1460
|
-
kwargs = {}
|
|
1461
1453
|
tagret = 0
|
|
1462
1454
|
propret = 0
|
|
1463
1455
|
if parsed_args.tags:
|
|
@@ -1466,10 +1458,11 @@ class UnsetImage(command.Command):
|
|
|
1466
1458
|
image_client.remove_tag(image.id, k)
|
|
1467
1459
|
except Exception:
|
|
1468
1460
|
LOG.error(
|
|
1469
|
-
_("tag unset failed, '%s' is a
|
|
1461
|
+
_("tag unset failed, '%s' is a nonexistent tag "), k
|
|
1470
1462
|
)
|
|
1471
1463
|
tagret += 1
|
|
1472
1464
|
|
|
1465
|
+
kwargs: dict[str, ty.Any] = {}
|
|
1473
1466
|
if parsed_args.properties:
|
|
1474
1467
|
for k in parsed_args.properties:
|
|
1475
1468
|
if k in image:
|
|
@@ -1519,7 +1512,7 @@ class UnsetImage(command.Command):
|
|
|
1519
1512
|
raise exceptions.CommandError(msg)
|
|
1520
1513
|
elif propret > 0:
|
|
1521
1514
|
msg = _(
|
|
1522
|
-
"Failed to unset %(propret)s of %(proptotal)s
|
|
1515
|
+
"Failed to unset %(propret)s of %(proptotal)s properties."
|
|
1523
1516
|
) % {'propret': propret, 'proptotal': proptotal}
|
|
1524
1517
|
raise exceptions.CommandError(msg)
|
|
1525
1518
|
|
|
@@ -1551,8 +1544,7 @@ class StageImage(command.Command):
|
|
|
1551
1544
|
action='store_true',
|
|
1552
1545
|
default=False,
|
|
1553
1546
|
help=_(
|
|
1554
|
-
'Show upload progress bar '
|
|
1555
|
-
'(ignored if passing data via stdin)'
|
|
1547
|
+
'Show upload progress bar (ignored if passing data via stdin)'
|
|
1556
1548
|
),
|
|
1557
1549
|
)
|
|
1558
1550
|
parser.add_argument(
|
|
@@ -1583,7 +1575,7 @@ class StageImage(command.Command):
|
|
|
1583
1575
|
else:
|
|
1584
1576
|
fp = get_data_from_stdin()
|
|
1585
1577
|
|
|
1586
|
-
kwargs = {}
|
|
1578
|
+
kwargs: dict[str, ty.Any] = {}
|
|
1587
1579
|
|
|
1588
1580
|
if parsed_args.progress and parsed_args.filename:
|
|
1589
1581
|
# NOTE(stephenfin): we only show a progress bar if the user
|
|
@@ -1689,7 +1681,8 @@ class ImportImage(command.ShowOne):
|
|
|
1689
1681
|
"'copy-image' import method)"
|
|
1690
1682
|
),
|
|
1691
1683
|
)
|
|
1692
|
-
parser.
|
|
1684
|
+
allow_failure_group = parser.add_mutually_exclusive_group()
|
|
1685
|
+
allow_failure_group.add_argument(
|
|
1693
1686
|
'--allow-failure',
|
|
1694
1687
|
action='store_true',
|
|
1695
1688
|
dest='allow_failure',
|
|
@@ -1700,9 +1693,9 @@ class ImportImage(command.ShowOne):
|
|
|
1700
1693
|
'Only usable with --stores or --all-stores'
|
|
1701
1694
|
),
|
|
1702
1695
|
)
|
|
1703
|
-
|
|
1696
|
+
allow_failure_group.add_argument(
|
|
1704
1697
|
'--disallow-failure',
|
|
1705
|
-
action='
|
|
1698
|
+
action='store_false',
|
|
1706
1699
|
dest='allow_failure',
|
|
1707
1700
|
default=True,
|
|
1708
1701
|
help=_(
|
|
@@ -1866,8 +1859,8 @@ class StoresInfo(command.Lister):
|
|
|
1866
1859
|
def take_action(self, parsed_args):
|
|
1867
1860
|
image_client = self.app.client_manager.image
|
|
1868
1861
|
try:
|
|
1869
|
-
columns = ("id", "description", "is_default")
|
|
1870
|
-
column_headers = ("ID", "Description", "Default")
|
|
1862
|
+
columns: tuple[str, ...] = ("id", "description", "is_default")
|
|
1863
|
+
column_headers: tuple[str, ...] = ("ID", "Description", "Default")
|
|
1871
1864
|
if parsed_args.detail:
|
|
1872
1865
|
columns += ("properties",)
|
|
1873
1866
|
column_headers += ("Properties",)
|