1 # -*- coding: utf-8 -*-
2 # pylint: disable=too-many-public-methods
4 from unittest
import TestCase
5 from unittest
.mock
import Mock
, patch
8 from ..exceptions
import DashboardException
9 from ..services
.rgw_client
import NoCredentialsException
, \
10 NoRgwDaemonsException
, RgwClient
, _parse_frontend_config
11 from ..settings
import Settings
12 from . import CLICommandTestMixin
, RgwStub
# pylint: disable=no-name-in-module
15 @patch('dashboard.services.rgw_client.RgwClient._get_user_id', Mock(
16 return_value
='dummy_admin'))
17 class RgwClientTest(TestCase
, CLICommandTestMixin
):
18 _dashboard_user_realm1_access_key
= 'VUOFXZFK24H81ISTVBTR'
19 _dashboard_user_realm1_secret_key
= '0PGsCvXPGWS3AGgibUZEcd9efLrbbshlUkY3jruR'
20 _dashboard_user_realm2_access_key
= 'OMDR282VYLBC1ZYMYDL0'
21 _dashboard_user_realm2_secret_key
= 'N3thf7jAiwQ90PsPrhC2DIcvCFOsBXtBvPJJMdC3'
22 _radosgw_admin_result_error
= (-errno
.EINVAL
, '', 'fake error')
23 _radosgw_admin_result_no_realms
= (0, {}, '')
24 _radosgw_admin_result_realms
= (0, {"realms": ["realm1", "realm2"]}, '')
25 _radosgw_admin_result_user_realm1
= (
31 "access_key": _dashboard_user_realm1_access_key
,
32 "secret_key": _dashboard_user_realm1_secret_key
38 _radosgw_admin_result_user_realm2
= (
44 "access_key": _dashboard_user_realm2_access_key
,
45 "secret_key": _dashboard_user_realm2_secret_key
55 self
.CONFIG_KEY_DICT
.update({
56 'RGW_API_ACCESS_KEY': 'klausmustermann',
57 'RGW_API_SECRET_KEY': 'supergeheim',
60 def test_configure_credentials_error(self
):
61 self
.CONFIG_KEY_DICT
.update({
62 'RGW_API_ACCESS_KEY': '',
63 'RGW_API_SECRET_KEY': '',
65 # Get no realms, get no user, user creation fails.
66 mgr
.send_rgwadmin_command
.side_effect
= [
67 self
._radosgw
_admin
_result
_error
,
68 self
._radosgw
_admin
_result
_error
,
69 self
._radosgw
_admin
_result
_error
,
71 with self
.assertRaises(NoCredentialsException
) as cm
:
72 RgwClient
.admin_instance()
73 self
.assertIn('No RGW credentials found', str(cm
.exception
))
75 def test_configure_credentials_error_with_realms(self
):
76 self
.CONFIG_KEY_DICT
.update({
77 'RGW_API_ACCESS_KEY': '',
78 'RGW_API_SECRET_KEY': '',
80 # Get realms, get no user, user creation fails.
81 mgr
.send_rgwadmin_command
.side_effect
= [
82 self
._radosgw
_admin
_result
_realms
,
83 self
._radosgw
_admin
_result
_error
,
84 self
._radosgw
_admin
_result
_error
,
85 self
._radosgw
_admin
_result
_error
,
86 self
._radosgw
_admin
_result
_error
,
88 with self
.assertRaises(NoCredentialsException
) as cm
:
89 RgwClient
.admin_instance()
90 self
.assertIn('No RGW credentials found', str(cm
.exception
))
92 def test_set_rgw_credentials_command(self
):
93 # Get no realms, get user.
94 mgr
.send_rgwadmin_command
.side_effect
= [
95 self
._radosgw
_admin
_result
_error
,
96 self
._radosgw
_admin
_result
_user
_realm
1
98 result
= self
.exec_cmd('set-rgw-credentials')
99 self
.assertEqual(result
, 'RGW credentials configured')
100 self
.assertEqual(Settings
.RGW_API_ACCESS_KEY
, self
._dashboard
_user
_realm
1_access
_key
)
101 self
.assertEqual(Settings
.RGW_API_SECRET_KEY
, self
._dashboard
_user
_realm
1_secret
_key
)
103 # Get no realms, get no user, user creation.
104 mgr
.send_rgwadmin_command
.side_effect
= [
105 self
._radosgw
_admin
_result
_error
,
106 self
._radosgw
_admin
_result
_error
,
107 self
._radosgw
_admin
_result
_user
_realm
1
109 result
= self
.exec_cmd('set-rgw-credentials')
110 self
.assertEqual(result
, 'RGW credentials configured')
111 self
.assertEqual(Settings
.RGW_API_ACCESS_KEY
, self
._dashboard
_user
_realm
1_access
_key
)
112 self
.assertEqual(Settings
.RGW_API_SECRET_KEY
, self
._dashboard
_user
_realm
1_secret
_key
)
114 # Get realms, get users.
115 mgr
.send_rgwadmin_command
.side_effect
= [
116 self
._radosgw
_admin
_result
_realms
,
117 self
._radosgw
_admin
_result
_user
_realm
1,
118 self
._radosgw
_admin
_result
_user
_realm
2
120 result
= self
.exec_cmd('set-rgw-credentials')
121 self
.assertEqual(result
, 'RGW credentials configured')
122 self
.assertEqual(Settings
.RGW_API_ACCESS_KEY
, {
123 'realm1': self
._dashboard
_user
_realm
1_access
_key
,
124 'realm2': self
._dashboard
_user
_realm
2_access
_key
126 self
.assertEqual(Settings
.RGW_API_SECRET_KEY
, {
127 'realm1': self
._dashboard
_user
_realm
1_secret
_key
,
128 'realm2': self
._dashboard
_user
_realm
2_secret
_key
131 # Get realms, get no users, users' creation.
132 mgr
.send_rgwadmin_command
.side_effect
= [
133 self
._radosgw
_admin
_result
_realms
,
134 self
._radosgw
_admin
_result
_error
,
135 self
._radosgw
_admin
_result
_user
_realm
1,
136 self
._radosgw
_admin
_result
_error
,
137 self
._radosgw
_admin
_result
_user
_realm
2
139 result
= self
.exec_cmd('set-rgw-credentials')
140 self
.assertEqual(result
, 'RGW credentials configured')
141 self
.assertEqual(Settings
.RGW_API_ACCESS_KEY
, {
142 'realm1': self
._dashboard
_user
_realm
1_access
_key
,
143 'realm2': self
._dashboard
_user
_realm
2_access
_key
145 self
.assertEqual(Settings
.RGW_API_SECRET_KEY
, {
146 'realm1': self
._dashboard
_user
_realm
1_secret
_key
,
147 'realm2': self
._dashboard
_user
_realm
2_secret
_key
150 # Get realms, get no users, realm 2 user creation fails.
151 mgr
.send_rgwadmin_command
.side_effect
= [
152 self
._radosgw
_admin
_result
_realms
,
153 self
._radosgw
_admin
_result
_error
,
154 self
._radosgw
_admin
_result
_user
_realm
1,
155 self
._radosgw
_admin
_result
_error
,
156 self
._radosgw
_admin
_result
_error
,
158 result
= self
.exec_cmd('set-rgw-credentials')
159 self
.assertEqual(result
, 'RGW credentials configured')
160 self
.assertEqual(Settings
.RGW_API_ACCESS_KEY
, {
161 'realm1': self
._dashboard
_user
_realm
1_access
_key
,
163 self
.assertEqual(Settings
.RGW_API_SECRET_KEY
, {
164 'realm1': self
._dashboard
_user
_realm
1_secret
_key
,
167 def test_ssl_verify(self
):
168 Settings
.RGW_API_SSL_VERIFY
= True
169 instance
= RgwClient
.admin_instance()
170 self
.assertTrue(instance
.session
.verify
)
172 def test_no_ssl_verify(self
):
173 Settings
.RGW_API_SSL_VERIFY
= False
174 instance
= RgwClient
.admin_instance()
175 self
.assertFalse(instance
.session
.verify
)
177 def test_no_daemons(self
):
178 RgwStub
.get_mgr_no_services()
179 with self
.assertRaises(NoRgwDaemonsException
) as cm
:
180 RgwClient
.admin_instance()
181 self
.assertIn('No RGW service is running.', str(cm
.exception
))
183 @patch.object(RgwClient
, '_get_daemon_zone_info')
184 def test_get_placement_targets_from_zone(self
, zone_info
):
185 zone_info
.return_value
= {
186 'id': 'a0df30ea-4b5b-4830-b143-2bedf684663d',
189 'key': 'default-placement',
191 'index_pool': 'default.rgw.buckets.index',
194 'data_pool': 'default.rgw.buckets.data'
202 instance
= RgwClient
.admin_instance()
204 'zonegroup': 'zonegroup1',
205 'placement_targets': [
207 'name': 'default-placement',
208 'data_pool': 'default.rgw.buckets.data'
212 self
.assertEqual(expected_result
, instance
.get_placement_targets())
214 @patch.object(RgwClient
, '_get_realms_info')
215 def test_get_realms(self
, realms_info
):
216 realms_info
.side_effect
= [
218 'default_info': '51de8373-bc24-4f74-a9b7-8e9ef4cb71f7',
226 instance
= RgwClient
.admin_instance()
228 self
.assertEqual(['realm1', 'realm2'], instance
.get_realms())
229 self
.assertEqual([], instance
.get_realms())
231 def test_set_bucket_locking_error(self
):
232 instance
= RgwClient
.admin_instance()
234 ('COMPLIANCE', 'null', None, 'must be a positive integer'),
235 ('COMPLIANCE', None, 'null', 'must be a positive integer'),
236 ('COMPLIANCE', -1, None, 'must be a positive integer'),
237 ('COMPLIANCE', None, -1, 'must be a positive integer'),
238 ('COMPLIANCE', 1, 1, 'You can\'t specify both at the same time'),
239 ('COMPLIANCE', None, None, 'You must specify at least one'),
240 ('COMPLIANCE', 0, 0, 'You must specify at least one'),
241 (None, 1, 0, 'must be either COMPLIANCE or GOVERNANCE'),
242 ('', 1, 0, 'must be either COMPLIANCE or GOVERNANCE'),
243 ('FAKE_MODE', 1, 0, 'must be either COMPLIANCE or GOVERNANCE')
245 for params
in test_params
:
246 mode
, days
, years
, error_msg
= params
247 with self
.assertRaises(DashboardException
) as cm
:
248 instance
.set_bucket_locking(
251 retention_period_days
=days
,
252 retention_period_years
=years
254 self
.assertIn(error_msg
, str(cm
.exception
))
256 @patch('dashboard.rest_client._Request', Mock())
257 def test_set_bucket_locking_success(self
):
258 instance
= RgwClient
.admin_instance()
260 ('Compliance', '1', None),
261 ('Governance', 1, None),
262 ('COMPLIANCE', None, '1'),
263 ('GOVERNANCE', None, 1),
265 for params
in test_params
:
266 mode
, days
, years
= params
267 self
.assertIsNone(instance
.set_bucket_locking(
270 retention_period_days
=days
,
271 retention_period_years
=years
275 class RgwClientHelperTest(TestCase
):
276 def test_parse_frontend_config_1(self
):
277 self
.assertEqual(_parse_frontend_config('beast port=8000'), (8000, False))
279 def test_parse_frontend_config_2(self
):
280 self
.assertEqual(_parse_frontend_config('beast port=80 port=8000'), (80, False))
282 def test_parse_frontend_config_3(self
):
283 self
.assertEqual(_parse_frontend_config('beast ssl_port=443 port=8000'), (443, True))
285 def test_parse_frontend_config_4(self
):
286 self
.assertEqual(_parse_frontend_config('beast endpoint=192.168.0.100:8000'), (8000, False))
288 def test_parse_frontend_config_5(self
):
289 self
.assertEqual(_parse_frontend_config('beast endpoint=[::1]'), (80, False))
291 def test_parse_frontend_config_6(self
):
292 self
.assertEqual(_parse_frontend_config(
293 'beast ssl_endpoint=192.168.0.100:8443'), (8443, True))
295 def test_parse_frontend_config_7(self
):
296 self
.assertEqual(_parse_frontend_config('beast ssl_endpoint=192.168.0.100'), (443, True))
298 def test_parse_frontend_config_8(self
):
299 self
.assertEqual(_parse_frontend_config(
300 'beast ssl_endpoint=[::1]:8443 endpoint=192.0.2.3:80'), (8443, True))
302 def test_parse_frontend_config_9(self
):
303 self
.assertEqual(_parse_frontend_config(
304 'beast port=8080 endpoint=192.0.2.3:80'), (8080, False))
306 def test_parse_frontend_config_10(self
):
307 self
.assertEqual(_parse_frontend_config(
308 'beast ssl_endpoint=192.0.2.3:8443 port=8080'), (8443, True))
310 def test_parse_frontend_config_11(self
):
311 self
.assertEqual(_parse_frontend_config('civetweb port=8000s'), (8000, True))
313 def test_parse_frontend_config_12(self
):
314 self
.assertEqual(_parse_frontend_config('civetweb port=443s port=8000'), (443, True))
316 def test_parse_frontend_config_13(self
):
317 self
.assertEqual(_parse_frontend_config('civetweb port=192.0.2.3:80'), (80, False))
319 def test_parse_frontend_config_14(self
):
320 self
.assertEqual(_parse_frontend_config('civetweb port=172.5.2.51:8080s'), (8080, True))
322 def test_parse_frontend_config_15(self
):
323 self
.assertEqual(_parse_frontend_config('civetweb port=[::]:8080'), (8080, False))
325 def test_parse_frontend_config_16(self
):
326 self
.assertEqual(_parse_frontend_config('civetweb port=ip6-localhost:80s'), (80, True))
328 def test_parse_frontend_config_17(self
):
329 self
.assertEqual(_parse_frontend_config('civetweb port=[2001:0db8::1234]:80'), (80, False))
331 def test_parse_frontend_config_18(self
):
332 self
.assertEqual(_parse_frontend_config('civetweb port=[::1]:8443s'), (8443, True))
334 def test_parse_frontend_config_19(self
):
335 self
.assertEqual(_parse_frontend_config('civetweb port=127.0.0.1:8443s+8000'), (8443, True))
337 def test_parse_frontend_config_20(self
):
338 self
.assertEqual(_parse_frontend_config('civetweb port=127.0.0.1:8080+443s'), (8080, False))
340 def test_parse_frontend_config_21(self
):
341 with self
.assertRaises(LookupError) as ctx
:
342 _parse_frontend_config('civetweb port=xyz')
343 self
.assertEqual(str(ctx
.exception
),
344 'Failed to determine RGW port from "civetweb port=xyz"')
346 def test_parse_frontend_config_22(self
):
347 with self
.assertRaises(LookupError) as ctx
:
348 _parse_frontend_config('civetweb')
349 self
.assertEqual(str(ctx
.exception
), 'Failed to determine RGW port from "civetweb"')
351 def test_parse_frontend_config_23(self
):
352 with self
.assertRaises(LookupError) as ctx
:
353 _parse_frontend_config('mongoose port=8080')
354 self
.assertEqual(str(ctx
.exception
),
355 'Failed to determine RGW port from "mongoose port=8080"')