python-openstackclient 8.1.0__py3-none-any.whl → 8.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openstackclient/api/compute_v2.py +2 -2
- openstackclient/api/object_store_v1.py +4 -1
- openstackclient/api/volume_v2.py +60 -0
- openstackclient/api/volume_v3.py +60 -0
- openstackclient/command.py +27 -0
- openstackclient/common/availability_zone.py +1 -1
- openstackclient/common/clientmanager.py +59 -21
- openstackclient/common/configuration.py +1 -1
- openstackclient/common/extension.py +1 -1
- openstackclient/common/limits.py +1 -1
- openstackclient/common/module.py +4 -2
- openstackclient/common/project_cleanup.py +10 -8
- openstackclient/common/quota.py +23 -6
- openstackclient/common/versions.py +1 -2
- openstackclient/compute/v2/agent.py +1 -1
- openstackclient/compute/v2/aggregate.py +6 -5
- openstackclient/compute/v2/console.py +5 -3
- openstackclient/compute/v2/console_connection.py +1 -1
- openstackclient/compute/v2/flavor.py +15 -2
- openstackclient/compute/v2/host.py +1 -1
- openstackclient/compute/v2/hypervisor.py +1 -1
- openstackclient/compute/v2/hypervisor_stats.py +1 -1
- openstackclient/compute/v2/keypair.py +1 -1
- openstackclient/compute/v2/server.py +77 -30
- openstackclient/compute/v2/server_backup.py +1 -1
- openstackclient/compute/v2/server_event.py +1 -1
- openstackclient/compute/v2/server_group.py +4 -2
- openstackclient/compute/v2/server_image.py +1 -1
- openstackclient/compute/v2/server_migration.py +1 -1
- openstackclient/compute/v2/server_volume.py +1 -1
- openstackclient/compute/v2/service.py +1 -1
- openstackclient/compute/v2/usage.py +6 -4
- openstackclient/identity/common.py +10 -14
- openstackclient/identity/v2_0/catalog.py +3 -2
- openstackclient/identity/v2_0/ec2creds.py +1 -1
- openstackclient/identity/v2_0/endpoint.py +1 -1
- openstackclient/identity/v2_0/project.py +17 -7
- openstackclient/identity/v2_0/role.py +1 -1
- openstackclient/identity/v2_0/role_assignment.py +3 -3
- openstackclient/identity/v2_0/service.py +1 -1
- openstackclient/identity/v2_0/token.py +1 -1
- openstackclient/identity/v2_0/user.py +2 -2
- openstackclient/identity/v3/access_rule.py +16 -4
- openstackclient/identity/v3/application_credential.py +116 -95
- openstackclient/identity/v3/catalog.py +3 -3
- openstackclient/identity/v3/consumer.py +1 -1
- openstackclient/identity/v3/credential.py +1 -1
- openstackclient/identity/v3/domain.py +15 -10
- openstackclient/identity/v3/ec2creds.py +1 -1
- openstackclient/identity/v3/endpoint.py +33 -12
- openstackclient/identity/v3/endpoint_group.py +1 -1
- openstackclient/identity/v3/federation_protocol.py +1 -1
- openstackclient/identity/v3/group.py +11 -5
- openstackclient/identity/v3/identity_provider.py +12 -10
- openstackclient/identity/v3/implied_role.py +1 -1
- openstackclient/identity/v3/limit.py +1 -1
- openstackclient/identity/v3/mapping.py +1 -1
- openstackclient/identity/v3/policy.py +1 -1
- openstackclient/identity/v3/project.py +34 -22
- openstackclient/identity/v3/region.py +1 -1
- openstackclient/identity/v3/registered_limit.py +16 -11
- openstackclient/identity/v3/role.py +27 -41
- openstackclient/identity/v3/role_assignment.py +12 -23
- openstackclient/identity/v3/service.py +1 -1
- openstackclient/identity/v3/service_provider.py +1 -1
- openstackclient/identity/v3/tag.py +3 -2
- openstackclient/identity/v3/token.py +3 -2
- openstackclient/identity/v3/trust.py +4 -2
- openstackclient/identity/v3/unscoped_saml.py +1 -1
- openstackclient/identity/v3/user.py +22 -13
- openstackclient/image/v1/image.py +35 -17
- openstackclient/image/v2/cache.py +11 -7
- openstackclient/image/v2/image.py +62 -12
- openstackclient/image/v2/info.py +1 -1
- openstackclient/image/v2/metadef_namespaces.py +1 -1
- openstackclient/image/v2/metadef_objects.py +9 -3
- openstackclient/image/v2/metadef_properties.py +11 -3
- openstackclient/image/v2/metadef_resource_type_association.py +1 -1
- openstackclient/image/v2/metadef_resource_types.py +1 -1
- openstackclient/image/v2/task.py +1 -1
- openstackclient/network/common.py +10 -9
- openstackclient/network/v2/address_group.py +4 -3
- openstackclient/network/v2/address_scope.py +8 -6
- openstackclient/network/v2/default_security_group_rule.py +9 -8
- openstackclient/network/v2/floating_ip.py +16 -9
- openstackclient/network/v2/floating_ip_port_forwarding.py +9 -6
- openstackclient/network/v2/ip_availability.py +7 -4
- openstackclient/network/v2/l3_conntrack_helper.py +11 -4
- openstackclient/network/v2/local_ip.py +13 -7
- openstackclient/network/v2/local_ip_association.py +7 -4
- openstackclient/network/v2/ndp_proxy.py +13 -6
- openstackclient/network/v2/network.py +33 -16
- openstackclient/network/v2/network_agent.py +5 -5
- openstackclient/network/v2/network_auto_allocated_topology.py +1 -1
- openstackclient/network/v2/network_flavor.py +1 -1
- openstackclient/network/v2/network_flavor_profile.py +1 -1
- openstackclient/network/v2/network_meter.py +1 -1
- openstackclient/network/v2/network_meter_rule.py +1 -1
- openstackclient/network/v2/network_qos_policy.py +7 -5
- openstackclient/network/v2/network_qos_rule.py +1 -1
- openstackclient/network/v2/network_qos_rule_type.py +1 -1
- openstackclient/network/v2/network_rbac.py +8 -5
- openstackclient/network/v2/network_segment.py +2 -2
- openstackclient/network/v2/network_segment_range.py +13 -6
- openstackclient/network/v2/network_service_provider.py +1 -1
- openstackclient/network/v2/network_trunk.py +65 -42
- openstackclient/network/v2/port.py +38 -20
- openstackclient/network/v2/router.py +19 -8
- openstackclient/network/v2/security_group.py +52 -7
- openstackclient/network/v2/security_group_rule.py +27 -4
- openstackclient/network/v2/subnet.py +17 -18
- openstackclient/network/v2/subnet_pool.py +11 -9
- openstackclient/network/v2/taas/__init__.py +0 -0
- openstackclient/network/v2/taas/tap_flow.py +245 -0
- openstackclient/network/v2/taas/tap_mirror.py +237 -0
- openstackclient/network/v2/taas/tap_service.py +211 -0
- openstackclient/object/v1/account.py +1 -1
- openstackclient/object/v1/container.py +1 -1
- openstackclient/object/v1/object.py +1 -1
- openstackclient/shell.py +18 -8
- openstackclient/tests/functional/identity/v3/test_access_rule.py +1 -1
- openstackclient/tests/functional/identity/v3/test_application_credential.py +7 -7
- openstackclient/tests/functional/identity/v3/test_catalog.py +42 -23
- openstackclient/tests/functional/identity/v3/test_role_assignment.py +174 -0
- openstackclient/tests/functional/image/v2/test_cache.py +54 -0
- openstackclient/tests/functional/image/v2/test_image.py +36 -14
- openstackclient/tests/functional/image/v2/test_metadef_resource_type.py +55 -0
- openstackclient/tests/functional/volume/v2/test_volume.py +1 -1
- openstackclient/tests/functional/volume/v3/test_volume.py +2 -2
- openstackclient/tests/unit/api/test_volume_v2.py +124 -0
- openstackclient/tests/unit/api/test_volume_v3.py +124 -0
- openstackclient/tests/unit/common/test_command.py +1 -1
- openstackclient/tests/unit/common/test_extension.py +2 -3
- openstackclient/tests/unit/common/test_module.py +14 -7
- openstackclient/tests/unit/common/test_quota.py +20 -0
- openstackclient/tests/unit/compute/v2/test_aggregate.py +5 -3
- openstackclient/tests/unit/compute/v2/test_console.py +1 -4
- openstackclient/tests/unit/compute/v2/test_flavor.py +160 -177
- openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +1 -9
- openstackclient/tests/unit/compute/v2/test_server.py +406 -81
- openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -3
- openstackclient/tests/unit/compute/v2/test_service.py +1 -3
- openstackclient/tests/unit/fakes.py +35 -134
- openstackclient/tests/unit/identity/test_common.py +100 -0
- openstackclient/tests/unit/identity/v2_0/test_project.py +4 -4
- openstackclient/tests/unit/identity/v3/fakes.py +10 -2
- openstackclient/tests/unit/identity/v3/test_application_credential.py +50 -44
- openstackclient/tests/unit/identity/v3/test_domain.py +3 -3
- openstackclient/tests/unit/identity/v3/test_endpoint.py +1 -1
- openstackclient/tests/unit/identity/v3/test_group.py +4 -2
- openstackclient/tests/unit/identity/v3/test_identity_provider.py +10 -10
- openstackclient/tests/unit/identity/v3/test_oauth.py +1 -1
- openstackclient/tests/unit/identity/v3/test_project.py +31 -54
- openstackclient/tests/unit/identity/v3/test_registered_limit.py +2 -2
- openstackclient/tests/unit/identity/v3/test_role.py +3 -90
- openstackclient/tests/unit/identity/v3/test_user.py +7 -51
- openstackclient/tests/unit/image/v1/test_image.py +47 -0
- openstackclient/tests/unit/image/v2/test_image.py +190 -9
- openstackclient/tests/unit/image/v2/test_metadef_objects.py +22 -0
- openstackclient/tests/unit/image/v2/test_metadef_properties.py +24 -10
- openstackclient/tests/unit/network/test_common.py +9 -13
- openstackclient/tests/unit/network/v2/fakes.py +1 -0
- openstackclient/tests/unit/network/v2/taas/__init__.py +0 -0
- openstackclient/tests/unit/network/v2/taas/test_osc_tap_flow.py +276 -0
- openstackclient/tests/unit/network/v2/taas/test_osc_tap_mirror.py +288 -0
- openstackclient/tests/unit/network/v2/taas/test_osc_tap_service.py +271 -0
- openstackclient/tests/unit/network/v2/test_address_group.py +19 -22
- openstackclient/tests/unit/network/v2/test_address_scope.py +10 -15
- openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +38 -49
- openstackclient/tests/unit/network/v2/test_floating_ip_network.py +21 -27
- openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +21 -18
- openstackclient/tests/unit/network/v2/test_ip_availability.py +6 -8
- openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +6 -15
- openstackclient/tests/unit/network/v2/test_local_ip.py +12 -23
- openstackclient/tests/unit/network/v2/test_local_ip_association.py +13 -18
- openstackclient/tests/unit/network/v2/test_ndp_proxy.py +13 -23
- openstackclient/tests/unit/network/v2/test_network.py +41 -37
- openstackclient/tests/unit/network/v2/test_network_agent.py +13 -20
- openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +5 -8
- openstackclient/tests/unit/network/v2/test_network_flavor.py +14 -26
- openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +14 -17
- openstackclient/tests/unit/network/v2/test_network_meter.py +7 -17
- openstackclient/tests/unit/network/v2/test_network_meter_rule.py +10 -20
- openstackclient/tests/unit/network/v2/test_network_qos_policy.py +7 -13
- openstackclient/tests/unit/network/v2/test_network_qos_rule.py +44 -54
- openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +2 -7
- openstackclient/tests/unit/network/v2/test_network_rbac.py +21 -36
- openstackclient/tests/unit/network/v2/test_network_segment.py +13 -29
- openstackclient/tests/unit/network/v2/test_network_segment_range.py +20 -19
- openstackclient/tests/unit/network/v2/test_network_service_provider.py +1 -4
- openstackclient/tests/unit/network/v2/test_network_trunk.py +52 -47
- openstackclient/tests/unit/network/v2/test_port.py +113 -84
- openstackclient/tests/unit/network/v2/test_router.py +104 -126
- openstackclient/tests/unit/network/v2/test_security_group_network.py +25 -26
- openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +66 -18
- openstackclient/tests/unit/network/v2/test_subnet.py +35 -46
- openstackclient/tests/unit/network/v2/test_subnet_pool.py +21 -33
- openstackclient/tests/unit/volume/test_find_resource.py +4 -13
- openstackclient/tests/unit/volume/v2/test_volume.py +358 -305
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +3 -1
- openstackclient/tests/unit/volume/v3/test_volume.py +443 -415
- openstackclient/tests/unit/volume/v3/test_volume_backup.py +9 -0
- openstackclient/volume/client.py +7 -17
- openstackclient/volume/v2/backup_record.py +1 -1
- openstackclient/volume/v2/consistency_group.py +1 -1
- openstackclient/volume/v2/consistency_group_snapshot.py +1 -1
- openstackclient/volume/v2/qos_specs.py +1 -1
- openstackclient/volume/v2/service.py +2 -2
- openstackclient/volume/v2/volume.py +80 -54
- openstackclient/volume/v2/volume_backend.py +1 -1
- openstackclient/volume/v2/volume_backup.py +5 -3
- openstackclient/volume/v2/volume_host.py +1 -2
- openstackclient/volume/v2/volume_snapshot.py +2 -2
- openstackclient/volume/v2/volume_transfer_request.py +1 -1
- openstackclient/volume/v2/volume_type.py +11 -6
- openstackclient/volume/v3/block_storage_cleanup.py +1 -1
- openstackclient/volume/v3/block_storage_cluster.py +1 -1
- openstackclient/volume/v3/block_storage_log_level.py +1 -1
- openstackclient/volume/v3/block_storage_manage.py +1 -1
- openstackclient/volume/v3/block_storage_resource_filter.py +1 -1
- openstackclient/volume/v3/service.py +2 -2
- openstackclient/volume/v3/volume.py +104 -77
- openstackclient/volume/v3/volume_attachment.py +6 -5
- openstackclient/volume/v3/volume_backup.py +18 -3
- openstackclient/volume/v3/volume_group.py +2 -2
- openstackclient/volume/v3/volume_group_snapshot.py +1 -1
- openstackclient/volume/v3/volume_group_type.py +1 -1
- openstackclient/volume/v3/volume_message.py +1 -1
- openstackclient/volume/v3/volume_snapshot.py +2 -2
- openstackclient/volume/v3/volume_transfer_request.py +1 -1
- openstackclient/volume/v3/volume_type.py +15 -9
- {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.3.0.dist-info}/METADATA +19 -17
- {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.3.0.dist-info}/RECORD +239 -224
- {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.3.0.dist-info}/WHEEL +1 -1
- {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.3.0.dist-info}/entry_points.txt +15 -0
- {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.3.0.dist-info/licenses}/AUTHORS +15 -0
- python_openstackclient-8.3.0.dist-info/pbr.json +1 -0
- openstackclient/tests/unit/common/test_logs.py +0 -221
- python_openstackclient-8.1.0.dist-info/pbr.json +0 -1
- {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.3.0.dist-info/licenses}/LICENSE +0 -0
- {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.3.0.dist-info}/top_level.txt +0 -0
|
@@ -64,7 +64,7 @@ def list_security_groups(compute_client, all_projects=None):
|
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
def find_security_group(compute_client, name_or_id):
|
|
67
|
-
"""Find the
|
|
67
|
+
"""Find the security group for a given name or ID
|
|
68
68
|
|
|
69
69
|
https://docs.openstack.org/api-ref/compute/#show-security-group-details
|
|
70
70
|
|
|
@@ -240,7 +240,7 @@ def list_networks(compute_client):
|
|
|
240
240
|
|
|
241
241
|
|
|
242
242
|
def find_network(compute_client, name_or_id):
|
|
243
|
-
"""Find the
|
|
243
|
+
"""Find the network for a given name or ID
|
|
244
244
|
|
|
245
245
|
https://docs.openstack.org/api-ref/compute/#show-network-details
|
|
246
246
|
|
|
@@ -256,7 +256,10 @@ class APIv1(api.BaseAPI):
|
|
|
256
256
|
# object's name in the container.
|
|
257
257
|
object_name_str = name if name else object
|
|
258
258
|
|
|
259
|
-
full_url =
|
|
259
|
+
full_url = (
|
|
260
|
+
f"{urllib.parse.quote(container)}/"
|
|
261
|
+
f"{urllib.parse.quote(object_name_str)}"
|
|
262
|
+
)
|
|
260
263
|
with open(object, 'rb') as f:
|
|
261
264
|
response = self.create(
|
|
262
265
|
full_url,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
2
|
+
# not use this file except in compliance with the License. You may obtain
|
|
3
|
+
# a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
9
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
10
|
+
# License for the specific language governing permissions and limitations
|
|
11
|
+
# under the License.
|
|
12
|
+
|
|
13
|
+
"""Volume v2 API Library
|
|
14
|
+
|
|
15
|
+
A collection of wrappers for deprecated Block Storage v2 APIs that are not
|
|
16
|
+
intentionally supported by SDK.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import http
|
|
20
|
+
|
|
21
|
+
from openstack import exceptions as sdk_exceptions
|
|
22
|
+
from osc_lib import exceptions
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# consistency groups
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def find_consistency_group(compute_client, name_or_id):
|
|
29
|
+
"""Find the consistency group for a given name or ID
|
|
30
|
+
|
|
31
|
+
https://docs.openstack.org/api-ref/block-storage/v3/#show-a-consistency-group-s-details
|
|
32
|
+
|
|
33
|
+
:param volume_client: A volume client
|
|
34
|
+
:param name_or_id: The name or ID of the consistency group to look up
|
|
35
|
+
:returns: A consistency group object
|
|
36
|
+
:raises exception.NotFound: If a matching consistency group could not be
|
|
37
|
+
found or more than one match was found
|
|
38
|
+
"""
|
|
39
|
+
response = compute_client.get(f'/consistencygroups/{name_or_id}')
|
|
40
|
+
if response.status_code != http.HTTPStatus.NOT_FOUND:
|
|
41
|
+
# there might be other, non-404 errors
|
|
42
|
+
sdk_exceptions.raise_from_response(response)
|
|
43
|
+
return response.json()['consistencygroup']
|
|
44
|
+
|
|
45
|
+
response = compute_client.get('/consistencygroups')
|
|
46
|
+
sdk_exceptions.raise_from_response(response)
|
|
47
|
+
found = None
|
|
48
|
+
consistency_groups = response.json()['consistencygroups']
|
|
49
|
+
for consistency_group in consistency_groups:
|
|
50
|
+
if consistency_group['name'] == name_or_id:
|
|
51
|
+
if found:
|
|
52
|
+
raise exceptions.NotFound(
|
|
53
|
+
f'multiple matches found for {name_or_id}'
|
|
54
|
+
)
|
|
55
|
+
found = consistency_group
|
|
56
|
+
|
|
57
|
+
if not found:
|
|
58
|
+
raise exceptions.NotFound(f'{name_or_id} not found')
|
|
59
|
+
|
|
60
|
+
return found
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
2
|
+
# not use this file except in compliance with the License. You may obtain
|
|
3
|
+
# a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
9
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
10
|
+
# License for the specific language governing permissions and limitations
|
|
11
|
+
# under the License.
|
|
12
|
+
|
|
13
|
+
"""Volume v3 API Library
|
|
14
|
+
|
|
15
|
+
A collection of wrappers for deprecated Block Storage v3 APIs that are not
|
|
16
|
+
intentionally supported by SDK.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import http
|
|
20
|
+
|
|
21
|
+
from openstack import exceptions as sdk_exceptions
|
|
22
|
+
from osc_lib import exceptions
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# consistency groups
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def find_consistency_group(compute_client, name_or_id):
|
|
29
|
+
"""Find the consistency group for a given name or ID
|
|
30
|
+
|
|
31
|
+
https://docs.openstack.org/api-ref/block-storage/v3/#show-a-consistency-group-s-details
|
|
32
|
+
|
|
33
|
+
:param volume_client: A volume client
|
|
34
|
+
:param name_or_id: The name or ID of the consistency group to look up
|
|
35
|
+
:returns: A consistency group object
|
|
36
|
+
:raises exception.NotFound: If a matching consistency group could not be
|
|
37
|
+
found or more than one match was found
|
|
38
|
+
"""
|
|
39
|
+
response = compute_client.get(f'/consistencygroups/{name_or_id}')
|
|
40
|
+
if response.status_code != http.HTTPStatus.NOT_FOUND:
|
|
41
|
+
# there might be other, non-404 errors
|
|
42
|
+
sdk_exceptions.raise_from_response(response)
|
|
43
|
+
return response.json()['consistencygroup']
|
|
44
|
+
|
|
45
|
+
response = compute_client.get('/consistencygroups')
|
|
46
|
+
sdk_exceptions.raise_from_response(response)
|
|
47
|
+
found = None
|
|
48
|
+
consistency_groups = response.json()['consistencygroups']
|
|
49
|
+
for consistency_group in consistency_groups:
|
|
50
|
+
if consistency_group['name'] == name_or_id:
|
|
51
|
+
if found:
|
|
52
|
+
raise exceptions.NotFound(
|
|
53
|
+
f'multiple matches found for {name_or_id}'
|
|
54
|
+
)
|
|
55
|
+
found = consistency_group
|
|
56
|
+
|
|
57
|
+
if not found:
|
|
58
|
+
raise exceptions.NotFound(f'{name_or_id} not found')
|
|
59
|
+
|
|
60
|
+
return found
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
2
|
+
# not use this file except in compliance with the License. You may obtain
|
|
3
|
+
# a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
9
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
10
|
+
# License for the specific language governing permissions and limitations
|
|
11
|
+
# under the License.
|
|
12
|
+
|
|
13
|
+
from cliff import lister
|
|
14
|
+
from cliff import show
|
|
15
|
+
from osc_lib.command import command
|
|
16
|
+
|
|
17
|
+
from openstackclient import shell
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Command(command.Command):
|
|
21
|
+
app: shell.OpenStackShell
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Lister(Command, lister.Lister): ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ShowOne(Command, show.ShowOne): ...
|
|
@@ -15,15 +15,25 @@
|
|
|
15
15
|
|
|
16
16
|
"""Manage access to the clients, including authenticating when needed."""
|
|
17
17
|
|
|
18
|
+
import argparse
|
|
19
|
+
from collections.abc import Callable
|
|
18
20
|
import importlib
|
|
19
21
|
import logging
|
|
20
22
|
import sys
|
|
21
23
|
import typing as ty
|
|
22
24
|
|
|
25
|
+
from osc_lib.cli import client_config
|
|
23
26
|
from osc_lib import clientmanager
|
|
24
27
|
from osc_lib import shell
|
|
25
28
|
import stevedore
|
|
26
29
|
|
|
30
|
+
if ty.TYPE_CHECKING:
|
|
31
|
+
from keystoneauth1 import access as ksa_access
|
|
32
|
+
from openstack.compute.v2 import _proxy as compute_proxy
|
|
33
|
+
from openstack.image.v2 import _proxy as image_proxy
|
|
34
|
+
from openstack.network.v2 import _proxy as network_proxy
|
|
35
|
+
|
|
36
|
+
from openstackclient.api import object_store_v1
|
|
27
37
|
|
|
28
38
|
LOG = logging.getLogger(__name__)
|
|
29
39
|
|
|
@@ -40,11 +50,23 @@ class ClientManager(clientmanager.ClientManager):
|
|
|
40
50
|
in osc-lib so we need to maintain a transition period.
|
|
41
51
|
"""
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
if ty.TYPE_CHECKING:
|
|
54
|
+
# we know this will be set by us and will not be nullable
|
|
55
|
+
auth_ref: ksa_access.AccessInfo
|
|
56
|
+
|
|
57
|
+
# this is a hack to keep mypy happy: the actual attributes are set in
|
|
58
|
+
# get_plugin_modules below
|
|
59
|
+
# TODO(stephenfin): Change the types of identity and volume once we've
|
|
60
|
+
# migrated everything to SDK. Hopefully by then we'll have figured out
|
|
61
|
+
# how to statically distinguish between the v2 and v3 versions of both
|
|
62
|
+
# services...
|
|
63
|
+
# TODO(stephenfin): We also need to migrate object storage...
|
|
64
|
+
compute: compute_proxy.Proxy
|
|
65
|
+
identity: ty.Any
|
|
66
|
+
image: image_proxy.Proxy
|
|
67
|
+
network: network_proxy.Proxy
|
|
68
|
+
object_store: object_store_v1.APIv1
|
|
69
|
+
volume: ty.Any
|
|
48
70
|
|
|
49
71
|
def __init__(
|
|
50
72
|
self,
|
|
@@ -81,6 +103,12 @@ class ClientManager(clientmanager.ClientManager):
|
|
|
81
103
|
self._auth_required
|
|
82
104
|
and self._cli_options._openstack_config is not None
|
|
83
105
|
):
|
|
106
|
+
if not isinstance(
|
|
107
|
+
self._cli_options._openstack_config, client_config.OSC_Config
|
|
108
|
+
):
|
|
109
|
+
# programmer error
|
|
110
|
+
raise TypeError('unexpected type for _openstack_config')
|
|
111
|
+
|
|
84
112
|
self._cli_options._openstack_config._pw_callback = (
|
|
85
113
|
shell.prompt_for_password
|
|
86
114
|
)
|
|
@@ -107,6 +135,13 @@ class ClientManager(clientmanager.ClientManager):
|
|
|
107
135
|
self._cli_options.config['auth_type'] = self._original_auth_type
|
|
108
136
|
del self._cli_options.config['auth']['token']
|
|
109
137
|
del self._cli_options.config['auth']['endpoint']
|
|
138
|
+
|
|
139
|
+
if not isinstance(
|
|
140
|
+
self._cli_options._openstack_config, client_config.OSC_Config
|
|
141
|
+
):
|
|
142
|
+
# programmer error
|
|
143
|
+
raise TypeError('unexpected type for _openstack_config')
|
|
144
|
+
|
|
110
145
|
self._cli_options._auth = (
|
|
111
146
|
self._cli_options._openstack_config.load_auth_plugin(
|
|
112
147
|
self._cli_options.config,
|
|
@@ -144,11 +179,25 @@ class ClientManager(clientmanager.ClientManager):
|
|
|
144
179
|
|
|
145
180
|
# Plugin Support
|
|
146
181
|
|
|
182
|
+
ArgumentParserT = ty.TypeVar('ArgumentParserT', bound=argparse.ArgumentParser)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@ty.runtime_checkable # Optional: allows usage with isinstance()
|
|
186
|
+
class PluginModule(ty.Protocol):
|
|
187
|
+
DEFAULT_API_VERSION: str
|
|
188
|
+
API_VERSION_OPTION: str
|
|
189
|
+
API_NAME: str
|
|
190
|
+
API_VERSIONS: tuple[str]
|
|
191
|
+
|
|
192
|
+
make_client: Callable[..., ty.Any]
|
|
193
|
+
build_option_parser: Callable[[ArgumentParserT], ArgumentParserT]
|
|
194
|
+
check_api_version: Callable[[str], bool]
|
|
195
|
+
|
|
147
196
|
|
|
148
197
|
def _on_load_failure_callback(
|
|
149
198
|
manager: stevedore.ExtensionManager,
|
|
150
199
|
ep: importlib.metadata.EntryPoint,
|
|
151
|
-
err:
|
|
200
|
+
err: BaseException,
|
|
152
201
|
) -> None:
|
|
153
202
|
sys.stderr.write(
|
|
154
203
|
f"WARNING: Failed to import plugin {ep.group}:{ep.name}: {err}.\n"
|
|
@@ -158,36 +207,25 @@ def _on_load_failure_callback(
|
|
|
158
207
|
def get_plugin_modules(group):
|
|
159
208
|
"""Find plugin entry points"""
|
|
160
209
|
mod_list = []
|
|
210
|
+
mgr: stevedore.ExtensionManager[PluginModule]
|
|
161
211
|
mgr = stevedore.ExtensionManager(
|
|
162
212
|
group, on_load_failure_callback=_on_load_failure_callback
|
|
163
213
|
)
|
|
164
214
|
for ep in mgr:
|
|
165
215
|
LOG.debug('Found plugin %s', ep.name)
|
|
166
216
|
|
|
167
|
-
|
|
168
|
-
# implementations of EntryPoint from other libraries, which
|
|
169
|
-
# are not API-compatible.
|
|
170
|
-
try:
|
|
171
|
-
module_name = ep.entry_point.module_name
|
|
172
|
-
except AttributeError:
|
|
173
|
-
try:
|
|
174
|
-
module_name = ep.entry_point.module
|
|
175
|
-
except AttributeError:
|
|
176
|
-
module_name = ep.entry_point.value
|
|
217
|
+
module_name = ep.entry_point.module
|
|
177
218
|
|
|
178
219
|
try:
|
|
179
220
|
module = importlib.import_module(module_name)
|
|
180
221
|
except Exception as err:
|
|
181
222
|
sys.stderr.write(
|
|
182
|
-
f"WARNING: Failed to import plugin
|
|
183
|
-
f"{err}.\n"
|
|
223
|
+
f"WARNING: Failed to import plugin "
|
|
224
|
+
f"{ep.module_name}:{ep.name}: {err}.\n"
|
|
184
225
|
)
|
|
185
226
|
continue
|
|
186
227
|
|
|
187
228
|
mod_list.append(module)
|
|
188
|
-
init_func = getattr(module, 'Initialize', None)
|
|
189
|
-
if init_func:
|
|
190
|
-
init_func('x')
|
|
191
229
|
|
|
192
230
|
# Add the plugin to the ClientManager
|
|
193
231
|
setattr(
|
openstackclient/common/limits.py
CHANGED
openstackclient/common/module.py
CHANGED
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
import sys
|
|
19
19
|
|
|
20
|
-
from osc_lib.command import command
|
|
21
20
|
from osc_lib import utils
|
|
22
21
|
|
|
22
|
+
from openstackclient import command
|
|
23
23
|
from openstackclient.i18n import _
|
|
24
24
|
|
|
25
25
|
|
|
@@ -48,7 +48,9 @@ class ListCommand(command.Lister):
|
|
|
48
48
|
columns = ('Command Group', 'Commands')
|
|
49
49
|
|
|
50
50
|
if parsed_args.group:
|
|
51
|
-
groups = (
|
|
51
|
+
groups = sorted(
|
|
52
|
+
group for group in groups if parsed_args.group in group
|
|
53
|
+
)
|
|
52
54
|
|
|
53
55
|
commands = []
|
|
54
56
|
for group in groups:
|
|
@@ -20,8 +20,8 @@ import queue
|
|
|
20
20
|
import typing as ty
|
|
21
21
|
|
|
22
22
|
from cliff.formatters import table
|
|
23
|
-
from osc_lib.command import command
|
|
24
23
|
|
|
24
|
+
from openstackclient import command
|
|
25
25
|
from openstackclient.i18n import _
|
|
26
26
|
from openstackclient.identity import common as identity_common
|
|
27
27
|
|
|
@@ -90,17 +90,19 @@ class ProjectCleanup(command.Command):
|
|
|
90
90
|
return parser
|
|
91
91
|
|
|
92
92
|
def take_action(self, parsed_args):
|
|
93
|
-
|
|
93
|
+
connection = self.app.client_manager.sdk_connection
|
|
94
94
|
|
|
95
95
|
if parsed_args.auth_project:
|
|
96
|
-
|
|
96
|
+
# is we've got a project already configured, use the connection
|
|
97
|
+
# as-is
|
|
98
|
+
pass
|
|
97
99
|
elif parsed_args.project:
|
|
98
|
-
project =
|
|
100
|
+
project = connection.identity.find_project(
|
|
99
101
|
name_or_id=parsed_args.project, ignore_missing=False
|
|
100
102
|
)
|
|
101
|
-
|
|
103
|
+
connection = connection.connect_as_project(project)
|
|
102
104
|
|
|
103
|
-
if
|
|
105
|
+
if connection:
|
|
104
106
|
status_queue: queue.Queue[ty.Any] = queue.Queue()
|
|
105
107
|
parsed_args.max_width = int(
|
|
106
108
|
os.environ.get('CLIFF_MAX_TERM_WIDTH', 0)
|
|
@@ -120,7 +122,7 @@ class ProjectCleanup(command.Command):
|
|
|
120
122
|
if parsed_args.updated_before:
|
|
121
123
|
filters['updated_at'] = parsed_args.updated_before
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
connection.project_cleanup(
|
|
124
126
|
dry_run=True,
|
|
125
127
|
status_queue=status_queue,
|
|
126
128
|
filters=filters,
|
|
@@ -150,7 +152,7 @@ class ProjectCleanup(command.Command):
|
|
|
150
152
|
|
|
151
153
|
self.log.warning(_('Deleting resources'))
|
|
152
154
|
|
|
153
|
-
|
|
155
|
+
connection.project_cleanup(
|
|
154
156
|
dry_run=False,
|
|
155
157
|
status_queue=status_queue,
|
|
156
158
|
filters=filters,
|
openstackclient/common/quota.py
CHANGED
|
@@ -21,10 +21,10 @@ import sys
|
|
|
21
21
|
import typing as ty
|
|
22
22
|
|
|
23
23
|
from openstack import exceptions as sdk_exceptions
|
|
24
|
-
from osc_lib.command import command
|
|
25
24
|
from osc_lib import exceptions
|
|
26
25
|
from osc_lib import utils
|
|
27
26
|
|
|
27
|
+
from openstackclient import command
|
|
28
28
|
from openstackclient.i18n import _
|
|
29
29
|
from openstackclient.network import common
|
|
30
30
|
|
|
@@ -746,21 +746,32 @@ and ``server-group-members`` output for a given quota class."""
|
|
|
746
746
|
# values if the project or class does not exist. This is expected
|
|
747
747
|
# behavior. However, we have already checked for the presence of the
|
|
748
748
|
# project above so it shouldn't be an issue.
|
|
749
|
-
if parsed_args.service
|
|
749
|
+
if parsed_args.service == 'compute' or (
|
|
750
|
+
parsed_args.service == 'all'
|
|
751
|
+
and self.app.client_manager.is_compute_endpoint_enabled()
|
|
752
|
+
):
|
|
750
753
|
compute_quota_info = get_compute_quotas(
|
|
751
754
|
self.app,
|
|
752
755
|
project,
|
|
753
756
|
detail=parsed_args.usage,
|
|
754
757
|
default=parsed_args.default,
|
|
755
758
|
)
|
|
756
|
-
|
|
759
|
+
|
|
760
|
+
if parsed_args.service == 'volume' or (
|
|
761
|
+
parsed_args.service == 'all'
|
|
762
|
+
and self.app.client_manager.is_volume_endpoint_enabled()
|
|
763
|
+
):
|
|
757
764
|
volume_quota_info = get_volume_quotas(
|
|
758
765
|
self.app,
|
|
759
766
|
project,
|
|
760
767
|
detail=parsed_args.usage,
|
|
761
768
|
default=parsed_args.default,
|
|
762
769
|
)
|
|
763
|
-
|
|
770
|
+
|
|
771
|
+
if parsed_args.service == 'network' or (
|
|
772
|
+
parsed_args.service == 'all'
|
|
773
|
+
and self.app.client_manager.is_network_endpoint_enabled()
|
|
774
|
+
):
|
|
764
775
|
network_quota_info = get_network_quotas(
|
|
765
776
|
self.app,
|
|
766
777
|
project,
|
|
@@ -906,12 +917,18 @@ class DeleteQuota(command.Command):
|
|
|
906
917
|
)
|
|
907
918
|
|
|
908
919
|
# compute quotas
|
|
909
|
-
if parsed_args.service
|
|
920
|
+
if parsed_args.service == 'compute' or (
|
|
921
|
+
parsed_args.service == 'all'
|
|
922
|
+
and self.app.client_manager.is_compute_endpoint_enabled()
|
|
923
|
+
):
|
|
910
924
|
compute_client = self.app.client_manager.compute
|
|
911
925
|
compute_client.revert_quota_set(project.id)
|
|
912
926
|
|
|
913
927
|
# volume quotas
|
|
914
|
-
if parsed_args.service
|
|
928
|
+
if parsed_args.service == 'volume' or (
|
|
929
|
+
parsed_args.service == 'all'
|
|
930
|
+
and self.app.client_manager.is_volume_endpoint_enabled()
|
|
931
|
+
):
|
|
915
932
|
volume_client = self.app.client_manager.sdk_connection.volume
|
|
916
933
|
volume_client.revert_quota_set(project.id)
|
|
917
934
|
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
import logging
|
|
19
19
|
|
|
20
20
|
from openstack import exceptions as sdk_exceptions
|
|
21
|
-
from osc_lib.command import command
|
|
22
21
|
from osc_lib import exceptions
|
|
23
22
|
from osc_lib import utils
|
|
24
23
|
|
|
24
|
+
from openstackclient import command
|
|
25
25
|
from openstackclient.i18n import _
|
|
26
26
|
|
|
27
27
|
|
|
@@ -19,20 +19,21 @@
|
|
|
19
19
|
import logging
|
|
20
20
|
import typing as ty
|
|
21
21
|
|
|
22
|
+
from cliff import columns
|
|
22
23
|
from openstack import utils as sdk_utils
|
|
23
24
|
from osc_lib.cli import format_columns
|
|
24
25
|
from osc_lib.cli import parseractions
|
|
25
|
-
from osc_lib.command import command
|
|
26
26
|
from osc_lib import exceptions
|
|
27
27
|
from osc_lib import utils
|
|
28
28
|
|
|
29
|
+
from openstackclient import command
|
|
29
30
|
from openstackclient.i18n import _
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
LOG = logging.getLogger(__name__)
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
_aggregate_formatters = {
|
|
36
|
+
_aggregate_formatters: dict[str, type[columns.FormattableColumn[ty.Any]]] = {
|
|
36
37
|
'Hosts': format_columns.ListColumn,
|
|
37
38
|
'Metadata': format_columns.DictColumn,
|
|
38
39
|
'hosts': format_columns.ListColumn,
|
|
@@ -438,15 +439,15 @@ class CacheImageForAggregate(command.Command):
|
|
|
438
439
|
)
|
|
439
440
|
raise exceptions.CommandError(msg)
|
|
440
441
|
|
|
442
|
+
image_client = self.app.client_manager.sdk_connection.image
|
|
443
|
+
|
|
441
444
|
aggregate = compute_client.find_aggregate(
|
|
442
445
|
parsed_args.aggregate, ignore_missing=False
|
|
443
446
|
)
|
|
444
447
|
|
|
445
448
|
images = []
|
|
446
449
|
for img in parsed_args.image:
|
|
447
|
-
image =
|
|
448
|
-
img, ignore_missing=False
|
|
449
|
-
)
|
|
450
|
+
image = image_client.find_image(img, ignore_missing=False)
|
|
450
451
|
images.append(image.id)
|
|
451
452
|
|
|
452
453
|
compute_client.aggregate_precache_images(aggregate.id, images)
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"""Compute v2 Console action implementations"""
|
|
17
17
|
|
|
18
18
|
from osc_lib.cli import parseractions
|
|
19
|
-
from osc_lib.command import command
|
|
20
19
|
from osc_lib import utils
|
|
21
20
|
|
|
21
|
+
from openstackclient import command
|
|
22
22
|
from openstackclient.i18n import _
|
|
23
23
|
|
|
24
24
|
|
|
@@ -64,13 +64,15 @@ class ShowConsoleLog(command.Command):
|
|
|
64
64
|
output = compute_client.get_server_console_output(
|
|
65
65
|
server.id, length=parsed_args.lines
|
|
66
66
|
)
|
|
67
|
-
data = None
|
|
67
|
+
data: str | None = None
|
|
68
68
|
if output:
|
|
69
69
|
data = output.get('output', None)
|
|
70
70
|
|
|
71
71
|
if data and data[-1] != '\n':
|
|
72
72
|
data += '\n'
|
|
73
|
-
|
|
73
|
+
|
|
74
|
+
if data:
|
|
75
|
+
self.app.stdout.write(data)
|
|
74
76
|
|
|
75
77
|
|
|
76
78
|
class ShowConsoleURL(command.ShowOne):
|
|
@@ -21,10 +21,10 @@ from openstack import exceptions as sdk_exceptions
|
|
|
21
21
|
from openstack import utils as sdk_utils
|
|
22
22
|
from osc_lib.cli import format_columns
|
|
23
23
|
from osc_lib.cli import parseractions
|
|
24
|
-
from osc_lib.command import command
|
|
25
24
|
from osc_lib import exceptions
|
|
26
25
|
from osc_lib import utils
|
|
27
26
|
|
|
27
|
+
from openstackclient import command
|
|
28
28
|
from openstackclient.common import pagination
|
|
29
29
|
from openstackclient.i18n import _
|
|
30
30
|
from openstackclient.identity import common as identity_common
|
|
@@ -156,12 +156,25 @@ class CreateFlavor(command.ShowOne):
|
|
|
156
156
|
msg = _("--project is only allowed with --private")
|
|
157
157
|
raise exceptions.CommandError(msg)
|
|
158
158
|
|
|
159
|
+
flavor_id = parsed_args.id
|
|
160
|
+
if parsed_args.id == 'auto':
|
|
161
|
+
# novaclient aliased 'auto' to mean "generate a UUID for me": we
|
|
162
|
+
# do the same to avoid breaking existing users
|
|
163
|
+
flavor_id = None
|
|
164
|
+
|
|
165
|
+
msg = _(
|
|
166
|
+
"Passing '--id auto' is deprecated. Nova will automatically "
|
|
167
|
+
"assign a UUID-like ID if no ID is provided. Omit the '--id' "
|
|
168
|
+
"parameter instead."
|
|
169
|
+
)
|
|
170
|
+
self.log.warning(msg)
|
|
171
|
+
|
|
159
172
|
args = {
|
|
160
173
|
'name': parsed_args.name,
|
|
161
174
|
'ram': parsed_args.ram,
|
|
162
175
|
'vcpus': parsed_args.vcpus,
|
|
163
176
|
'disk': parsed_args.disk,
|
|
164
|
-
'id':
|
|
177
|
+
'id': flavor_id,
|
|
165
178
|
'ephemeral': parsed_args.ephemeral,
|
|
166
179
|
'swap': parsed_args.swap,
|
|
167
180
|
'rxtx_factor': parsed_args.rxtx_factor,
|