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
|
@@ -459,3 +459,68 @@ class TestVolumeGroupTypeList(TestVolumeGroupType):
|
|
|
459
459
|
self.assertIn(
|
|
460
460
|
'--os-volume-api-version 3.11 or greater is required', str(exc)
|
|
461
461
|
)
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
class TestVolumeGroupTypeShow(TestVolumeGroupType):
|
|
465
|
+
fake_volume_group_type = volume_fakes.create_one_volume_group_type()
|
|
466
|
+
|
|
467
|
+
columns = (
|
|
468
|
+
'ID',
|
|
469
|
+
'Name',
|
|
470
|
+
'Description',
|
|
471
|
+
'Is Public',
|
|
472
|
+
'Properties',
|
|
473
|
+
)
|
|
474
|
+
data = (
|
|
475
|
+
fake_volume_group_type.id,
|
|
476
|
+
fake_volume_group_type.name,
|
|
477
|
+
fake_volume_group_type.description,
|
|
478
|
+
fake_volume_group_type.is_public,
|
|
479
|
+
format_columns.DictColumn(fake_volume_group_type.group_specs),
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
def setUp(self):
|
|
483
|
+
super().setUp()
|
|
484
|
+
|
|
485
|
+
self.volume_group_types_mock.get.return_value = (
|
|
486
|
+
self.fake_volume_group_type
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
self.cmd = volume_group_type.ShowVolumeGroupType(self.app, None)
|
|
490
|
+
|
|
491
|
+
def test_volume_group_type_show(self):
|
|
492
|
+
self.set_volume_api_version('3.11')
|
|
493
|
+
|
|
494
|
+
arglist = [
|
|
495
|
+
self.fake_volume_group_type.id,
|
|
496
|
+
]
|
|
497
|
+
verifylist = [
|
|
498
|
+
('group_type', self.fake_volume_group_type.id),
|
|
499
|
+
]
|
|
500
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
501
|
+
|
|
502
|
+
columns, data = self.cmd.take_action(parsed_args)
|
|
503
|
+
|
|
504
|
+
self.volume_group_types_mock.get.assert_called_once_with(
|
|
505
|
+
self.fake_volume_group_type.id,
|
|
506
|
+
)
|
|
507
|
+
self.assertEqual(self.columns, columns)
|
|
508
|
+
self.assertCountEqual(self.data, data)
|
|
509
|
+
|
|
510
|
+
def test_volume_group_type_show_pre_v311(self):
|
|
511
|
+
self.set_volume_api_version('3.10')
|
|
512
|
+
|
|
513
|
+
arglist = [
|
|
514
|
+
self.fake_volume_group_type.id,
|
|
515
|
+
]
|
|
516
|
+
verifylist = [
|
|
517
|
+
('group_type', self.fake_volume_group_type.id),
|
|
518
|
+
]
|
|
519
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
520
|
+
|
|
521
|
+
exc = self.assertRaises(
|
|
522
|
+
exceptions.CommandError, self.cmd.take_action, parsed_args
|
|
523
|
+
)
|
|
524
|
+
self.assertIn(
|
|
525
|
+
'--os-volume-api-version 3.11 or greater is required', str(exc)
|
|
526
|
+
)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
3
|
+
# not use this file except in compliance with the License. You may obtain
|
|
4
|
+
# a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
10
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
11
|
+
# License for the specific language governing permissions and limitations
|
|
12
|
+
# under the License.
|
|
13
|
+
|
|
14
|
+
from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
|
|
15
|
+
from openstackclient.volume.v3 import volume_host
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TestVolumeHost(volume_fakes.TestVolume):
|
|
19
|
+
def setUp(self):
|
|
20
|
+
super().setUp()
|
|
21
|
+
|
|
22
|
+
self.host_mock = self.volume_client.services
|
|
23
|
+
self.host_mock.reset_mock()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TestVolumeHostSet(TestVolumeHost):
|
|
27
|
+
service = volume_fakes.create_one_service()
|
|
28
|
+
|
|
29
|
+
def setUp(self):
|
|
30
|
+
super().setUp()
|
|
31
|
+
|
|
32
|
+
self.host_mock.freeze_host.return_value = None
|
|
33
|
+
self.host_mock.thaw_host.return_value = None
|
|
34
|
+
|
|
35
|
+
# Get the command object to mock
|
|
36
|
+
self.cmd = volume_host.SetVolumeHost(self.app, None)
|
|
37
|
+
|
|
38
|
+
def test_volume_host_set_nothing(self):
|
|
39
|
+
arglist = [
|
|
40
|
+
self.service.host,
|
|
41
|
+
]
|
|
42
|
+
verifylist = [
|
|
43
|
+
('host', self.service.host),
|
|
44
|
+
]
|
|
45
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
46
|
+
result = self.cmd.take_action(parsed_args)
|
|
47
|
+
|
|
48
|
+
self.host_mock.freeze_host.assert_not_called()
|
|
49
|
+
self.host_mock.thaw_host.assert_not_called()
|
|
50
|
+
self.assertIsNone(result)
|
|
51
|
+
|
|
52
|
+
def test_volume_host_set_enable(self):
|
|
53
|
+
arglist = [
|
|
54
|
+
'--enable',
|
|
55
|
+
self.service.host,
|
|
56
|
+
]
|
|
57
|
+
verifylist = [
|
|
58
|
+
('enable', True),
|
|
59
|
+
('host', self.service.host),
|
|
60
|
+
]
|
|
61
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
62
|
+
|
|
63
|
+
result = self.cmd.take_action(parsed_args)
|
|
64
|
+
|
|
65
|
+
self.host_mock.thaw_host.assert_called_with(self.service.host)
|
|
66
|
+
self.host_mock.freeze_host.assert_not_called()
|
|
67
|
+
self.assertIsNone(result)
|
|
68
|
+
|
|
69
|
+
def test_volume_host_set_disable(self):
|
|
70
|
+
arglist = [
|
|
71
|
+
'--disable',
|
|
72
|
+
self.service.host,
|
|
73
|
+
]
|
|
74
|
+
verifylist = [
|
|
75
|
+
('disable', True),
|
|
76
|
+
('host', self.service.host),
|
|
77
|
+
]
|
|
78
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
79
|
+
|
|
80
|
+
result = self.cmd.take_action(parsed_args)
|
|
81
|
+
|
|
82
|
+
self.host_mock.freeze_host.assert_called_with(self.service.host)
|
|
83
|
+
self.host_mock.thaw_host.assert_not_called()
|
|
84
|
+
self.assertIsNone(result)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class TestVolumeHostFailover(TestVolumeHost):
|
|
88
|
+
service = volume_fakes.create_one_service()
|
|
89
|
+
|
|
90
|
+
def setUp(self):
|
|
91
|
+
super().setUp()
|
|
92
|
+
|
|
93
|
+
self.host_mock.failover_host.return_value = None
|
|
94
|
+
|
|
95
|
+
# Get the command object to mock
|
|
96
|
+
self.cmd = volume_host.FailoverVolumeHost(self.app, None)
|
|
97
|
+
|
|
98
|
+
def test_volume_host_failover(self):
|
|
99
|
+
arglist = [
|
|
100
|
+
'--volume-backend',
|
|
101
|
+
'backend_test',
|
|
102
|
+
self.service.host,
|
|
103
|
+
]
|
|
104
|
+
verifylist = [
|
|
105
|
+
('volume_backend', 'backend_test'),
|
|
106
|
+
('host', self.service.host),
|
|
107
|
+
]
|
|
108
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
109
|
+
|
|
110
|
+
result = self.cmd.take_action(parsed_args)
|
|
111
|
+
|
|
112
|
+
self.host_mock.failover_host.assert_called_with(
|
|
113
|
+
self.service.host, 'backend_test'
|
|
114
|
+
)
|
|
115
|
+
self.assertIsNone(result)
|
|
@@ -439,6 +439,7 @@ class TestVolumeSnapshotList(volume_fakes.TestVolume):
|
|
|
439
439
|
self.volume_sdk_client.snapshots.assert_called_once_with(
|
|
440
440
|
limit=None,
|
|
441
441
|
marker=None,
|
|
442
|
+
max_items=None,
|
|
442
443
|
all_projects=False,
|
|
443
444
|
name=None,
|
|
444
445
|
status=None,
|
|
@@ -472,6 +473,7 @@ class TestVolumeSnapshotList(volume_fakes.TestVolume):
|
|
|
472
473
|
self.volume_sdk_client.snapshots.assert_called_once_with(
|
|
473
474
|
limit=2,
|
|
474
475
|
marker=self.snapshots[0].id,
|
|
476
|
+
max_items=None,
|
|
475
477
|
all_projects=True,
|
|
476
478
|
project_id=self.project.id,
|
|
477
479
|
name=None,
|
|
@@ -493,6 +495,7 @@ class TestVolumeSnapshotList(volume_fakes.TestVolume):
|
|
|
493
495
|
self.volume_sdk_client.snapshots.assert_called_once_with(
|
|
494
496
|
limit=None,
|
|
495
497
|
marker=None,
|
|
498
|
+
max_items=None,
|
|
496
499
|
all_projects=True,
|
|
497
500
|
name=None,
|
|
498
501
|
status=None,
|
|
@@ -519,6 +522,7 @@ class TestVolumeSnapshotList(volume_fakes.TestVolume):
|
|
|
519
522
|
self.volume_sdk_client.snapshots.assert_called_once_with(
|
|
520
523
|
limit=None,
|
|
521
524
|
marker=None,
|
|
525
|
+
max_items=None,
|
|
522
526
|
all_projects=False,
|
|
523
527
|
name=self.snapshots[0].name,
|
|
524
528
|
status=None,
|
|
@@ -545,6 +549,7 @@ class TestVolumeSnapshotList(volume_fakes.TestVolume):
|
|
|
545
549
|
self.volume_sdk_client.snapshots.assert_called_once_with(
|
|
546
550
|
limit=None,
|
|
547
551
|
marker=None,
|
|
552
|
+
max_items=None,
|
|
548
553
|
all_projects=False,
|
|
549
554
|
name=None,
|
|
550
555
|
status='available',
|
|
@@ -571,6 +576,7 @@ class TestVolumeSnapshotList(volume_fakes.TestVolume):
|
|
|
571
576
|
self.volume_sdk_client.snapshots.assert_called_once_with(
|
|
572
577
|
limit=None,
|
|
573
578
|
marker=None,
|
|
579
|
+
max_items=None,
|
|
574
580
|
all_projects=False,
|
|
575
581
|
name=None,
|
|
576
582
|
status=None,
|
|
@@ -102,7 +102,7 @@ class AttachmentsColumn(cliff_columns.FormattableColumn[list[Any]]):
|
|
|
102
102
|
return msg
|
|
103
103
|
|
|
104
104
|
|
|
105
|
-
def _format_volume(volume: _volume.Volume) -> dict[str,
|
|
105
|
+
def _format_volume(volume: _volume.Volume) -> dict[str, object]:
|
|
106
106
|
# Some columns returned by openstacksdk should not be shown because they're
|
|
107
107
|
# either irrelevant or duplicates
|
|
108
108
|
ignored_columns = {
|
|
@@ -494,7 +494,9 @@ class ListVolume(command.Lister):
|
|
|
494
494
|
default=False,
|
|
495
495
|
help=_('List additional fields in output'),
|
|
496
496
|
)
|
|
497
|
-
pagination.add_marker_pagination_option_to_parser(
|
|
497
|
+
pagination.add_marker_pagination_option_to_parser(
|
|
498
|
+
parser, include_max_items=False
|
|
499
|
+
)
|
|
498
500
|
return parser
|
|
499
501
|
|
|
500
502
|
def take_action(
|
|
@@ -322,6 +322,7 @@ class ListVolumeBackup(command.Lister):
|
|
|
322
322
|
all_tenants=parsed_args.all_projects,
|
|
323
323
|
marker=marker_backup_id,
|
|
324
324
|
limit=parsed_args.limit,
|
|
325
|
+
max_items=parsed_args.max_items,
|
|
325
326
|
)
|
|
326
327
|
|
|
327
328
|
return (
|
|
@@ -404,9 +405,7 @@ class RestoreVolumeBackup(command.ShowOne):
|
|
|
404
405
|
raise exceptions.CommandError(msg % parsed_args.volume)
|
|
405
406
|
|
|
406
407
|
restore = volume_client.restore_backup(
|
|
407
|
-
backup.id,
|
|
408
|
-
volume_id=volume_id,
|
|
409
|
-
name=volume_name,
|
|
408
|
+
backup.id, volume=volume_id, name=volume_name
|
|
410
409
|
)
|
|
411
410
|
|
|
412
411
|
data = utils.get_dict_properties(restore, columns)
|
|
@@ -66,7 +66,7 @@ class VolumeIdColumn(cliff_columns.FormattableColumn[str]):
|
|
|
66
66
|
return volume
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
def _format_snapshot(snapshot: _snapshot.Snapshot) -> dict[str,
|
|
69
|
+
def _format_snapshot(snapshot: _snapshot.Snapshot) -> dict[str, object]:
|
|
70
70
|
# Some columns returned by openstacksdk should not be shown because they're
|
|
71
71
|
# either irrelevant or duplicates
|
|
72
72
|
ignored_columns = {
|
|
@@ -231,11 +231,9 @@ class DeleteVolumeSnapshot(command.Command):
|
|
|
231
231
|
snapshot_id = volume_client.find_snapshot(
|
|
232
232
|
snapshot, ignore_missing=False
|
|
233
233
|
).id
|
|
234
|
-
# FIXME(stephenfin): This parameter is missing from sdk
|
|
235
|
-
# https://review.opendev.org/c/openstack/openstacksdk/+/984529
|
|
236
234
|
volume_client.delete_snapshot(
|
|
237
235
|
snapshot_id,
|
|
238
|
-
force=parsed_args.force,
|
|
236
|
+
force=parsed_args.force,
|
|
239
237
|
)
|
|
240
238
|
except Exception as e:
|
|
241
239
|
result += 1
|
|
@@ -378,6 +376,7 @@ class ListVolumeSnapshot(command.Lister):
|
|
|
378
376
|
data = volume_client.snapshots(
|
|
379
377
|
marker=parsed_args.marker,
|
|
380
378
|
limit=parsed_args.limit,
|
|
379
|
+
max_items=parsed_args.max_items,
|
|
381
380
|
all_projects=all_projects,
|
|
382
381
|
project_id=project_id,
|
|
383
382
|
name=parsed_args.name,
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
3
|
+
# not use this file except in compliance with the License. You may obtain
|
|
4
|
+
# a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
10
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
11
|
+
# License for the specific language governing permissions and limitations
|
|
12
|
+
# under the License.
|
|
13
|
+
|
|
14
|
+
"""Volume v3 Backup action implementations"""
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import logging
|
|
18
|
+
from collections.abc import Iterable, Sequence
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from osc_lib import utils
|
|
22
|
+
|
|
23
|
+
from openstackclient import command
|
|
24
|
+
from openstackclient.i18n import _
|
|
25
|
+
|
|
26
|
+
LOG = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ExportBackupRecord(command.ShowOne):
|
|
30
|
+
_description = _(
|
|
31
|
+
"""Export volume backup details.
|
|
32
|
+
|
|
33
|
+
Backup information can be imported into a new service instance to be able to
|
|
34
|
+
restore."""
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
38
|
+
parser = super().get_parser(prog_name)
|
|
39
|
+
parser.add_argument(
|
|
40
|
+
"backup",
|
|
41
|
+
metavar="<backup>",
|
|
42
|
+
help=_("Backup to export (name or ID)"),
|
|
43
|
+
)
|
|
44
|
+
return parser
|
|
45
|
+
|
|
46
|
+
def take_action(
|
|
47
|
+
self, parsed_args: argparse.Namespace
|
|
48
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
49
|
+
volume_client = self.app.client_manager.volume
|
|
50
|
+
backup = utils.find_resource(volume_client.backups, parsed_args.backup)
|
|
51
|
+
backup_data = volume_client.backups.export_record(backup.id)
|
|
52
|
+
|
|
53
|
+
# We only want to show "friendly" display names, but also want to keep
|
|
54
|
+
# json structure compatibility with cinderclient
|
|
55
|
+
if parsed_args.formatter == 'table':
|
|
56
|
+
backup_data['Backup Service'] = backup_data.pop('backup_service')
|
|
57
|
+
backup_data['Metadata'] = backup_data.pop('backup_url')
|
|
58
|
+
|
|
59
|
+
col_headers, col_data = zip(*sorted(backup_data.items()))
|
|
60
|
+
return col_headers, col_data
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ImportBackupRecord(command.ShowOne):
|
|
64
|
+
_description = _(
|
|
65
|
+
"""Import volume backup details.
|
|
66
|
+
|
|
67
|
+
Exported backup details contain the metadata necessary to restore to a new or
|
|
68
|
+
rebuilt service instance"""
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
72
|
+
parser = super().get_parser(prog_name)
|
|
73
|
+
parser.add_argument(
|
|
74
|
+
"backup_service",
|
|
75
|
+
metavar="<backup_service>",
|
|
76
|
+
help=_("Backup service containing the backup."),
|
|
77
|
+
)
|
|
78
|
+
parser.add_argument(
|
|
79
|
+
"backup_metadata",
|
|
80
|
+
metavar="<backup_metadata>",
|
|
81
|
+
help=_("Encoded backup metadata from export."),
|
|
82
|
+
)
|
|
83
|
+
return parser
|
|
84
|
+
|
|
85
|
+
def take_action(
|
|
86
|
+
self, parsed_args: argparse.Namespace
|
|
87
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
88
|
+
volume_client = self.app.client_manager.volume
|
|
89
|
+
backup_data = volume_client.backups.import_record(
|
|
90
|
+
parsed_args.backup_service, parsed_args.backup_metadata
|
|
91
|
+
)
|
|
92
|
+
backup_data.pop('links', None)
|
|
93
|
+
col_headers, col_data = zip(*sorted(backup_data.items()))
|
|
94
|
+
return col_headers, col_data
|