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.
Files changed (162) hide show
  1. openstackclient/common/availability_zone.py +4 -4
  2. openstackclient/common/pagination.py +82 -0
  3. openstackclient/compute/v2/flavor.py +2 -16
  4. openstackclient/compute/v2/hypervisor.py +2 -21
  5. openstackclient/compute/v2/keypair.py +2 -9
  6. openstackclient/compute/v2/server.py +220 -131
  7. openstackclient/compute/v2/server_event.py +30 -19
  8. openstackclient/compute/v2/server_group.py +2 -23
  9. openstackclient/compute/v2/server_migration.py +2 -22
  10. openstackclient/compute/v2/usage.py +4 -6
  11. openstackclient/identity/v3/mapping.py +25 -3
  12. openstackclient/identity/v3/policy.py +3 -1
  13. openstackclient/image/v2/cache.py +218 -0
  14. openstackclient/image/v2/image.py +40 -17
  15. openstackclient/image/v2/metadef_namespaces.py +25 -21
  16. openstackclient/image/v2/metadef_objects.py +189 -0
  17. openstackclient/image/v2/metadef_properties.py +284 -0
  18. openstackclient/network/utils.py +100 -0
  19. openstackclient/network/v2/default_security_group_rule.py +418 -0
  20. openstackclient/network/v2/local_ip_association.py +1 -1
  21. openstackclient/network/v2/ndp_proxy.py +7 -3
  22. openstackclient/network/v2/network.py +2 -2
  23. openstackclient/network/v2/port.py +65 -19
  24. openstackclient/network/v2/security_group_rule.py +18 -111
  25. openstackclient/network/v2/subnet.py +1 -0
  26. openstackclient/object/v1/container.py +2 -12
  27. openstackclient/object/v1/object.py +2 -11
  28. openstackclient/tests/functional/base.py +13 -6
  29. openstackclient/tests/functional/identity/v3/test_role.py +11 -3
  30. openstackclient/tests/functional/network/v2/common.py +7 -1
  31. openstackclient/tests/functional/network/v2/test_address_group.py +2 -4
  32. openstackclient/tests/functional/network/v2/test_address_scope.py +0 -6
  33. openstackclient/tests/functional/network/v2/test_default_security_group_rule.py +67 -0
  34. openstackclient/tests/functional/network/v2/test_floating_ip.py +3 -6
  35. openstackclient/tests/functional/network/v2/test_ip_availability.py +3 -8
  36. openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py +3 -4
  37. openstackclient/tests/functional/network/v2/test_local_ip.py +2 -4
  38. openstackclient/tests/functional/network/v2/test_network.py +18 -17
  39. openstackclient/tests/functional/network/v2/test_network_agent.py +24 -21
  40. openstackclient/tests/functional/network/v2/test_network_flavor.py +0 -6
  41. openstackclient/tests/functional/network/v2/test_network_flavor_profile.py +0 -6
  42. openstackclient/tests/functional/network/v2/test_network_meter.py +6 -6
  43. openstackclient/tests/functional/network/v2/test_network_meter_rule.py +7 -8
  44. openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py +1 -3
  45. openstackclient/tests/functional/network/v2/test_network_qos_policy.py +4 -4
  46. openstackclient/tests/functional/network/v2/test_network_qos_rule.py +16 -20
  47. openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py +4 -4
  48. openstackclient/tests/functional/network/v2/test_network_rbac.py +1 -4
  49. openstackclient/tests/functional/network/v2/test_network_segment.py +7 -12
  50. openstackclient/tests/functional/network/v2/test_network_segment_range.py +3 -4
  51. openstackclient/tests/functional/network/v2/test_network_service_provider.py +2 -4
  52. openstackclient/tests/functional/network/v2/test_network_trunk.py +3 -3
  53. openstackclient/tests/functional/network/v2/test_port.py +2 -8
  54. openstackclient/tests/functional/network/v2/test_router.py +0 -6
  55. openstackclient/tests/functional/network/v2/test_security_group.py +1 -4
  56. openstackclient/tests/functional/network/v2/test_security_group_rule.py +1 -4
  57. openstackclient/tests/functional/network/v2/test_subnet.py +4 -22
  58. openstackclient/tests/functional/network/v2/test_subnet_pool.py +0 -6
  59. openstackclient/tests/unit/common/test_availability_zone.py +28 -30
  60. openstackclient/tests/unit/common/test_extension.py +1 -4
  61. openstackclient/tests/unit/common/test_limits.py +2 -4
  62. openstackclient/tests/unit/common/test_project_cleanup.py +3 -10
  63. openstackclient/tests/unit/common/test_quota.py +18 -24
  64. openstackclient/tests/unit/compute/v2/fakes.py +24 -11
  65. openstackclient/tests/unit/compute/v2/test_agent.py +1 -1
  66. openstackclient/tests/unit/compute/v2/test_aggregate.py +62 -72
  67. openstackclient/tests/unit/compute/v2/test_console.py +18 -30
  68. openstackclient/tests/unit/compute/v2/test_flavor.py +85 -89
  69. openstackclient/tests/unit/compute/v2/test_host.py +12 -19
  70. openstackclient/tests/unit/compute/v2/test_hypervisor.py +23 -25
  71. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -6
  72. openstackclient/tests/unit/compute/v2/test_keypair.py +25 -39
  73. openstackclient/tests/unit/compute/v2/test_server.py +316 -365
  74. openstackclient/tests/unit/compute/v2/test_server_backup.py +5 -17
  75. openstackclient/tests/unit/compute/v2/test_server_event.py +23 -25
  76. openstackclient/tests/unit/compute/v2/test_server_group.py +41 -33
  77. openstackclient/tests/unit/compute/v2/test_server_image.py +6 -18
  78. openstackclient/tests/unit/compute/v2/test_server_migration.py +45 -45
  79. openstackclient/tests/unit/compute/v2/test_server_volume.py +15 -31
  80. openstackclient/tests/unit/compute/v2/test_service.py +51 -56
  81. openstackclient/tests/unit/compute/v2/test_usage.py +10 -13
  82. openstackclient/tests/unit/fakes.py +4 -0
  83. openstackclient/tests/unit/identity/v3/test_mappings.py +9 -4
  84. openstackclient/tests/unit/identity/v3/test_trust.py +0 -2
  85. openstackclient/tests/unit/image/v1/fakes.py +2 -1
  86. openstackclient/tests/unit/image/v1/test_image.py +1 -1
  87. openstackclient/tests/unit/image/v2/fakes.py +82 -0
  88. openstackclient/tests/unit/image/v2/test_cache.py +214 -0
  89. openstackclient/tests/unit/image/v2/test_image.py +62 -4
  90. openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +5 -19
  91. openstackclient/tests/unit/image/v2/test_metadef_objects.py +162 -0
  92. openstackclient/tests/unit/image/v2/test_metadef_properties.py +227 -0
  93. openstackclient/tests/unit/integ/cli/test_shell.py +0 -2
  94. openstackclient/tests/unit/network/test_common.py +3 -3
  95. openstackclient/tests/unit/network/v2/fakes.py +1 -0
  96. openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +1133 -0
  97. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +5 -13
  98. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +1 -9
  99. openstackclient/tests/unit/network/v2/test_network.py +33 -0
  100. openstackclient/tests/unit/network/v2/test_network_compute.py +5 -11
  101. openstackclient/tests/unit/network/v2/test_network_trunk.py +6 -8
  102. openstackclient/tests/unit/network/v2/test_port.py +83 -38
  103. openstackclient/tests/unit/network/v2/test_security_group_compute.py +7 -15
  104. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +19 -27
  105. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +3 -6
  106. openstackclient/tests/unit/network/v2/test_subnet.py +92 -0
  107. openstackclient/tests/unit/network/v2/test_subnet_pool.py +11 -13
  108. openstackclient/tests/unit/test_shell.py +1 -7
  109. openstackclient/tests/unit/utils.py +10 -4
  110. openstackclient/tests/unit/volume/v1/fakes.py +7 -1
  111. openstackclient/tests/unit/volume/v1/test_qos_specs.py +2 -2
  112. openstackclient/tests/unit/volume/v1/test_service.py +1 -1
  113. openstackclient/tests/unit/volume/v1/test_transfer_request.py +2 -2
  114. openstackclient/tests/unit/volume/v1/test_type.py +2 -4
  115. openstackclient/tests/unit/volume/v1/test_volume.py +5 -7
  116. openstackclient/tests/unit/volume/v1/test_volume_backup.py +4 -4
  117. openstackclient/tests/unit/volume/v2/fakes.py +32 -12
  118. openstackclient/tests/unit/volume/v2/test_backup_record.py +1 -1
  119. openstackclient/tests/unit/volume/v2/test_consistency_group.py +4 -6
  120. openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py +2 -4
  121. openstackclient/tests/unit/volume/v2/test_qos_specs.py +2 -2
  122. openstackclient/tests/unit/volume/v2/test_service.py +1 -1
  123. openstackclient/tests/unit/volume/v2/test_volume.py +78 -16
  124. openstackclient/tests/unit/volume/v2/test_volume_backend.py +10 -22
  125. openstackclient/tests/unit/volume/v2/test_volume_backup.py +76 -89
  126. openstackclient/tests/unit/volume/v2/test_volume_host.py +1 -1
  127. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +5 -7
  128. openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +4 -8
  129. openstackclient/tests/unit/volume/v2/test_volume_type.py +164 -24
  130. openstackclient/tests/unit/volume/v3/fakes.py +91 -15
  131. openstackclient/tests/unit/volume/v3/test_block_storage_cleanup.py +3 -7
  132. openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py +11 -31
  133. openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +6 -16
  134. openstackclient/tests/unit/volume/v3/test_block_storage_manage.py +219 -157
  135. openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py +32 -23
  136. openstackclient/tests/unit/volume/v3/test_volume.py +50 -48
  137. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +17 -47
  138. openstackclient/tests/unit/volume/v3/test_volume_group.py +23 -65
  139. openstackclient/tests/unit/volume/v3/test_volume_group_snapshot.py +88 -77
  140. openstackclient/tests/unit/volume/v3/test_volume_group_type.py +14 -42
  141. openstackclient/tests/unit/volume/v3/test_volume_message.py +10 -28
  142. openstackclient/volume/v1/volume.py +2 -14
  143. openstackclient/volume/v2/volume.py +30 -15
  144. openstackclient/volume/v2/volume_backend.py +10 -18
  145. openstackclient/volume/v2/volume_backup.py +18 -15
  146. openstackclient/volume/v2/volume_snapshot.py +2 -12
  147. openstackclient/volume/v2/volume_type.py +211 -14
  148. openstackclient/volume/v3/block_storage_manage.py +72 -11
  149. openstackclient/volume/v3/block_storage_resource_filter.py +33 -11
  150. openstackclient/volume/v3/volume_attachment.py +2 -14
  151. openstackclient/volume/v3/volume_group_snapshot.py +27 -27
  152. openstackclient/volume/v3/volume_message.py +2 -13
  153. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/AUTHORS +11 -0
  154. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/METADATA +6 -5
  155. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/RECORD +160 -151
  156. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/entry_points.txt +23 -5
  157. python_openstackclient-6.5.0.dist-info/pbr.json +1 -0
  158. openstackclient/tests/unit/common/test_parseractions.py +0 -233
  159. python_openstackclient-6.3.0.dist-info/pbr.json +0 -1
  160. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/LICENSE +0 -0
  161. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/WHEEL +0 -0
  162. {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.app.client_manager.volume.volume_types
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.app.client_manager.volume.volume_encryption_types
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 test_public_type_create_with_project(self):
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, self.cmd.take_action, parsed_args
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(is_public=None)
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(is_public=True)
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(is_public=False)
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(is_public=None)
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
- ('property', None),
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
- ('property', {'myprop': 'myvalue'}),
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
- {'myprop': 'myvalue'}
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
- ('property', ['property', 'multi_property']),
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 TestVolume(utils.TestCommand):
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 fakes.FakeResource(None, resource_filter_info, loaded=True)
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.app.client_manager.volume.workers
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.clusters
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.services
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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.app.client_manager.volume.api_version = api_versions.APIVersion(
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',