python-openstackclient 8.0.0__py3-none-any.whl → 8.2.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 (106) hide show
  1. openstackclient/api/compute_v2.py +2 -2
  2. openstackclient/api/volume_v2.py +60 -0
  3. openstackclient/api/volume_v3.py +60 -0
  4. openstackclient/compute/client.py +5 -0
  5. openstackclient/compute/v2/console.py +7 -0
  6. openstackclient/compute/v2/console_connection.py +48 -0
  7. openstackclient/compute/v2/flavor.py +14 -1
  8. openstackclient/compute/v2/keypair.py +10 -3
  9. openstackclient/compute/v2/server.py +76 -13
  10. openstackclient/compute/v2/server_event.py +1 -1
  11. openstackclient/identity/common.py +85 -11
  12. openstackclient/identity/v3/application_credential.py +88 -87
  13. openstackclient/identity/v3/domain.py +67 -49
  14. openstackclient/identity/v3/group.py +113 -68
  15. openstackclient/identity/v3/project.py +42 -20
  16. openstackclient/identity/v3/role.py +7 -2
  17. openstackclient/identity/v3/user.py +38 -5
  18. openstackclient/image/client.py +5 -0
  19. openstackclient/image/v1/image.py +16 -1
  20. openstackclient/image/v2/cache.py +10 -6
  21. openstackclient/image/v2/image.py +59 -12
  22. openstackclient/image/v2/metadef_objects.py +8 -2
  23. openstackclient/image/v2/metadef_properties.py +9 -2
  24. openstackclient/network/client.py +0 -6
  25. openstackclient/network/v2/floating_ip.py +58 -29
  26. openstackclient/network/v2/network_qos_rule.py +3 -11
  27. openstackclient/network/v2/port.py +16 -0
  28. openstackclient/network/v2/router.py +1 -1
  29. openstackclient/network/v2/security_group.py +49 -7
  30. openstackclient/network/v2/security_group_rule.py +18 -1
  31. openstackclient/shell.py +1 -1
  32. openstackclient/tests/functional/base.py +5 -1
  33. openstackclient/tests/functional/compute/v2/test_keypair.py +41 -5
  34. openstackclient/tests/functional/identity/v3/test_access_rule.py +1 -1
  35. openstackclient/tests/functional/identity/v3/test_application_credential.py +7 -7
  36. openstackclient/tests/functional/image/v2/test_image.py +36 -14
  37. openstackclient/tests/functional/volume/v2/test_volume.py +1 -1
  38. openstackclient/tests/functional/volume/v3/test_volume.py +2 -2
  39. openstackclient/tests/unit/api/test_volume_v2.py +124 -0
  40. openstackclient/tests/unit/api/test_volume_v3.py +124 -0
  41. openstackclient/tests/unit/compute/v2/fakes.py +81 -305
  42. openstackclient/tests/unit/compute/v2/test_console.py +18 -1
  43. openstackclient/tests/unit/compute/v2/test_console_connection.py +72 -0
  44. openstackclient/tests/unit/compute/v2/test_flavor.py +160 -175
  45. openstackclient/tests/unit/compute/v2/test_keypair.py +12 -5
  46. openstackclient/tests/unit/compute/v2/test_server.py +211 -97
  47. openstackclient/tests/unit/compute/v2/test_server_backup.py +32 -71
  48. openstackclient/tests/unit/compute/v2/test_server_event.py +2 -2
  49. openstackclient/tests/unit/compute/v2/test_server_image.py +33 -72
  50. openstackclient/tests/unit/compute/v2/test_server_migration.py +4 -4
  51. openstackclient/tests/unit/identity/v3/test_application_credential.py +93 -65
  52. openstackclient/tests/unit/identity/v3/test_domain.py +117 -107
  53. openstackclient/tests/unit/identity/v3/test_group.py +353 -202
  54. openstackclient/tests/unit/identity/v3/test_project.py +46 -53
  55. openstackclient/tests/unit/identity/v3/test_role.py +2 -8
  56. openstackclient/tests/unit/identity/v3/test_user.py +86 -6
  57. openstackclient/tests/unit/image/v1/test_image.py +55 -9
  58. openstackclient/tests/unit/image/v2/test_image.py +128 -58
  59. openstackclient/tests/unit/image/v2/test_metadef_objects.py +22 -0
  60. openstackclient/tests/unit/image/v2/test_metadef_properties.py +24 -10
  61. openstackclient/tests/unit/network/v2/fakes.py +406 -485
  62. openstackclient/tests/unit/network/v2/test_floating_ip_network.py +13 -19
  63. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +2 -2
  64. openstackclient/tests/unit/network/v2/test_ndp_proxy.py +3 -5
  65. openstackclient/tests/unit/network/v2/test_network.py +4 -4
  66. openstackclient/tests/unit/network/v2/test_network_agent.py +15 -29
  67. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +16 -19
  68. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +79 -152
  69. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +4 -6
  70. openstackclient/tests/unit/network/v2/test_network_rbac.py +2 -2
  71. openstackclient/tests/unit/network/v2/test_port.py +57 -17
  72. openstackclient/tests/unit/network/v2/test_router.py +73 -57
  73. openstackclient/tests/unit/network/v2/test_security_group_network.py +31 -27
  74. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +1 -3
  75. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +82 -39
  76. openstackclient/tests/unit/volume/v2/fakes.py +1 -2
  77. openstackclient/tests/unit/volume/v2/test_service.py +57 -91
  78. openstackclient/tests/unit/volume/v2/test_volume.py +466 -410
  79. openstackclient/tests/unit/volume/v2/test_volume_backup.py +141 -148
  80. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +293 -283
  81. openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +61 -71
  82. openstackclient/tests/unit/volume/v3/test_service.py +221 -141
  83. openstackclient/tests/unit/volume/v3/test_volume.py +569 -534
  84. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
  85. openstackclient/tests/unit/volume/v3/test_volume_backup.py +198 -203
  86. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +682 -47
  87. openstackclient/volume/v2/service.py +41 -38
  88. openstackclient/volume/v2/volume.py +140 -88
  89. openstackclient/volume/v2/volume_backup.py +9 -3
  90. openstackclient/volume/v2/volume_snapshot.py +121 -84
  91. openstackclient/volume/v3/block_storage_log_level.py +22 -28
  92. openstackclient/volume/v3/service.py +105 -14
  93. openstackclient/volume/v3/volume.py +287 -99
  94. openstackclient/volume/v3/volume_backup.py +24 -19
  95. openstackclient/volume/v3/volume_group.py +1 -1
  96. openstackclient/volume/v3/volume_snapshot.py +485 -10
  97. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/AUTHORS +13 -0
  98. python_openstackclient-8.2.0.dist-info/METADATA +264 -0
  99. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/RECORD +104 -98
  100. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/entry_points.txt +7 -6
  101. python_openstackclient-8.2.0.dist-info/pbr.json +1 -0
  102. python_openstackclient-8.0.0.dist-info/METADATA +0 -166
  103. python_openstackclient-8.0.0.dist-info/pbr.json +0 -1
  104. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/LICENSE +0 -0
  105. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/WHEEL +0 -0
  106. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/top_level.txt +0 -0
@@ -21,12 +21,18 @@ from openstackclient.tests.functional import base
21
21
  class KeypairBase(base.TestCase):
22
22
  """Methods for functional tests."""
23
23
 
24
- def keypair_create(self, name=data_utils.rand_uuid()):
24
+ def keypair_create(self, name=data_utils.rand_uuid(), user=None):
25
25
  """Create keypair and add cleanup."""
26
- raw_output = self.openstack('keypair create ' + name)
27
- self.addCleanup(self.keypair_delete, name, True)
26
+ cmd = 'keypair create ' + name
27
+ if user is not None:
28
+ cmd += ' --user ' + user
29
+ raw_output = self.openstack(cmd)
30
+ self.addCleanup(
31
+ self.keypair_delete, name, ignore_exceptions=True, user=user
32
+ )
28
33
  if not raw_output:
29
34
  self.fail('Keypair has not been created!')
35
+ return name
30
36
 
31
37
  def keypair_list(self, params=''):
32
38
  """Return dictionary with list of keypairs."""
@@ -34,10 +40,13 @@ class KeypairBase(base.TestCase):
34
40
  keypairs = self.parse_show_as_object(raw_output)
35
41
  return keypairs
36
42
 
37
- def keypair_delete(self, name, ignore_exceptions=False):
43
+ def keypair_delete(self, name, ignore_exceptions=False, user=None):
38
44
  """Try to delete keypair by name."""
39
45
  try:
40
- self.openstack('keypair delete ' + name)
46
+ cmd = 'keypair delete ' + name
47
+ if user is not None:
48
+ cmd += ' --user ' + user
49
+ self.openstack(cmd)
41
50
  except exceptions.CommandFailed:
42
51
  if not ignore_exceptions:
43
52
  raise
@@ -200,3 +209,30 @@ class KeypairTests(KeypairBase):
200
209
  items = self.parse_listing(raw_output)
201
210
  self.assert_table_structure(items, HEADERS)
202
211
  self.assertInOutput(self.KPName, raw_output)
212
+
213
+ def test_keypair_list_by_project(self):
214
+ """Test keypair list by project.
215
+
216
+ Test steps:
217
+ 1) Create keypair for admin project in setUp
218
+ 2) Create a new project
219
+ 3) Create a new user
220
+ 4) Associate the new user with the new project
221
+ 5) Create keypair for the new user
222
+ 6) List keypairs by the new project
223
+ 7) Check that only the keypair from step 5 is returned
224
+ """
225
+ project_name = data_utils.rand_name('TestProject')
226
+ self.openstack(f'project create {project_name}')
227
+ self.addCleanup(self.openstack, f'project delete {project_name}')
228
+ user_name = data_utils.rand_name('TestUser')
229
+ self.openstack(f'user create {user_name}')
230
+ self.addCleanup(self.openstack, f'user delete {user_name}')
231
+ self.openstack(
232
+ f'role add --user {user_name} --project {project_name} member'
233
+ )
234
+ keypair_name = self.keypair_create(user=user_name)
235
+ raw_output = self.openstack(f'keypair list --project {project_name}')
236
+ items = self.parse_listing(raw_output)
237
+ self.assertEqual(1, len(items))
238
+ self.assertEqual(keypair_name, items[0]['Name'])
@@ -62,7 +62,7 @@ class AccessRuleTests(common.IdentityTests):
62
62
 
63
63
  items = self.parse_show_as_object(raw_output)
64
64
  self.access_rule_ids = [
65
- x['id'] for x in ast.literal_eval(items['access_rules'])
65
+ x['id'] for x in ast.literal_eval(items['Access Rules'])
66
66
  ]
67
67
  self.addCleanup(
68
68
  self.openstack,
@@ -21,13 +21,13 @@ from openstackclient.tests.functional.identity.v3 import common
21
21
 
22
22
  class ApplicationCredentialTests(common.IdentityTests):
23
23
  APPLICATION_CREDENTIAL_FIELDS = [
24
- 'id',
25
- 'name',
26
- 'project_id',
27
- 'description',
28
- 'roles',
29
- 'expires_at',
30
- 'unrestricted',
24
+ 'ID',
25
+ 'Name',
26
+ 'Project ID',
27
+ 'Description',
28
+ 'Roles',
29
+ 'Expires At',
30
+ 'Unrestricted',
31
31
  ]
32
32
  APPLICATION_CREDENTIAL_LIST_HEADERS = [
33
33
  'ID',
@@ -218,17 +218,39 @@ class ImageTests(base.BaseImageTests):
218
218
  'image remove project ' + self.name + ' ' + my_project_id
219
219
  )
220
220
 
221
- # else:
222
- # # Test not shared
223
- # self.assertRaises(
224
- # image_exceptions.HTTPForbidden,
225
- # self.openstack,
226
- # 'image add project ' +
227
- # self.name + ' ' +
228
- # my_project_id
229
- # )
230
- # self.openstack(
231
- # 'image set ' +
232
- # '--share ' +
233
- # self.name
234
- # )
221
+ def test_image_hidden(self):
222
+ # Test image is shown in list
223
+ output = self.openstack(
224
+ 'image list',
225
+ parse_output=True,
226
+ )
227
+ self.assertIn(
228
+ self.name,
229
+ [img['Name'] for img in output],
230
+ )
231
+
232
+ # Hide the image and test image not show in the list
233
+ self.openstack('image set ' + '--hidden ' + self.name)
234
+ output = self.openstack(
235
+ 'image list',
236
+ parse_output=True,
237
+ )
238
+ self.assertNotIn(self.name, [img['Name'] for img in output])
239
+
240
+ # Test image show in the list with flag
241
+ output = self.openstack(
242
+ 'image list',
243
+ parse_output=True,
244
+ )
245
+ self.assertNotIn(self.name, [img['Name'] for img in output])
246
+
247
+ # Unhide the image and test image is again visible in regular list
248
+ self.openstack('image set ' + '--unhidden ' + self.name)
249
+ output = self.openstack(
250
+ 'image list',
251
+ parse_output=True,
252
+ )
253
+ self.assertIn(
254
+ self.name,
255
+ [img['Name'] for img in output],
256
+ )
@@ -171,7 +171,7 @@ class VolumeTests(common.BaseVolumeTests):
171
171
  cmd_output["volume_image_metadata"],
172
172
  )
173
173
  self.assertEqual(
174
- 'true',
174
+ True,
175
175
  cmd_output["bootable"],
176
176
  )
177
177
 
@@ -124,7 +124,7 @@ class VolumeTests(common.BaseVolumeTests):
124
124
  cmd_output["properties"],
125
125
  )
126
126
  self.assertEqual(
127
- 'false',
127
+ False,
128
128
  cmd_output["bootable"],
129
129
  )
130
130
  self.wait_for_status("volume", name, "available")
@@ -172,7 +172,7 @@ class VolumeTests(common.BaseVolumeTests):
172
172
  cmd_output["volume_image_metadata"],
173
173
  )
174
174
  self.assertEqual(
175
- 'true',
175
+ True,
176
176
  cmd_output["bootable"],
177
177
  )
178
178
 
@@ -0,0 +1,124 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+ # not use this file except in compliance with the License. You may obtain
3
+ # a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+ # License for the specific language governing permissions and limitations
11
+ # under the License.
12
+ #
13
+
14
+ """Volume v2 API Library Tests"""
15
+
16
+ import http
17
+ from unittest import mock
18
+ import uuid
19
+
20
+ from openstack.block_storage.v2 import _proxy
21
+ from osc_lib import exceptions as osc_lib_exceptions
22
+
23
+ from openstackclient.api import volume_v2 as volume
24
+ from openstackclient.tests.unit import fakes
25
+ from openstackclient.tests.unit import utils
26
+
27
+
28
+ class TestConsistencyGroup(utils.TestCase):
29
+ def setUp(self):
30
+ super().setUp()
31
+
32
+ self.volume_sdk_client = mock.Mock(_proxy.Proxy)
33
+
34
+ def test_find_consistency_group_by_id(self):
35
+ cg_id = uuid.uuid4().hex
36
+ cg_name = 'name-' + uuid.uuid4().hex
37
+ data = {
38
+ 'consistencygroup': {
39
+ 'id': cg_id,
40
+ 'name': cg_name,
41
+ 'status': 'available',
42
+ 'availability_zone': 'az1',
43
+ 'created_at': '2015-09-16T09:28:52.000000',
44
+ 'description': 'description-' + uuid.uuid4().hex,
45
+ 'volume_types': ['123456'],
46
+ }
47
+ }
48
+ self.volume_sdk_client.get.side_effect = [
49
+ fakes.FakeResponse(data=data),
50
+ ]
51
+
52
+ result = volume.find_consistency_group(self.volume_sdk_client, cg_id)
53
+
54
+ self.volume_sdk_client.get.assert_has_calls(
55
+ [
56
+ mock.call(f'/consistencygroups/{cg_id}'),
57
+ ]
58
+ )
59
+ self.assertEqual(data['consistencygroup'], result)
60
+
61
+ def test_find_consistency_group_by_name(self):
62
+ cg_id = uuid.uuid4().hex
63
+ cg_name = 'name-' + uuid.uuid4().hex
64
+ data = {
65
+ 'consistencygroups': [
66
+ {
67
+ 'id': cg_id,
68
+ 'name': cg_name,
69
+ }
70
+ ],
71
+ }
72
+ self.volume_sdk_client.get.side_effect = [
73
+ fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
74
+ fakes.FakeResponse(data=data),
75
+ ]
76
+
77
+ result = volume.find_consistency_group(self.volume_sdk_client, cg_name)
78
+
79
+ self.volume_sdk_client.get.assert_has_calls(
80
+ [
81
+ mock.call(f'/consistencygroups/{cg_name}'),
82
+ mock.call('/consistencygroups'),
83
+ ]
84
+ )
85
+ self.assertEqual(data['consistencygroups'][0], result)
86
+
87
+ def test_find_consistency_group_not_found(self):
88
+ data = {'consistencygroups': []}
89
+ self.volume_sdk_client.get.side_effect = [
90
+ fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
91
+ fakes.FakeResponse(data=data),
92
+ ]
93
+ self.assertRaises(
94
+ osc_lib_exceptions.NotFound,
95
+ volume.find_consistency_group,
96
+ self.volume_sdk_client,
97
+ 'invalid-cg',
98
+ )
99
+
100
+ def test_find_consistency_group_by_name_duplicate(self):
101
+ cg_name = 'name-' + uuid.uuid4().hex
102
+ data = {
103
+ 'consistencygroups': [
104
+ {
105
+ 'id': uuid.uuid4().hex,
106
+ 'name': cg_name,
107
+ },
108
+ {
109
+ 'id': uuid.uuid4().hex,
110
+ 'name': cg_name,
111
+ },
112
+ ],
113
+ }
114
+ self.volume_sdk_client.get.side_effect = [
115
+ fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
116
+ fakes.FakeResponse(data=data),
117
+ ]
118
+
119
+ self.assertRaises(
120
+ osc_lib_exceptions.NotFound,
121
+ volume.find_consistency_group,
122
+ self.volume_sdk_client,
123
+ cg_name,
124
+ )
@@ -0,0 +1,124 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+ # not use this file except in compliance with the License. You may obtain
3
+ # a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+ # License for the specific language governing permissions and limitations
11
+ # under the License.
12
+ #
13
+
14
+ """Volume v3 API Library Tests"""
15
+
16
+ import http
17
+ from unittest import mock
18
+ import uuid
19
+
20
+ from openstack.block_storage.v3 import _proxy
21
+ from osc_lib import exceptions as osc_lib_exceptions
22
+
23
+ from openstackclient.api import volume_v3 as volume
24
+ from openstackclient.tests.unit import fakes
25
+ from openstackclient.tests.unit import utils
26
+
27
+
28
+ class TestConsistencyGroup(utils.TestCase):
29
+ def setUp(self):
30
+ super().setUp()
31
+
32
+ self.volume_sdk_client = mock.Mock(_proxy.Proxy)
33
+
34
+ def test_find_consistency_group_by_id(self):
35
+ cg_id = uuid.uuid4().hex
36
+ cg_name = 'name-' + uuid.uuid4().hex
37
+ data = {
38
+ 'consistencygroup': {
39
+ 'id': cg_id,
40
+ 'name': cg_name,
41
+ 'status': 'available',
42
+ 'availability_zone': 'az1',
43
+ 'created_at': '2015-09-16T09:28:52.000000',
44
+ 'description': 'description-' + uuid.uuid4().hex,
45
+ 'volume_types': ['123456'],
46
+ }
47
+ }
48
+ self.volume_sdk_client.get.side_effect = [
49
+ fakes.FakeResponse(data=data),
50
+ ]
51
+
52
+ result = volume.find_consistency_group(self.volume_sdk_client, cg_id)
53
+
54
+ self.volume_sdk_client.get.assert_has_calls(
55
+ [
56
+ mock.call(f'/consistencygroups/{cg_id}'),
57
+ ]
58
+ )
59
+ self.assertEqual(data['consistencygroup'], result)
60
+
61
+ def test_find_consistency_group_by_name(self):
62
+ cg_id = uuid.uuid4().hex
63
+ cg_name = 'name-' + uuid.uuid4().hex
64
+ data = {
65
+ 'consistencygroups': [
66
+ {
67
+ 'id': cg_id,
68
+ 'name': cg_name,
69
+ }
70
+ ],
71
+ }
72
+ self.volume_sdk_client.get.side_effect = [
73
+ fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
74
+ fakes.FakeResponse(data=data),
75
+ ]
76
+
77
+ result = volume.find_consistency_group(self.volume_sdk_client, cg_name)
78
+
79
+ self.volume_sdk_client.get.assert_has_calls(
80
+ [
81
+ mock.call(f'/consistencygroups/{cg_name}'),
82
+ mock.call('/consistencygroups'),
83
+ ]
84
+ )
85
+ self.assertEqual(data['consistencygroups'][0], result)
86
+
87
+ def test_find_consistency_group_not_found(self):
88
+ data = {'consistencygroups': []}
89
+ self.volume_sdk_client.get.side_effect = [
90
+ fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
91
+ fakes.FakeResponse(data=data),
92
+ ]
93
+ self.assertRaises(
94
+ osc_lib_exceptions.NotFound,
95
+ volume.find_consistency_group,
96
+ self.volume_sdk_client,
97
+ 'invalid-cg',
98
+ )
99
+
100
+ def test_find_consistency_group_by_name_duplicate(self):
101
+ cg_name = 'name-' + uuid.uuid4().hex
102
+ data = {
103
+ 'consistencygroups': [
104
+ {
105
+ 'id': uuid.uuid4().hex,
106
+ 'name': cg_name,
107
+ },
108
+ {
109
+ 'id': uuid.uuid4().hex,
110
+ 'name': cg_name,
111
+ },
112
+ ],
113
+ }
114
+ self.volume_sdk_client.get.side_effect = [
115
+ fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
116
+ fakes.FakeResponse(data=data),
117
+ ]
118
+
119
+ self.assertRaises(
120
+ osc_lib_exceptions.NotFound,
121
+ volume.find_consistency_group,
122
+ self.volume_sdk_client,
123
+ cg_name,
124
+ )