python-openstackclient 6.6.1__py3-none-any.whl → 7.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/api/api.py +4 -4
- openstackclient/api/compute_v2.py +352 -638
- openstackclient/api/image_v1.py +1 -1
- openstackclient/api/object_store_v1.py +3 -4
- openstackclient/common/availability_zone.py +1 -1
- openstackclient/common/clientmanager.py +16 -4
- openstackclient/common/configuration.py +1 -1
- openstackclient/common/extension.py +1 -1
- openstackclient/common/limits.py +66 -32
- openstackclient/common/module.py +3 -3
- openstackclient/common/progressbar.py +2 -2
- openstackclient/common/project_cleanup.py +5 -2
- openstackclient/common/quota.py +281 -410
- openstackclient/common/versions.py +1 -1
- openstackclient/compute/client.py +7 -116
- openstackclient/compute/v2/agent.py +75 -49
- openstackclient/compute/v2/aggregate.py +9 -9
- openstackclient/compute/v2/console.py +2 -2
- openstackclient/compute/v2/flavor.py +6 -6
- openstackclient/compute/v2/host.py +38 -33
- openstackclient/compute/v2/hypervisor.py +4 -3
- openstackclient/compute/v2/keypair.py +7 -8
- openstackclient/compute/v2/server.py +478 -396
- openstackclient/compute/v2/server_backup.py +1 -1
- openstackclient/compute/v2/server_group.py +4 -4
- openstackclient/compute/v2/server_image.py +1 -1
- openstackclient/compute/v2/server_migration.py +3 -4
- openstackclient/compute/v2/service.py +4 -4
- openstackclient/compute/v2/usage.py +3 -3
- openstackclient/identity/common.py +34 -0
- openstackclient/identity/v2_0/catalog.py +2 -2
- openstackclient/identity/v2_0/ec2creds.py +4 -4
- openstackclient/identity/v2_0/endpoint.py +4 -4
- openstackclient/identity/v2_0/project.py +6 -6
- openstackclient/identity/v2_0/role.py +5 -5
- openstackclient/identity/v2_0/role_assignment.py +1 -1
- openstackclient/identity/v2_0/service.py +4 -4
- openstackclient/identity/v2_0/token.py +2 -2
- openstackclient/identity/v2_0/user.py +7 -7
- openstackclient/identity/v3/access_rule.py +3 -3
- openstackclient/identity/v3/application_credential.py +127 -45
- openstackclient/identity/v3/catalog.py +2 -2
- openstackclient/identity/v3/consumer.py +4 -4
- openstackclient/identity/v3/credential.py +5 -5
- openstackclient/identity/v3/domain.py +5 -5
- openstackclient/identity/v3/ec2creds.py +4 -4
- openstackclient/identity/v3/endpoint.py +7 -7
- openstackclient/identity/v3/endpoint_group.py +8 -10
- openstackclient/identity/v3/federation_protocol.py +5 -5
- openstackclient/identity/v3/group.py +8 -8
- openstackclient/identity/v3/identity_provider.py +5 -5
- openstackclient/identity/v3/implied_role.py +3 -3
- openstackclient/identity/v3/limit.py +5 -5
- openstackclient/identity/v3/mapping.py +5 -5
- openstackclient/identity/v3/policy.py +5 -5
- openstackclient/identity/v3/project.py +5 -5
- openstackclient/identity/v3/region.py +5 -5
- openstackclient/identity/v3/registered_limit.py +5 -5
- openstackclient/identity/v3/role.py +7 -7
- openstackclient/identity/v3/role_assignment.py +92 -140
- openstackclient/identity/v3/service.py +64 -34
- openstackclient/identity/v3/service_provider.py +4 -4
- openstackclient/identity/v3/tag.py +2 -2
- openstackclient/identity/v3/token.py +5 -5
- openstackclient/identity/v3/trust.py +3 -3
- openstackclient/identity/v3/user.py +144 -80
- openstackclient/image/client.py +4 -4
- openstackclient/image/v1/image.py +8 -9
- openstackclient/image/v2/cache.py +12 -10
- openstackclient/image/v2/metadef_objects.py +44 -0
- openstackclient/image/v2/metadef_resource_type_association.py +189 -0
- openstackclient/image/v2/task.py +1 -1
- openstackclient/network/common.py +6 -5
- openstackclient/network/utils.py +2 -2
- openstackclient/network/v2/address_group.py +6 -6
- openstackclient/network/v2/address_scope.py +5 -5
- openstackclient/network/v2/default_security_group_rule.py +1 -1
- openstackclient/network/v2/floating_ip.py +8 -10
- openstackclient/network/v2/floating_ip_pool.py +6 -15
- openstackclient/network/v2/floating_ip_port_forwarding.py +5 -13
- openstackclient/network/v2/ip_availability.py +2 -2
- openstackclient/network/v2/l3_conntrack_helper.py +5 -5
- openstackclient/network/v2/network.py +8 -8
- openstackclient/network/v2/network_agent.py +8 -8
- openstackclient/network/v2/network_auto_allocated_topology.py +2 -2
- openstackclient/network/v2/network_flavor.py +6 -8
- openstackclient/network/v2/network_flavor_profile.py +4 -4
- openstackclient/network/v2/network_meter.py +3 -3
- openstackclient/network/v2/network_meter_rule.py +3 -3
- openstackclient/network/v2/network_qos_policy.py +5 -5
- openstackclient/network/v2/network_qos_rule.py +9 -9
- openstackclient/network/v2/network_qos_rule_type.py +1 -1
- openstackclient/network/v2/network_rbac.py +5 -5
- openstackclient/network/v2/network_segment.py +5 -5
- openstackclient/network/v2/network_segment_range.py +7 -7
- openstackclient/network/v2/network_trunk.py +7 -7
- openstackclient/network/v2/port.py +26 -12
- openstackclient/network/v2/router.py +403 -54
- openstackclient/network/v2/security_group.py +18 -14
- openstackclient/network/v2/security_group_rule.py +18 -15
- openstackclient/network/v2/subnet.py +15 -8
- openstackclient/network/v2/subnet_pool.py +6 -6
- openstackclient/object/v1/account.py +2 -2
- openstackclient/object/v1/container.py +7 -7
- openstackclient/object/v1/object.py +7 -7
- openstackclient/shell.py +4 -6
- openstackclient/tests/functional/base.py +1 -1
- openstackclient/tests/functional/common/test_extension.py +1 -1
- openstackclient/tests/functional/common/test_help.py +2 -2
- openstackclient/tests/functional/common/test_module.py +1 -1
- openstackclient/tests/functional/common/test_quota.py +43 -61
- openstackclient/tests/functional/compute/v2/common.py +2 -2
- openstackclient/tests/functional/compute/v2/test_flavor.py +2 -2
- openstackclient/tests/functional/compute/v2/test_keypair.py +1 -1
- openstackclient/tests/functional/compute/v2/test_server.py +5 -5
- openstackclient/tests/functional/compute/v2/test_server_event.py +1 -1
- openstackclient/tests/functional/identity/v2/common.py +3 -3
- openstackclient/tests/functional/identity/v3/common.py +14 -6
- openstackclient/tests/functional/identity/v3/test_application_credential.py +13 -19
- openstackclient/tests/functional/identity/v3/test_domain.py +1 -3
- openstackclient/tests/functional/identity/v3/test_endpoint.py +1 -1
- openstackclient/tests/functional/identity/v3/test_idp.py +1 -1
- openstackclient/tests/functional/identity/v3/test_limit.py +2 -2
- openstackclient/tests/functional/identity/v3/test_region.py +1 -3
- openstackclient/tests/functional/identity/v3/test_registered_limit.py +1 -1
- openstackclient/tests/functional/identity/v3/test_role.py +2 -2
- openstackclient/tests/functional/identity/v3/test_role_assignment.py +210 -0
- openstackclient/tests/functional/identity/v3/test_service.py +4 -6
- openstackclient/tests/functional/identity/v3/test_service_provider.py +1 -3
- openstackclient/tests/functional/image/base.py +1 -1
- openstackclient/tests/functional/image/v2/test_image.py +1 -1
- openstackclient/tests/functional/image/v2/test_info.py +1 -1
- openstackclient/tests/functional/network/v2/common.py +4 -6
- openstackclient/tests/functional/network/v2/test_network.py +5 -3
- openstackclient/tests/functional/network/v2/test_network_agent.py +7 -5
- openstackclient/tests/functional/network/v2/test_network_qos_rule.py +4 -4
- openstackclient/tests/functional/network/v2/test_port.py +11 -7
- openstackclient/tests/functional/network/v2/test_router.py +2 -2
- openstackclient/tests/functional/object/v1/common.py +1 -1
- openstackclient/tests/functional/object/v1/test_container.py +3 -3
- openstackclient/tests/functional/object/v1/test_object.py +9 -13
- openstackclient/tests/functional/volume/base.py +1 -1
- openstackclient/tests/functional/volume/v1/test_service.py +1 -1
- openstackclient/tests/functional/volume/v1/test_snapshot.py +2 -2
- openstackclient/tests/functional/volume/v1/test_transfer_request.py +2 -2
- openstackclient/tests/functional/volume/v1/test_volume_type.py +1 -1
- openstackclient/tests/functional/volume/v2/test_service.py +2 -2
- openstackclient/tests/functional/volume/v2/test_volume_backup.py +2 -2
- openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +2 -2
- openstackclient/tests/functional/volume/v2/test_volume_type.py +1 -1
- openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +2 -2
- openstackclient/tests/functional/volume/v3/test_volume_type.py +1 -1
- openstackclient/tests/unit/api/fakes.py +1 -1
- openstackclient/tests/unit/api/test_api.py +2 -2
- openstackclient/tests/unit/api/test_compute_v2.py +522 -707
- openstackclient/tests/unit/api/test_image_v1.py +1 -1
- openstackclient/tests/unit/api/test_image_v2.py +1 -1
- openstackclient/tests/unit/api/test_object_store_v1.py +4 -4
- openstackclient/tests/unit/common/test_limits.py +73 -35
- openstackclient/tests/unit/common/test_logs.py +2 -2
- openstackclient/tests/unit/common/test_module.py +4 -2
- openstackclient/tests/unit/common/test_project_cleanup.py +31 -6
- openstackclient/tests/unit/common/test_quota.py +490 -630
- openstackclient/tests/unit/compute/v2/fakes.py +37 -286
- openstackclient/tests/unit/compute/v2/test_agent.py +189 -147
- openstackclient/tests/unit/compute/v2/test_aggregate.py +18 -16
- openstackclient/tests/unit/compute/v2/test_console.py +4 -5
- openstackclient/tests/unit/compute/v2/test_flavor.py +59 -68
- openstackclient/tests/unit/compute/v2/test_host.py +83 -54
- openstackclient/tests/unit/compute/v2/test_hypervisor.py +28 -31
- openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -2
- openstackclient/tests/unit/compute/v2/test_keypair.py +65 -50
- openstackclient/tests/unit/compute/v2/test_server.py +2895 -2459
- openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -1
- openstackclient/tests/unit/compute/v2/test_server_event.py +14 -39
- openstackclient/tests/unit/compute/v2/test_server_group.py +28 -29
- openstackclient/tests/unit/compute/v2/test_server_migration.py +43 -68
- openstackclient/tests/unit/compute/v2/test_server_volume.py +17 -34
- openstackclient/tests/unit/compute/v2/test_service.py +34 -52
- openstackclient/tests/unit/compute/v2/test_usage.py +4 -4
- openstackclient/tests/unit/fakes.py +11 -11
- openstackclient/tests/unit/identity/v2_0/fakes.py +27 -10
- openstackclient/tests/unit/identity/v2_0/test_catalog.py +3 -3
- openstackclient/tests/unit/identity/v2_0/test_endpoint.py +7 -7
- openstackclient/tests/unit/identity/v2_0/test_project.py +8 -8
- openstackclient/tests/unit/identity/v2_0/test_role.py +10 -10
- openstackclient/tests/unit/identity/v2_0/test_role_assignment.py +4 -4
- openstackclient/tests/unit/identity/v2_0/test_service.py +6 -6
- openstackclient/tests/unit/identity/v2_0/test_token.py +4 -4
- openstackclient/tests/unit/identity/v2_0/test_user.py +8 -8
- openstackclient/tests/unit/identity/v3/fakes.py +59 -20
- openstackclient/tests/unit/identity/v3/test_access_rule.py +5 -5
- openstackclient/tests/unit/identity/v3/test_application_credential.py +212 -235
- openstackclient/tests/unit/identity/v3/test_catalog.py +3 -3
- openstackclient/tests/unit/identity/v3/test_consumer.py +7 -8
- openstackclient/tests/unit/identity/v3/test_credential.py +9 -9
- openstackclient/tests/unit/identity/v3/test_domain.py +8 -8
- openstackclient/tests/unit/identity/v3/test_endpoint.py +13 -13
- openstackclient/tests/unit/identity/v3/test_endpoint_group.py +12 -14
- openstackclient/tests/unit/identity/v3/test_group.py +12 -12
- openstackclient/tests/unit/identity/v3/test_identity_provider.py +8 -8
- openstackclient/tests/unit/identity/v3/test_implied_role.py +5 -5
- openstackclient/tests/unit/identity/v3/test_limit.py +7 -7
- openstackclient/tests/unit/identity/v3/test_mappings.py +7 -7
- openstackclient/tests/unit/identity/v3/test_oauth.py +5 -5
- openstackclient/tests/unit/identity/v3/test_project.py +16 -16
- openstackclient/tests/unit/identity/v3/test_protocol.py +7 -7
- openstackclient/tests/unit/identity/v3/test_region.py +7 -7
- openstackclient/tests/unit/identity/v3/test_registered_limit.py +12 -13
- openstackclient/tests/unit/identity/v3/test_role.py +13 -13
- openstackclient/tests/unit/identity/v3/test_role_assignment.py +410 -331
- openstackclient/tests/unit/identity/v3/test_service.py +93 -97
- openstackclient/tests/unit/identity/v3/test_service_provider.py +7 -7
- openstackclient/tests/unit/identity/v3/test_token.py +4 -4
- openstackclient/tests/unit/identity/v3/test_trust.py +9 -9
- openstackclient/tests/unit/identity/v3/test_unscoped_saml.py +4 -4
- openstackclient/tests/unit/identity/v3/test_user.py +299 -327
- openstackclient/tests/unit/image/v1/test_image.py +6 -6
- openstackclient/tests/unit/image/v2/fakes.py +46 -9
- openstackclient/tests/unit/image/v2/test_cache.py +2 -2
- openstackclient/tests/unit/image/v2/test_image.py +3 -3
- openstackclient/tests/unit/image/v2/test_metadef_objects.py +62 -0
- openstackclient/tests/unit/image/v2/test_metadef_resource_type_association.py +131 -0
- openstackclient/tests/unit/integ/base.py +1 -1
- openstackclient/tests/unit/integ/cli/test_project.py +4 -4
- openstackclient/tests/unit/integ/cli/test_shell.py +7 -7
- openstackclient/tests/unit/network/test_common.py +12 -21
- openstackclient/tests/unit/network/v2/fakes.py +64 -130
- openstackclient/tests/unit/network/v2/test_address_group.py +15 -15
- openstackclient/tests/unit/network/v2/test_address_scope.py +13 -13
- openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +49 -27
- openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +40 -38
- openstackclient/tests/unit/network/v2/test_floating_ip_network.py +15 -15
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +4 -7
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +3 -5
- openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +11 -11
- openstackclient/tests/unit/network/v2/test_ip_availability.py +6 -6
- openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +11 -21
- openstackclient/tests/unit/network/v2/test_local_ip.py +7 -7
- openstackclient/tests/unit/network/v2/test_local_ip_association.py +3 -5
- openstackclient/tests/unit/network/v2/test_ndp_proxy.py +13 -13
- openstackclient/tests/unit/network/v2/test_network.py +23 -28
- openstackclient/tests/unit/network/v2/test_network_agent.py +17 -21
- openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +8 -8
- openstackclient/tests/unit/network/v2/test_network_compute.py +66 -65
- openstackclient/tests/unit/network/v2/test_network_flavor.py +17 -19
- openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +13 -13
- openstackclient/tests/unit/network/v2/test_network_meter.py +11 -11
- openstackclient/tests/unit/network/v2/test_network_meter_rule.py +11 -11
- openstackclient/tests/unit/network/v2/test_network_qos_policy.py +11 -21
- openstackclient/tests/unit/network/v2/test_network_qos_rule.py +51 -77
- openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +5 -9
- openstackclient/tests/unit/network/v2/test_network_rbac.py +12 -12
- openstackclient/tests/unit/network/v2/test_network_segment.py +11 -15
- openstackclient/tests/unit/network/v2/test_network_segment_range.py +11 -13
- openstackclient/tests/unit/network/v2/test_network_service_provider.py +3 -5
- openstackclient/tests/unit/network/v2/test_network_trunk.py +11 -11
- openstackclient/tests/unit/network/v2/test_port.py +22 -25
- openstackclient/tests/unit/network/v2/test_router.py +721 -51
- openstackclient/tests/unit/network/v2/test_security_group_compute.py +65 -49
- openstackclient/tests/unit/network/v2/test_security_group_network.py +15 -15
- openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +57 -45
- openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +11 -19
- openstackclient/tests/unit/network/v2/test_subnet.py +29 -25
- openstackclient/tests/unit/network/v2/test_subnet_pool.py +15 -15
- openstackclient/tests/unit/object/v1/fakes.py +1 -1
- openstackclient/tests/unit/object/v1/test_container.py +5 -5
- openstackclient/tests/unit/object/v1/test_container_all.py +6 -6
- openstackclient/tests/unit/object/v1/test_object.py +3 -3
- openstackclient/tests/unit/object/v1/test_object_all.py +5 -5
- openstackclient/tests/unit/test_shell.py +5 -5
- openstackclient/tests/unit/utils.py +4 -1
- openstackclient/tests/unit/volume/test_find_resource.py +2 -2
- openstackclient/tests/unit/volume/v1/fakes.py +5 -6
- openstackclient/tests/unit/volume/v1/test_volume.py +5 -4
- openstackclient/tests/unit/volume/v2/fakes.py +39 -259
- openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py +5 -5
- openstackclient/tests/unit/volume/v2/test_qos_specs.py +9 -9
- openstackclient/tests/unit/volume/v2/test_volume.py +21 -87
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +7 -368
- openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +1 -1
- openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +0 -44
- openstackclient/tests/unit/volume/v2/test_volume_type.py +6 -87
- openstackclient/tests/unit/volume/v3/fakes.py +505 -22
- openstackclient/tests/unit/volume/v3/test_block_storage_cleanup.py +2 -3
- openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py +10 -11
- openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +10 -6
- openstackclient/tests/unit/volume/v3/test_block_storage_manage.py +25 -17
- openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py +6 -32
- openstackclient/tests/unit/volume/v3/test_service.py +271 -0
- openstackclient/tests/unit/volume/v3/test_volume.py +2177 -33
- openstackclient/tests/unit/volume/v3/test_volume_attachment.py +48 -52
- openstackclient/tests/unit/volume/v3/test_volume_backup.py +892 -0
- openstackclient/tests/unit/volume/v3/test_volume_group.py +19 -20
- openstackclient/tests/unit/volume/v3/test_volume_group_snapshot.py +14 -34
- openstackclient/tests/unit/volume/v3/test_volume_group_type.py +13 -16
- openstackclient/tests/unit/volume/v3/test_volume_message.py +10 -11
- openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +161 -0
- openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py +425 -0
- openstackclient/tests/unit/volume/v3/test_volume_type.py +1109 -0
- openstackclient/volume/v1/qos_specs.py +7 -7
- openstackclient/volume/v1/service.py +2 -2
- openstackclient/volume/v1/volume.py +12 -12
- openstackclient/volume/v1/volume_backup.py +7 -7
- openstackclient/volume/v1/volume_snapshot.py +8 -8
- openstackclient/volume/v1/volume_transfer_request.py +5 -5
- openstackclient/volume/v1/volume_type.py +7 -7
- openstackclient/volume/v2/backup_record.py +2 -2
- openstackclient/volume/v2/consistency_group.py +7 -9
- openstackclient/volume/v2/consistency_group_snapshot.py +4 -12
- openstackclient/volume/v2/qos_specs.py +7 -7
- openstackclient/volume/v2/service.py +2 -2
- openstackclient/volume/v2/volume.py +80 -80
- openstackclient/volume/v2/volume_backend.py +2 -2
- openstackclient/volume/v2/volume_backup.py +7 -217
- openstackclient/volume/v2/volume_host.py +2 -2
- openstackclient/volume/v2/volume_snapshot.py +8 -8
- openstackclient/volume/v2/volume_transfer_request.py +5 -37
- openstackclient/volume/v2/volume_type.py +7 -89
- openstackclient/volume/v3/service.py +56 -0
- openstackclient/volume/v3/volume.py +971 -0
- openstackclient/volume/v3/volume_attachment.py +31 -29
- openstackclient/volume/v3/volume_backup.py +670 -0
- openstackclient/volume/v3/volume_message.py +1 -1
- openstackclient/volume/v3/volume_snapshot.py +97 -0
- openstackclient/volume/v3/volume_transfer_request.py +233 -0
- openstackclient/volume/v3/volume_type.py +967 -0
- {python_openstackclient-6.6.1.dist-info → python_openstackclient-7.0.0.dist-info}/AUTHORS +4 -0
- {python_openstackclient-6.6.1.dist-info → python_openstackclient-7.0.0.dist-info}/METADATA +2 -3
- python_openstackclient-7.0.0.dist-info/RECORD +502 -0
- {python_openstackclient-6.6.1.dist-info → python_openstackclient-7.0.0.dist-info}/entry_points.txt +33 -27
- python_openstackclient-7.0.0.dist-info/pbr.json +1 -0
- python_openstackclient-6.6.1.dist-info/RECORD +0 -489
- python_openstackclient-6.6.1.dist-info/pbr.json +0 -1
- {python_openstackclient-6.6.1.dist-info → python_openstackclient-7.0.0.dist-info}/LICENSE +0 -0
- {python_openstackclient-6.6.1.dist-info → python_openstackclient-7.0.0.dist-info}/WHEEL +0 -0
- {python_openstackclient-6.6.1.dist-info → python_openstackclient-7.0.0.dist-info}/top_level.txt +0 -0
|
@@ -20,6 +20,7 @@ import functools
|
|
|
20
20
|
import logging
|
|
21
21
|
|
|
22
22
|
from cliff import columns as cliff_columns
|
|
23
|
+
from openstack import exceptions as sdk_exceptions
|
|
23
24
|
from osc_lib.cli import format_columns
|
|
24
25
|
from osc_lib.cli import parseractions
|
|
25
26
|
from osc_lib.command import command
|
|
@@ -69,7 +70,7 @@ class AttachmentsColumn(cliff_columns.FormattableColumn):
|
|
|
69
70
|
"""
|
|
70
71
|
|
|
71
72
|
def __init__(self, value, server_cache=None):
|
|
72
|
-
super(
|
|
73
|
+
super().__init__(value)
|
|
73
74
|
self._server_cache = server_cache or {}
|
|
74
75
|
|
|
75
76
|
def human_readable(self):
|
|
@@ -84,31 +85,29 @@ class AttachmentsColumn(cliff_columns.FormattableColumn):
|
|
|
84
85
|
if server in self._server_cache.keys():
|
|
85
86
|
server = self._server_cache[server].name
|
|
86
87
|
device = attachment['device']
|
|
87
|
-
msg += 'Attached to
|
|
88
|
+
msg += f'Attached to {server} on {device} '
|
|
88
89
|
return msg
|
|
89
90
|
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
class CreateVolume(command.ShowOne):
|
|
93
|
+
_description = _("Create new volume")
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (
|
|
99
|
-
args.snapshot or args.source or args.backup
|
|
100
|
-
) is None and args.size is None:
|
|
101
|
-
msg = _(
|
|
102
|
-
"--size is a required option if snapshot, backup "
|
|
103
|
-
"or source volume are not specified."
|
|
104
|
-
)
|
|
105
|
-
raise exceptions.CommandError(msg)
|
|
95
|
+
@staticmethod
|
|
96
|
+
def _check_size_arg(args):
|
|
97
|
+
"""Check whether --size option is required or not.
|
|
106
98
|
|
|
99
|
+
Require size parameter only in case when snapshot or source
|
|
100
|
+
volume is not specified.
|
|
101
|
+
"""
|
|
107
102
|
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
if (args.snapshot or args.source) is None and args.size is None:
|
|
104
|
+
msg = _(
|
|
105
|
+
"--size is a required option if --snapshot or --source are "
|
|
106
|
+
"not specified"
|
|
107
|
+
)
|
|
108
|
+
raise exceptions.CommandError(msg)
|
|
110
109
|
|
|
111
|
-
def
|
|
110
|
+
def _get_parser(self, prog_name):
|
|
112
111
|
parser = super().get_parser(prog_name)
|
|
113
112
|
parser.add_argument(
|
|
114
113
|
"name",
|
|
@@ -121,8 +120,8 @@ class CreateVolume(command.ShowOne):
|
|
|
121
120
|
metavar="<size>",
|
|
122
121
|
type=int,
|
|
123
122
|
help=_(
|
|
124
|
-
"Volume size in GB (required unless --snapshot
|
|
125
|
-
"--source
|
|
123
|
+
"Volume size in GB (required unless --snapshot or "
|
|
124
|
+
"--source specified)"
|
|
126
125
|
),
|
|
127
126
|
)
|
|
128
127
|
parser.add_argument(
|
|
@@ -146,14 +145,6 @@ class CreateVolume(command.ShowOne):
|
|
|
146
145
|
metavar="<volume>",
|
|
147
146
|
help=_("Volume to clone (name or ID)"),
|
|
148
147
|
)
|
|
149
|
-
source_group.add_argument(
|
|
150
|
-
"--backup",
|
|
151
|
-
metavar="<backup>",
|
|
152
|
-
help=_(
|
|
153
|
-
"Restore backup to a volume (name or ID) "
|
|
154
|
-
"(supported by --os-volume-api-version 3.47 or later)"
|
|
155
|
-
),
|
|
156
|
-
)
|
|
157
148
|
source_group.add_argument(
|
|
158
149
|
"--source-replicated",
|
|
159
150
|
metavar="<replicated-volume>",
|
|
@@ -216,28 +207,23 @@ class CreateVolume(command.ShowOne):
|
|
|
216
207
|
action="store_true",
|
|
217
208
|
help=_("Set volume to read-write access mode (default)"),
|
|
218
209
|
)
|
|
210
|
+
return parser, source_group
|
|
211
|
+
|
|
212
|
+
def get_parser(self, prog_name):
|
|
213
|
+
parser, _ = self._get_parser(prog_name)
|
|
219
214
|
return parser
|
|
220
215
|
|
|
221
216
|
def take_action(self, parsed_args):
|
|
222
|
-
_check_size_arg(parsed_args)
|
|
217
|
+
CreateVolume._check_size_arg(parsed_args)
|
|
223
218
|
# size is validated in the above call to
|
|
224
219
|
# _check_size_arg where we check that size
|
|
225
220
|
# should be passed if we are not creating a
|
|
226
|
-
# volume from snapshot
|
|
221
|
+
# volume from snapshot or source volume
|
|
227
222
|
size = parsed_args.size
|
|
228
223
|
|
|
229
224
|
volume_client = self.app.client_manager.volume
|
|
230
225
|
image_client = self.app.client_manager.image
|
|
231
226
|
|
|
232
|
-
if parsed_args.backup and not (
|
|
233
|
-
volume_client.api_version.matches('3.47')
|
|
234
|
-
):
|
|
235
|
-
msg = _(
|
|
236
|
-
"--os-volume-api-version 3.47 or greater is required "
|
|
237
|
-
"to create a volume from backup."
|
|
238
|
-
)
|
|
239
|
-
raise exceptions.CommandError(msg)
|
|
240
|
-
|
|
241
227
|
source_volume = None
|
|
242
228
|
if parsed_args.source:
|
|
243
229
|
source_volume_obj = utils.find_resource(
|
|
@@ -272,15 +258,6 @@ class CreateVolume(command.ShowOne):
|
|
|
272
258
|
# snapshot size.
|
|
273
259
|
size = max(size or 0, snapshot_obj.size)
|
|
274
260
|
|
|
275
|
-
backup = None
|
|
276
|
-
if parsed_args.backup:
|
|
277
|
-
backup_obj = utils.find_resource(
|
|
278
|
-
volume_client.backups, parsed_args.backup
|
|
279
|
-
)
|
|
280
|
-
backup = backup_obj.id
|
|
281
|
-
# As above
|
|
282
|
-
size = max(size or 0, backup_obj.size)
|
|
283
|
-
|
|
284
261
|
volume = volume_client.volumes.create(
|
|
285
262
|
size=size,
|
|
286
263
|
snapshot_id=snapshot,
|
|
@@ -293,7 +270,6 @@ class CreateVolume(command.ShowOne):
|
|
|
293
270
|
source_volid=source_volume,
|
|
294
271
|
consistencygroup_id=consistency_group,
|
|
295
272
|
scheduler_hints=parsed_args.hint,
|
|
296
|
-
backup_id=backup,
|
|
297
273
|
)
|
|
298
274
|
|
|
299
275
|
if parsed_args.bootable or parsed_args.non_bootable:
|
|
@@ -360,7 +336,7 @@ class DeleteVolume(command.Command):
|
|
|
360
336
|
_description = _("Delete volume(s)")
|
|
361
337
|
|
|
362
338
|
def get_parser(self, prog_name):
|
|
363
|
-
parser = super(
|
|
339
|
+
parser = super().get_parser(prog_name)
|
|
364
340
|
parser.add_argument(
|
|
365
341
|
"volumes",
|
|
366
342
|
metavar="<volume>",
|
|
@@ -422,7 +398,7 @@ class ListVolume(command.Lister):
|
|
|
422
398
|
_description = _("List volumes")
|
|
423
399
|
|
|
424
400
|
def get_parser(self, prog_name):
|
|
425
|
-
parser = super(
|
|
401
|
+
parser = super().get_parser(prog_name)
|
|
426
402
|
parser.add_argument(
|
|
427
403
|
'--project',
|
|
428
404
|
metavar='<project>',
|
|
@@ -490,19 +466,6 @@ class ListVolume(command.Lister):
|
|
|
490
466
|
column_headers = copy.deepcopy(columns)
|
|
491
467
|
column_headers[4] = 'Attached to'
|
|
492
468
|
|
|
493
|
-
# Cache the server list
|
|
494
|
-
server_cache = {}
|
|
495
|
-
try:
|
|
496
|
-
compute_client = self.app.client_manager.compute
|
|
497
|
-
for s in compute_client.servers.list():
|
|
498
|
-
server_cache[s.id] = s
|
|
499
|
-
except Exception:
|
|
500
|
-
# Just forget it if there's any trouble
|
|
501
|
-
pass
|
|
502
|
-
AttachmentsColumnWithCache = functools.partial(
|
|
503
|
-
AttachmentsColumn, server_cache=server_cache
|
|
504
|
-
)
|
|
505
|
-
|
|
506
469
|
project_id = None
|
|
507
470
|
if parsed_args.project:
|
|
508
471
|
project_id = identity_common.find_project(
|
|
@@ -533,6 +496,28 @@ class ListVolume(command.Lister):
|
|
|
533
496
|
marker=parsed_args.marker,
|
|
534
497
|
limit=parsed_args.limit,
|
|
535
498
|
)
|
|
499
|
+
|
|
500
|
+
do_server_list = False
|
|
501
|
+
|
|
502
|
+
for vol in data:
|
|
503
|
+
if vol.status == 'in-use':
|
|
504
|
+
do_server_list = True
|
|
505
|
+
break
|
|
506
|
+
|
|
507
|
+
# Cache the server list
|
|
508
|
+
server_cache = {}
|
|
509
|
+
if do_server_list:
|
|
510
|
+
try:
|
|
511
|
+
compute_client = self.app.client_manager.sdk_connection.compute
|
|
512
|
+
for s in compute_client.servers():
|
|
513
|
+
server_cache[s.id] = s
|
|
514
|
+
except sdk_exceptions.SDKException:
|
|
515
|
+
# Just forget it if there's any trouble
|
|
516
|
+
pass # nosec: B110
|
|
517
|
+
AttachmentsColumnWithCache = functools.partial(
|
|
518
|
+
AttachmentsColumn, server_cache=server_cache
|
|
519
|
+
)
|
|
520
|
+
|
|
536
521
|
column_headers = utils.backward_compat_col_lister(
|
|
537
522
|
column_headers, parsed_args.columns, {'Display Name': 'Name'}
|
|
538
523
|
)
|
|
@@ -557,7 +542,7 @@ class MigrateVolume(command.Command):
|
|
|
557
542
|
_description = _("Migrate volume to a new host")
|
|
558
543
|
|
|
559
544
|
def get_parser(self, prog_name):
|
|
560
|
-
parser = super(
|
|
545
|
+
parser = super().get_parser(prog_name)
|
|
561
546
|
parser.add_argument(
|
|
562
547
|
'volume',
|
|
563
548
|
metavar="<volume>",
|
|
@@ -605,7 +590,7 @@ class SetVolume(command.Command):
|
|
|
605
590
|
_description = _("Set volume properties")
|
|
606
591
|
|
|
607
592
|
def get_parser(self, prog_name):
|
|
608
|
-
parser = super(
|
|
593
|
+
parser = super().get_parser(prog_name)
|
|
609
594
|
parser.add_argument(
|
|
610
595
|
'volume',
|
|
611
596
|
metavar='<volume>',
|
|
@@ -711,6 +696,12 @@ class SetVolume(command.Command):
|
|
|
711
696
|
'--retype-policy',
|
|
712
697
|
metavar='<retype-policy>',
|
|
713
698
|
choices=['never', 'on-demand'],
|
|
699
|
+
help=argparse.SUPPRESS,
|
|
700
|
+
)
|
|
701
|
+
parser.add_argument(
|
|
702
|
+
'--migration-policy',
|
|
703
|
+
metavar='<migration-policy>',
|
|
704
|
+
choices=['never', 'on-demand'],
|
|
714
705
|
help=_(
|
|
715
706
|
'Migration policy while re-typing volume '
|
|
716
707
|
'("never" or "on-demand", default is "never" ) '
|
|
@@ -746,6 +737,15 @@ class SetVolume(command.Command):
|
|
|
746
737
|
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
|
|
747
738
|
|
|
748
739
|
result = 0
|
|
740
|
+
if parsed_args.retype_policy:
|
|
741
|
+
msg = _(
|
|
742
|
+
"The '--retype-policy' option has been deprecated in favor "
|
|
743
|
+
"of '--migration-policy' option. The '--retype-policy' option "
|
|
744
|
+
"will be removed in a future release. Please use "
|
|
745
|
+
"'--migration-policy' instead."
|
|
746
|
+
)
|
|
747
|
+
self.log.warning(msg)
|
|
748
|
+
|
|
749
749
|
if parsed_args.size:
|
|
750
750
|
try:
|
|
751
751
|
if parsed_args.size <= volume.size:
|
|
@@ -753,10 +753,7 @@ class SetVolume(command.Command):
|
|
|
753
753
|
_("New size must be greater than %s GB") % volume.size
|
|
754
754
|
)
|
|
755
755
|
raise exceptions.CommandError(msg)
|
|
756
|
-
if
|
|
757
|
-
volume.status != 'available'
|
|
758
|
-
and not volume_client.api_version.matches('3.42')
|
|
759
|
-
):
|
|
756
|
+
if volume.status != 'available':
|
|
760
757
|
msg = (
|
|
761
758
|
_(
|
|
762
759
|
"Volume is in %s state, it must be available "
|
|
@@ -839,11 +836,12 @@ class SetVolume(command.Command):
|
|
|
839
836
|
e,
|
|
840
837
|
)
|
|
841
838
|
result += 1
|
|
839
|
+
policy = parsed_args.migration_policy or parsed_args.retype_policy
|
|
842
840
|
if parsed_args.type:
|
|
843
841
|
# get the migration policy
|
|
844
842
|
migration_policy = 'never'
|
|
845
|
-
if
|
|
846
|
-
migration_policy =
|
|
843
|
+
if policy:
|
|
844
|
+
migration_policy = policy
|
|
847
845
|
try:
|
|
848
846
|
# find the volume type
|
|
849
847
|
volume_type = utils.find_resource(
|
|
@@ -856,12 +854,14 @@ class SetVolume(command.Command):
|
|
|
856
854
|
except Exception as e:
|
|
857
855
|
LOG.error(_("Failed to set volume type: %s"), e)
|
|
858
856
|
result += 1
|
|
859
|
-
elif
|
|
860
|
-
# If the "--
|
|
857
|
+
elif policy:
|
|
858
|
+
# If the "--migration-policy" is specified without "--type"
|
|
861
859
|
LOG.warning(
|
|
862
|
-
_(
|
|
863
|
-
|
|
864
|
-
|
|
860
|
+
_("'%s' option will not work without '--type' option")
|
|
861
|
+
% (
|
|
862
|
+
'--migration-policy'
|
|
863
|
+
if parsed_args.migration_policy
|
|
864
|
+
else '--retype-policy'
|
|
865
865
|
)
|
|
866
866
|
)
|
|
867
867
|
|
|
@@ -893,7 +893,7 @@ class ShowVolume(command.ShowOne):
|
|
|
893
893
|
_description = _("Display volume details")
|
|
894
894
|
|
|
895
895
|
def get_parser(self, prog_name):
|
|
896
|
-
parser = super(
|
|
896
|
+
parser = super().get_parser(prog_name)
|
|
897
897
|
parser.add_argument(
|
|
898
898
|
'volume',
|
|
899
899
|
metavar="<volume>",
|
|
@@ -926,7 +926,7 @@ class UnsetVolume(command.Command):
|
|
|
926
926
|
_description = _("Unset volume properties")
|
|
927
927
|
|
|
928
928
|
def get_parser(self, prog_name):
|
|
929
|
-
parser = super(
|
|
929
|
+
parser = super().get_parser(prog_name)
|
|
930
930
|
parser.add_argument(
|
|
931
931
|
'volume',
|
|
932
932
|
metavar='<volume>',
|
|
@@ -25,7 +25,7 @@ class ShowCapability(command.Lister):
|
|
|
25
25
|
_description = _("Show capability command")
|
|
26
26
|
|
|
27
27
|
def get_parser(self, prog_name):
|
|
28
|
-
parser = super(
|
|
28
|
+
parser = super().get_parser(prog_name)
|
|
29
29
|
parser.add_argument(
|
|
30
30
|
"host",
|
|
31
31
|
metavar="<host>",
|
|
@@ -72,7 +72,7 @@ class ListPool(command.Lister):
|
|
|
72
72
|
_description = _("List pool command")
|
|
73
73
|
|
|
74
74
|
def get_parser(self, prog_name):
|
|
75
|
-
parser = super(
|
|
75
|
+
parser = super().get_parser(prog_name)
|
|
76
76
|
parser.add_argument(
|
|
77
77
|
"--long",
|
|
78
78
|
action="store_true",
|
|
@@ -14,14 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
"""Volume v2 Backup action implementations"""
|
|
16
16
|
|
|
17
|
-
import copy
|
|
18
17
|
import functools
|
|
19
18
|
import logging
|
|
20
19
|
|
|
21
|
-
from cinderclient import api_versions
|
|
22
20
|
from cliff import columns as cliff_columns
|
|
23
|
-
from openstack import utils as sdk_utils
|
|
24
|
-
from osc_lib.cli import parseractions
|
|
25
21
|
from osc_lib.command import command
|
|
26
22
|
from osc_lib import exceptions
|
|
27
23
|
from osc_lib import utils
|
|
@@ -44,7 +40,7 @@ class VolumeIdColumn(cliff_columns.FormattableColumn):
|
|
|
44
40
|
"""
|
|
45
41
|
|
|
46
42
|
def __init__(self, value, volume_cache=None):
|
|
47
|
-
super(
|
|
43
|
+
super().__init__(value)
|
|
48
44
|
self._volume_cache = volume_cache or {}
|
|
49
45
|
|
|
50
46
|
def human_readable(self):
|
|
@@ -104,26 +100,6 @@ class CreateVolumeBackup(command.ShowOne):
|
|
|
104
100
|
action='store_false',
|
|
105
101
|
help=_("Do not perform an incremental backup"),
|
|
106
102
|
)
|
|
107
|
-
parser.add_argument(
|
|
108
|
-
'--property',
|
|
109
|
-
metavar='<key=value>',
|
|
110
|
-
action=parseractions.KeyValueAction,
|
|
111
|
-
dest='properties',
|
|
112
|
-
help=_(
|
|
113
|
-
'Set a property on this backup '
|
|
114
|
-
'(repeat option to remove multiple values) '
|
|
115
|
-
'(supported by --os-volume-api-version 3.43 or above)'
|
|
116
|
-
),
|
|
117
|
-
)
|
|
118
|
-
parser.add_argument(
|
|
119
|
-
'--availability-zone',
|
|
120
|
-
metavar='<zone-name>',
|
|
121
|
-
help=_(
|
|
122
|
-
'AZ where the backup should be stored; by default it will be '
|
|
123
|
-
'the same as the source '
|
|
124
|
-
'(supported by --os-volume-api-version 3.51 or above)'
|
|
125
|
-
),
|
|
126
|
-
)
|
|
127
103
|
return parser
|
|
128
104
|
|
|
129
105
|
def take_action(self, parsed_args):
|
|
@@ -142,26 +118,6 @@ class CreateVolumeBackup(command.ShowOne):
|
|
|
142
118
|
ignore_missing=False,
|
|
143
119
|
).id
|
|
144
120
|
|
|
145
|
-
if parsed_args.properties:
|
|
146
|
-
if not sdk_utils.supports_microversion(volume_client, '3.43'):
|
|
147
|
-
msg = _(
|
|
148
|
-
'--os-volume-api-version 3.43 or greater is required to '
|
|
149
|
-
'support the --property option'
|
|
150
|
-
)
|
|
151
|
-
raise exceptions.CommandError(msg)
|
|
152
|
-
|
|
153
|
-
kwargs['metadata'] = parsed_args.properties
|
|
154
|
-
|
|
155
|
-
if parsed_args.availability_zone:
|
|
156
|
-
if not sdk_utils.supports_microversion(volume_client, '3.51'):
|
|
157
|
-
msg = _(
|
|
158
|
-
'--os-volume-api-version 3.51 or greater is required to '
|
|
159
|
-
'support the --availability-zone option'
|
|
160
|
-
)
|
|
161
|
-
raise exceptions.CommandError(msg)
|
|
162
|
-
|
|
163
|
-
kwargs['availability_zone'] = parsed_args.availability_zone
|
|
164
|
-
|
|
165
121
|
columns = (
|
|
166
122
|
"id",
|
|
167
123
|
"name",
|
|
@@ -173,7 +129,7 @@ class CreateVolumeBackup(command.ShowOne):
|
|
|
173
129
|
name=parsed_args.name,
|
|
174
130
|
description=parsed_args.description,
|
|
175
131
|
force=parsed_args.force,
|
|
176
|
-
|
|
132
|
+
is_incremental=parsed_args.incremental,
|
|
177
133
|
**kwargs,
|
|
178
134
|
)
|
|
179
135
|
data = utils.get_dict_properties(backup, columns)
|
|
@@ -184,7 +140,7 @@ class DeleteVolumeBackup(command.Command):
|
|
|
184
140
|
_description = _("Delete volume backup(s)")
|
|
185
141
|
|
|
186
142
|
def get_parser(self, prog_name):
|
|
187
|
-
parser = super(
|
|
143
|
+
parser = super().get_parser(prog_name)
|
|
188
144
|
parser.add_argument(
|
|
189
145
|
"backups",
|
|
190
146
|
metavar="<backup>",
|
|
@@ -236,7 +192,7 @@ class ListVolumeBackup(command.Lister):
|
|
|
236
192
|
_description = _("List volume backups")
|
|
237
193
|
|
|
238
194
|
def get_parser(self, prog_name):
|
|
239
|
-
parser = super(
|
|
195
|
+
parser = super().get_parser(prog_name)
|
|
240
196
|
parser.add_argument(
|
|
241
197
|
"--long",
|
|
242
198
|
action="store_true",
|
|
@@ -279,20 +235,6 @@ class ListVolumeBackup(command.Lister):
|
|
|
279
235
|
default=False,
|
|
280
236
|
help=_('Include all projects (admin only)'),
|
|
281
237
|
)
|
|
282
|
-
# TODO(stephenfin): Add once we have an equivalent command for
|
|
283
|
-
# 'cinder list-filters'
|
|
284
|
-
# parser.add_argument(
|
|
285
|
-
# '--filter',
|
|
286
|
-
# metavar='<key=value>',
|
|
287
|
-
# action=parseractions.KeyValueAction,
|
|
288
|
-
# dest='filters',
|
|
289
|
-
# help=_(
|
|
290
|
-
# "Filter key and value pairs. Use 'foo' to "
|
|
291
|
-
# "check enabled filters from server. Use 'key~=value' for "
|
|
292
|
-
# "inexact filtering if the key supports "
|
|
293
|
-
# "(supported by --os-volume-api-version 3.33 or above)"
|
|
294
|
-
# ),
|
|
295
|
-
# )
|
|
296
238
|
return parser
|
|
297
239
|
|
|
298
240
|
def take_action(self, parsed_args):
|
|
@@ -325,7 +267,7 @@ class ListVolumeBackup(command.Lister):
|
|
|
325
267
|
volume_cache[s.id] = s
|
|
326
268
|
except Exception:
|
|
327
269
|
# Just forget it if there's any trouble
|
|
328
|
-
pass
|
|
270
|
+
pass # nosec: B110
|
|
329
271
|
|
|
330
272
|
_VolumeIdColumn = functools.partial(
|
|
331
273
|
VolumeIdColumn, volume_cache=volume_cache
|
|
@@ -381,7 +323,7 @@ class RestoreVolumeBackup(command.ShowOne):
|
|
|
381
323
|
_description = _("Restore volume backup")
|
|
382
324
|
|
|
383
325
|
def get_parser(self, prog_name):
|
|
384
|
-
parser = super(
|
|
326
|
+
parser = super().get_parser(prog_name)
|
|
385
327
|
parser.add_argument(
|
|
386
328
|
"backup",
|
|
387
329
|
metavar="<backup>",
|
|
@@ -451,22 +393,6 @@ class SetVolumeBackup(command.Command):
|
|
|
451
393
|
metavar="<backup>",
|
|
452
394
|
help=_("Backup to modify (name or ID)"),
|
|
453
395
|
)
|
|
454
|
-
parser.add_argument(
|
|
455
|
-
'--name',
|
|
456
|
-
metavar='<name>',
|
|
457
|
-
help=_(
|
|
458
|
-
'New backup name'
|
|
459
|
-
'(supported by --os-volume-api-version 3.9 or above)'
|
|
460
|
-
),
|
|
461
|
-
)
|
|
462
|
-
parser.add_argument(
|
|
463
|
-
'--description',
|
|
464
|
-
metavar='<description>',
|
|
465
|
-
help=_(
|
|
466
|
-
'New backup description '
|
|
467
|
-
'(supported by --os-volume-api-version 3.9 or above)'
|
|
468
|
-
),
|
|
469
|
-
)
|
|
470
396
|
parser.add_argument(
|
|
471
397
|
'--state',
|
|
472
398
|
metavar='<state>',
|
|
@@ -478,27 +404,6 @@ class SetVolumeBackup(command.Command):
|
|
|
478
404
|
'exercise caution when using)'
|
|
479
405
|
),
|
|
480
406
|
)
|
|
481
|
-
parser.add_argument(
|
|
482
|
-
'--no-property',
|
|
483
|
-
action='store_true',
|
|
484
|
-
help=_(
|
|
485
|
-
'Remove all properties from this backup '
|
|
486
|
-
'(specify both --no-property and --property to remove the '
|
|
487
|
-
'current properties before setting new properties)'
|
|
488
|
-
),
|
|
489
|
-
)
|
|
490
|
-
parser.add_argument(
|
|
491
|
-
'--property',
|
|
492
|
-
metavar='<key=value>',
|
|
493
|
-
action=parseractions.KeyValueAction,
|
|
494
|
-
dest='properties',
|
|
495
|
-
default={},
|
|
496
|
-
help=_(
|
|
497
|
-
'Set a property on this backup '
|
|
498
|
-
'(repeat option to set multiple values) '
|
|
499
|
-
'(supported by --os-volume-api-version 3.43 or above)'
|
|
500
|
-
),
|
|
501
|
-
)
|
|
502
407
|
return parser
|
|
503
408
|
|
|
504
409
|
def take_action(self, parsed_args):
|
|
@@ -513,127 +418,16 @@ class SetVolumeBackup(command.Command):
|
|
|
513
418
|
LOG.error(_("Failed to set backup state: %s"), e)
|
|
514
419
|
result += 1
|
|
515
420
|
|
|
516
|
-
kwargs = {}
|
|
517
|
-
|
|
518
|
-
if parsed_args.name:
|
|
519
|
-
if volume_client.api_version < api_versions.APIVersion('3.9'):
|
|
520
|
-
msg = _(
|
|
521
|
-
'--os-volume-api-version 3.9 or greater is required to '
|
|
522
|
-
'support the --name option'
|
|
523
|
-
)
|
|
524
|
-
raise exceptions.CommandError(msg)
|
|
525
|
-
|
|
526
|
-
kwargs['name'] = parsed_args.name
|
|
527
|
-
|
|
528
|
-
if parsed_args.description:
|
|
529
|
-
if volume_client.api_version < api_versions.APIVersion('3.9'):
|
|
530
|
-
msg = _(
|
|
531
|
-
'--os-volume-api-version 3.9 or greater is required to '
|
|
532
|
-
'support the --description option'
|
|
533
|
-
)
|
|
534
|
-
raise exceptions.CommandError(msg)
|
|
535
|
-
|
|
536
|
-
kwargs['description'] = parsed_args.description
|
|
537
|
-
|
|
538
|
-
if parsed_args.no_property:
|
|
539
|
-
if volume_client.api_version < api_versions.APIVersion('3.43'):
|
|
540
|
-
msg = _(
|
|
541
|
-
'--os-volume-api-version 3.43 or greater is required to '
|
|
542
|
-
'support the --no-property option'
|
|
543
|
-
)
|
|
544
|
-
raise exceptions.CommandError(msg)
|
|
545
|
-
|
|
546
|
-
if parsed_args.properties:
|
|
547
|
-
if volume_client.api_version < api_versions.APIVersion('3.43'):
|
|
548
|
-
msg = _(
|
|
549
|
-
'--os-volume-api-version 3.43 or greater is required to '
|
|
550
|
-
'support the --property option'
|
|
551
|
-
)
|
|
552
|
-
raise exceptions.CommandError(msg)
|
|
553
|
-
|
|
554
|
-
if volume_client.api_version >= api_versions.APIVersion('3.43'):
|
|
555
|
-
metadata = copy.deepcopy(backup.metadata)
|
|
556
|
-
|
|
557
|
-
if parsed_args.no_property:
|
|
558
|
-
metadata = {}
|
|
559
|
-
|
|
560
|
-
metadata.update(parsed_args.properties)
|
|
561
|
-
kwargs['metadata'] = metadata
|
|
562
|
-
|
|
563
|
-
if kwargs:
|
|
564
|
-
try:
|
|
565
|
-
volume_client.backups.update(backup.id, **kwargs)
|
|
566
|
-
except Exception as e:
|
|
567
|
-
LOG.error("Failed to update backup: %s", e)
|
|
568
|
-
result += 1
|
|
569
|
-
|
|
570
421
|
if result > 0:
|
|
571
422
|
msg = _("One or more of the set operations failed")
|
|
572
423
|
raise exceptions.CommandError(msg)
|
|
573
424
|
|
|
574
425
|
|
|
575
|
-
class UnsetVolumeBackup(command.Command):
|
|
576
|
-
"""Unset volume backup properties.
|
|
577
|
-
|
|
578
|
-
This command requires ``--os-volume-api-version`` 3.43 or greater.
|
|
579
|
-
"""
|
|
580
|
-
|
|
581
|
-
def get_parser(self, prog_name):
|
|
582
|
-
parser = super().get_parser(prog_name)
|
|
583
|
-
parser.add_argument(
|
|
584
|
-
'backup',
|
|
585
|
-
metavar='<backup>',
|
|
586
|
-
help=_('Backup to modify (name or ID)'),
|
|
587
|
-
)
|
|
588
|
-
parser.add_argument(
|
|
589
|
-
'--property',
|
|
590
|
-
metavar='<key>',
|
|
591
|
-
action='append',
|
|
592
|
-
dest='properties',
|
|
593
|
-
help=_(
|
|
594
|
-
'Property to remove from this backup '
|
|
595
|
-
'(repeat option to unset multiple values) '
|
|
596
|
-
),
|
|
597
|
-
)
|
|
598
|
-
return parser
|
|
599
|
-
|
|
600
|
-
def take_action(self, parsed_args):
|
|
601
|
-
volume_client = self.app.client_manager.volume
|
|
602
|
-
|
|
603
|
-
if volume_client.api_version < api_versions.APIVersion('3.43'):
|
|
604
|
-
msg = _(
|
|
605
|
-
'--os-volume-api-version 3.43 or greater is required to '
|
|
606
|
-
'support the --property option'
|
|
607
|
-
)
|
|
608
|
-
raise exceptions.CommandError(msg)
|
|
609
|
-
|
|
610
|
-
backup = utils.find_resource(volume_client.backups, parsed_args.backup)
|
|
611
|
-
metadata = copy.deepcopy(backup.metadata)
|
|
612
|
-
|
|
613
|
-
for key in parsed_args.properties:
|
|
614
|
-
if key not in metadata:
|
|
615
|
-
# ignore invalid properties but continue
|
|
616
|
-
LOG.warning(
|
|
617
|
-
"'%s' is not a valid property for backup '%s'",
|
|
618
|
-
key,
|
|
619
|
-
parsed_args.backup,
|
|
620
|
-
)
|
|
621
|
-
continue
|
|
622
|
-
|
|
623
|
-
del metadata[key]
|
|
624
|
-
|
|
625
|
-
kwargs = {
|
|
626
|
-
'metadata': metadata,
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
volume_client.backups.update(backup.id, **kwargs)
|
|
630
|
-
|
|
631
|
-
|
|
632
426
|
class ShowVolumeBackup(command.ShowOne):
|
|
633
427
|
_description = _("Display volume backup details")
|
|
634
428
|
|
|
635
429
|
def get_parser(self, prog_name):
|
|
636
|
-
parser = super(
|
|
430
|
+
parser = super().get_parser(prog_name)
|
|
637
431
|
parser.add_argument(
|
|
638
432
|
"backup",
|
|
639
433
|
metavar="<backup>",
|
|
@@ -650,20 +444,16 @@ class ShowVolumeBackup(command.ShowOne):
|
|
|
650
444
|
"created_at",
|
|
651
445
|
"data_timestamp",
|
|
652
446
|
"description",
|
|
653
|
-
"encryption_key_id",
|
|
654
447
|
"fail_reason",
|
|
655
448
|
"has_dependent_backups",
|
|
656
449
|
"id",
|
|
657
450
|
"is_incremental",
|
|
658
|
-
"metadata",
|
|
659
451
|
"name",
|
|
660
452
|
"object_count",
|
|
661
|
-
"project_id",
|
|
662
453
|
"size",
|
|
663
454
|
"snapshot_id",
|
|
664
455
|
"status",
|
|
665
456
|
"updated_at",
|
|
666
|
-
"user_id",
|
|
667
457
|
"volume_id",
|
|
668
458
|
)
|
|
669
459
|
data = utils.get_dict_properties(backup, columns)
|