python-openstackclient 6.3.0__py3-none-any.whl → 6.5.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 +4 -4
- openstackclient/common/pagination.py +82 -0
- openstackclient/compute/v2/flavor.py +2 -16
- openstackclient/compute/v2/hypervisor.py +2 -21
- openstackclient/compute/v2/keypair.py +2 -9
- openstackclient/compute/v2/server.py +220 -131
- openstackclient/compute/v2/server_event.py +30 -19
- openstackclient/compute/v2/server_group.py +2 -23
- openstackclient/compute/v2/server_migration.py +2 -22
- openstackclient/compute/v2/usage.py +4 -6
- openstackclient/identity/v3/mapping.py +25 -3
- openstackclient/identity/v3/policy.py +3 -1
- openstackclient/image/v2/cache.py +218 -0
- openstackclient/image/v2/image.py +40 -17
- openstackclient/image/v2/metadef_namespaces.py +25 -21
- openstackclient/image/v2/metadef_objects.py +189 -0
- openstackclient/image/v2/metadef_properties.py +284 -0
- openstackclient/network/utils.py +100 -0
- openstackclient/network/v2/default_security_group_rule.py +418 -0
- openstackclient/network/v2/local_ip_association.py +1 -1
- openstackclient/network/v2/ndp_proxy.py +7 -3
- openstackclient/network/v2/network.py +2 -2
- openstackclient/network/v2/port.py +65 -19
- openstackclient/network/v2/security_group_rule.py +18 -111
- openstackclient/network/v2/subnet.py +1 -0
- openstackclient/object/v1/container.py +2 -12
- openstackclient/object/v1/object.py +2 -11
- openstackclient/tests/functional/base.py +13 -6
- openstackclient/tests/functional/identity/v3/test_role.py +11 -3
- openstackclient/tests/functional/network/v2/common.py +7 -1
- openstackclient/tests/functional/network/v2/test_address_group.py +2 -4
- openstackclient/tests/functional/network/v2/test_address_scope.py +0 -6
- openstackclient/tests/functional/network/v2/test_default_security_group_rule.py +67 -0
- openstackclient/tests/functional/network/v2/test_floating_ip.py +3 -6
- openstackclient/tests/functional/network/v2/test_ip_availability.py +3 -8
- openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py +3 -4
- openstackclient/tests/functional/network/v2/test_local_ip.py +2 -4
- openstackclient/tests/functional/network/v2/test_network.py +18 -17
- openstackclient/tests/functional/network/v2/test_network_agent.py +24 -21
- openstackclient/tests/functional/network/v2/test_network_flavor.py +0 -6
- openstackclient/tests/functional/network/v2/test_network_flavor_profile.py +0 -6
- openstackclient/tests/functional/network/v2/test_network_meter.py +6 -6
- openstackclient/tests/functional/network/v2/test_network_meter_rule.py +7 -8
- openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py +1 -3
- openstackclient/tests/functional/network/v2/test_network_qos_policy.py +4 -4
- openstackclient/tests/functional/network/v2/test_network_qos_rule.py +16 -20
- openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py +4 -4
- openstackclient/tests/functional/network/v2/test_network_rbac.py +1 -4
- openstackclient/tests/functional/network/v2/test_network_segment.py +7 -12
- openstackclient/tests/functional/network/v2/test_network_segment_range.py +3 -4
- openstackclient/tests/functional/network/v2/test_network_service_provider.py +2 -4
- openstackclient/tests/functional/network/v2/test_network_trunk.py +3 -3
- openstackclient/tests/functional/network/v2/test_port.py +2 -8
- openstackclient/tests/functional/network/v2/test_router.py +0 -6
- openstackclient/tests/functional/network/v2/test_security_group.py +1 -4
- openstackclient/tests/functional/network/v2/test_security_group_rule.py +1 -4
- openstackclient/tests/functional/network/v2/test_subnet.py +4 -22
- openstackclient/tests/functional/network/v2/test_subnet_pool.py +0 -6
- openstackclient/tests/unit/common/test_availability_zone.py +28 -30
- openstackclient/tests/unit/common/test_extension.py +1 -4
- openstackclient/tests/unit/common/test_limits.py +2 -4
- openstackclient/tests/unit/common/test_project_cleanup.py +3 -10
- openstackclient/tests/unit/common/test_quota.py +18 -24
- openstackclient/tests/unit/compute/v2/fakes.py +24 -11
- openstackclient/tests/unit/compute/v2/test_agent.py +1 -1
- openstackclient/tests/unit/compute/v2/test_aggregate.py +62 -72
- openstackclient/tests/unit/compute/v2/test_console.py +18 -30
- openstackclient/tests/unit/compute/v2/test_flavor.py +85 -89
- openstackclient/tests/unit/compute/v2/test_host.py +12 -19
- openstackclient/tests/unit/compute/v2/test_hypervisor.py +23 -25
- openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -6
- openstackclient/tests/unit/compute/v2/test_keypair.py +25 -39
- openstackclient/tests/unit/compute/v2/test_server.py +316 -365
- openstackclient/tests/unit/compute/v2/test_server_backup.py +5 -17
- openstackclient/tests/unit/compute/v2/test_server_event.py +23 -25
- openstackclient/tests/unit/compute/v2/test_server_group.py +41 -33
- openstackclient/tests/unit/compute/v2/test_server_image.py +6 -18
- openstackclient/tests/unit/compute/v2/test_server_migration.py +45 -45
- openstackclient/tests/unit/compute/v2/test_server_volume.py +15 -31
- openstackclient/tests/unit/compute/v2/test_service.py +51 -56
- openstackclient/tests/unit/compute/v2/test_usage.py +10 -13
- openstackclient/tests/unit/fakes.py +4 -0
- openstackclient/tests/unit/identity/v3/test_mappings.py +9 -4
- openstackclient/tests/unit/identity/v3/test_trust.py +0 -2
- openstackclient/tests/unit/image/v1/fakes.py +2 -1
- openstackclient/tests/unit/image/v1/test_image.py +1 -1
- openstackclient/tests/unit/image/v2/fakes.py +82 -0
- openstackclient/tests/unit/image/v2/test_cache.py +214 -0
- openstackclient/tests/unit/image/v2/test_image.py +62 -4
- openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +5 -19
- openstackclient/tests/unit/image/v2/test_metadef_objects.py +162 -0
- openstackclient/tests/unit/image/v2/test_metadef_properties.py +227 -0
- openstackclient/tests/unit/integ/cli/test_shell.py +0 -2
- openstackclient/tests/unit/network/test_common.py +3 -3
- openstackclient/tests/unit/network/v2/fakes.py +1 -0
- openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +1133 -0
- openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +5 -13
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +1 -9
- openstackclient/tests/unit/network/v2/test_network.py +33 -0
- openstackclient/tests/unit/network/v2/test_network_compute.py +5 -11
- openstackclient/tests/unit/network/v2/test_network_trunk.py +6 -8
- openstackclient/tests/unit/network/v2/test_port.py +83 -38
- openstackclient/tests/unit/network/v2/test_security_group_compute.py +7 -15
- openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +19 -27
- openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +3 -6
- openstackclient/tests/unit/network/v2/test_subnet.py +92 -0
- openstackclient/tests/unit/network/v2/test_subnet_pool.py +11 -13
- openstackclient/tests/unit/test_shell.py +1 -7
- openstackclient/tests/unit/utils.py +10 -4
- openstackclient/tests/unit/volume/v1/fakes.py +7 -1
- openstackclient/tests/unit/volume/v1/test_qos_specs.py +2 -2
- openstackclient/tests/unit/volume/v1/test_service.py +1 -1
- openstackclient/tests/unit/volume/v1/test_transfer_request.py +2 -2
- openstackclient/tests/unit/volume/v1/test_type.py +2 -4
- openstackclient/tests/unit/volume/v1/test_volume.py +5 -7
- openstackclient/tests/unit/volume/v1/test_volume_backup.py +4 -4
- openstackclient/tests/unit/volume/v2/fakes.py +32 -12
- openstackclient/tests/unit/volume/v2/test_backup_record.py +1 -1
- openstackclient/tests/unit/volume/v2/test_consistency_group.py +4 -6
- openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py +2 -4
- openstackclient/tests/unit/volume/v2/test_qos_specs.py +2 -2
- openstackclient/tests/unit/volume/v2/test_service.py +1 -1
- openstackclient/tests/unit/volume/v2/test_volume.py +78 -16
- openstackclient/tests/unit/volume/v2/test_volume_backend.py +10 -22
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +76 -89
- openstackclient/tests/unit/volume/v2/test_volume_host.py +1 -1
- openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +5 -7
- openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +4 -8
- openstackclient/tests/unit/volume/v2/test_volume_type.py +164 -24
- openstackclient/tests/unit/volume/v3/fakes.py +91 -15
- openstackclient/tests/unit/volume/v3/test_block_storage_cleanup.py +3 -7
- openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py +11 -31
- openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +6 -16
- openstackclient/tests/unit/volume/v3/test_block_storage_manage.py +219 -157
- openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py +32 -23
- openstackclient/tests/unit/volume/v3/test_volume.py +50 -48
- openstackclient/tests/unit/volume/v3/test_volume_attachment.py +17 -47
- openstackclient/tests/unit/volume/v3/test_volume_group.py +23 -65
- openstackclient/tests/unit/volume/v3/test_volume_group_snapshot.py +88 -77
- openstackclient/tests/unit/volume/v3/test_volume_group_type.py +14 -42
- openstackclient/tests/unit/volume/v3/test_volume_message.py +10 -28
- openstackclient/volume/v1/volume.py +2 -14
- openstackclient/volume/v2/volume.py +30 -15
- openstackclient/volume/v2/volume_backend.py +10 -18
- openstackclient/volume/v2/volume_backup.py +18 -15
- openstackclient/volume/v2/volume_snapshot.py +2 -12
- openstackclient/volume/v2/volume_type.py +211 -14
- openstackclient/volume/v3/block_storage_manage.py +72 -11
- openstackclient/volume/v3/block_storage_resource_filter.py +33 -11
- openstackclient/volume/v3/volume_attachment.py +2 -14
- openstackclient/volume/v3/volume_group_snapshot.py +27 -27
- openstackclient/volume/v3/volume_message.py +2 -13
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/AUTHORS +11 -0
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/METADATA +6 -5
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/RECORD +160 -151
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/entry_points.txt +23 -5
- python_openstackclient-6.5.0.dist-info/pbr.json +1 -0
- openstackclient/tests/unit/common/test_parseractions.py +0 -233
- python_openstackclient-6.3.0.dist-info/pbr.json +0 -1
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/LICENSE +0 -0
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/WHEEL +0 -0
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/top_level.txt +0 -0
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
from unittest import mock
|
|
16
16
|
from unittest.mock import call
|
|
17
17
|
|
|
18
|
+
from cinderclient import api_versions
|
|
18
19
|
from osc_lib.cli import format_columns
|
|
19
20
|
from osc_lib import exceptions
|
|
20
21
|
from osc_lib import utils
|
|
@@ -29,16 +30,14 @@ class TestType(volume_fakes.TestVolume):
|
|
|
29
30
|
def setUp(self):
|
|
30
31
|
super().setUp()
|
|
31
32
|
|
|
32
|
-
self.volume_types_mock = self.
|
|
33
|
+
self.volume_types_mock = self.volume_client.volume_types
|
|
33
34
|
self.volume_types_mock.reset_mock()
|
|
34
35
|
|
|
35
|
-
self.volume_type_access_mock =
|
|
36
|
-
self.app.client_manager.volume.volume_type_access
|
|
37
|
-
)
|
|
36
|
+
self.volume_type_access_mock = self.volume_client.volume_type_access
|
|
38
37
|
self.volume_type_access_mock.reset_mock()
|
|
39
38
|
|
|
40
39
|
self.volume_encryption_types_mock = (
|
|
41
|
-
self.
|
|
40
|
+
self.volume_client.volume_encryption_types
|
|
42
41
|
)
|
|
43
42
|
self.volume_encryption_types_mock.reset_mock()
|
|
44
43
|
|
|
@@ -47,18 +46,19 @@ class TestType(volume_fakes.TestVolume):
|
|
|
47
46
|
|
|
48
47
|
|
|
49
48
|
class TestTypeCreate(TestType):
|
|
50
|
-
project = identity_fakes.FakeProject.create_one_project()
|
|
51
|
-
columns = (
|
|
52
|
-
'description',
|
|
53
|
-
'id',
|
|
54
|
-
'is_public',
|
|
55
|
-
'name',
|
|
56
|
-
)
|
|
57
|
-
|
|
58
49
|
def setUp(self):
|
|
59
50
|
super().setUp()
|
|
60
51
|
|
|
61
|
-
self.new_volume_type = volume_fakes.create_one_volume_type(
|
|
52
|
+
self.new_volume_type = volume_fakes.create_one_volume_type(
|
|
53
|
+
methods={'set_keys': None},
|
|
54
|
+
)
|
|
55
|
+
self.project = identity_fakes.FakeProject.create_one_project()
|
|
56
|
+
self.columns = (
|
|
57
|
+
'description',
|
|
58
|
+
'id',
|
|
59
|
+
'is_public',
|
|
60
|
+
'name',
|
|
61
|
+
)
|
|
62
62
|
self.data = (
|
|
63
63
|
self.new_volume_type.description,
|
|
64
64
|
self.new_volume_type.id,
|
|
@@ -122,20 +122,65 @@ class TestTypeCreate(TestType):
|
|
|
122
122
|
self.assertEqual(self.columns, columns)
|
|
123
123
|
self.assertCountEqual(self.data, data)
|
|
124
124
|
|
|
125
|
-
def
|
|
125
|
+
def test_type_create_with_properties(self):
|
|
126
|
+
arglist = [
|
|
127
|
+
'--property',
|
|
128
|
+
'myprop=myvalue',
|
|
129
|
+
# this combination isn't viable server-side but is okay for testing
|
|
130
|
+
'--multiattach',
|
|
131
|
+
'--cacheable',
|
|
132
|
+
'--replicated',
|
|
133
|
+
'--availability-zone',
|
|
134
|
+
'az1',
|
|
135
|
+
self.new_volume_type.name,
|
|
136
|
+
]
|
|
137
|
+
verifylist = [
|
|
138
|
+
('properties', {'myprop': 'myvalue'}),
|
|
139
|
+
('multiattach', True),
|
|
140
|
+
('cacheable', True),
|
|
141
|
+
('replicated', True),
|
|
142
|
+
('availability_zones', ['az1']),
|
|
143
|
+
('name', self.new_volume_type.name),
|
|
144
|
+
]
|
|
145
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
146
|
+
|
|
147
|
+
columns, data = self.cmd.take_action(parsed_args)
|
|
148
|
+
self.volume_types_mock.create.assert_called_with(
|
|
149
|
+
self.new_volume_type.name, description=None
|
|
150
|
+
)
|
|
151
|
+
self.new_volume_type.set_keys.assert_called_once_with(
|
|
152
|
+
{
|
|
153
|
+
'myprop': 'myvalue',
|
|
154
|
+
'multiattach': '<is> True',
|
|
155
|
+
'cacheable': '<is> True',
|
|
156
|
+
'replication_enabled': '<is> True',
|
|
157
|
+
'RESKEY:availability_zones': 'az1',
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
self.columns += ('properties',)
|
|
162
|
+
self.data += (format_columns.DictColumn(None),)
|
|
163
|
+
|
|
164
|
+
self.assertEqual(self.columns, columns)
|
|
165
|
+
self.assertCountEqual(self.data, data)
|
|
166
|
+
|
|
167
|
+
def test_public_type_create_with_project_public(self):
|
|
126
168
|
arglist = [
|
|
127
169
|
'--project',
|
|
128
170
|
self.project.id,
|
|
129
171
|
self.new_volume_type.name,
|
|
130
172
|
]
|
|
131
173
|
verifylist = [
|
|
174
|
+
('is_public', None),
|
|
132
175
|
('project', self.project.id),
|
|
133
176
|
('name', self.new_volume_type.name),
|
|
134
177
|
]
|
|
135
178
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
136
179
|
|
|
137
180
|
self.assertRaises(
|
|
138
|
-
exceptions.CommandError,
|
|
181
|
+
exceptions.CommandError,
|
|
182
|
+
self.cmd.take_action,
|
|
183
|
+
parsed_args,
|
|
139
184
|
)
|
|
140
185
|
|
|
141
186
|
def test_type_create_with_encryption(self):
|
|
@@ -329,7 +374,9 @@ class TestTypeList(TestType):
|
|
|
329
374
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
330
375
|
|
|
331
376
|
columns, data = self.cmd.take_action(parsed_args)
|
|
332
|
-
self.volume_types_mock.list.assert_called_once_with(
|
|
377
|
+
self.volume_types_mock.list.assert_called_once_with(
|
|
378
|
+
search_opts={}, is_public=None
|
|
379
|
+
)
|
|
333
380
|
self.assertEqual(self.columns, columns)
|
|
334
381
|
self.assertCountEqual(self.data, list(data))
|
|
335
382
|
|
|
@@ -346,7 +393,9 @@ class TestTypeList(TestType):
|
|
|
346
393
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
347
394
|
|
|
348
395
|
columns, data = self.cmd.take_action(parsed_args)
|
|
349
|
-
self.volume_types_mock.list.assert_called_once_with(
|
|
396
|
+
self.volume_types_mock.list.assert_called_once_with(
|
|
397
|
+
search_opts={}, is_public=True
|
|
398
|
+
)
|
|
350
399
|
self.assertEqual(self.columns_long, columns)
|
|
351
400
|
self.assertCountEqual(self.data_long, list(data))
|
|
352
401
|
|
|
@@ -362,7 +411,9 @@ class TestTypeList(TestType):
|
|
|
362
411
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
363
412
|
|
|
364
413
|
columns, data = self.cmd.take_action(parsed_args)
|
|
365
|
-
self.volume_types_mock.list.assert_called_once_with(
|
|
414
|
+
self.volume_types_mock.list.assert_called_once_with(
|
|
415
|
+
search_opts={}, is_public=False
|
|
416
|
+
)
|
|
366
417
|
self.assertEqual(self.columns, columns)
|
|
367
418
|
self.assertCountEqual(self.data, list(data))
|
|
368
419
|
|
|
@@ -383,6 +434,77 @@ class TestTypeList(TestType):
|
|
|
383
434
|
self.assertEqual(self.columns, columns)
|
|
384
435
|
self.assertCountEqual(self.data_with_default_type, list(data))
|
|
385
436
|
|
|
437
|
+
def test_type_list_with_properties(self):
|
|
438
|
+
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
|
439
|
+
'3.52'
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
arglist = [
|
|
443
|
+
"--property",
|
|
444
|
+
"foo=bar",
|
|
445
|
+
"--multiattach",
|
|
446
|
+
"--cacheable",
|
|
447
|
+
"--replicated",
|
|
448
|
+
"--availability-zone",
|
|
449
|
+
"az1",
|
|
450
|
+
]
|
|
451
|
+
verifylist = [
|
|
452
|
+
("encryption_type", False),
|
|
453
|
+
("long", False),
|
|
454
|
+
("is_public", None),
|
|
455
|
+
("default", False),
|
|
456
|
+
("properties", {"foo": "bar"}),
|
|
457
|
+
("multiattach", True),
|
|
458
|
+
("cacheable", True),
|
|
459
|
+
("replicated", True),
|
|
460
|
+
("availability_zones", ["az1"]),
|
|
461
|
+
]
|
|
462
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
463
|
+
|
|
464
|
+
columns, data = self.cmd.take_action(parsed_args)
|
|
465
|
+
self.volume_types_mock.list.assert_called_once_with(
|
|
466
|
+
search_opts={
|
|
467
|
+
"extra_specs": {
|
|
468
|
+
"foo": "bar",
|
|
469
|
+
"multiattach": "<is> True",
|
|
470
|
+
"cacheable": "<is> True",
|
|
471
|
+
"replication_enabled": "<is> True",
|
|
472
|
+
"RESKEY:availability_zones": "az1",
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
is_public=None,
|
|
476
|
+
)
|
|
477
|
+
self.assertEqual(self.columns, columns)
|
|
478
|
+
self.assertCountEqual(self.data, list(data))
|
|
479
|
+
|
|
480
|
+
def test_type_list_with_properties_pre_v352(self):
|
|
481
|
+
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
|
482
|
+
'3.51'
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
arglist = [
|
|
486
|
+
"--property",
|
|
487
|
+
"foo=bar",
|
|
488
|
+
]
|
|
489
|
+
verifylist = [
|
|
490
|
+
("encryption_type", False),
|
|
491
|
+
("long", False),
|
|
492
|
+
("is_public", None),
|
|
493
|
+
("default", False),
|
|
494
|
+
("properties", {"foo": "bar"}),
|
|
495
|
+
]
|
|
496
|
+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
497
|
+
|
|
498
|
+
exc = self.assertRaises(
|
|
499
|
+
exceptions.CommandError,
|
|
500
|
+
self.cmd.take_action,
|
|
501
|
+
parsed_args,
|
|
502
|
+
)
|
|
503
|
+
self.assertIn(
|
|
504
|
+
'--os-volume-api-version 3.52 or greater is required',
|
|
505
|
+
str(exc),
|
|
506
|
+
)
|
|
507
|
+
|
|
386
508
|
def test_type_list_with_encryption(self):
|
|
387
509
|
encryption_type = volume_fakes.create_one_encryption_volume_type(
|
|
388
510
|
attrs={'volume_type_id': self.volume_types[0].id},
|
|
@@ -428,7 +550,9 @@ class TestTypeList(TestType):
|
|
|
428
550
|
|
|
429
551
|
columns, data = self.cmd.take_action(parsed_args)
|
|
430
552
|
self.volume_encryption_types_mock.list.assert_called_once_with()
|
|
431
|
-
self.volume_types_mock.list.assert_called_once_with(
|
|
553
|
+
self.volume_types_mock.list.assert_called_once_with(
|
|
554
|
+
search_opts={}, is_public=None
|
|
555
|
+
)
|
|
432
556
|
self.assertEqual(encryption_columns, columns)
|
|
433
557
|
self.assertCountEqual(encryption_data, list(data))
|
|
434
558
|
|
|
@@ -461,7 +585,7 @@ class TestTypeSet(TestType):
|
|
|
461
585
|
verifylist = [
|
|
462
586
|
('name', 'new_name'),
|
|
463
587
|
('description', 'new_description'),
|
|
464
|
-
('
|
|
588
|
+
('properties', None),
|
|
465
589
|
('volume_type', self.volume_type.id),
|
|
466
590
|
]
|
|
467
591
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
@@ -486,12 +610,22 @@ class TestTypeSet(TestType):
|
|
|
486
610
|
arglist = [
|
|
487
611
|
'--property',
|
|
488
612
|
'myprop=myvalue',
|
|
613
|
+
# this combination isn't viable server-side but is okay for testing
|
|
614
|
+
'--multiattach',
|
|
615
|
+
'--cacheable',
|
|
616
|
+
'--replicated',
|
|
617
|
+
'--availability-zone',
|
|
618
|
+
'az1',
|
|
489
619
|
self.volume_type.id,
|
|
490
620
|
]
|
|
491
621
|
verifylist = [
|
|
492
622
|
('name', None),
|
|
493
623
|
('description', None),
|
|
494
|
-
('
|
|
624
|
+
('properties', {'myprop': 'myvalue'}),
|
|
625
|
+
('multiattach', True),
|
|
626
|
+
('cacheable', True),
|
|
627
|
+
('replicated', True),
|
|
628
|
+
('availability_zones', ['az1']),
|
|
495
629
|
('volume_type', self.volume_type.id),
|
|
496
630
|
]
|
|
497
631
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
@@ -500,7 +634,13 @@ class TestTypeSet(TestType):
|
|
|
500
634
|
self.assertIsNone(result)
|
|
501
635
|
|
|
502
636
|
self.volume_type.set_keys.assert_called_once_with(
|
|
503
|
-
{
|
|
637
|
+
{
|
|
638
|
+
'myprop': 'myvalue',
|
|
639
|
+
'multiattach': '<is> True',
|
|
640
|
+
'cacheable': '<is> True',
|
|
641
|
+
'replication_enabled': '<is> True',
|
|
642
|
+
'RESKEY:availability_zones': 'az1',
|
|
643
|
+
}
|
|
504
644
|
)
|
|
505
645
|
self.volume_type_access_mock.add_project_access.assert_not_called()
|
|
506
646
|
self.volume_encryption_types_mock.update.assert_not_called()
|
|
@@ -859,7 +999,7 @@ class TestTypeUnset(TestType):
|
|
|
859
999
|
self.volume_type.id,
|
|
860
1000
|
]
|
|
861
1001
|
verifylist = [
|
|
862
|
-
('
|
|
1002
|
+
('properties', ['property', 'multi_property']),
|
|
863
1003
|
('volume_type', self.volume_type.id),
|
|
864
1004
|
]
|
|
865
1005
|
|
|
@@ -15,11 +15,12 @@ from unittest import mock
|
|
|
15
15
|
import uuid
|
|
16
16
|
|
|
17
17
|
from cinderclient import api_versions
|
|
18
|
+
from openstack.block_storage.v3 import _proxy
|
|
18
19
|
from openstack.block_storage.v3 import availability_zone as _availability_zone
|
|
19
|
-
from openstack.block_storage.v3 import block_storage_summary as _summary
|
|
20
20
|
from openstack.block_storage.v3 import extension as _extension
|
|
21
|
+
from openstack.block_storage.v3 import resource_filter as _filters
|
|
22
|
+
from openstack.block_storage.v3 import volume as _volume
|
|
21
23
|
|
|
22
|
-
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
|
|
23
24
|
from openstackclient.tests.unit import fakes
|
|
24
25
|
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
|
|
25
26
|
from openstackclient.tests.unit import utils
|
|
@@ -32,6 +33,8 @@ class FakeVolumeClient:
|
|
|
32
33
|
self.management_url = kwargs['endpoint']
|
|
33
34
|
self.api_version = api_versions.APIVersion('3.0')
|
|
34
35
|
|
|
36
|
+
self.availability_zones = mock.Mock()
|
|
37
|
+
self.availability_zones.resource_class = fakes.FakeResource(None, {})
|
|
35
38
|
self.attachments = mock.Mock()
|
|
36
39
|
self.attachments.resource_class = fakes.FakeResource(None, {})
|
|
37
40
|
self.clusters = mock.Mock()
|
|
@@ -44,10 +47,16 @@ class FakeVolumeClient:
|
|
|
44
47
|
self.group_types.resource_class = fakes.FakeResource(None, {})
|
|
45
48
|
self.messages = mock.Mock()
|
|
46
49
|
self.messages.resource_class = fakes.FakeResource(None, {})
|
|
50
|
+
self.quota_classes = mock.Mock()
|
|
51
|
+
self.quota_classes.resource_class = fakes.FakeResource(None, {})
|
|
52
|
+
self.quotas = mock.Mock()
|
|
53
|
+
self.quotas.resource_class = fakes.FakeResource(None, {})
|
|
47
54
|
self.resource_filters = mock.Mock()
|
|
48
55
|
self.resource_filters.resource_class = fakes.FakeResource(None, {})
|
|
49
56
|
self.volumes = mock.Mock()
|
|
50
57
|
self.volumes.resource_class = fakes.FakeResource(None, {})
|
|
58
|
+
self.volume_snapshots = mock.Mock()
|
|
59
|
+
self.volume_snapshots.resource_class = fakes.FakeResource(None, {})
|
|
51
60
|
self.volume_types = mock.Mock()
|
|
52
61
|
self.volume_types.resource_class = fakes.FakeResource(None, {})
|
|
53
62
|
self.services = mock.Mock()
|
|
@@ -56,23 +65,45 @@ class FakeVolumeClient:
|
|
|
56
65
|
self.workers.resource_class = fakes.FakeResource(None, {})
|
|
57
66
|
|
|
58
67
|
|
|
59
|
-
class
|
|
68
|
+
class FakeClientMixin:
|
|
60
69
|
def setUp(self):
|
|
61
70
|
super().setUp()
|
|
62
71
|
|
|
63
72
|
self.app.client_manager.volume = FakeVolumeClient(
|
|
64
73
|
endpoint=fakes.AUTH_URL, token=fakes.AUTH_TOKEN
|
|
65
74
|
)
|
|
75
|
+
self.volume_client = self.app.client_manager.volume
|
|
76
|
+
|
|
77
|
+
# TODO(stephenfin): Rename to 'volume_client' once all commands are
|
|
78
|
+
# migrated to SDK
|
|
79
|
+
self.app.client_manager.sdk_connection.volume = mock.Mock(
|
|
80
|
+
spec=_proxy.Proxy,
|
|
81
|
+
)
|
|
82
|
+
self.volume_sdk_client = self.app.client_manager.sdk_connection.volume
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class TestVolume(FakeClientMixin, utils.TestCommand):
|
|
86
|
+
def setUp(self):
|
|
87
|
+
super().setUp()
|
|
88
|
+
|
|
66
89
|
self.app.client_manager.identity = identity_fakes.FakeIdentityv3Client(
|
|
67
90
|
endpoint=fakes.AUTH_URL, token=fakes.AUTH_TOKEN
|
|
68
91
|
)
|
|
92
|
+
|
|
93
|
+
# avoid circular imports
|
|
94
|
+
from openstackclient.tests.unit.compute.v2 import (
|
|
95
|
+
fakes as compute_fakes,
|
|
96
|
+
)
|
|
97
|
+
|
|
69
98
|
self.app.client_manager.compute = compute_fakes.FakeComputev2Client(
|
|
70
99
|
endpoint=fakes.AUTH_URL,
|
|
71
100
|
token=fakes.AUTH_TOKEN,
|
|
72
101
|
)
|
|
102
|
+
self.compute_client = self.app.client_manager.compute
|
|
73
103
|
|
|
74
104
|
|
|
75
105
|
# TODO(stephenfin): Check if the responses are actually the same
|
|
106
|
+
create_one_snapshot = volume_v2_fakes.create_one_snapshot
|
|
76
107
|
create_one_volume = volume_v2_fakes.create_one_volume
|
|
77
108
|
create_one_volume_type = volume_v2_fakes.create_one_volume_type
|
|
78
109
|
|
|
@@ -217,7 +248,7 @@ def create_one_resource_filter(attrs=None):
|
|
|
217
248
|
# Overwrite default attributes if there are some attributes set
|
|
218
249
|
resource_filter_info.update(attrs)
|
|
219
250
|
|
|
220
|
-
return
|
|
251
|
+
return _filters.ResourceFilter(**resource_filter_info)
|
|
221
252
|
|
|
222
253
|
|
|
223
254
|
def create_resource_filters(attrs=None, count=2):
|
|
@@ -234,6 +265,62 @@ def create_resource_filters(attrs=None, count=2):
|
|
|
234
265
|
return resource_filters
|
|
235
266
|
|
|
236
267
|
|
|
268
|
+
def create_one_sdk_volume(attrs=None):
|
|
269
|
+
"""Create a fake volume.
|
|
270
|
+
|
|
271
|
+
:param dict attrs:
|
|
272
|
+
A dictionary with all attributes of volume
|
|
273
|
+
:return:
|
|
274
|
+
A FakeResource object with id, name, status, etc.
|
|
275
|
+
"""
|
|
276
|
+
attrs = attrs or {}
|
|
277
|
+
|
|
278
|
+
# Set default attribute
|
|
279
|
+
volume_info = {
|
|
280
|
+
'id': 'volume-id' + uuid.uuid4().hex,
|
|
281
|
+
'name': 'volume-name' + uuid.uuid4().hex,
|
|
282
|
+
'description': 'description' + uuid.uuid4().hex,
|
|
283
|
+
'status': random.choice(['available', 'in_use']),
|
|
284
|
+
'size': random.randint(1, 20),
|
|
285
|
+
'volume_type': random.choice(['fake_lvmdriver-1', 'fake_lvmdriver-2']),
|
|
286
|
+
'bootable': random.choice(['true', 'false']),
|
|
287
|
+
'metadata': {
|
|
288
|
+
'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
|
|
289
|
+
'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
|
|
290
|
+
'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
|
|
291
|
+
},
|
|
292
|
+
'snapshot_id': random.randint(1, 5),
|
|
293
|
+
'availability_zone': 'zone' + uuid.uuid4().hex,
|
|
294
|
+
'attachments': [
|
|
295
|
+
{
|
|
296
|
+
'device': '/dev/' + uuid.uuid4().hex,
|
|
297
|
+
'server_id': uuid.uuid4().hex,
|
|
298
|
+
},
|
|
299
|
+
],
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
# Overwrite default attributes if there are some attributes set
|
|
303
|
+
volume_info.update(attrs)
|
|
304
|
+
return _volume.Volume(**volume_info)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def create_sdk_volumes(attrs=None, count=2):
|
|
308
|
+
"""Create multiple fake volumes.
|
|
309
|
+
|
|
310
|
+
:param dict attrs:
|
|
311
|
+
A dictionary with all attributes of volume
|
|
312
|
+
:param Integer count:
|
|
313
|
+
The number of volumes to be faked
|
|
314
|
+
:return:
|
|
315
|
+
A list of FakeResource objects
|
|
316
|
+
"""
|
|
317
|
+
volumes = []
|
|
318
|
+
for n in range(0, count):
|
|
319
|
+
volumes.append(create_one_sdk_volume(attrs))
|
|
320
|
+
|
|
321
|
+
return volumes
|
|
322
|
+
|
|
323
|
+
|
|
237
324
|
def create_one_volume_group(attrs=None):
|
|
238
325
|
"""Create a fake group.
|
|
239
326
|
|
|
@@ -605,14 +692,3 @@ def create_snapshot_manage_list_records(count=2):
|
|
|
605
692
|
)
|
|
606
693
|
|
|
607
694
|
return snapshot_manage_list
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
def get_one_block_storage_summary(total_size, metadata=None):
|
|
611
|
-
summary_dict = {
|
|
612
|
-
'total_count': 2,
|
|
613
|
-
'total_size': total_size,
|
|
614
|
-
}
|
|
615
|
-
if metadata:
|
|
616
|
-
summary_dict['metadata'] = metadata
|
|
617
|
-
block_storage_summary = _summary.BlockStorageSummary(**summary_dict)
|
|
618
|
-
return block_storage_summary
|
|
@@ -24,7 +24,7 @@ class TestBlockStorage(volume_fakes.TestVolume):
|
|
|
24
24
|
super().setUp()
|
|
25
25
|
|
|
26
26
|
# Get a shortcut to the BlockStorageWorkerManager Mock
|
|
27
|
-
self.worker_mock = self.
|
|
27
|
+
self.worker_mock = self.volume_client.workers
|
|
28
28
|
self.worker_mock.reset_mock()
|
|
29
29
|
|
|
30
30
|
|
|
@@ -40,9 +40,7 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
|
|
40
40
|
self.cmd = block_storage_cleanup.BlockStorageCleanup(self.app, None)
|
|
41
41
|
|
|
42
42
|
def test_cleanup(self):
|
|
43
|
-
self.
|
|
44
|
-
'3.24'
|
|
45
|
-
)
|
|
43
|
+
self.volume_client.api_version = api_versions.APIVersion('3.24')
|
|
46
44
|
|
|
47
45
|
arglist = []
|
|
48
46
|
verifylist = [
|
|
@@ -98,9 +96,7 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
|
|
98
96
|
)
|
|
99
97
|
|
|
100
98
|
def test_cleanup_with_args(self):
|
|
101
|
-
self.
|
|
102
|
-
'3.24'
|
|
103
|
-
)
|
|
99
|
+
self.volume_client.api_version = api_versions.APIVersion('3.24')
|
|
104
100
|
|
|
105
101
|
fake_cluster = 'fake-cluster'
|
|
106
102
|
fake_host = 'fake-host'
|
|
@@ -22,7 +22,7 @@ class TestBlockStorageCluster(volume_fakes.TestVolume):
|
|
|
22
22
|
super().setUp()
|
|
23
23
|
|
|
24
24
|
# Get a shortcut to the BlockStorageClusterManager Mock
|
|
25
|
-
self.cluster_mock = self.
|
|
25
|
+
self.cluster_mock = self.volume_client.clusters
|
|
26
26
|
self.cluster_mock.reset_mock()
|
|
27
27
|
|
|
28
28
|
|
|
@@ -41,9 +41,7 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
def test_cluster_list(self):
|
|
44
|
-
self.
|
|
45
|
-
'3.7'
|
|
46
|
-
)
|
|
44
|
+
self.volume_client.api_version = api_versions.APIVersion('3.7')
|
|
47
45
|
|
|
48
46
|
arglist = []
|
|
49
47
|
verifylist = [
|
|
@@ -84,9 +82,7 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
|
|
84
82
|
)
|
|
85
83
|
|
|
86
84
|
def test_cluster_list_with_full_options(self):
|
|
87
|
-
self.
|
|
88
|
-
'3.7'
|
|
89
|
-
)
|
|
85
|
+
self.volume_client.api_version = api_versions.APIVersion('3.7')
|
|
90
86
|
|
|
91
87
|
arglist = [
|
|
92
88
|
'--cluster',
|
|
@@ -156,9 +152,7 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
|
|
156
152
|
)
|
|
157
153
|
|
|
158
154
|
def test_cluster_list_pre_v37(self):
|
|
159
|
-
self.
|
|
160
|
-
'3.6'
|
|
161
|
-
)
|
|
155
|
+
self.volume_client.api_version = api_versions.APIVersion('3.6')
|
|
162
156
|
|
|
163
157
|
arglist = []
|
|
164
158
|
verifylist = [
|
|
@@ -221,9 +215,7 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
|
|
221
215
|
self.cmd = block_storage_cluster.SetBlockStorageCluster(self.app, None)
|
|
222
216
|
|
|
223
217
|
def test_cluster_set(self):
|
|
224
|
-
self.
|
|
225
|
-
'3.7'
|
|
226
|
-
)
|
|
218
|
+
self.volume_client.api_version = api_versions.APIVersion('3.7')
|
|
227
219
|
|
|
228
220
|
arglist = [
|
|
229
221
|
'--enable',
|
|
@@ -250,9 +242,7 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
|
|
250
242
|
)
|
|
251
243
|
|
|
252
244
|
def test_cluster_set_disable_with_reason(self):
|
|
253
|
-
self.
|
|
254
|
-
'3.7'
|
|
255
|
-
)
|
|
245
|
+
self.volume_client.api_version = api_versions.APIVersion('3.7')
|
|
256
246
|
|
|
257
247
|
arglist = [
|
|
258
248
|
'--binary',
|
|
@@ -282,9 +272,7 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
|
|
282
272
|
)
|
|
283
273
|
|
|
284
274
|
def test_cluster_set_only_with_disable_reason(self):
|
|
285
|
-
self.
|
|
286
|
-
'3.7'
|
|
287
|
-
)
|
|
275
|
+
self.volume_client.api_version = api_versions.APIVersion('3.7')
|
|
288
276
|
|
|
289
277
|
arglist = [
|
|
290
278
|
'--disable-reason',
|
|
@@ -307,9 +295,7 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
|
|
307
295
|
)
|
|
308
296
|
|
|
309
297
|
def test_cluster_set_enable_with_disable_reason(self):
|
|
310
|
-
self.
|
|
311
|
-
'3.7'
|
|
312
|
-
)
|
|
298
|
+
self.volume_client.api_version = api_versions.APIVersion('3.7')
|
|
313
299
|
|
|
314
300
|
arglist = [
|
|
315
301
|
'--enable',
|
|
@@ -333,9 +319,7 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
|
|
333
319
|
)
|
|
334
320
|
|
|
335
321
|
def test_cluster_set_pre_v37(self):
|
|
336
|
-
self.
|
|
337
|
-
'3.6'
|
|
338
|
-
)
|
|
322
|
+
self.volume_client.api_version = api_versions.APIVersion('3.6')
|
|
339
323
|
|
|
340
324
|
arglist = [
|
|
341
325
|
'--enable',
|
|
@@ -401,9 +385,7 @@ class TestBlockStorageClusterShow(TestBlockStorageCluster):
|
|
|
401
385
|
)
|
|
402
386
|
|
|
403
387
|
def test_cluster_show(self):
|
|
404
|
-
self.
|
|
405
|
-
'3.7'
|
|
406
|
-
)
|
|
388
|
+
self.volume_client.api_version = api_versions.APIVersion('3.7')
|
|
407
389
|
|
|
408
390
|
arglist = [
|
|
409
391
|
'--binary',
|
|
@@ -427,9 +409,7 @@ class TestBlockStorageClusterShow(TestBlockStorageCluster):
|
|
|
427
409
|
)
|
|
428
410
|
|
|
429
411
|
def test_cluster_show_pre_v37(self):
|
|
430
|
-
self.
|
|
431
|
-
'3.6'
|
|
432
|
-
)
|
|
412
|
+
self.volume_client.api_version = api_versions.APIVersion('3.6')
|
|
433
413
|
|
|
434
414
|
arglist = [
|
|
435
415
|
'--binary',
|
|
@@ -26,7 +26,7 @@ class TestService(volume_fakes.TestVolume):
|
|
|
26
26
|
super().setUp()
|
|
27
27
|
|
|
28
28
|
# Get a shortcut to the ServiceManager Mock
|
|
29
|
-
self.service_mock = self.
|
|
29
|
+
self.service_mock = self.volume_client.services
|
|
30
30
|
self.service_mock.reset_mock()
|
|
31
31
|
|
|
32
32
|
|
|
@@ -42,9 +42,7 @@ class TestBlockStorageLogLevelList(TestService):
|
|
|
42
42
|
self.cmd = service.BlockStorageLogLevelList(self.app, None)
|
|
43
43
|
|
|
44
44
|
def test_block_storage_log_level_list(self):
|
|
45
|
-
self.
|
|
46
|
-
'3.32'
|
|
47
|
-
)
|
|
45
|
+
self.volume_client.api_version = api_versions.APIVersion('3.32')
|
|
48
46
|
arglist = [
|
|
49
47
|
'--host',
|
|
50
48
|
self.service_log.host,
|
|
@@ -115,9 +113,7 @@ class TestBlockStorageLogLevelList(TestService):
|
|
|
115
113
|
)
|
|
116
114
|
|
|
117
115
|
def test_block_storage_log_level_list_invalid_service_name(self):
|
|
118
|
-
self.
|
|
119
|
-
'3.32'
|
|
120
|
-
)
|
|
116
|
+
self.volume_client.api_version = api_versions.APIVersion('3.32')
|
|
121
117
|
arglist = [
|
|
122
118
|
'--host',
|
|
123
119
|
self.service_log.host,
|
|
@@ -152,9 +148,7 @@ class TestBlockStorageLogLevelSet(TestService):
|
|
|
152
148
|
self.cmd = service.BlockStorageLogLevelSet(self.app, None)
|
|
153
149
|
|
|
154
150
|
def test_block_storage_log_level_set(self):
|
|
155
|
-
self.
|
|
156
|
-
'3.32'
|
|
157
|
-
)
|
|
151
|
+
self.volume_client.api_version = api_versions.APIVersion('3.32')
|
|
158
152
|
arglist = [
|
|
159
153
|
'ERROR',
|
|
160
154
|
'--host',
|
|
@@ -208,9 +202,7 @@ class TestBlockStorageLogLevelSet(TestService):
|
|
|
208
202
|
)
|
|
209
203
|
|
|
210
204
|
def test_block_storage_log_level_set_invalid_service_name(self):
|
|
211
|
-
self.
|
|
212
|
-
'3.32'
|
|
213
|
-
)
|
|
205
|
+
self.volume_client.api_version = api_versions.APIVersion('3.32')
|
|
214
206
|
arglist = [
|
|
215
207
|
'ERROR',
|
|
216
208
|
'--host',
|
|
@@ -237,9 +229,7 @@ class TestBlockStorageLogLevelSet(TestService):
|
|
|
237
229
|
|
|
238
230
|
@ddt.data('WARNING', 'info', 'Error', 'debuG', 'fake-log-level')
|
|
239
231
|
def test_block_storage_log_level_set_log_level(self, log_level):
|
|
240
|
-
self.
|
|
241
|
-
'3.32'
|
|
242
|
-
)
|
|
232
|
+
self.volume_client.api_version = api_versions.APIVersion('3.32')
|
|
243
233
|
arglist = [
|
|
244
234
|
log_level,
|
|
245
235
|
'--host',
|