python-openstackclient 8.3.0__py3-none-any.whl → 10.0.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/__init__.py +2 -6
- openstackclient/api/api.py +41 -23
- openstackclient/api/compute_v2.py +44 -25
- openstackclient/api/object_store_v1.py +75 -97
- openstackclient/api/volume_v2.py +2 -1
- openstackclient/api/volume_v3.py +2 -1
- openstackclient/common/availability_zone.py +58 -42
- openstackclient/common/clientmanager.py +56 -29
- openstackclient/common/configuration.py +10 -3
- openstackclient/common/envvars.py +2 -2
- openstackclient/common/extension.py +14 -5
- openstackclient/common/limits.py +10 -5
- openstackclient/common/module.py +14 -6
- openstackclient/common/pagination.py +8 -2
- openstackclient/common/progressbar.py +7 -6
- openstackclient/common/project_cleanup.py +13 -7
- openstackclient/common/quota.py +126 -114
- openstackclient/common/versions.py +8 -2
- openstackclient/compute/client.py +7 -3
- openstackclient/compute/v2/agent.py +17 -10
- openstackclient/compute/v2/aggregate.py +36 -22
- openstackclient/compute/v2/console.py +14 -8
- openstackclient/compute/v2/console_connection.py +11 -3
- openstackclient/compute/v2/flavor.py +39 -21
- openstackclient/compute/v2/host.py +14 -6
- openstackclient/compute/v2/hypervisor.py +14 -5
- openstackclient/compute/v2/hypervisor_stats.py +10 -2
- openstackclient/compute/v2/keypair.py +29 -14
- openstackclient/compute/v2/server.py +251 -171
- openstackclient/compute/v2/server_backup.py +10 -4
- openstackclient/compute/v2/server_event.py +21 -12
- openstackclient/compute/v2/server_group.py +21 -11
- openstackclient/compute/v2/server_image.py +19 -10
- openstackclient/compute/v2/server_migration.py +24 -10
- openstackclient/compute/v2/server_share.py +274 -0
- openstackclient/compute/v2/server_volume.py +10 -4
- openstackclient/compute/v2/service.py +14 -7
- openstackclient/compute/v2/usage.py +26 -21
- openstackclient/identity/client.py +8 -3
- openstackclient/identity/common.py +103 -41
- openstackclient/identity/v2_0/catalog.py +14 -7
- openstackclient/identity/v2_0/ec2creds.py +21 -10
- openstackclient/identity/v2_0/endpoint.py +23 -11
- openstackclient/identity/v2_0/project.py +25 -14
- openstackclient/identity/v2_0/role.py +28 -14
- openstackclient/identity/v2_0/role_assignment.py +9 -3
- openstackclient/identity/v2_0/service.py +26 -12
- openstackclient/identity/v2_0/token.py +12 -5
- openstackclient/identity/v2_0/user.py +26 -15
- openstackclient/identity/v3/access_rule.py +26 -12
- openstackclient/identity/v3/application_credential.py +59 -24
- openstackclient/identity/v3/catalog.py +14 -7
- openstackclient/identity/v3/consumer.py +22 -11
- openstackclient/identity/v3/credential.py +36 -16
- openstackclient/identity/v3/domain.py +37 -18
- openstackclient/identity/v3/ec2creds.py +25 -12
- openstackclient/identity/v3/endpoint.py +42 -20
- openstackclient/identity/v3/endpoint_group.py +28 -17
- openstackclient/identity/v3/federation_protocol.py +71 -50
- openstackclient/identity/v3/group.py +55 -32
- openstackclient/identity/v3/identity_provider.py +92 -57
- openstackclient/identity/v3/implied_role.py +21 -9
- openstackclient/identity/v3/limit.py +115 -92
- openstackclient/identity/v3/mapping.py +26 -13
- openstackclient/identity/v3/policy.py +23 -12
- openstackclient/identity/v3/project.py +211 -122
- openstackclient/identity/v3/region.py +36 -16
- openstackclient/identity/v3/registered_limit.py +116 -109
- openstackclient/identity/v3/role.py +61 -31
- openstackclient/identity/v3/role_assignment.py +23 -6
- openstackclient/identity/v3/service.py +36 -16
- openstackclient/identity/v3/service_provider.py +37 -15
- openstackclient/identity/v3/tag.py +23 -17
- openstackclient/identity/v3/token.py +30 -14
- openstackclient/identity/v3/trust.py +32 -14
- openstackclient/identity/v3/unscoped_saml.py +10 -2
- openstackclient/identity/v3/user.py +49 -26
- openstackclient/image/client.py +7 -3
- openstackclient/image/v1/image.py +33 -26
- openstackclient/image/v2/cache.py +14 -9
- openstackclient/image/v2/image.py +76 -49
- openstackclient/image/v2/info.py +7 -1
- openstackclient/image/v2/metadef_namespaces.py +109 -13
- openstackclient/image/v2/metadef_objects.py +28 -15
- openstackclient/image/v2/metadef_properties.py +24 -13
- openstackclient/image/v2/metadef_resource_type_association.py +14 -7
- openstackclient/image/v2/metadef_resource_types.py +7 -1
- openstackclient/image/v2/task.py +15 -6
- openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +7 -192
- openstackclient/network/client.py +7 -2
- openstackclient/network/common.py +16 -241
- openstackclient/network/utils.py +36 -22
- openstackclient/network/v2/address_group.py +27 -16
- openstackclient/network/v2/address_scope.py +24 -13
- openstackclient/network/v2/bgpvpn/bgpvpn.py +463 -0
- openstackclient/network/v2/bgpvpn/constants.py +30 -0
- openstackclient/network/v2/bgpvpn/network_association.py +214 -0
- openstackclient/network/v2/bgpvpn/port_association.py +490 -0
- openstackclient/network/v2/bgpvpn/router_association.py +288 -0
- openstackclient/network/v2/default_security_group_rule.py +19 -10
- openstackclient/network/v2/floating_ip.py +110 -159
- openstackclient/network/v2/floating_ip_port_forwarding.py +30 -18
- openstackclient/network/v2/fwaas/__init__.py +0 -0
- openstackclient/network/v2/fwaas/group.py +466 -0
- openstackclient/network/v2/fwaas/policy.py +518 -0
- openstackclient/network/v2/fwaas/rule.py +574 -0
- openstackclient/network/v2/ip_availability.py +13 -5
- openstackclient/network/v2/l3_conntrack_helper.py +22 -13
- openstackclient/network/v2/local_ip.py +24 -13
- openstackclient/network/v2/local_ip_association.py +14 -7
- openstackclient/network/v2/ndp_proxy.py +20 -11
- openstackclient/network/v2/network.py +129 -196
- openstackclient/network/v2/network_agent.py +46 -25
- openstackclient/network/v2/network_auto_allocated_topology.py +22 -11
- openstackclient/network/v2/network_flavor.py +27 -16
- openstackclient/network/v2/network_flavor_profile.py +23 -12
- openstackclient/network/v2/network_meter.py +21 -10
- openstackclient/network/v2/network_meter_rule.py +21 -11
- openstackclient/network/v2/network_qos_policy.py +25 -15
- openstackclient/network/v2/network_qos_rule.py +32 -17
- openstackclient/network/v2/network_qos_rule_type.py +13 -5
- openstackclient/network/v2/network_rbac.py +23 -12
- openstackclient/network/v2/network_segment.py +20 -11
- openstackclient/network/v2/network_segment_range.py +56 -29
- openstackclient/network/v2/network_service_provider.py +7 -1
- openstackclient/network/v2/network_trunk.py +38 -22
- openstackclient/network/v2/port.py +54 -29
- openstackclient/network/v2/router.py +75 -52
- openstackclient/network/v2/security_group.py +87 -157
- openstackclient/network/v2/security_group_rule.py +100 -280
- openstackclient/network/v2/subnet.py +49 -28
- openstackclient/network/v2/subnet_pool.py +30 -17
- openstackclient/network/v2/taas/tap_flow.py +22 -11
- openstackclient/network/v2/taas/tap_mirror.py +22 -11
- openstackclient/network/v2/taas/tap_service.py +23 -12
- openstackclient/object/client.py +7 -2
- openstackclient/object/v1/account.py +13 -6
- openstackclient/object/v1/container.py +25 -15
- openstackclient/object/v1/object.py +25 -15
- openstackclient/py.typed +0 -0
- openstackclient/shell.py +46 -10
- openstackclient/tests/functional/base.py +55 -20
- openstackclient/tests/functional/common/test_extension.py +4 -0
- openstackclient/tests/functional/common/test_quota.py +3 -1
- openstackclient/tests/functional/compute/v2/common.py +14 -13
- openstackclient/tests/functional/compute/v2/test_flavor.py +3 -1
- openstackclient/tests/functional/compute/v2/test_server.py +3 -0
- openstackclient/tests/functional/identity/v2/common.py +10 -6
- openstackclient/tests/functional/identity/v2/test_role.py +4 -4
- openstackclient/tests/functional/identity/v3/common.py +25 -19
- openstackclient/tests/functional/identity/v3/test_group.py +20 -20
- openstackclient/tests/functional/identity/v3/test_idp.py +3 -1
- openstackclient/tests/functional/identity/v3/test_limit.py +47 -0
- openstackclient/tests/functional/identity/v3/test_project.py +10 -10
- openstackclient/tests/functional/identity/v3/test_role.py +18 -18
- openstackclient/tests/functional/identity/v3/test_role_assignment.py +12 -12
- openstackclient/tests/functional/identity/v3/test_user.py +8 -8
- openstackclient/tests/functional/image/base.py +1 -6
- openstackclient/tests/functional/image/v2/test_metadef_objects.py +69 -0
- openstackclient/tests/functional/network/v2/common.py +5 -2
- openstackclient/tests/functional/network/v2/test_floating_ip.py +10 -4
- openstackclient/tests/functional/network/v2/test_ip_availability.py +4 -0
- openstackclient/tests/functional/network/v2/test_network_meter_rule.py +3 -2
- openstackclient/tests/functional/network/v2/test_network_segment.py +5 -0
- openstackclient/tests/functional/network/v2/test_subnet.py +13 -9
- openstackclient/tests/functional/object/v1/common.py +4 -0
- openstackclient/tests/functional/volume/v2/common.py +4 -0
- openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +27 -11
- openstackclient/tests/functional/volume/v2/test_volume_type.py +2 -2
- openstackclient/tests/functional/volume/v3/common.py +4 -0
- openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +56 -138
- openstackclient/tests/functional/volume/v3/test_volume_type.py +2 -2
- openstackclient/tests/unit/common/test_availability_zone.py +35 -49
- openstackclient/tests/unit/common/test_extension.py +2 -2
- openstackclient/tests/unit/common/test_module.py +12 -7
- openstackclient/tests/unit/common/test_project_cleanup.py +3 -1
- openstackclient/tests/unit/common/test_quota.py +62 -23
- openstackclient/tests/unit/compute/v2/fakes.py +25 -0
- openstackclient/tests/unit/compute/v2/test_flavor.py +28 -2
- openstackclient/tests/unit/compute/v2/test_keypair.py +6 -6
- openstackclient/tests/unit/compute/v2/test_server.py +17 -104
- openstackclient/tests/unit/compute/v2/test_server_share.py +287 -0
- openstackclient/tests/unit/identity/v3/fakes.py +3 -0
- openstackclient/tests/unit/identity/v3/test_group.py +4 -14
- openstackclient/tests/unit/identity/v3/test_identity_provider.py +303 -299
- openstackclient/tests/unit/identity/v3/test_limit.py +197 -145
- openstackclient/tests/unit/identity/v3/test_project.py +831 -512
- openstackclient/tests/unit/identity/v3/test_protocol.py +97 -88
- openstackclient/tests/unit/identity/v3/test_registered_limit.py +355 -220
- openstackclient/tests/unit/identity/v3/test_user.py +4 -4
- openstackclient/tests/unit/image/v2/test_image.py +16 -16
- openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +105 -6
- openstackclient/tests/unit/network/test_common.py +0 -155
- openstackclient/tests/unit/network/v2/bgpvpn/__init__.py +0 -0
- openstackclient/tests/unit/network/v2/bgpvpn/fakes.py +179 -0
- openstackclient/tests/unit/network/v2/bgpvpn/test_bgpvpn.py +584 -0
- openstackclient/tests/unit/network/v2/bgpvpn/test_network_association.py +285 -0
- openstackclient/tests/unit/network/v2/bgpvpn/test_port_association.py +384 -0
- openstackclient/tests/unit/network/v2/bgpvpn/test_router_association.py +297 -0
- openstackclient/tests/unit/network/v2/fwaas/__init__.py +0 -0
- openstackclient/tests/unit/network/v2/fwaas/test_group.py +897 -0
- openstackclient/tests/unit/network/v2/fwaas/test_policy.py +869 -0
- openstackclient/tests/unit/network/v2/fwaas/test_rule.py +980 -0
- openstackclient/tests/unit/network/v2/taas/{test_osc_tap_flow.py → test_tap_flow.py} +18 -25
- openstackclient/tests/unit/network/v2/taas/{test_osc_tap_mirror.py → test_tap_mirror.py} +19 -29
- openstackclient/tests/unit/network/v2/taas/{test_osc_tap_service.py → test_tap_service.py} +19 -29
- openstackclient/tests/unit/network/v2/test_address_group.py +2 -2
- openstackclient/tests/unit/network/v2/{test_floating_ip_network.py → test_floating_ip.py} +3 -2
- openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +13 -13
- openstackclient/tests/unit/network/v2/test_network_agent.py +8 -4
- openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +3 -3
- openstackclient/tests/unit/network/v2/test_network_flavor.py +2 -2
- openstackclient/tests/unit/network/v2/test_network_qos_policy.py +1 -1
- openstackclient/tests/unit/network/v2/test_network_qos_rule.py +2 -2
- openstackclient/tests/unit/network/v2/test_network_rbac.py +1 -1
- openstackclient/tests/unit/network/v2/test_network_segment.py +1 -1
- openstackclient/tests/unit/network/v2/test_network_segment_range.py +7 -10
- openstackclient/tests/unit/network/v2/test_network_trunk.py +1 -1
- openstackclient/tests/unit/network/v2/test_router.py +8 -9
- openstackclient/tests/unit/network/v2/{test_security_group_network.py → test_security_group.py} +1 -20
- openstackclient/tests/unit/network/v2/{test_security_group_rule_network.py → test_security_group_rule.py} +7 -41
- openstackclient/tests/unit/network/v2/test_subnet.py +2 -1
- openstackclient/tests/unit/network/v2/test_subnet_pool.py +2 -1
- openstackclient/tests/unit/object/v1/fakes.py +8 -7
- openstackclient/tests/unit/object/v1/test_container.py +65 -101
- openstackclient/tests/unit/object/v1/test_container_all.py +8 -1
- openstackclient/tests/unit/object/v1/test_object.py +44 -84
- openstackclient/tests/unit/object/v1/test_object_all.py +8 -1
- openstackclient/tests/unit/test_hacking.py +108 -0
- openstackclient/tests/unit/volume/v2/fakes.py +1 -0
- openstackclient/tests/unit/volume/v2/test_consistency_group.py +8 -2
- openstackclient/tests/unit/volume/v2/test_volume.py +7 -6
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +1 -5
- openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +2 -1
- openstackclient/tests/unit/volume/v2/test_volume_type.py +2 -4
- openstackclient/tests/unit/volume/v3/fakes.py +1 -0
- openstackclient/tests/unit/volume/v3/test_volume.py +94 -15
- openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
- openstackclient/tests/unit/volume/v3/test_volume_backup.py +1 -5
- openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +55 -1
- openstackclient/tests/unit/volume/v3/test_volume_type.py +2 -4
- openstackclient/volume/client.py +7 -3
- openstackclient/volume/v2/backup_record.py +15 -6
- openstackclient/volume/v2/consistency_group.py +37 -25
- openstackclient/volume/v2/consistency_group_snapshot.py +27 -12
- openstackclient/volume/v2/qos_specs.py +30 -19
- openstackclient/volume/v2/service.py +17 -6
- openstackclient/volume/v2/volume.py +69 -34
- openstackclient/volume/v2/volume_backend.py +19 -6
- openstackclient/volume/v2/volume_backup.py +48 -22
- openstackclient/volume/v2/volume_host.py +6 -4
- openstackclient/volume/v2/volume_snapshot.py +52 -26
- openstackclient/volume/v2/volume_transfer_request.py +33 -15
- openstackclient/volume/v2/volume_type.py +46 -27
- openstackclient/volume/v3/block_storage_cleanup.py +11 -3
- openstackclient/volume/v3/block_storage_cluster.py +19 -7
- openstackclient/volume/v3/block_storage_log_level.py +15 -6
- openstackclient/volume/v3/block_storage_manage.py +10 -4
- openstackclient/volume/v3/block_storage_resource_filter.py +17 -5
- openstackclient/volume/v3/service.py +16 -6
- openstackclient/volume/v3/volume.py +103 -46
- openstackclient/volume/v3/volume_attachment.py +43 -21
- openstackclient/volume/v3/volume_backup.py +55 -26
- openstackclient/volume/v3/volume_group.py +23 -13
- openstackclient/volume/v3/volume_group_snapshot.py +32 -13
- openstackclient/volume/v3/volume_group_type.py +26 -13
- openstackclient/volume/v3/volume_message.py +15 -7
- openstackclient/volume/v3/volume_snapshot.py +71 -34
- openstackclient/volume/v3/volume_transfer_request.py +33 -15
- openstackclient/volume/v3/volume_type.py +45 -27
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/METADATA +6 -6
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/RECORD +279 -267
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/WHEEL +1 -1
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/entry_points.txt +53 -1
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/AUTHORS +9 -0
- python_openstackclient-10.0.0.dist-info/pbr.json +1 -0
- openstackclient/api/image_v1.py +0 -69
- openstackclient/api/image_v2.py +0 -79
- openstackclient/network/v2/floating_ip_pool.py +0 -38
- openstackclient/tests/functional/image/v1/test_image.py +0 -97
- openstackclient/tests/unit/api/test_image_v1.py +0 -96
- openstackclient/tests/unit/api/test_image_v2.py +0 -96
- openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +0 -248
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +0 -49
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +0 -39
- openstackclient/tests/unit/network/v2/test_network_compute.py +0 -404
- openstackclient/tests/unit/network/v2/test_security_group_compute.py +0 -392
- openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +0 -555
- python_openstackclient-8.3.0.dist-info/pbr.json +0 -1
- /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/LICENSE +0 -0
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/top_level.txt +0 -0
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
|
|
18
18
|
import argparse
|
|
19
19
|
from base64 import b64encode
|
|
20
|
+
from collections.abc import Iterable, Sequence
|
|
20
21
|
import copy
|
|
21
22
|
import logging
|
|
22
23
|
import os
|
|
23
24
|
import sys
|
|
24
|
-
|
|
25
|
+
from typing import Any
|
|
25
26
|
import urllib.parse
|
|
26
27
|
|
|
27
28
|
from openstack import exceptions as sdk_exceptions
|
|
@@ -73,7 +74,7 @@ MEMBER_STATUS_CHOICES = ["accepted", "pending", "rejected", "all"]
|
|
|
73
74
|
LOG = logging.getLogger(__name__)
|
|
74
75
|
|
|
75
76
|
|
|
76
|
-
def _format_image(image, human_readable=False):
|
|
77
|
+
def _format_image(image: Any, human_readable: bool = False) -> dict[str, Any]:
|
|
77
78
|
"""Format an image to make it more consistent with OSC operations."""
|
|
78
79
|
|
|
79
80
|
info = {}
|
|
@@ -137,7 +138,7 @@ _formatters = {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
|
|
140
|
-
def _get_member_columns(item):
|
|
141
|
+
def _get_member_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
|
|
141
142
|
column_map = {'image_id': 'image_id'}
|
|
142
143
|
hidden_columns = ['id', 'location', 'name']
|
|
143
144
|
return utils.get_osc_show_columns_for_sdk_resource(
|
|
@@ -147,7 +148,7 @@ def _get_member_columns(item):
|
|
|
147
148
|
)
|
|
148
149
|
|
|
149
150
|
|
|
150
|
-
def get_data_from_stdin():
|
|
151
|
+
def get_data_from_stdin() -> Any:
|
|
151
152
|
# distinguish cases where:
|
|
152
153
|
# (1) stdin is not valid (as in cron jobs):
|
|
153
154
|
# openstack ... <&-
|
|
@@ -166,10 +167,10 @@ def get_data_from_stdin():
|
|
|
166
167
|
image = sys.stdin
|
|
167
168
|
if hasattr(sys.stdin, 'buffer'):
|
|
168
169
|
image = sys.stdin.buffer
|
|
169
|
-
if
|
|
170
|
+
if sys.platform == "win32":
|
|
170
171
|
import msvcrt
|
|
171
172
|
|
|
172
|
-
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
|
|
173
|
+
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
|
|
173
174
|
|
|
174
175
|
return image
|
|
175
176
|
else:
|
|
@@ -177,7 +178,7 @@ def get_data_from_stdin():
|
|
|
177
178
|
return None
|
|
178
179
|
|
|
179
180
|
|
|
180
|
-
def _add_is_protected_args(parser):
|
|
181
|
+
def _add_is_protected_args(parser: argparse.ArgumentParser) -> None:
|
|
181
182
|
protected_group = parser.add_mutually_exclusive_group()
|
|
182
183
|
protected_group.add_argument(
|
|
183
184
|
"--protected",
|
|
@@ -195,7 +196,7 @@ def _add_is_protected_args(parser):
|
|
|
195
196
|
)
|
|
196
197
|
|
|
197
198
|
|
|
198
|
-
def _add_visibility_args(parser):
|
|
199
|
+
def _add_visibility_args(parser: argparse.ArgumentParser) -> None:
|
|
199
200
|
public_group = parser.add_mutually_exclusive_group()
|
|
200
201
|
public_group.add_argument(
|
|
201
202
|
"--public",
|
|
@@ -241,7 +242,7 @@ def _add_visibility_args(parser):
|
|
|
241
242
|
class AddProjectToImage(command.ShowOne):
|
|
242
243
|
_description = _("Associate project with image")
|
|
243
244
|
|
|
244
|
-
def get_parser(self, prog_name):
|
|
245
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
245
246
|
parser = super().get_parser(prog_name)
|
|
246
247
|
parser.add_argument(
|
|
247
248
|
"image",
|
|
@@ -256,7 +257,9 @@ class AddProjectToImage(command.ShowOne):
|
|
|
256
257
|
identity_common.add_project_domain_option_to_parser(parser)
|
|
257
258
|
return parser
|
|
258
259
|
|
|
259
|
-
def take_action(
|
|
260
|
+
def take_action(
|
|
261
|
+
self, parsed_args: argparse.Namespace
|
|
262
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
260
263
|
image_client = self.app.client_manager.image
|
|
261
264
|
identity_client = self.app.client_manager.identity
|
|
262
265
|
|
|
@@ -287,7 +290,7 @@ class CreateImage(command.ShowOne):
|
|
|
287
290
|
|
|
288
291
|
deadopts = ('size', 'location', 'copy-from', 'checksum', 'store')
|
|
289
292
|
|
|
290
|
-
def get_parser(self, prog_name):
|
|
293
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
291
294
|
parser = super().get_parser(prog_name)
|
|
292
295
|
# TODO(bunting): There are additional arguments that v1 supported
|
|
293
296
|
# that v2 either doesn't support or supports weirdly.
|
|
@@ -440,13 +443,15 @@ class CreateImage(command.ShowOne):
|
|
|
440
443
|
)
|
|
441
444
|
return parser
|
|
442
445
|
|
|
443
|
-
def _take_action_image(
|
|
446
|
+
def _take_action_image(
|
|
447
|
+
self, parsed_args: argparse.Namespace
|
|
448
|
+
) -> dict[str, Any]:
|
|
444
449
|
identity_client = self.app.client_manager.identity
|
|
445
450
|
image_client = self.app.client_manager.image
|
|
446
451
|
|
|
447
452
|
# Build an attribute dict from the parsed args, only include
|
|
448
453
|
# attributes that were actually set on the command line
|
|
449
|
-
kwargs: dict[str,
|
|
454
|
+
kwargs: dict[str, Any] = {'allow_duplicates': True}
|
|
450
455
|
copy_attrs = (
|
|
451
456
|
'name',
|
|
452
457
|
'id',
|
|
@@ -592,8 +597,12 @@ class CreateImage(command.ShowOne):
|
|
|
592
597
|
image = image_client.get_image(image)
|
|
593
598
|
return _format_image(image)
|
|
594
599
|
|
|
595
|
-
def _take_action_volume(
|
|
596
|
-
|
|
600
|
+
def _take_action_volume(
|
|
601
|
+
self, parsed_args: argparse.Namespace
|
|
602
|
+
) -> dict[str, Any]:
|
|
603
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
604
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
605
|
+
)
|
|
597
606
|
|
|
598
607
|
unsupported_opts = {
|
|
599
608
|
# 'name', # 'name' is a positional argument and will always exist
|
|
@@ -622,12 +631,12 @@ class CreateImage(command.ShowOne):
|
|
|
622
631
|
)
|
|
623
632
|
# TODO(stephenfin): These should be an error in a future
|
|
624
633
|
# version
|
|
625
|
-
LOG.warning(msg
|
|
634
|
+
LOG.warning(msg, opt_name)
|
|
626
635
|
|
|
627
636
|
source_volume = volume_client.find_volume(
|
|
628
637
|
parsed_args.volume, ignore_missing=False
|
|
629
638
|
)
|
|
630
|
-
kwargs: dict[str,
|
|
639
|
+
kwargs: dict[str, Any] = {
|
|
631
640
|
'visibility': None,
|
|
632
641
|
'protected': None,
|
|
633
642
|
}
|
|
@@ -643,7 +652,7 @@ class CreateImage(command.ShowOne):
|
|
|
643
652
|
kwargs['visibility'] = parsed_args.visibility or 'private'
|
|
644
653
|
kwargs['protected'] = parsed_args.is_protected or False
|
|
645
654
|
|
|
646
|
-
response = volume_client.upload_volume_to_image(
|
|
655
|
+
response: dict[str, Any] = volume_client.upload_volume_to_image(
|
|
647
656
|
source_volume.id,
|
|
648
657
|
parsed_args.name,
|
|
649
658
|
force=parsed_args.force,
|
|
@@ -659,7 +668,9 @@ class CreateImage(command.ShowOne):
|
|
|
659
668
|
|
|
660
669
|
return info
|
|
661
670
|
|
|
662
|
-
def take_action(
|
|
671
|
+
def take_action(
|
|
672
|
+
self, parsed_args: argparse.Namespace
|
|
673
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
663
674
|
for deadopt in self.deadopts:
|
|
664
675
|
if getattr(parsed_args, deadopt.replace('-', '_'), None):
|
|
665
676
|
msg = _(
|
|
@@ -673,13 +684,14 @@ class CreateImage(command.ShowOne):
|
|
|
673
684
|
else:
|
|
674
685
|
info = self._take_action_image(parsed_args)
|
|
675
686
|
|
|
676
|
-
|
|
687
|
+
col_headers, col_data = zip(*sorted(info.items()))
|
|
688
|
+
return col_headers, col_data
|
|
677
689
|
|
|
678
690
|
|
|
679
691
|
class DeleteImage(command.Command):
|
|
680
692
|
_description = _("Delete image(s)")
|
|
681
693
|
|
|
682
|
-
def get_parser(self, prog_name):
|
|
694
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
683
695
|
parser = super().get_parser(prog_name)
|
|
684
696
|
parser.add_argument(
|
|
685
697
|
"images",
|
|
@@ -696,7 +708,7 @@ class DeleteImage(command.Command):
|
|
|
696
708
|
)
|
|
697
709
|
return parser
|
|
698
710
|
|
|
699
|
-
def take_action(self, parsed_args):
|
|
711
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
700
712
|
result = 0
|
|
701
713
|
image_client = self.app.client_manager.image
|
|
702
714
|
for image in parsed_args.images:
|
|
@@ -732,7 +744,7 @@ class DeleteImage(command.Command):
|
|
|
732
744
|
class ListImage(command.Lister):
|
|
733
745
|
_description = _("List available images")
|
|
734
746
|
|
|
735
|
-
def get_parser(self, prog_name):
|
|
747
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
736
748
|
parser = super().get_parser(prog_name)
|
|
737
749
|
public_group = parser.add_mutually_exclusive_group()
|
|
738
750
|
public_group.add_argument(
|
|
@@ -861,7 +873,9 @@ class ListImage(command.Lister):
|
|
|
861
873
|
pagination.add_marker_pagination_option_to_parser(parser)
|
|
862
874
|
return parser
|
|
863
875
|
|
|
864
|
-
def take_action(
|
|
876
|
+
def take_action(
|
|
877
|
+
self, parsed_args: argparse.Namespace
|
|
878
|
+
) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
|
|
865
879
|
identity_client = self.app.client_manager.identity
|
|
866
880
|
image_client = self.app.client_manager.image
|
|
867
881
|
|
|
@@ -962,7 +976,7 @@ class ListImage(command.Lister):
|
|
|
962
976
|
class ListImageProjects(command.Lister):
|
|
963
977
|
_description = _("List projects associated with image")
|
|
964
978
|
|
|
965
|
-
def get_parser(self, prog_name):
|
|
979
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
966
980
|
parser = super().get_parser(prog_name)
|
|
967
981
|
parser.add_argument(
|
|
968
982
|
"image",
|
|
@@ -972,7 +986,9 @@ class ListImageProjects(command.Lister):
|
|
|
972
986
|
identity_common.add_project_domain_option_to_parser(parser)
|
|
973
987
|
return parser
|
|
974
988
|
|
|
975
|
-
def take_action(
|
|
989
|
+
def take_action(
|
|
990
|
+
self, parsed_args: argparse.Namespace
|
|
991
|
+
) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
|
|
976
992
|
image_client = self.app.client_manager.image
|
|
977
993
|
columns: tuple[str, ...] = ("Image ID", "Member ID", "Status")
|
|
978
994
|
|
|
@@ -998,7 +1014,7 @@ class ListImageProjects(command.Lister):
|
|
|
998
1014
|
class RemoveProjectImage(command.Command):
|
|
999
1015
|
_description = _("Disassociate project with image")
|
|
1000
1016
|
|
|
1001
|
-
def get_parser(self, prog_name):
|
|
1017
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1002
1018
|
parser = super().get_parser(prog_name)
|
|
1003
1019
|
parser.add_argument(
|
|
1004
1020
|
"image",
|
|
@@ -1013,7 +1029,7 @@ class RemoveProjectImage(command.Command):
|
|
|
1013
1029
|
identity_common.add_project_domain_option_to_parser(parser)
|
|
1014
1030
|
return parser
|
|
1015
1031
|
|
|
1016
|
-
def take_action(self, parsed_args):
|
|
1032
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
1017
1033
|
image_client = self.app.client_manager.image
|
|
1018
1034
|
identity_client = self.app.client_manager.identity
|
|
1019
1035
|
|
|
@@ -1034,7 +1050,7 @@ class RemoveProjectImage(command.Command):
|
|
|
1034
1050
|
class ShowProjectImage(command.ShowOne):
|
|
1035
1051
|
_description = _("Show a particular project associated with image")
|
|
1036
1052
|
|
|
1037
|
-
def get_parser(self, prog_name):
|
|
1053
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1038
1054
|
parser = super().get_parser(prog_name)
|
|
1039
1055
|
parser.add_argument(
|
|
1040
1056
|
"image",
|
|
@@ -1049,7 +1065,9 @@ class ShowProjectImage(command.ShowOne):
|
|
|
1049
1065
|
identity_common.add_project_domain_option_to_parser(parser)
|
|
1050
1066
|
return parser
|
|
1051
1067
|
|
|
1052
|
-
def take_action(
|
|
1068
|
+
def take_action(
|
|
1069
|
+
self, parsed_args: argparse.Namespace
|
|
1070
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
1053
1071
|
image_client = self.app.client_manager.image
|
|
1054
1072
|
|
|
1055
1073
|
image = image_client.find_image(
|
|
@@ -1071,7 +1089,7 @@ class ShowProjectImage(command.ShowOne):
|
|
|
1071
1089
|
class SaveImage(command.Command):
|
|
1072
1090
|
_description = _("Save an image locally")
|
|
1073
1091
|
|
|
1074
|
-
def get_parser(self, prog_name):
|
|
1092
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1075
1093
|
parser = super().get_parser(prog_name)
|
|
1076
1094
|
parser.add_argument(
|
|
1077
1095
|
"--chunk-size",
|
|
@@ -1096,7 +1114,7 @@ class SaveImage(command.Command):
|
|
|
1096
1114
|
)
|
|
1097
1115
|
return parser
|
|
1098
1116
|
|
|
1099
|
-
def take_action(self, parsed_args):
|
|
1117
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
1100
1118
|
image_client = self.app.client_manager.image
|
|
1101
1119
|
image = image_client.find_image(
|
|
1102
1120
|
parsed_args.image,
|
|
@@ -1120,7 +1138,7 @@ class SetImage(command.Command):
|
|
|
1120
1138
|
|
|
1121
1139
|
deadopts = ('visibility',)
|
|
1122
1140
|
|
|
1123
|
-
def get_parser(self, prog_name):
|
|
1141
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1124
1142
|
parser = super().get_parser(prog_name)
|
|
1125
1143
|
# TODO(bunting): There are additional arguments that v1 supported
|
|
1126
1144
|
# --size - does not exist in v2
|
|
@@ -1296,7 +1314,7 @@ class SetImage(command.Command):
|
|
|
1296
1314
|
)
|
|
1297
1315
|
return parser
|
|
1298
1316
|
|
|
1299
|
-
def take_action(self, parsed_args):
|
|
1317
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
1300
1318
|
identity_client = self.app.client_manager.identity
|
|
1301
1319
|
image_client = self.app.client_manager.image
|
|
1302
1320
|
|
|
@@ -1421,7 +1439,7 @@ class SetImage(command.Command):
|
|
|
1421
1439
|
class ShowImage(command.ShowOne):
|
|
1422
1440
|
_description = _("Display image details")
|
|
1423
1441
|
|
|
1424
|
-
def get_parser(self, prog_name):
|
|
1442
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1425
1443
|
parser = super().get_parser(prog_name)
|
|
1426
1444
|
parser.add_argument(
|
|
1427
1445
|
"--human-readable",
|
|
@@ -1436,7 +1454,9 @@ class ShowImage(command.ShowOne):
|
|
|
1436
1454
|
)
|
|
1437
1455
|
return parser
|
|
1438
1456
|
|
|
1439
|
-
def take_action(
|
|
1457
|
+
def take_action(
|
|
1458
|
+
self, parsed_args: argparse.Namespace
|
|
1459
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
1440
1460
|
image_client = self.app.client_manager.image
|
|
1441
1461
|
|
|
1442
1462
|
image = image_client.find_image(
|
|
@@ -1445,13 +1465,14 @@ class ShowImage(command.ShowOne):
|
|
|
1445
1465
|
)
|
|
1446
1466
|
|
|
1447
1467
|
info = _format_image(image, parsed_args.human_readable)
|
|
1448
|
-
|
|
1468
|
+
col_headers, col_data = zip(*sorted(info.items()))
|
|
1469
|
+
return col_headers, col_data
|
|
1449
1470
|
|
|
1450
1471
|
|
|
1451
1472
|
class UnsetImage(command.Command):
|
|
1452
1473
|
_description = _("Unset image tags and properties")
|
|
1453
1474
|
|
|
1454
|
-
def get_parser(self, prog_name):
|
|
1475
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1455
1476
|
parser = super().get_parser(prog_name)
|
|
1456
1477
|
parser.add_argument(
|
|
1457
1478
|
"image",
|
|
@@ -1482,7 +1503,7 @@ class UnsetImage(command.Command):
|
|
|
1482
1503
|
)
|
|
1483
1504
|
return parser
|
|
1484
1505
|
|
|
1485
|
-
def take_action(self, parsed_args):
|
|
1506
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
1486
1507
|
image_client = self.app.client_manager.image
|
|
1487
1508
|
image = image_client.find_image(
|
|
1488
1509
|
parsed_args.image,
|
|
@@ -1501,7 +1522,7 @@ class UnsetImage(command.Command):
|
|
|
1501
1522
|
)
|
|
1502
1523
|
tagret += 1
|
|
1503
1524
|
|
|
1504
|
-
kwargs: dict[str,
|
|
1525
|
+
kwargs: dict[str, Any] = {}
|
|
1505
1526
|
if parsed_args.properties:
|
|
1506
1527
|
for k in parsed_args.properties:
|
|
1507
1528
|
if k in image:
|
|
@@ -1512,7 +1533,7 @@ class UnsetImage(command.Command):
|
|
|
1512
1533
|
# out, what was changed inside
|
|
1513
1534
|
# NOTE: ping gtema to improve that in SDK
|
|
1514
1535
|
new_props = kwargs.get(
|
|
1515
|
-
'properties', image
|
|
1536
|
+
'properties', image['properties'].copy()
|
|
1516
1537
|
)
|
|
1517
1538
|
new_props.pop(k, None)
|
|
1518
1539
|
kwargs['properties'] = new_props
|
|
@@ -1569,7 +1590,7 @@ class StageImage(command.Command):
|
|
|
1569
1590
|
"(Glance 16.0.0 (Queens))"
|
|
1570
1591
|
)
|
|
1571
1592
|
|
|
1572
|
-
def get_parser(self, prog_name):
|
|
1593
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1573
1594
|
parser = super().get_parser(prog_name)
|
|
1574
1595
|
|
|
1575
1596
|
parser.add_argument(
|
|
@@ -1599,7 +1620,7 @@ class StageImage(command.Command):
|
|
|
1599
1620
|
|
|
1600
1621
|
return parser
|
|
1601
1622
|
|
|
1602
|
-
def take_action(self, parsed_args):
|
|
1623
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
1603
1624
|
image_client = self.app.client_manager.image
|
|
1604
1625
|
|
|
1605
1626
|
image = image_client.find_image(
|
|
@@ -1619,7 +1640,7 @@ class StageImage(command.Command):
|
|
|
1619
1640
|
else:
|
|
1620
1641
|
fp = get_data_from_stdin()
|
|
1621
1642
|
|
|
1622
|
-
kwargs: dict[str,
|
|
1643
|
+
kwargs: dict[str, Any] = {}
|
|
1623
1644
|
|
|
1624
1645
|
if parsed_args.progress and parsed_args.filename:
|
|
1625
1646
|
# NOTE(stephenfin): we only show a progress bar if the user
|
|
@@ -1645,7 +1666,7 @@ class ImportImage(command.ShowOne):
|
|
|
1645
1666
|
"(Glance 16.0.0 (Queens))"
|
|
1646
1667
|
)
|
|
1647
1668
|
|
|
1648
|
-
def get_parser(self, prog_name):
|
|
1669
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1649
1670
|
parser = super().get_parser(prog_name)
|
|
1650
1671
|
|
|
1651
1672
|
parser.add_argument(
|
|
@@ -1719,6 +1740,7 @@ class ImportImage(command.ShowOne):
|
|
|
1719
1740
|
)
|
|
1720
1741
|
stores_group.add_argument(
|
|
1721
1742
|
'--all-stores',
|
|
1743
|
+
action='store_true',
|
|
1722
1744
|
help=_(
|
|
1723
1745
|
"Make image available to all stores "
|
|
1724
1746
|
"(either '--store' or '--all-stores' required with the "
|
|
@@ -1755,7 +1777,9 @@ class ImportImage(command.ShowOne):
|
|
|
1755
1777
|
)
|
|
1756
1778
|
return parser
|
|
1757
1779
|
|
|
1758
|
-
def take_action(
|
|
1780
|
+
def take_action(
|
|
1781
|
+
self, parsed_args: argparse.Namespace
|
|
1782
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
1759
1783
|
image_client = self.app.client_manager.image
|
|
1760
1784
|
|
|
1761
1785
|
try:
|
|
@@ -1885,7 +1909,8 @@ class ImportImage(command.ShowOne):
|
|
|
1885
1909
|
)
|
|
1886
1910
|
|
|
1887
1911
|
info = _format_image(image)
|
|
1888
|
-
|
|
1912
|
+
col_headers, col_data = zip(*sorted(info.items()))
|
|
1913
|
+
return col_headers, col_data
|
|
1889
1914
|
|
|
1890
1915
|
|
|
1891
1916
|
class StoresInfo(command.Lister):
|
|
@@ -1893,7 +1918,7 @@ class StoresInfo(command.Lister):
|
|
|
1893
1918
|
"Get available backends (only valid with Multi-Backend support)"
|
|
1894
1919
|
)
|
|
1895
1920
|
|
|
1896
|
-
def get_parser(self, prog_name):
|
|
1921
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1897
1922
|
parser = super().get_parser(prog_name)
|
|
1898
1923
|
parser.add_argument(
|
|
1899
1924
|
"--detail",
|
|
@@ -1906,7 +1931,9 @@ class StoresInfo(command.Lister):
|
|
|
1906
1931
|
)
|
|
1907
1932
|
return parser
|
|
1908
1933
|
|
|
1909
|
-
def take_action(
|
|
1934
|
+
def take_action(
|
|
1935
|
+
self, parsed_args: argparse.Namespace
|
|
1936
|
+
) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
|
|
1910
1937
|
image_client = self.app.client_manager.image
|
|
1911
1938
|
try:
|
|
1912
1939
|
columns: tuple[str, ...] = ("id", "description", "is_default")
|
openstackclient/image/v2/info.py
CHANGED
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
# under the License.
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
import argparse
|
|
15
|
+
from collections.abc import Iterable, Sequence
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
14
18
|
from osc_lib.cli import format_columns
|
|
15
19
|
|
|
16
20
|
from openstackclient import command
|
|
@@ -20,7 +24,9 @@ from openstackclient.i18n import _
|
|
|
20
24
|
class ImportInfo(command.ShowOne):
|
|
21
25
|
_description = _("Show available import methods")
|
|
22
26
|
|
|
23
|
-
def take_action(
|
|
27
|
+
def take_action(
|
|
28
|
+
self, parsed_args: argparse.Namespace
|
|
29
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
24
30
|
image_client = self.app.client_manager.image
|
|
25
31
|
|
|
26
32
|
import_info = image_client.get_import_info()
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
|
|
16
16
|
"""Image V2 Action Implementations"""
|
|
17
17
|
|
|
18
|
+
import argparse
|
|
19
|
+
from collections.abc import Iterable, Sequence
|
|
18
20
|
import logging
|
|
21
|
+
from typing import Any
|
|
19
22
|
|
|
20
23
|
from osc_lib.cli import format_columns
|
|
21
24
|
from osc_lib import exceptions
|
|
@@ -31,7 +34,7 @@ _formatters = {
|
|
|
31
34
|
LOG = logging.getLogger(__name__)
|
|
32
35
|
|
|
33
36
|
|
|
34
|
-
def _format_namespace(namespace):
|
|
37
|
+
def _format_namespace(namespace: Any) -> dict[str, Any]:
|
|
35
38
|
info = {}
|
|
36
39
|
|
|
37
40
|
fields_to_show = [
|
|
@@ -41,6 +44,7 @@ def _format_namespace(namespace):
|
|
|
41
44
|
'namespace',
|
|
42
45
|
'owner',
|
|
43
46
|
'protected',
|
|
47
|
+
'tags',
|
|
44
48
|
'schema',
|
|
45
49
|
'updated_at',
|
|
46
50
|
'visibility',
|
|
@@ -65,7 +69,7 @@ def _format_namespace(namespace):
|
|
|
65
69
|
class CreateMetadefNamespace(command.ShowOne):
|
|
66
70
|
_description = _("Create a metadef namespace")
|
|
67
71
|
|
|
68
|
-
def get_parser(self, prog_name):
|
|
72
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
69
73
|
parser = super().get_parser(prog_name)
|
|
70
74
|
parser.add_argument(
|
|
71
75
|
"namespace",
|
|
@@ -114,7 +118,9 @@ class CreateMetadefNamespace(command.ShowOne):
|
|
|
114
118
|
)
|
|
115
119
|
return parser
|
|
116
120
|
|
|
117
|
-
def take_action(
|
|
121
|
+
def take_action(
|
|
122
|
+
self, parsed_args: argparse.Namespace
|
|
123
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
118
124
|
image_client = self.app.client_manager.image
|
|
119
125
|
filter_keys = ['namespace', 'display_name', 'description']
|
|
120
126
|
kwargs = {}
|
|
@@ -133,13 +139,14 @@ class CreateMetadefNamespace(command.ShowOne):
|
|
|
133
139
|
data = image_client.create_metadef_namespace(**kwargs)
|
|
134
140
|
info = _format_namespace(data)
|
|
135
141
|
|
|
136
|
-
|
|
142
|
+
col_headers, col_data = zip(*sorted(info.items()))
|
|
143
|
+
return col_headers, col_data
|
|
137
144
|
|
|
138
145
|
|
|
139
146
|
class DeleteMetadefNamespace(command.Command):
|
|
140
147
|
_description = _("Delete metadef namespace")
|
|
141
148
|
|
|
142
|
-
def get_parser(self, prog_name):
|
|
149
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
143
150
|
parser = super().get_parser(prog_name)
|
|
144
151
|
parser.add_argument(
|
|
145
152
|
"namespace",
|
|
@@ -149,7 +156,7 @@ class DeleteMetadefNamespace(command.Command):
|
|
|
149
156
|
)
|
|
150
157
|
return parser
|
|
151
158
|
|
|
152
|
-
def take_action(self, parsed_args):
|
|
159
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
153
160
|
image_client = self.app.client_manager.image
|
|
154
161
|
|
|
155
162
|
result = 0
|
|
@@ -179,7 +186,7 @@ class DeleteMetadefNamespace(command.Command):
|
|
|
179
186
|
class ListMetadefNamespace(command.Lister):
|
|
180
187
|
_description = _("List metadef namespaces")
|
|
181
188
|
|
|
182
|
-
def get_parser(self, prog_name):
|
|
189
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
183
190
|
parser = super().get_parser(prog_name)
|
|
184
191
|
parser.add_argument(
|
|
185
192
|
"--resource-types",
|
|
@@ -193,7 +200,9 @@ class ListMetadefNamespace(command.Lister):
|
|
|
193
200
|
)
|
|
194
201
|
return parser
|
|
195
202
|
|
|
196
|
-
def take_action(
|
|
203
|
+
def take_action(
|
|
204
|
+
self, parsed_args: argparse.Namespace
|
|
205
|
+
) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
|
|
197
206
|
image_client = self.app.client_manager.image
|
|
198
207
|
filter_keys = ['resource_types', 'visibility']
|
|
199
208
|
kwargs = {}
|
|
@@ -221,7 +230,7 @@ class ListMetadefNamespace(command.Lister):
|
|
|
221
230
|
class SetMetadefNamespace(command.Command):
|
|
222
231
|
_description = _("Set metadef namespace properties")
|
|
223
232
|
|
|
224
|
-
def get_parser(self, prog_name):
|
|
233
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
225
234
|
parser = super().get_parser(prog_name)
|
|
226
235
|
parser.add_argument(
|
|
227
236
|
"namespace",
|
|
@@ -270,9 +279,20 @@ class SetMetadefNamespace(command.Command):
|
|
|
270
279
|
dest="is_protected",
|
|
271
280
|
help=_("Allow metadef namespace to be deleted (default)"),
|
|
272
281
|
)
|
|
282
|
+
parser.add_argument(
|
|
283
|
+
"--tag",
|
|
284
|
+
metavar="<tag>",
|
|
285
|
+
action='append',
|
|
286
|
+
default=[],
|
|
287
|
+
dest='tags',
|
|
288
|
+
help=_(
|
|
289
|
+
"Set a tag on this metadef namespace "
|
|
290
|
+
"(repeat option to set multiple tags)"
|
|
291
|
+
),
|
|
292
|
+
)
|
|
273
293
|
return parser
|
|
274
294
|
|
|
275
|
-
def take_action(self, parsed_args):
|
|
295
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
276
296
|
image_client = self.app.client_manager.image
|
|
277
297
|
|
|
278
298
|
namespace = parsed_args.namespace
|
|
@@ -293,11 +313,26 @@ class SetMetadefNamespace(command.Command):
|
|
|
293
313
|
|
|
294
314
|
image_client.update_metadef_namespace(namespace, **kwargs)
|
|
295
315
|
|
|
316
|
+
errors = 0
|
|
317
|
+
for tag in parsed_args.tags:
|
|
318
|
+
try:
|
|
319
|
+
image_client.add_tag_to_metadef_namespace(namespace, tag)
|
|
320
|
+
except Exception:
|
|
321
|
+
LOG.error(_("Tag set failed for tag %s"), tag)
|
|
322
|
+
errors += 1
|
|
323
|
+
|
|
324
|
+
if errors > 0:
|
|
325
|
+
msg = _("Failed to set %(errors)s of %(total)s tags.") % {
|
|
326
|
+
'errors': errors,
|
|
327
|
+
'total': len(parsed_args.tags),
|
|
328
|
+
}
|
|
329
|
+
raise exceptions.CommandError(msg)
|
|
330
|
+
|
|
296
331
|
|
|
297
332
|
class ShowMetadefNamespace(command.ShowOne):
|
|
298
333
|
_description = _("Show a metadef namespace")
|
|
299
334
|
|
|
300
|
-
def get_parser(self, prog_name):
|
|
335
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
301
336
|
parser = super().get_parser(prog_name)
|
|
302
337
|
parser.add_argument(
|
|
303
338
|
"namespace",
|
|
@@ -306,7 +341,9 @@ class ShowMetadefNamespace(command.ShowOne):
|
|
|
306
341
|
)
|
|
307
342
|
return parser
|
|
308
343
|
|
|
309
|
-
def take_action(
|
|
344
|
+
def take_action(
|
|
345
|
+
self, parsed_args: argparse.Namespace
|
|
346
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
310
347
|
image_client = self.app.client_manager.image
|
|
311
348
|
|
|
312
349
|
namespace = parsed_args.namespace
|
|
@@ -314,4 +351,63 @@ class ShowMetadefNamespace(command.ShowOne):
|
|
|
314
351
|
data = image_client.get_metadef_namespace(namespace)
|
|
315
352
|
info = _format_namespace(data)
|
|
316
353
|
|
|
317
|
-
|
|
354
|
+
col_headers, col_data = zip(*sorted(info.items()))
|
|
355
|
+
return col_headers, col_data
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
class UnsetMetadefNamespace(command.Command):
|
|
359
|
+
_description = _("Unset metadef namespace tags")
|
|
360
|
+
|
|
361
|
+
def get_parser(self, prog_name):
|
|
362
|
+
parser = super().get_parser(prog_name)
|
|
363
|
+
parser.add_argument(
|
|
364
|
+
"namespace",
|
|
365
|
+
metavar="<namespace>",
|
|
366
|
+
help=_("Metadef namespace to modify (name)"),
|
|
367
|
+
)
|
|
368
|
+
tag_group = parser.add_mutually_exclusive_group(required=True)
|
|
369
|
+
tag_group.add_argument(
|
|
370
|
+
"--tag",
|
|
371
|
+
metavar="<tag>",
|
|
372
|
+
action='append',
|
|
373
|
+
default=[],
|
|
374
|
+
dest='tags',
|
|
375
|
+
help=_(
|
|
376
|
+
"Unset a tag on this metadef namespace "
|
|
377
|
+
"(repeat option to unset multiple tags)"
|
|
378
|
+
),
|
|
379
|
+
)
|
|
380
|
+
tag_group.add_argument(
|
|
381
|
+
"--all-tags",
|
|
382
|
+
action="store_true",
|
|
383
|
+
default=False,
|
|
384
|
+
help=_("Unset all metadef tags"),
|
|
385
|
+
)
|
|
386
|
+
return parser
|
|
387
|
+
|
|
388
|
+
def take_action(self, parsed_args):
|
|
389
|
+
image_client = self.app.client_manager.image
|
|
390
|
+
|
|
391
|
+
namespace = image_client.get_metadef_namespace(parsed_args.namespace)
|
|
392
|
+
|
|
393
|
+
errors = 0
|
|
394
|
+
if parsed_args.all_tags:
|
|
395
|
+
namespace = image_client.remove_tags_from_metadef_namespace(
|
|
396
|
+
namespace
|
|
397
|
+
)
|
|
398
|
+
elif parsed_args.tags:
|
|
399
|
+
for tag in parsed_args.tags:
|
|
400
|
+
try:
|
|
401
|
+
image_client.remove_tag_from_metadef_namespace(
|
|
402
|
+
namespace, tag
|
|
403
|
+
)
|
|
404
|
+
except Exception:
|
|
405
|
+
LOG.error(_("tag unset failed for tag %s"), tag)
|
|
406
|
+
errors += 1
|
|
407
|
+
|
|
408
|
+
if errors > 0:
|
|
409
|
+
msg = _("Failed to unset %(errors)s of %(total)s tags.") % {
|
|
410
|
+
'errors': errors,
|
|
411
|
+
'total': len(parsed_args.tags),
|
|
412
|
+
}
|
|
413
|
+
raise exceptions.CommandError(msg)
|