python-openstackclient 10.0.0__py3-none-any.whl → 10.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 +1 -1
- openstackclient/common/module.py +21 -27
- openstackclient/common/pagination.py +42 -4
- openstackclient/common/project_cleanup.py +1 -2
- openstackclient/common/quota.py +9 -5
- openstackclient/compute/v2/flavor.py +3 -1
- openstackclient/compute/v2/hypervisor.py +2 -0
- openstackclient/compute/v2/keypair.py +6 -2
- openstackclient/compute/v2/server.py +21 -12
- openstackclient/compute/v2/server_event.py +8 -1
- openstackclient/compute/v2/server_group.py +2 -0
- openstackclient/compute/v2/server_migration.py +3 -0
- openstackclient/compute/v2/server_volume.py +3 -1
- openstackclient/compute/v2/service.py +3 -1
- openstackclient/compute/v2/usage.py +2 -2
- openstackclient/identity/common.py +5 -1
- openstackclient/identity/v3/access_rule.py +6 -0
- openstackclient/identity/v3/application_credential.py +10 -3
- openstackclient/identity/v3/credential.py +4 -2
- openstackclient/identity/v3/domain.py +4 -2
- openstackclient/identity/v3/endpoint.py +57 -45
- openstackclient/identity/v3/federation_protocol.py +7 -5
- openstackclient/identity/v3/group.py +11 -10
- openstackclient/identity/v3/identity_provider.py +4 -1
- openstackclient/identity/v3/limit.py +5 -2
- openstackclient/identity/v3/mapping.py +36 -19
- openstackclient/identity/v3/project.py +18 -5
- openstackclient/identity/v3/region.py +4 -2
- openstackclient/identity/v3/registered_limit.py +3 -2
- openstackclient/identity/v3/role.py +2 -1
- openstackclient/identity/v3/role_assignment.py +3 -2
- openstackclient/identity/v3/service.py +4 -2
- openstackclient/identity/v3/service_provider.py +4 -2
- openstackclient/identity/v3/trust.py +8 -5
- openstackclient/identity/v3/user.py +38 -11
- openstackclient/image/v2/cache.py +2 -2
- openstackclient/image/v2/image.py +15 -9
- openstackclient/image/v2/metadef_namespaces.py +11 -10
- openstackclient/image/v2/metadef_objects.py +5 -5
- openstackclient/image/v2/metadef_properties.py +7 -4
- openstackclient/image/v2/task.py +11 -22
- openstackclient/network/utils.py +0 -41
- openstackclient/network/v2/address_group.py +13 -1
- openstackclient/network/v2/address_scope.py +13 -8
- openstackclient/network/v2/bgpvpn/bgpvpn.py +33 -19
- openstackclient/network/v2/bgpvpn/network_association.py +25 -13
- openstackclient/network/v2/bgpvpn/port_association.py +35 -21
- openstackclient/network/v2/bgpvpn/router_association.py +27 -14
- openstackclient/network/v2/default_security_group_rule.py +14 -6
- openstackclient/network/v2/floating_ip.py +12 -4
- openstackclient/network/v2/floating_ip_port_forwarding.py +12 -2
- openstackclient/network/v2/fwaas/group.py +34 -1
- openstackclient/network/v2/fwaas/rule.py +39 -3
- openstackclient/network/v2/ip_availability.py +13 -4
- openstackclient/network/v2/l3_conntrack_helper.py +14 -1
- openstackclient/network/v2/local_ip.py +4 -1
- openstackclient/network/v2/local_ip_association.py +4 -1
- openstackclient/network/v2/ndp_proxy.py +4 -1
- openstackclient/network/v2/network.py +87 -20
- openstackclient/network/v2/network_agent.py +32 -10
- openstackclient/network/v2/network_auto_allocated_topology.py +6 -5
- openstackclient/network/v2/network_flavor.py +19 -6
- openstackclient/network/v2/network_flavor_profile.py +20 -6
- openstackclient/network/v2/network_meter.py +19 -6
- openstackclient/network/v2/network_meter_rule.py +20 -2
- openstackclient/network/v2/network_qos_policy.py +15 -7
- openstackclient/network/v2/network_qos_rule.py +16 -1
- openstackclient/network/v2/network_qos_rule_type.py +16 -5
- openstackclient/network/v2/network_rbac.py +12 -5
- openstackclient/network/v2/network_segment.py +13 -1
- openstackclient/network/v2/network_segment_range.py +15 -3
- openstackclient/network/v2/network_trunk.py +4 -1
- openstackclient/network/v2/port.py +88 -12
- openstackclient/network/v2/router.py +27 -16
- openstackclient/network/v2/security_group.py +18 -49
- openstackclient/network/v2/security_group_rule.py +18 -5
- openstackclient/network/v2/subnet.py +15 -7
- openstackclient/network/v2/subnet_pool.py +13 -8
- openstackclient/network/v2/taas/tap_flow.py +13 -3
- openstackclient/network/v2/taas/tap_mirror.py +7 -4
- openstackclient/network/v2/taas/tap_service.py +4 -1
- openstackclient/object/v1/container.py +3 -1
- openstackclient/object/v1/object.py +3 -1
- openstackclient/tests/functional/identity/v3/common.py +34 -0
- openstackclient/tests/functional/identity/v3/test_application_credential.py +1 -1
- openstackclient/tests/functional/identity/v3/test_mapping.py +81 -0
- openstackclient/tests/functional/volume/v3/test_volume_group.py +163 -0
- openstackclient/tests/unit/common/test_limits.py +1 -1
- openstackclient/tests/unit/common/test_module.py +77 -44
- openstackclient/tests/unit/common/test_quota.py +9 -0
- openstackclient/tests/unit/compute/v2/fakes.py +1 -57
- openstackclient/tests/unit/compute/v2/test_agent.py +4 -4
- openstackclient/tests/unit/compute/v2/test_aggregate.py +1 -1
- openstackclient/tests/unit/compute/v2/test_console.py +2 -2
- openstackclient/tests/unit/compute/v2/test_console_connection.py +1 -1
- openstackclient/tests/unit/compute/v2/test_flavor.py +1 -1
- openstackclient/tests/unit/compute/v2/test_host.py +3 -3
- openstackclient/tests/unit/compute/v2/test_hypervisor.py +2 -2
- openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +1 -1
- openstackclient/tests/unit/compute/v2/test_keypair.py +1 -1
- openstackclient/tests/unit/compute/v2/test_server.py +15 -15
- openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -1
- openstackclient/tests/unit/compute/v2/test_server_event.py +2 -2
- openstackclient/tests/unit/compute/v2/test_server_group.py +1 -1
- openstackclient/tests/unit/compute/v2/test_server_image.py +1 -1
- openstackclient/tests/unit/compute/v2/test_server_migration.py +4 -4
- openstackclient/tests/unit/compute/v2/test_server_share.py +4 -4
- openstackclient/tests/unit/compute/v2/test_server_volume.py +2 -2
- openstackclient/tests/unit/compute/v2/test_service.py +3 -3
- openstackclient/tests/unit/compute/v2/test_usage.py +1 -1
- openstackclient/tests/unit/identity/v2_0/fakes.py +3 -7
- openstackclient/tests/unit/identity/v2_0/test_endpoint.py +1 -1
- openstackclient/tests/unit/identity/v2_0/test_project.py +1 -1
- openstackclient/tests/unit/identity/v2_0/test_role.py +1 -1
- openstackclient/tests/unit/identity/v2_0/test_role_assignment.py +1 -1
- openstackclient/tests/unit/identity/v2_0/test_service.py +1 -1
- openstackclient/tests/unit/identity/v2_0/test_token.py +2 -2
- openstackclient/tests/unit/identity/v2_0/test_user.py +1 -1
- openstackclient/tests/unit/identity/v3/fakes.py +5 -38
- openstackclient/tests/unit/identity/v3/test_access_rule.py +3 -3
- openstackclient/tests/unit/identity/v3/test_application_credential.py +4 -4
- openstackclient/tests/unit/identity/v3/test_credential.py +5 -5
- openstackclient/tests/unit/identity/v3/test_domain.py +5 -5
- openstackclient/tests/unit/identity/v3/test_endpoint.py +6 -6
- openstackclient/tests/unit/identity/v3/test_endpoint_group.py +1 -1
- openstackclient/tests/unit/identity/v3/test_group.py +8 -8
- openstackclient/tests/unit/identity/v3/test_implied_role.py +1 -1
- openstackclient/tests/unit/identity/v3/test_limit.py +5 -5
- openstackclient/tests/unit/identity/v3/test_mappings.py +163 -79
- openstackclient/tests/unit/identity/v3/test_project.py +28 -5
- openstackclient/tests/unit/identity/v3/test_protocol.py +3 -3
- openstackclient/tests/unit/identity/v3/test_region.py +5 -5
- openstackclient/tests/unit/identity/v3/test_registered_limit.py +5 -5
- openstackclient/tests/unit/identity/v3/test_role.py +8 -8
- openstackclient/tests/unit/identity/v3/test_role_assignment.py +1 -1
- openstackclient/tests/unit/identity/v3/test_service.py +5 -5
- openstackclient/tests/unit/identity/v3/test_token.py +2 -2
- openstackclient/tests/unit/identity/v3/test_trust.py +4 -4
- openstackclient/tests/unit/identity/v3/test_user.py +73 -6
- openstackclient/tests/unit/network/v2/fakes.py +5 -77
- openstackclient/tests/unit/network/v2/fwaas/test_group.py +28 -2
- openstackclient/tests/unit/network/v2/fwaas/test_rule.py +28 -3
- openstackclient/tests/unit/network/v2/test_address_group.py +24 -0
- openstackclient/tests/unit/network/v2/test_address_scope.py +24 -0
- openstackclient/tests/unit/network/v2/test_floating_ip.py +24 -0
- openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +24 -0
- openstackclient/tests/unit/network/v2/test_ip_availability.py +25 -0
- openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +29 -3
- openstackclient/tests/unit/network/v2/test_network.py +74 -12
- openstackclient/tests/unit/network/v2/test_network_agent.py +50 -1
- openstackclient/tests/unit/network/v2/test_network_flavor.py +24 -0
- openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +24 -0
- openstackclient/tests/unit/network/v2/test_network_meter.py +24 -0
- openstackclient/tests/unit/network/v2/test_network_qos_policy.py +24 -0
- openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +24 -0
- openstackclient/tests/unit/network/v2/test_network_rbac.py +24 -0
- openstackclient/tests/unit/network/v2/test_network_segment.py +24 -0
- openstackclient/tests/unit/network/v2/test_network_segment_range.py +24 -0
- openstackclient/tests/unit/network/v2/test_port.py +166 -0
- openstackclient/tests/unit/network/v2/test_router.py +28 -7
- openstackclient/tests/unit/network/v2/test_security_group.py +22 -0
- openstackclient/tests/unit/network/v2/test_security_group_rule.py +25 -0
- openstackclient/tests/unit/network/v2/test_subnet.py +28 -4
- openstackclient/tests/unit/network/v2/test_subnet_pool.py +24 -0
- openstackclient/tests/unit/volume/v2/fakes.py +20 -140
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +5 -9
- openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +6 -0
- openstackclient/tests/unit/volume/v3/fakes.py +204 -100
- openstackclient/tests/unit/volume/v3/test_backup_record.py +114 -0
- openstackclient/tests/unit/volume/v3/test_consistency_group.py +720 -0
- openstackclient/tests/unit/volume/v3/test_consistency_group_snapshot.py +354 -0
- openstackclient/tests/unit/volume/v3/test_qos_specs.py +455 -0
- openstackclient/tests/unit/volume/v3/test_volume_attachment.py +2 -0
- openstackclient/tests/unit/volume/v3/test_volume_backend.py +158 -0
- openstackclient/tests/unit/volume/v3/test_volume_backup.py +5 -9
- openstackclient/tests/unit/volume/v3/test_volume_group_type.py +65 -0
- openstackclient/tests/unit/volume/v3/test_volume_host.py +115 -0
- openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +6 -0
- openstackclient/volume/v2/volume.py +4 -2
- openstackclient/volume/v2/volume_backup.py +2 -3
- openstackclient/volume/v2/volume_snapshot.py +3 -4
- openstackclient/volume/v3/backup_record.py +94 -0
- openstackclient/volume/v3/consistency_group.py +400 -0
- openstackclient/volume/v3/consistency_group_snapshot.py +225 -0
- openstackclient/volume/v3/qos_specs.py +389 -0
- openstackclient/volume/v3/volume.py +4 -2
- openstackclient/volume/v3/volume_attachment.py +5 -1
- openstackclient/volume/v3/volume_backend.py +130 -0
- openstackclient/volume/v3/volume_backup.py +2 -3
- openstackclient/volume/v3/volume_group_snapshot.py +4 -6
- openstackclient/volume/v3/volume_group_type.py +1 -1
- openstackclient/volume/v3/volume_host.py +74 -0
- openstackclient/volume/v3/volume_message.py +3 -1
- openstackclient/volume/v3/volume_snapshot.py +2 -1
- {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/METADATA +3 -4
- {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/RECORD +202 -188
- {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/entry_points.txt +24 -24
- {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/licenses/AUTHORS +5 -0
- python_openstackclient-10.1.0.dist-info/pbr.json +1 -0
- python_openstackclient-10.0.0.dist-info/pbr.json +0 -1
- {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/WHEEL +0 -0
- {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/licenses/LICENSE +0 -0
- {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/top_level.txt +0 -0
|
@@ -130,7 +130,7 @@ class ListAvailabilityZone(command.Lister):
|
|
|
130
130
|
data = list(compute_client.availability_zones(details=True))
|
|
131
131
|
except sdk_exceptions.ForbiddenException: # policy doesn't allow
|
|
132
132
|
try:
|
|
133
|
-
data = compute_client.availability_zones(details=False)
|
|
133
|
+
data = list(compute_client.availability_zones(details=False))
|
|
134
134
|
except Exception:
|
|
135
135
|
raise
|
|
136
136
|
|
openstackclient/common/module.py
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"""Module action implementation"""
|
|
17
17
|
|
|
18
18
|
import argparse
|
|
19
|
+
import importlib.metadata
|
|
19
20
|
import sys
|
|
20
21
|
from collections.abc import Iterable, Sequence
|
|
21
22
|
from typing import Any
|
|
@@ -93,36 +94,29 @@ class ListModule(command.ShowOne):
|
|
|
93
94
|
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
94
95
|
data = {}
|
|
95
96
|
# Get module versions
|
|
96
|
-
|
|
97
|
-
for k in
|
|
98
|
-
|
|
97
|
+
package_distributions = importlib.metadata.packages_distributions()
|
|
98
|
+
for k in sys.modules.keys():
|
|
99
|
+
module = k.split('.')[0]
|
|
99
100
|
# Skip private modules and the modules that had been added,
|
|
100
101
|
# like: keystoneclient, keystoneclient.exceptions and
|
|
101
102
|
# keystoneclient.auth
|
|
102
|
-
if
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if k == 'openstack':
|
|
120
|
-
data[k] = mods[k].version.__version__
|
|
121
|
-
else:
|
|
122
|
-
data[k] = mods[k].__version__
|
|
123
|
-
except Exception: # noqa: S110
|
|
124
|
-
# Catch all exceptions, just skip it
|
|
125
|
-
pass
|
|
103
|
+
if module.startswith('_') or module in data:
|
|
104
|
+
continue
|
|
105
|
+
|
|
106
|
+
# TODO(dtroyer): Need a better way to decide which modules to
|
|
107
|
+
# show for the default (not --all) invocation.
|
|
108
|
+
# It should be just the things we actually care
|
|
109
|
+
# about like client and plugin modules...
|
|
110
|
+
# Handle xxxclient and openstacksdk
|
|
111
|
+
if parsed_args.all or (
|
|
112
|
+
module.endswith('client') or module == 'openstack'
|
|
113
|
+
):
|
|
114
|
+
try:
|
|
115
|
+
package = package_distributions[module][0]
|
|
116
|
+
data[module] = importlib.metadata.version(package)
|
|
117
|
+
except Exception: # noqa: S110
|
|
118
|
+
# Catch all exceptions, just skip it
|
|
119
|
+
pass
|
|
126
120
|
|
|
127
121
|
col_headers, col_data = zip(*sorted(data.items()))
|
|
128
122
|
return col_headers, col_data
|
|
@@ -21,8 +21,11 @@ from openstackclient.i18n import _
|
|
|
21
21
|
# useful
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
# TODO(stephenfin): include_max_items should not be necessary once we need to
|
|
25
|
+
# migrate remaining users to openstacksdk
|
|
24
26
|
def add_marker_pagination_option_to_parser(
|
|
25
27
|
parser: argparse.ArgumentParser,
|
|
28
|
+
include_max_items: bool = True,
|
|
26
29
|
) -> None:
|
|
27
30
|
"""Add marker-based pagination options to the parser.
|
|
28
31
|
|
|
@@ -39,8 +42,11 @@ def add_marker_pagination_option_to_parser(
|
|
|
39
42
|
type=int,
|
|
40
43
|
action=parseractions.NonNegativeAction,
|
|
41
44
|
help=_(
|
|
42
|
-
'The maximum number of entries to return. If the value
|
|
43
|
-
'the server-defined maximum, then the
|
|
45
|
+
'The maximum number of entries to return per page. If the value '
|
|
46
|
+
'exceeds the server-defined maximum, then the server-defined '
|
|
47
|
+
'value will be used. Note that this controls the page size, not '
|
|
48
|
+
'the total number of entries returned. Use --max-items to limit '
|
|
49
|
+
'the total number of entries returned.'
|
|
44
50
|
),
|
|
45
51
|
)
|
|
46
52
|
parser.add_argument(
|
|
@@ -52,10 +58,26 @@ def add_marker_pagination_option_to_parser(
|
|
|
52
58
|
'This should be a value that was returned in a previous request.'
|
|
53
59
|
),
|
|
54
60
|
)
|
|
61
|
+
if include_max_items:
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
'--max-items',
|
|
64
|
+
metavar='<max-items>',
|
|
65
|
+
type=int,
|
|
66
|
+
action=parseractions.NonNegativeAction,
|
|
67
|
+
default=None,
|
|
68
|
+
help=_(
|
|
69
|
+
'The maximum number of entries to return in total, paging '
|
|
70
|
+
'through multiple requests if needed. Use --limit to control '
|
|
71
|
+
'the page size.'
|
|
72
|
+
),
|
|
73
|
+
)
|
|
55
74
|
|
|
56
75
|
|
|
76
|
+
# TODO(stephenfin): include_max_items should not be necessary once we need to
|
|
77
|
+
# migrate remaining users to openstacksdk
|
|
57
78
|
def add_offset_pagination_option_to_parser(
|
|
58
79
|
parser: argparse.ArgumentParser,
|
|
80
|
+
include_max_items: bool = True,
|
|
59
81
|
) -> None:
|
|
60
82
|
"""Add offset-based pagination options to the parser.
|
|
61
83
|
|
|
@@ -71,8 +93,11 @@ def add_offset_pagination_option_to_parser(
|
|
|
71
93
|
type=int,
|
|
72
94
|
action=parseractions.NonNegativeAction,
|
|
73
95
|
help=_(
|
|
74
|
-
'The maximum number of entries to return. If the value
|
|
75
|
-
'the server-defined maximum, then the maximum value will
|
|
96
|
+
'The maximum number of entries to return per page. If the value '
|
|
97
|
+
'exceeds the server-defined maximum, then the maximum value will '
|
|
98
|
+
'be used. Note that this controls the page size, not the total '
|
|
99
|
+
'number of entries returned. Use --max-items to limit the total '
|
|
100
|
+
'number of entries returned.'
|
|
76
101
|
),
|
|
77
102
|
)
|
|
78
103
|
parser.add_argument(
|
|
@@ -86,3 +111,16 @@ def add_offset_pagination_option_to_parser(
|
|
|
86
111
|
'return.'
|
|
87
112
|
),
|
|
88
113
|
)
|
|
114
|
+
if include_max_items:
|
|
115
|
+
parser.add_argument(
|
|
116
|
+
'--max-items',
|
|
117
|
+
metavar='<max-items>',
|
|
118
|
+
type=int,
|
|
119
|
+
action=parseractions.NonNegativeAction,
|
|
120
|
+
default=None,
|
|
121
|
+
help=_(
|
|
122
|
+
'The maximum number of entries to return in total, paging '
|
|
123
|
+
'through multiple requests if needed. Use --limit to control '
|
|
124
|
+
'the page size.'
|
|
125
|
+
),
|
|
126
|
+
)
|
|
@@ -105,8 +105,7 @@ class ProjectCleanup(command.Command):
|
|
|
105
105
|
project = identity_client.find_project(
|
|
106
106
|
name_or_id=parsed_args.project, ignore_missing=False
|
|
107
107
|
)
|
|
108
|
-
|
|
109
|
-
connection = connection.connect_as_project(project) # type: ignore
|
|
108
|
+
connection = connection.connect_as_project(project)
|
|
110
109
|
|
|
111
110
|
if connection:
|
|
112
111
|
status_queue: queue.Queue[Any] = queue.Queue()
|
openstackclient/common/quota.py
CHANGED
|
@@ -51,6 +51,7 @@ VOLUME_QUOTAS = {
|
|
|
51
51
|
'backups': 'backups',
|
|
52
52
|
'backup_gigabytes': 'backup-gigabytes',
|
|
53
53
|
'gigabytes': 'gigabytes',
|
|
54
|
+
'groups': 'groups',
|
|
54
55
|
'per_volume_gigabytes': 'per-volume-gigabytes',
|
|
55
56
|
'snapshots': 'snapshots',
|
|
56
57
|
'volumes': 'volumes',
|
|
@@ -70,6 +71,7 @@ NETWORK_QUOTAS = {
|
|
|
70
71
|
'subnet': 'subnets',
|
|
71
72
|
'port': 'ports',
|
|
72
73
|
'router': 'routers',
|
|
74
|
+
'router_route': 'router-routes',
|
|
73
75
|
'rbac_policy': 'rbac-policies',
|
|
74
76
|
'subnetpool': 'subnetpools',
|
|
75
77
|
}
|
|
@@ -78,6 +80,7 @@ NETWORK_KEYS = [
|
|
|
78
80
|
'floating_ips',
|
|
79
81
|
'networks',
|
|
80
82
|
'rbac_policies',
|
|
83
|
+
'router_routes',
|
|
81
84
|
'routers',
|
|
82
85
|
'ports',
|
|
83
86
|
'security_group_rules',
|
|
@@ -102,7 +105,7 @@ def _xform_get_quota(
|
|
|
102
105
|
return res
|
|
103
106
|
|
|
104
107
|
|
|
105
|
-
def get_project(app: Any, project: str | None) -> dict[str, str
|
|
108
|
+
def get_project(app: Any, project: str | None) -> dict[str, str]:
|
|
106
109
|
if project is not None:
|
|
107
110
|
identity_client = sdk_utils.ensure_service_version(
|
|
108
111
|
app.client_manager.sdk_connection.identity, '3'
|
|
@@ -112,14 +115,11 @@ def get_project(app: Any, project: str | None) -> dict[str, str | None]:
|
|
|
112
115
|
)
|
|
113
116
|
project_id = found_project.id
|
|
114
117
|
project_name = found_project.name
|
|
115
|
-
|
|
118
|
+
else:
|
|
116
119
|
# Get the project from the current auth
|
|
117
120
|
auth_ref = app.client_manager.auth_ref
|
|
118
121
|
project_id = auth_ref.project_id
|
|
119
122
|
project_name = auth_ref.project_name
|
|
120
|
-
else:
|
|
121
|
-
project_id = None
|
|
122
|
-
project_name = None
|
|
123
123
|
|
|
124
124
|
return {
|
|
125
125
|
'id': project_id,
|
|
@@ -376,6 +376,7 @@ class ListQuota(command.Lister):
|
|
|
376
376
|
'backups',
|
|
377
377
|
'backup_gigabytes',
|
|
378
378
|
'gigabytes',
|
|
379
|
+
'groups',
|
|
379
380
|
'per_volume_gigabytes',
|
|
380
381
|
'snapshots',
|
|
381
382
|
'volumes',
|
|
@@ -385,6 +386,7 @@ class ListQuota(command.Lister):
|
|
|
385
386
|
'Backups',
|
|
386
387
|
'Backup Gigabytes',
|
|
387
388
|
'Gigabytes',
|
|
389
|
+
'Groups',
|
|
388
390
|
'Per Volume Gigabytes',
|
|
389
391
|
'Snapshots',
|
|
390
392
|
'Volumes',
|
|
@@ -439,6 +441,7 @@ class ListQuota(command.Lister):
|
|
|
439
441
|
'networks',
|
|
440
442
|
'ports',
|
|
441
443
|
'rbac_policies',
|
|
444
|
+
'router_routes',
|
|
442
445
|
'routers',
|
|
443
446
|
'security_groups',
|
|
444
447
|
'security_group_rules',
|
|
@@ -451,6 +454,7 @@ class ListQuota(command.Lister):
|
|
|
451
454
|
'Networks',
|
|
452
455
|
'Ports',
|
|
453
456
|
'RBAC Policies',
|
|
457
|
+
'Router Routes',
|
|
454
458
|
'Routers',
|
|
455
459
|
'Security Groups',
|
|
456
460
|
'Security Group Rules',
|
|
@@ -339,6 +339,8 @@ class ListFlavor(command.Lister):
|
|
|
339
339
|
|
|
340
340
|
if parsed_args.limit:
|
|
341
341
|
query_attrs['limit'] = parsed_args.limit
|
|
342
|
+
if parsed_args.max_items is not None:
|
|
343
|
+
query_attrs['max_items'] = parsed_args.max_items
|
|
342
344
|
|
|
343
345
|
if parsed_args.limit or parsed_args.marker:
|
|
344
346
|
# User passed explicit pagination request, switch off SDK
|
|
@@ -351,7 +353,7 @@ class ListFlavor(command.Lister):
|
|
|
351
353
|
if parsed_args.min_ram:
|
|
352
354
|
query_attrs['min_ram'] = parsed_args.min_ram
|
|
353
355
|
|
|
354
|
-
data = list(compute_client.flavors(**query_attrs))
|
|
356
|
+
data = list(compute_client.flavors(**query_attrs)) # type: ignore[arg-type]
|
|
355
357
|
# Even if server supports 2.61 some policy might stop it sending us
|
|
356
358
|
# extra_specs. So try to fetch them if they are absent
|
|
357
359
|
for f in data:
|
|
@@ -122,6 +122,8 @@ class ListHypervisor(command.Lister):
|
|
|
122
122
|
)
|
|
123
123
|
raise exceptions.CommandError(msg)
|
|
124
124
|
list_opts['limit'] = parsed_args.limit
|
|
125
|
+
if parsed_args.max_items is not None:
|
|
126
|
+
list_opts['max_items'] = parsed_args.max_items
|
|
125
127
|
|
|
126
128
|
if parsed_args.matching:
|
|
127
129
|
list_opts['hypervisor_hostname_pattern'] = parsed_args.matching
|
|
@@ -23,6 +23,7 @@ from typing import Any
|
|
|
23
23
|
|
|
24
24
|
from cryptography.hazmat.primitives.asymmetric import ed25519
|
|
25
25
|
from cryptography.hazmat.primitives import serialization
|
|
26
|
+
from openstack.compute.v2 import keypair as _keypair
|
|
26
27
|
from openstack import resource
|
|
27
28
|
from openstack import utils as sdk_utils
|
|
28
29
|
from osc_lib import exceptions
|
|
@@ -336,7 +337,10 @@ class ListKeypair(command.Lister):
|
|
|
336
337
|
raise exceptions.CommandError(msg)
|
|
337
338
|
|
|
338
339
|
kwargs['limit'] = parsed_args.limit
|
|
340
|
+
if parsed_args.max_items is not None:
|
|
341
|
+
kwargs['max_items'] = parsed_args.max_items
|
|
339
342
|
|
|
343
|
+
data: list[_keypair.Keypair]
|
|
340
344
|
if parsed_args.project:
|
|
341
345
|
if not sdk_utils.supports_microversion(compute_client, '2.10'):
|
|
342
346
|
msg = _(
|
|
@@ -386,9 +390,9 @@ class ListKeypair(command.Lister):
|
|
|
386
390
|
)
|
|
387
391
|
kwargs['user_id'] = user.id
|
|
388
392
|
|
|
389
|
-
data = compute_client.keypairs(**kwargs)
|
|
393
|
+
data = list(compute_client.keypairs(**kwargs))
|
|
390
394
|
else:
|
|
391
|
-
data = compute_client.keypairs(**kwargs)
|
|
395
|
+
data = list(compute_client.keypairs(**kwargs))
|
|
392
396
|
|
|
393
397
|
columns: tuple[str, ...] = ("Name", "Fingerprint")
|
|
394
398
|
|
|
@@ -2854,6 +2854,9 @@ class ListServer(command.Lister):
|
|
|
2854
2854
|
search_opts['limit'] = parsed_args.limit
|
|
2855
2855
|
search_opts['paginated'] = False
|
|
2856
2856
|
|
|
2857
|
+
if parsed_args.max_items is not None:
|
|
2858
|
+
search_opts['max_items'] = parsed_args.max_items
|
|
2859
|
+
|
|
2857
2860
|
LOG.debug('search options: %s', search_opts)
|
|
2858
2861
|
|
|
2859
2862
|
if search_opts['changes-before']:
|
|
@@ -3102,8 +3105,8 @@ class ListServer(command.Lister):
|
|
|
3102
3105
|
else:
|
|
3103
3106
|
try:
|
|
3104
3107
|
flavors_list = compute_client.flavors(is_public=None)
|
|
3105
|
-
for
|
|
3106
|
-
flavors[
|
|
3108
|
+
for f in flavors_list:
|
|
3109
|
+
flavors[f.id] = f
|
|
3107
3110
|
except Exception: # noqa: S110
|
|
3108
3111
|
# retrieving flavor names is not crucial, so we swallow any
|
|
3109
3112
|
# exceptions
|
|
@@ -3124,29 +3127,33 @@ class ListServer(command.Lister):
|
|
|
3124
3127
|
if 'id' in s.image and s.image.id is not None:
|
|
3125
3128
|
image = images.get(s.image['id'])
|
|
3126
3129
|
if image:
|
|
3127
|
-
s
|
|
3130
|
+
setattr(s, 'image_name', image.name)
|
|
3128
3131
|
s.image_id = s.image['id']
|
|
3129
3132
|
else:
|
|
3130
3133
|
# NOTE(melwitt): An server booted from a volume will have no
|
|
3131
3134
|
# image associated with it. We fill in the Image Name and ID
|
|
3132
3135
|
# with "N/A (booted from volume)" to help users who want to be
|
|
3133
3136
|
# able to grep for boot-from-volume servers when using the CLI.
|
|
3134
|
-
s
|
|
3137
|
+
setattr(s, 'image_name', IMAGE_STRING_FOR_BFV)
|
|
3135
3138
|
s.image_id = IMAGE_STRING_FOR_BFV
|
|
3136
3139
|
|
|
3137
3140
|
if not sdk_utils.supports_microversion(compute_client, '2.47'):
|
|
3138
3141
|
if s.flavor['id'] in flavors:
|
|
3139
|
-
s
|
|
3142
|
+
setattr(s, 'flavor_name', flavors[s.flavor['id']].name)
|
|
3140
3143
|
s.flavor_id = s.flavor['id']
|
|
3141
3144
|
else:
|
|
3142
|
-
s
|
|
3145
|
+
setattr(s, 'flavor_name', s.flavor['original_name'])
|
|
3143
3146
|
|
|
3144
3147
|
# Add a list with security group name as attribute
|
|
3145
3148
|
for s in data:
|
|
3146
3149
|
if hasattr(s, 'security_groups') and s.security_groups is not None:
|
|
3147
|
-
|
|
3150
|
+
setattr(
|
|
3151
|
+
s,
|
|
3152
|
+
'security_groups_name',
|
|
3153
|
+
[x["name"] for x in s.security_groups],
|
|
3154
|
+
)
|
|
3148
3155
|
else:
|
|
3149
|
-
s
|
|
3156
|
+
setattr(s, 'security_groups_name', [])
|
|
3150
3157
|
|
|
3151
3158
|
# The host_status field contains the status of the compute host the
|
|
3152
3159
|
# server is on. It is only returned by the API when the nova-api
|
|
@@ -4256,7 +4263,9 @@ volume from a server with status ``SHELVED`` or ``SHELVED_OFFLOADED``."""
|
|
|
4256
4263
|
|
|
4257
4264
|
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
4258
4265
|
compute_client = self.app.client_manager.compute
|
|
4259
|
-
volume_client =
|
|
4266
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
4267
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
4268
|
+
)
|
|
4260
4269
|
|
|
4261
4270
|
server = compute_client.find_server(
|
|
4262
4271
|
parsed_args.server,
|
|
@@ -4268,8 +4277,8 @@ volume from a server with status ``SHELVED`` or ``SHELVED_OFFLOADED``."""
|
|
|
4268
4277
|
)
|
|
4269
4278
|
|
|
4270
4279
|
compute_client.delete_volume_attachment(
|
|
4271
|
-
volume,
|
|
4272
4280
|
server,
|
|
4281
|
+
volume,
|
|
4273
4282
|
ignore_missing=False,
|
|
4274
4283
|
)
|
|
4275
4284
|
|
|
@@ -4919,8 +4928,8 @@ information for the server."""
|
|
|
4919
4928
|
)
|
|
4920
4929
|
|
|
4921
4930
|
if parsed_args.diagnostics:
|
|
4922
|
-
|
|
4923
|
-
col_headers, col_data = zip(*sorted(
|
|
4931
|
+
diagnostics = compute_client.get_server_diagnostics(server)
|
|
4932
|
+
col_headers, col_data = zip(*sorted(diagnostics.items()))
|
|
4924
4933
|
return col_headers, col_data
|
|
4925
4934
|
|
|
4926
4935
|
topology = None
|
|
@@ -23,6 +23,7 @@ import uuid
|
|
|
23
23
|
|
|
24
24
|
from cliff import columns
|
|
25
25
|
import iso8601
|
|
26
|
+
from openstack.compute.v2 import server_action as _server_action
|
|
26
27
|
from openstack import exceptions as sdk_exceptions
|
|
27
28
|
from openstack import utils as sdk_utils
|
|
28
29
|
from osc_lib import exceptions
|
|
@@ -67,7 +68,8 @@ class ServerActionEventColumn(columns.FormattableColumn[Any]):
|
|
|
67
68
|
objects as we'd like.
|
|
68
69
|
"""
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
@staticmethod
|
|
72
|
+
def _format_event(event: _server_action.ServerAction) -> dict[str, Any]:
|
|
71
73
|
hidden_columns = ['id', 'name', 'location']
|
|
72
74
|
_, columns = utils.get_osc_show_columns_for_sdk_resource(
|
|
73
75
|
event, {}, hidden_columns
|
|
@@ -171,6 +173,9 @@ class ListServerEvent(command.Lister):
|
|
|
171
173
|
kwargs['limit'] = parsed_args.limit
|
|
172
174
|
kwargs['paginated'] = False
|
|
173
175
|
|
|
176
|
+
if parsed_args.max_items is not None:
|
|
177
|
+
kwargs['max_items'] = parsed_args.max_items
|
|
178
|
+
|
|
174
179
|
if parsed_args.changes_since:
|
|
175
180
|
if not sdk_utils.supports_microversion(compute_client, '2.58'):
|
|
176
181
|
msg = _(
|
|
@@ -295,6 +300,8 @@ class ShowServerEvent(command.ShowOne):
|
|
|
295
300
|
parsed_args.request_id,
|
|
296
301
|
server_id,
|
|
297
302
|
)
|
|
303
|
+
# this is a bug is SDK
|
|
304
|
+
assert server_action is not None
|
|
298
305
|
|
|
299
306
|
column_headers, columns = _get_server_event_columns(
|
|
300
307
|
server_action,
|
|
@@ -219,6 +219,8 @@ class ListServerGroup(command.Lister):
|
|
|
219
219
|
|
|
220
220
|
if parsed_args.limit:
|
|
221
221
|
kwargs['limit'] = parsed_args.limit
|
|
222
|
+
if parsed_args.max_items is not None:
|
|
223
|
+
kwargs['max_items'] = parsed_args.max_items
|
|
222
224
|
|
|
223
225
|
data = compute_client.server_groups(**kwargs)
|
|
224
226
|
|
|
@@ -207,6 +207,9 @@ class ListMigration(command.Lister):
|
|
|
207
207
|
search_opts['limit'] = parsed_args.limit
|
|
208
208
|
search_opts['paginated'] = False
|
|
209
209
|
|
|
210
|
+
if parsed_args.max_items is not None:
|
|
211
|
+
search_opts['max_items'] = parsed_args.max_items
|
|
212
|
+
|
|
210
213
|
if parsed_args.changes_since:
|
|
211
214
|
if not sdk_utils.supports_microversion(compute_client, "2.59"):
|
|
212
215
|
msg = _(
|
|
@@ -121,7 +121,9 @@ class SetServerVolume(command.Command):
|
|
|
121
121
|
|
|
122
122
|
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
123
123
|
compute_client = self.app.client_manager.compute
|
|
124
|
-
volume_client =
|
|
124
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
125
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
126
|
+
)
|
|
125
127
|
|
|
126
128
|
if parsed_args.delete_on_termination is not None:
|
|
127
129
|
if not sdk_utils.supports_microversion(compute_client, '2.85'):
|
|
@@ -290,8 +290,10 @@ class SetService(command.Command):
|
|
|
290
290
|
msg = _('--os-compute-api-version 2.11 or later is required')
|
|
291
291
|
raise exceptions.CommandError(msg)
|
|
292
292
|
try:
|
|
293
|
+
# FIXME(stephenfin): This is broken between 2.11 and 2.53. What
|
|
294
|
+
# is the expected ID here?
|
|
293
295
|
compute_client.update_service_forced_down(
|
|
294
|
-
service_id,
|
|
296
|
+
service_id, # type: ignore[arg-type]
|
|
295
297
|
parsed_args.host,
|
|
296
298
|
parsed_args.service,
|
|
297
299
|
force_down,
|
|
@@ -157,7 +157,7 @@ class ListUsage(command.Lister):
|
|
|
157
157
|
)
|
|
158
158
|
|
|
159
159
|
date_cli_format = "%Y-%m-%d"
|
|
160
|
-
now = datetime.datetime.now(datetime.
|
|
160
|
+
now = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
|
161
161
|
|
|
162
162
|
if parsed_args.start:
|
|
163
163
|
start = datetime.datetime.strptime(
|
|
@@ -243,7 +243,7 @@ class ShowUsage(command.ShowOne):
|
|
|
243
243
|
identity_client = self.app.client_manager.identity
|
|
244
244
|
compute_client = self.app.client_manager.compute
|
|
245
245
|
date_cli_format = "%Y-%m-%d"
|
|
246
|
-
now = datetime.datetime.now(datetime.
|
|
246
|
+
now = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
|
247
247
|
|
|
248
248
|
if parsed_args.start:
|
|
249
249
|
start = datetime.datetime.strptime(
|
|
@@ -25,6 +25,8 @@ from keystoneclient.v3 import groups
|
|
|
25
25
|
from keystoneclient.v3 import projects
|
|
26
26
|
from keystoneclient.v3 import users
|
|
27
27
|
from openstack import exceptions as sdk_exceptions
|
|
28
|
+
from openstack.identity import v3 as identity
|
|
29
|
+
from openstack.identity.v3 import service as _service
|
|
28
30
|
from osc_lib import exceptions
|
|
29
31
|
from osc_lib import utils
|
|
30
32
|
|
|
@@ -78,7 +80,9 @@ def find_service(identity_client: Any, name_type_or_id: str) -> Any:
|
|
|
78
80
|
raise exceptions.CommandError(msg % name_type_or_id)
|
|
79
81
|
|
|
80
82
|
|
|
81
|
-
def find_service_sdk(
|
|
83
|
+
def find_service_sdk(
|
|
84
|
+
identity_client: identity.Proxy, name_type_or_id: str
|
|
85
|
+
) -> _service.Service:
|
|
82
86
|
"""Find a service by id, name or type."""
|
|
83
87
|
|
|
84
88
|
try:
|
|
@@ -55,6 +55,9 @@ class DeleteAccessRule(command.Command):
|
|
|
55
55
|
# this will never happen
|
|
56
56
|
raise exceptions.CommandError('invalid authentication info')
|
|
57
57
|
user_id = auth.get_user_id(conn.session)
|
|
58
|
+
if user_id is None:
|
|
59
|
+
# this will never happen
|
|
60
|
+
raise exceptions.CommandError('invalid authentication info')
|
|
58
61
|
|
|
59
62
|
errors = 0
|
|
60
63
|
for ac in parsed_args.access_rule:
|
|
@@ -146,6 +149,9 @@ class ShowAccessRule(command.ShowOne):
|
|
|
146
149
|
# this will never happen
|
|
147
150
|
raise exceptions.CommandError('invalid authentication info')
|
|
148
151
|
user_id = auth.get_user_id(conn.session)
|
|
152
|
+
if user_id is None:
|
|
153
|
+
# this will never happen
|
|
154
|
+
raise exceptions.CommandError('invalid authentication info')
|
|
149
155
|
|
|
150
156
|
access_rule = identity_client.get_access_rule(
|
|
151
157
|
user_id, parsed_args.access_rule
|
|
@@ -24,6 +24,9 @@ from typing import Any
|
|
|
24
24
|
import uuid
|
|
25
25
|
|
|
26
26
|
from cliff import columns as cliff_columns
|
|
27
|
+
from openstack.identity.v3 import (
|
|
28
|
+
application_credential as _application_credential,
|
|
29
|
+
)
|
|
27
30
|
from openstack import utils as sdk_utils
|
|
28
31
|
from osc_lib import exceptions
|
|
29
32
|
from osc_lib import utils
|
|
@@ -43,8 +46,10 @@ class RolesColumn(cliff_columns.FormattableColumn[Any]):
|
|
|
43
46
|
|
|
44
47
|
|
|
45
48
|
def _format_application_credential(
|
|
46
|
-
application_credential:
|
|
47
|
-
|
|
49
|
+
application_credential: _application_credential.ApplicationCredential,
|
|
50
|
+
*,
|
|
51
|
+
include_secret: bool = False,
|
|
52
|
+
) -> tuple[tuple[str, ...], Iterable[Any]]:
|
|
48
53
|
column_headers: tuple[str, ...] = (
|
|
49
54
|
'ID',
|
|
50
55
|
'Name',
|
|
@@ -78,7 +83,9 @@ def _format_application_credential(
|
|
|
78
83
|
|
|
79
84
|
|
|
80
85
|
def _format_application_credentials(
|
|
81
|
-
application_credentials:
|
|
86
|
+
application_credentials: Iterable[
|
|
87
|
+
_application_credential.ApplicationCredential
|
|
88
|
+
],
|
|
82
89
|
) -> tuple[tuple[str, ...], Any]:
|
|
83
90
|
column_headers = (
|
|
84
91
|
'ID',
|
|
@@ -20,6 +20,7 @@ from collections.abc import Iterable, Sequence
|
|
|
20
20
|
import logging
|
|
21
21
|
from typing import Any
|
|
22
22
|
|
|
23
|
+
from openstack.identity.v3 import credential as _credential
|
|
23
24
|
from openstack import utils as sdk_utils
|
|
24
25
|
from osc_lib import exceptions
|
|
25
26
|
from osc_lib import utils
|
|
@@ -28,11 +29,12 @@ from openstackclient import command
|
|
|
28
29
|
from openstackclient.i18n import _
|
|
29
30
|
from openstackclient.identity import common
|
|
30
31
|
|
|
31
|
-
|
|
32
32
|
LOG = logging.getLogger(__name__)
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def _format_credential(
|
|
35
|
+
def _format_credential(
|
|
36
|
+
credential: _credential.Credential,
|
|
37
|
+
) -> tuple[tuple[str, ...], Iterable[Any]]:
|
|
36
38
|
columns = (
|
|
37
39
|
'blob',
|
|
38
40
|
'id',
|
|
@@ -21,6 +21,7 @@ import logging
|
|
|
21
21
|
from typing import Any
|
|
22
22
|
|
|
23
23
|
from openstack import exceptions as sdk_exceptions
|
|
24
|
+
from openstack.identity.v3 import domain as _domain
|
|
24
25
|
from openstack import utils as sdk_utils
|
|
25
26
|
from osc_lib import exceptions
|
|
26
27
|
from osc_lib import utils
|
|
@@ -29,11 +30,12 @@ from openstackclient import command
|
|
|
29
30
|
from openstackclient.i18n import _
|
|
30
31
|
from openstackclient.identity import common
|
|
31
32
|
|
|
32
|
-
|
|
33
33
|
LOG = logging.getLogger(__name__)
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
def _format_domain(
|
|
36
|
+
def _format_domain(
|
|
37
|
+
domain: _domain.Domain,
|
|
38
|
+
) -> tuple[tuple[str, ...], tuple[Any, ...]]:
|
|
37
39
|
columns = (
|
|
38
40
|
'id',
|
|
39
41
|
'name',
|