1 # pylint: disable=too-many-public-methods, too-many-lines
11 import unittest
.mock
as mock
13 from mgr_module
import ERROR_MSG_NO_INPUT_FILE
16 from ..controllers
.iscsi
import Iscsi
, IscsiTarget
, IscsiUi
17 from ..exceptions
import DashboardException
18 from ..rest_client
import RequestException
19 from ..services
.exception
import handle_request_error
20 from ..services
.iscsi_client
import IscsiClient
21 from ..services
.orchestrator
import OrchClient
22 from ..tests
import CLICommandTestMixin
, CmdException
, ControllerTestCase
, KVStoreMockMixin
23 from ..tools
import NotificationQueue
, TaskManager
26 class IscsiTestCli(unittest
.TestCase
, CLICommandTestMixin
):
30 # pylint: disable=protected-access
31 IscsiClientMock
._instance
= IscsiClientMock()
32 IscsiClient
.instance
= IscsiClientMock
.instance
34 def test_cli_add_gateway_invalid_url(self
):
35 with self
.assertRaises(CmdException
) as ctx
:
36 self
.exec_cmd('iscsi-gateway-add', name
='node1',
37 inbuf
='http:/hello.com')
39 self
.assertEqual(ctx
.exception
.retcode
, -errno
.EINVAL
)
40 self
.assertEqual(str(ctx
.exception
),
41 "Invalid service URL 'http:/hello.com'. Valid format: "
42 "'<scheme>://<username>:<password>@<host>[:port]'.")
44 def test_cli_add_gateway_empty_url(self
):
45 with self
.assertRaises(CmdException
) as ctx
:
46 self
.exec_cmd('iscsi-gateway-add', name
='node1',
49 self
.assertEqual(ctx
.exception
.retcode
, -errno
.EINVAL
)
50 self
.assertIn(ERROR_MSG_NO_INPUT_FILE
, str(ctx
.exception
))
52 def test_cli_add_gateway(self
):
53 self
.exec_cmd('iscsi-gateway-add', name
='node1',
54 inbuf
='https://admin:admin@10.17.5.1:5001')
55 self
.exec_cmd('iscsi-gateway-add', name
='node2',
56 inbuf
='https://admin:admin@10.17.5.2:5001')
57 iscsi_config
= json
.loads(self
.get_key("_iscsi_config"))
58 self
.assertEqual(iscsi_config
['gateways'], {
60 'service_url': 'https://admin:admin@10.17.5.1:5001'
63 'service_url': 'https://admin:admin@10.17.5.2:5001'
67 def test_cli_remove_gateway(self
):
68 self
.test_cli_add_gateway()
69 self
.exec_cmd('iscsi-gateway-rm', name
='node1')
70 iscsi_config
= json
.loads(self
.get_key("_iscsi_config"))
71 self
.assertEqual(iscsi_config
['gateways'], {
73 'service_url': 'https://admin:admin@10.17.5.2:5001'
78 class IscsiTestController(ControllerTestCase
, KVStoreMockMixin
):
81 def setup_server(cls
):
82 NotificationQueue
.start_queue()
84 OrchClient
.instance().available
= lambda: False
85 mgr
.rados
.side_effect
= None
86 cls
.setup_controllers([Iscsi
, IscsiTarget
])
89 def tearDownClass(cls
):
90 NotificationQueue
.stop()
94 self
.CONFIG_KEY_DICT
['_iscsi_config'] = '''
98 "service_url": "https://admin:admin@10.17.5.1:5001"
101 "service_url": "https://admin:admin@10.17.5.2:5001"
106 # pylint: disable=protected-access
107 IscsiClientMock
._instance
= IscsiClientMock()
108 IscsiClient
.instance
= IscsiClientMock
.instance
110 def test_enable_discoveryauth(self
):
112 'user': 'myiscsiusername',
113 'password': 'myiscsipassword',
114 'mutual_user': 'myiscsiusername2',
115 'mutual_password': 'myiscsipassword2'
117 self
._put
('/api/iscsi/discoveryauth', discoveryauth
)
118 self
.assertStatus(200)
119 self
.assertJsonBody(discoveryauth
)
120 self
._get
('/api/iscsi/discoveryauth')
121 self
.assertStatus(200)
122 self
.assertJsonBody(discoveryauth
)
124 def test_bad_discoveryauth(self
):
126 'user': 'myiscsiusername',
127 'password': 'myiscsipasswordmyiscsipasswordmyiscsipassword',
129 'mutual_password': ''
132 'detail': 'Bad authentication',
133 'code': 'target_bad_auth',
140 'mutual_password': ''
142 self
._put
('/api/iscsi/discoveryauth', discoveryauth
)
143 self
.assertStatus(400)
144 self
.assertJsonBody(put_response
)
145 self
._get
('/api/iscsi/discoveryauth')
146 self
.assertStatus(200)
147 self
.assertJsonBody(get_response
)
149 def test_disable_discoveryauth(self
):
154 'mutual_password': ''
156 self
._put
('/api/iscsi/discoveryauth', discoveryauth
)
157 self
.assertStatus(200)
158 self
.assertJsonBody(discoveryauth
)
159 self
._get
('/api/iscsi/discoveryauth')
160 self
.assertStatus(200)
161 self
.assertJsonBody(discoveryauth
)
163 def test_list_empty(self
):
164 self
._get
('/api/iscsi/target')
165 self
.assertStatus(200)
166 self
.assertJsonBody([])
168 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
169 def test_list(self
, _validate_image_mock
):
170 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw1"
171 request
= copy
.deepcopy(iscsi_target_request
)
172 request
['target_iqn'] = target_iqn
173 self
._task
_post
('/api/iscsi/target', request
)
174 self
.assertStatus(201)
175 self
._get
('/api/iscsi/target')
176 self
.assertStatus(200)
177 response
= copy
.deepcopy(iscsi_target_response
)
178 response
['target_iqn'] = target_iqn
179 self
.assertJsonBody([response
])
181 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
182 def test_create(self
, _validate_image_mock
):
183 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw2"
184 request
= copy
.deepcopy(iscsi_target_request
)
185 request
['target_iqn'] = target_iqn
186 self
._task
_post
('/api/iscsi/target', request
)
187 self
.assertStatus(201)
188 self
._get
('/api/iscsi/target/{}'.format(request
['target_iqn']))
189 self
.assertStatus(200)
190 response
= copy
.deepcopy(iscsi_target_response
)
191 response
['target_iqn'] = target_iqn
192 self
.assertJsonBody(response
)
194 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
195 def test_create_acl_enabled(self
, _validate_image_mock
):
196 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw2"
197 request
= copy
.deepcopy(iscsi_target_request
)
198 request
['target_iqn'] = target_iqn
199 request
['acl_enabled'] = False
200 self
._task
_post
('/api/iscsi/target', request
)
201 self
.assertStatus(201)
202 self
._get
('/api/iscsi/target/{}'.format(request
['target_iqn']))
203 self
.assertStatus(200)
204 response
= copy
.deepcopy(iscsi_target_response
)
205 response
['target_iqn'] = target_iqn
206 response
['acl_enabled'] = False
207 self
.assertJsonBody(response
)
209 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._create')
210 def test_create_error(self
, _create_mock
):
211 # pylint: disable=protected-access
212 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw2"
213 request
= copy
.deepcopy(iscsi_target_request
)
214 request
['target_iqn'] = target_iqn
215 request
['config'] = ""
216 request
['settings'] = ""
217 request
['task_progress_begin'] = 0
218 request
['task_progress_end'] = 100
219 _create_mock
.side_effect
= RequestException("message error")
220 with self
.assertRaises(DashboardException
):
221 with
handle_request_error('iscsi'):
222 IscsiTarget
._create
(**request
)
224 def test_validate_error_iqn(self
):
225 # pylint: disable=protected-access
226 with self
.assertRaises(DashboardException
) as ctx
:
227 IscsiTarget
._validate
(None, None, None, None, None, None)
228 self
.assertEquals(ctx
.exception
.__str
__(),
229 "Target IQN is required")
231 def test_validate_error_portals(self
):
232 # pylint: disable=protected-access
233 target_iqn
= iscsi_target_request
['target_iqn']
234 target_controls
= iscsi_target_request
['target_controls']
236 disks
= iscsi_target_request
['disks']
237 groups
= iscsi_target_request
['groups']
238 settings
= {'config': {'minimum_gateways': 1}}
239 with self
.assertRaises(DashboardException
) as ctx
:
240 IscsiTarget
._validate
(target_iqn
, target_controls
, portals
, disks
, groups
, settings
)
241 self
.assertEquals(ctx
.exception
.__str
__(),
242 "At least one portal is required")
243 settings
= {'config': {'minimum_gateways': 2}}
244 with self
.assertRaises(DashboardException
) as ctx
:
245 IscsiTarget
._validate
(target_iqn
, target_controls
, portals
, disks
, groups
, settings
)
246 self
.assertEquals(ctx
.exception
.__str
__(),
247 "At least 2 portals are required")
249 def test_validate_error_target_control(self
):
250 # pylint: disable=protected-access
251 target_iqn
= iscsi_target_request
['target_iqn']
255 portals
= iscsi_target_request
['portals']
256 disks
= iscsi_target_request
['disks']
257 groups
= iscsi_target_request
['groups']
259 'config': {'minimum_gateways': 1},
260 'target_controls_limits': {
267 with self
.assertRaises(DashboardException
) as ctx
:
268 IscsiTarget
._validate
(target_iqn
, target_controls
, portals
, disks
, groups
, settings
)
269 self
.assertEquals(ctx
.exception
.__str
__(),
270 "Target control target_name must be >= 1")
274 with self
.assertRaises(DashboardException
) as ctx
:
275 IscsiTarget
._validate
(target_iqn
, target_controls
, portals
, disks
, groups
, settings
)
276 self
.assertEquals(ctx
.exception
.__str
__(),
277 "Target control target_name must be <= 2")
279 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
280 def test_validate_error_disk_control(self
, _validate_image_mock
):
281 # pylint: disable=protected-access
282 target_iqn
= iscsi_target_request
['target_iqn']
284 portals
= iscsi_target_request
['portals']
285 disks
= iscsi_target_request
['disks']
286 groups
= iscsi_target_request
['groups']
288 'config': {'minimum_gateways': 1},
289 'required_rbd_features': {
292 'unsupported_rbd_features': {
295 'disk_controls_limits': {
296 'user:rbd': {'max_data_area_mb': {
302 with self
.assertRaises(DashboardException
) as ctx
:
303 IscsiTarget
._validate
(target_iqn
, target_controls
, portals
, disks
, groups
, settings
)
304 self
.assertEquals(ctx
.exception
.__str
__(),
305 "Disk control max_data_area_mb must be >= 129")
306 settings
['disk_controls_limits']['user:rbd']['max_data_area_mb']['min'] = 1
307 with self
.assertRaises(DashboardException
) as ctx
:
308 IscsiTarget
._validate
(target_iqn
, target_controls
, portals
, disks
, groups
, settings
)
309 self
.assertEquals(ctx
.exception
.__str
__(),
310 "Disk control max_data_area_mb must be <= 127")
312 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
313 def test_delete(self
, _validate_image_mock
):
314 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw3"
315 request
= copy
.deepcopy(iscsi_target_request
)
316 request
['target_iqn'] = target_iqn
317 self
._task
_post
('/api/iscsi/target', request
)
318 self
.assertStatus(201)
319 self
._task
_delete
('/api/iscsi/target/{}'.format(request
['target_iqn']))
320 self
.assertStatus(204)
321 self
._get
('/api/iscsi/target')
322 self
.assertStatus(200)
323 self
.assertJsonBody([])
325 @mock.patch('dashboard.tools.TaskManager.current_task')
326 def test_delete_raises_exception(self
, _validate_image_mock
):
327 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw3"
328 request
= copy
.deepcopy(iscsi_target_request
)
329 request
['target_iqn'] = target_iqn
330 configs
= {'targets': {target_iqn
: {'portals': {}}}}
331 with self
.assertRaises(DashboardException
):
332 # pylint: disable=protected-access
333 IscsiTarget
._delete
(target_iqn
, configs
, 0, 100)
335 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
336 def test_add_client(self
, _validate_image_mock
):
337 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw4"
338 create_request
= copy
.deepcopy(iscsi_target_request
)
339 create_request
['target_iqn'] = target_iqn
340 update_request
= copy
.deepcopy(create_request
)
341 update_request
['new_target_iqn'] = target_iqn
342 update_request
['clients'].append(
344 "luns": [{"image": "lun1", "pool": "rbd"}],
345 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
347 "password": "myiscsipassword5",
348 "user": "myiscsiusername5",
349 "mutual_password": "myiscsipassword6",
350 "mutual_user": "myiscsiusername6"}
352 response
= copy
.deepcopy(iscsi_target_response
)
353 response
['target_iqn'] = target_iqn
354 response
['clients'].append(
356 "luns": [{"image": "lun1", "pool": "rbd"}],
357 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
359 "password": "myiscsipassword5",
360 "user": "myiscsiusername5",
361 "mutual_password": "myiscsipassword6",
362 "mutual_user": "myiscsiusername6"},
369 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
371 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
372 def test_add_bad_client(self
, _validate_image_mock
):
373 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw4"
374 create_request
= copy
.deepcopy(iscsi_target_request
)
375 create_request
['target_iqn'] = target_iqn
376 update_request
= copy
.deepcopy(create_request
)
377 update_request
['new_target_iqn'] = target_iqn
378 update_request
['clients'].append(
380 "luns": [{"image": "lun1", "pool": "rbd"}],
381 "client_iqn": "iqn.1994-05.com.redhat:rh7-client4",
383 "password": "myiscsipassword7myiscsipassword7myiscsipasswo",
384 "user": "myiscsiusername7",
385 "mutual_password": "myiscsipassword8",
386 "mutual_user": "myiscsiusername8"}
388 response
= copy
.deepcopy(iscsi_target_response
)
389 response
['target_iqn'] = target_iqn
391 self
._task
_post
('/api/iscsi/target', create_request
)
392 self
.assertStatus(201)
393 self
._task
_put
('/api/iscsi/target/{}'.format(create_request
['target_iqn']), update_request
)
394 self
.assertStatus(400)
395 self
._get
('/api/iscsi/target/{}'.format(update_request
['new_target_iqn']))
396 self
.assertStatus(200)
397 self
.assertJsonBody(response
)
399 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
400 def test_change_client_password(self
, _validate_image_mock
):
401 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw5"
402 create_request
= copy
.deepcopy(iscsi_target_request
)
403 create_request
['target_iqn'] = target_iqn
404 update_request
= copy
.deepcopy(create_request
)
405 update_request
['new_target_iqn'] = target_iqn
406 update_request
['clients'][0]['auth']['password'] = 'MyNewPassword'
407 response
= copy
.deepcopy(iscsi_target_response
)
408 response
['target_iqn'] = target_iqn
409 response
['clients'][0]['auth']['password'] = 'MyNewPassword'
410 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
412 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
413 def test_rename_client(self
, _validate_image_mock
):
414 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw6"
415 create_request
= copy
.deepcopy(iscsi_target_request
)
416 create_request
['target_iqn'] = target_iqn
417 update_request
= copy
.deepcopy(create_request
)
418 update_request
['new_target_iqn'] = target_iqn
419 update_request
['clients'][0]['client_iqn'] = 'iqn.1994-05.com.redhat:rh7-client0'
420 response
= copy
.deepcopy(iscsi_target_response
)
421 response
['target_iqn'] = target_iqn
422 response
['clients'][0]['client_iqn'] = 'iqn.1994-05.com.redhat:rh7-client0'
423 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
425 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
426 def test_add_disk(self
, _validate_image_mock
):
427 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw7"
428 create_request
= copy
.deepcopy(iscsi_target_request
)
429 create_request
['target_iqn'] = target_iqn
430 update_request
= copy
.deepcopy(create_request
)
431 update_request
['new_target_iqn'] = target_iqn
432 update_request
['disks'].append(
437 "backstore": "user:rbd"
439 update_request
['clients'][0]['luns'].append({"image": "lun3", "pool": "rbd"})
440 response
= copy
.deepcopy(iscsi_target_response
)
441 response
['target_iqn'] = target_iqn
442 response
['disks'].append(
447 "backstore": "user:rbd",
448 "wwn": "64af6678-9694-4367-bacc-f8eb0baa2",
452 response
['clients'][0]['luns'].append({"image": "lun3", "pool": "rbd"})
453 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
455 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
456 def test_change_disk_image(self
, _validate_image_mock
):
457 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw8"
458 create_request
= copy
.deepcopy(iscsi_target_request
)
459 create_request
['target_iqn'] = target_iqn
460 update_request
= copy
.deepcopy(create_request
)
461 update_request
['new_target_iqn'] = target_iqn
462 update_request
['disks'][0]['image'] = 'lun0'
463 update_request
['clients'][0]['luns'][0]['image'] = 'lun0'
464 response
= copy
.deepcopy(iscsi_target_response
)
465 response
['target_iqn'] = target_iqn
466 response
['disks'][0]['image'] = 'lun0'
467 response
['clients'][0]['luns'][0]['image'] = 'lun0'
468 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
470 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
471 def test_change_disk_controls(self
, _validate_image_mock
):
472 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw9"
473 create_request
= copy
.deepcopy(iscsi_target_request
)
474 create_request
['target_iqn'] = target_iqn
475 update_request
= copy
.deepcopy(create_request
)
476 update_request
['new_target_iqn'] = target_iqn
477 update_request
['disks'][0]['controls'] = {"qfull_timeout": 15}
478 response
= copy
.deepcopy(iscsi_target_response
)
479 response
['target_iqn'] = target_iqn
480 response
['disks'][0]['controls'] = {"qfull_timeout": 15}
481 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
483 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
484 def test_rename_target(self
, _validate_image_mock
):
485 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw10"
486 new_target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw11"
487 create_request
= copy
.deepcopy(iscsi_target_request
)
488 create_request
['target_iqn'] = target_iqn
489 update_request
= copy
.deepcopy(create_request
)
490 update_request
['new_target_iqn'] = new_target_iqn
491 response
= copy
.deepcopy(iscsi_target_response
)
492 response
['target_iqn'] = new_target_iqn
493 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
495 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
496 def test_rename_group(self
, _validate_image_mock
):
497 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw12"
498 create_request
= copy
.deepcopy(iscsi_target_request
)
499 create_request
['target_iqn'] = target_iqn
500 update_request
= copy
.deepcopy(create_request
)
501 update_request
['new_target_iqn'] = target_iqn
502 update_request
['groups'][0]['group_id'] = 'mygroup0'
503 response
= copy
.deepcopy(iscsi_target_response
)
504 response
['target_iqn'] = target_iqn
505 response
['groups'][0]['group_id'] = 'mygroup0'
506 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
508 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
509 def test_add_client_to_group(self
, _validate_image_mock
):
510 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw13"
511 create_request
= copy
.deepcopy(iscsi_target_request
)
512 create_request
['target_iqn'] = target_iqn
513 update_request
= copy
.deepcopy(create_request
)
514 update_request
['new_target_iqn'] = target_iqn
515 update_request
['clients'].append(
518 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
522 "mutual_password": None,
525 update_request
['groups'][0]['members'].append('iqn.1994-05.com.redhat:rh7-client3')
526 response
= copy
.deepcopy(iscsi_target_response
)
527 response
['target_iqn'] = target_iqn
528 response
['clients'].append(
531 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
535 "mutual_password": None,
536 "mutual_user": None},
543 response
['groups'][0]['members'].append('iqn.1994-05.com.redhat:rh7-client3')
544 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
546 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
547 def test_remove_client_from_group(self
, _validate_image_mock
):
548 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw14"
549 create_request
= copy
.deepcopy(iscsi_target_request
)
550 create_request
['target_iqn'] = target_iqn
551 update_request
= copy
.deepcopy(create_request
)
552 update_request
['new_target_iqn'] = target_iqn
553 update_request
['groups'][0]['members'].remove('iqn.1994-05.com.redhat:rh7-client2')
554 response
= copy
.deepcopy(iscsi_target_response
)
555 response
['target_iqn'] = target_iqn
556 response
['groups'][0]['members'].remove('iqn.1994-05.com.redhat:rh7-client2')
557 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
559 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
560 def test_remove_groups(self
, _validate_image_mock
):
561 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw15"
562 create_request
= copy
.deepcopy(iscsi_target_request
)
563 create_request
['target_iqn'] = target_iqn
564 update_request
= copy
.deepcopy(create_request
)
565 update_request
['new_target_iqn'] = target_iqn
566 update_request
['groups'] = []
567 response
= copy
.deepcopy(iscsi_target_response
)
568 response
['target_iqn'] = target_iqn
569 response
['groups'] = []
570 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
572 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
573 def test_add_client_to_multiple_groups(self
, _validate_image_mock
):
574 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw16"
575 create_request
= copy
.deepcopy(iscsi_target_request
)
576 create_request
['target_iqn'] = target_iqn
577 create_request
['groups'].append(copy
.deepcopy(create_request
['groups'][0]))
578 create_request
['groups'][1]['group_id'] = 'mygroup2'
579 self
._task
_post
('/api/iscsi/target', create_request
)
580 self
.assertStatus(400)
581 self
.assertJsonBody({
582 'detail': 'Each initiator can only be part of 1 group at a time',
583 'code': 'initiator_in_multiple_groups',
587 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
588 def test_remove_client_lun(self
, _validate_image_mock
):
589 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw17"
590 create_request
= copy
.deepcopy(iscsi_target_request
)
591 create_request
['target_iqn'] = target_iqn
592 create_request
['clients'][0]['luns'] = [
593 {"image": "lun1", "pool": "rbd"},
594 {"image": "lun2", "pool": "rbd"},
595 {"image": "lun3", "pool": "rbd"}
597 update_request
= copy
.deepcopy(create_request
)
598 update_request
['new_target_iqn'] = target_iqn
599 update_request
['clients'][0]['luns'] = [
600 {"image": "lun1", "pool": "rbd"},
601 {"image": "lun3", "pool": "rbd"}
603 response
= copy
.deepcopy(iscsi_target_response
)
604 response
['target_iqn'] = target_iqn
605 response
['clients'][0]['luns'] = [
606 {"image": "lun1", "pool": "rbd"},
607 {"image": "lun3", "pool": "rbd"}
609 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
611 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
612 def test_change_client_auth(self
, _validate_image_mock
):
613 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw18"
614 create_request
= copy
.deepcopy(iscsi_target_request
)
615 create_request
['target_iqn'] = target_iqn
616 update_request
= copy
.deepcopy(create_request
)
617 update_request
['new_target_iqn'] = target_iqn
618 update_request
['clients'][0]['auth']['password'] = 'myiscsipasswordX'
619 response
= copy
.deepcopy(iscsi_target_response
)
620 response
['target_iqn'] = target_iqn
621 response
['clients'][0]['auth']['password'] = 'myiscsipasswordX'
622 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
624 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
625 def test_remove_client_logged_in(self
, _validate_image_mock
):
629 'state': {'LOGGED_IN': ['node1']}
631 # pylint: disable=protected-access
632 IscsiClientMock
._instance
.clientinfo
= client_info
633 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw19"
634 create_request
= copy
.deepcopy(iscsi_target_request
)
635 create_request
['target_iqn'] = target_iqn
636 update_request
= copy
.deepcopy(create_request
)
637 update_request
['new_target_iqn'] = target_iqn
638 update_request
['clients'].pop(0)
639 response
= copy
.deepcopy(iscsi_target_response
)
640 response
['target_iqn'] = target_iqn
641 for client
in response
['clients']:
642 client
['info'] = client_info
644 'detail': "Client 'iqn.1994-05.com.redhat:rh7-client' cannot be deleted until it's "
646 'code': 'client_logged_in',
649 self
._update
_iscsi
_target
(create_request
, update_request
, 400, update_response
, response
)
651 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
652 def test_remove_client(self
, _validate_image_mock
):
653 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw20"
654 create_request
= copy
.deepcopy(iscsi_target_request
)
655 create_request
['target_iqn'] = target_iqn
656 update_request
= copy
.deepcopy(create_request
)
657 update_request
['new_target_iqn'] = target_iqn
658 update_request
['clients'].pop(0)
659 response
= copy
.deepcopy(iscsi_target_response
)
660 response
['target_iqn'] = target_iqn
661 response
['clients'].pop(0)
662 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
664 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
665 def test_add_image_to_group_with_client_logged_in(self
, _validate_image_mock
):
669 'state': {'LOGGED_IN': ['node1']}
671 new_disk
= {"pool": "rbd", "image": "lun1"}
672 # pylint: disable=protected-access
673 IscsiClientMock
._instance
.clientinfo
= client_info
674 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw21"
675 create_request
= copy
.deepcopy(iscsi_target_request
)
676 create_request
['target_iqn'] = target_iqn
677 update_request
= copy
.deepcopy(create_request
)
678 update_request
['new_target_iqn'] = target_iqn
679 update_request
['groups'][0]['disks'].append(new_disk
)
680 response
= copy
.deepcopy(iscsi_target_response
)
681 response
['target_iqn'] = target_iqn
682 response
['groups'][0]['disks'].insert(0, new_disk
)
683 for client
in response
['clients']:
684 client
['info'] = client_info
685 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
687 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
688 def test_add_image_to_initiator_with_client_logged_in(self
, _validate_image_mock
):
692 'state': {'LOGGED_IN': ['node1']}
694 new_disk
= {"pool": "rbd", "image": "lun2"}
695 # pylint: disable=protected-access
696 IscsiClientMock
._instance
.clientinfo
= client_info
697 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw22"
698 create_request
= copy
.deepcopy(iscsi_target_request
)
699 create_request
['target_iqn'] = target_iqn
700 update_request
= copy
.deepcopy(create_request
)
701 update_request
['new_target_iqn'] = target_iqn
702 update_request
['clients'][0]['luns'].append(new_disk
)
703 response
= copy
.deepcopy(iscsi_target_response
)
704 response
['target_iqn'] = target_iqn
705 response
['clients'][0]['luns'].append(new_disk
)
706 for client
in response
['clients']:
707 client
['info'] = client_info
708 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
710 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
711 def test_remove_image_from_group_with_client_logged_in(self
, _validate_image_mock
):
715 'state': {'LOGGED_IN': ['node1']}
717 # pylint: disable=protected-access
718 IscsiClientMock
._instance
.clientinfo
= client_info
719 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw23"
720 create_request
= copy
.deepcopy(iscsi_target_request
)
721 create_request
['target_iqn'] = target_iqn
722 update_request
= copy
.deepcopy(create_request
)
723 update_request
['new_target_iqn'] = target_iqn
724 update_request
['groups'][0]['disks'] = []
725 response
= copy
.deepcopy(iscsi_target_response
)
726 response
['target_iqn'] = target_iqn
727 response
['groups'][0]['disks'] = []
728 for client
in response
['clients']:
729 client
['info'] = client_info
730 self
._update
_iscsi
_target
(create_request
, update_request
, 200, None, response
)
732 def _update_iscsi_target(self
, create_request
, update_request
, update_response_code
,
733 update_response
, response
):
734 self
._task
_post
('/api/iscsi/target', create_request
)
735 self
.assertStatus(201)
737 '/api/iscsi/target/{}'.format(create_request
['target_iqn']), update_request
)
738 self
.assertStatus(update_response_code
)
739 self
.assertJsonBody(update_response
)
741 '/api/iscsi/target/{}'.format(update_request
['new_target_iqn']))
742 self
.assertStatus(200)
743 self
.assertJsonBody(response
)
746 class TestIscsiUi(ControllerTestCase
):
748 def setup_server(cls
):
749 cls
.setup_controllers([IscsiUi
])
751 @mock.patch('dashboard.services.tcmu_service.TcmuService.get_image_info')
752 @mock.patch('dashboard.services.tcmu_service.TcmuService.get_iscsi_info')
753 def test_overview(self
, get_iscsi_info_mock
, get_image_info_mock
):
754 get_iscsi_info_mock
.return_value
= None
755 get_image_info_mock
.return_value
= None
756 response
= copy
.deepcopy(iscsiui_response
)
757 response
['images'] = []
758 self
._get
('/ui-api/iscsi/overview')
759 self
.assertStatus(200)
760 self
.assertJsonBody(response
)
762 @mock.patch('dashboard.services.iscsi_config.IscsiGatewaysConfig.get_gateways_config')
763 @mock.patch('dashboard.services.tcmu_service.TcmuService.get_image_info')
764 @mock.patch('dashboard.services.tcmu_service.TcmuService.get_iscsi_info')
765 def test_overview_config(self
, get_iscsi_info_mock
, get_image_info_mock
,
766 get_gateways_config_mock
):
767 get_iscsi_info_mock
.return_value
= None
768 get_image_info_mock
.return_value
= None
769 response
= copy
.deepcopy(iscsiui_response
)
770 response
['images'] = []
771 get_gateways_config_mock
.return_value
= iscsiui_gateways_config_mock
772 self
._get
('/ui-api/iscsi/overview')
773 self
.assertStatus(200)
774 self
.assertJsonBody(response
)
777 raise RequestException('error')
778 config_method
= IscsiClientMock
.get_config
779 IscsiClientMock
.get_config
= raise_ex
780 response
['gateways'][0]['num_sessions'] = 'n/a'
781 response
['gateways'][1]['num_sessions'] = 'n/a'
782 response
['gateways'][0]['num_targets'] = 'n/a'
783 response
['gateways'][1]['num_targets'] = 'n/a'
784 self
._get
('/ui-api/iscsi/overview')
785 self
.assertStatus(200)
786 self
.assertJsonBody(response
)
787 IscsiClientMock
.get_config
= config_method
789 @mock.patch('dashboard.services.iscsi_config.IscsiGatewaysConfig.get_gateways_config')
790 @mock.patch('dashboard.services.tcmu_service.TcmuService.get_image_info')
791 @mock.patch('dashboard.services.tcmu_service.TcmuService.get_iscsi_info')
792 def test_overview_ping(self
, get_iscsi_info_mock
, get_image_info_mock
,
793 get_gateways_config_mock
):
794 get_iscsi_info_mock
.return_value
= None
795 get_image_info_mock
.return_value
= None
796 get_gateways_config_mock
.return_value
= iscsiui_gateways_config_mock
797 response
= copy
.deepcopy(iscsiui_response
)
798 response
['gateways'][0]['num_sessions'] = 0
799 response
['gateways'][1]['num_sessions'] = 0
800 response
['gateways'][0]['num_targets'] = 0
801 response
['gateways'][1]['num_targets'] = 0
802 self
._get
('/ui-api/iscsi/overview')
803 self
.assertStatus(200)
804 self
.assertJsonBody(response
)
807 raise RequestException('error')
808 ping_method
= IscsiClientMock
.ping
809 IscsiClientMock
.ping
= raise_ex
810 response
['gateways'][0]['num_sessions'] = 'n/a'
811 response
['gateways'][1]['num_sessions'] = 'n/a'
812 response
['gateways'][0]['state'] = 'down'
813 response
['gateways'][1]['state'] = 'down'
814 self
._get
('/ui-api/iscsi/overview')
815 self
.assertStatus(200)
816 self
.assertJsonBody(response
)
817 IscsiClientMock
.ping
= ping_method
820 'dashboard.services.iscsi_config.IscsiGatewaysConfig.get_gateways_config')
821 @mock.patch('dashboard.services.tcmu_service.TcmuService.get_image_info')
822 @mock.patch('dashboard.services.tcmu_service.TcmuService.get_iscsi_info')
823 def test_overview_images_info(self
, get_iscsi_info_mock
, get_image_info_mock
,
824 get_gateways_config_mock
):
825 get_iscsi_info_mock
.return_value
= None
826 image_info
= {"optimized_since": "1616735075", "stats": {}, "stats_history": {}}
827 # pylint: disable=protected-access
828 IscsiClientMock
._instance
.config
['disks'] = {
829 1: {"image": "lun1", "pool": "rbd", "backstore": "user:rbd",
830 "optimized_since": "1616735075", "stats": {}, "stats_history": {}},
831 2: {"image": "lun2", "pool": "rbd", "backstore": "user:rbd",
832 "optimized_since": "1616735075", "stats": {}, "stats_history": {}},
834 response
= copy
.deepcopy(iscsiui_response
)
835 response
['images'][0]['optimized_since'] = '1616735075'
836 response
['images'][1]['optimized_since'] = '1616735075'
837 response
['images'][0]['stats'] = {}
838 response
['images'][1]['stats'] = {}
839 response
['images'][0]['stats_history'] = {}
840 response
['images'][1]['stats_history'] = {}
841 get_gateways_config_mock
.return_value
= iscsiui_gateways_config_mock
842 get_image_info_mock
.return_value
= image_info
843 self
._get
('/ui-api/iscsi/overview')
844 self
.assertStatus(200)
845 self
.assertJsonBody(response
)
848 iscsiui_gateways_config_mock
= {
854 1: {"image": "lun1", "pool": "rbd", "backstore": "user:rbd",
855 "controls": {"max_data_area_mb": 128}},
856 2: {"image": "lun2", "pool": "rbd", "backstore": "user:rbd",
857 "controls": {"max_data_area_mb": 128}}
862 {"name": "node1", "state": "up", "num_targets": 0, "num_sessions": 0},
863 {"name": "node2", "state": "up", "num_targets": 0, "num_sessions": 0}
869 'backstore': 'user:rbd',
870 'optimized_since': None,
872 'stats_history': None
877 'backstore': 'user:rbd',
878 'optimized_since': None,
880 'stats_history': None
884 iscsi_target_request
= {
885 "target_iqn": "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw",
887 {"ip": "192.168.100.202", "host": "node2"},
888 {"ip": "10.0.2.15", "host": "node2"},
889 {"ip": "192.168.100.203", "host": "node3"}
892 {"image": "lun1", "pool": "rbd", "backstore": "user:rbd",
893 "controls": {"max_data_area_mb": 128}},
894 {"image": "lun2", "pool": "rbd", "backstore": "user:rbd",
895 "controls": {"max_data_area_mb": 128}}
899 "luns": [{"image": "lun1", "pool": "rbd"}],
900 "client_iqn": "iqn.1994-05.com.redhat:rh7-client",
902 "password": "myiscsipassword1",
903 "user": "myiscsiusername1",
904 "mutual_password": "myiscsipassword2",
905 "mutual_user": "myiscsiusername2"}
909 "client_iqn": "iqn.1994-05.com.redhat:rh7-client2",
911 "password": "myiscsipassword3",
912 "user": "myiscsiusername3",
913 "mutual_password": "myiscsipassword4",
914 "mutual_user": "myiscsiusername4"
922 "mutual_password": "",
924 "target_controls": {},
927 "group_id": "mygroup",
928 "disks": [{"pool": "rbd", "image": "lun2"}],
929 "members": ["iqn.1994-05.com.redhat:rh7-client2"]
934 iscsi_target_response
= {
935 'target_iqn': 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw',
937 {'host': 'node2', 'ip': '10.0.2.15'},
938 {'host': 'node2', 'ip': '192.168.100.202'},
939 {'host': 'node3', 'ip': '192.168.100.203'}
942 {'pool': 'rbd', 'image': 'lun1', 'backstore': 'user:rbd',
943 'wwn': '64af6678-9694-4367-bacc-f8eb0baa0', 'lun': 0,
944 'controls': {'max_data_area_mb': 128}},
945 {'pool': 'rbd', 'image': 'lun2', 'backstore': 'user:rbd',
946 'wwn': '64af6678-9694-4367-bacc-f8eb0baa1', 'lun': 1,
947 'controls': {'max_data_area_mb': 128}}
951 'client_iqn': 'iqn.1994-05.com.redhat:rh7-client',
952 'luns': [{'pool': 'rbd', 'image': 'lun1'}],
954 'user': 'myiscsiusername1',
955 'password': 'myiscsipassword1',
956 'mutual_password': 'myiscsipassword2',
957 'mutual_user': 'myiscsiusername2'
966 'client_iqn': 'iqn.1994-05.com.redhat:rh7-client2',
969 'user': 'myiscsiusername3',
970 'password': 'myiscsipassword3',
971 'mutual_password': 'myiscsipassword4',
972 'mutual_user': 'myiscsiusername4'
985 "mutual_password": "",
989 'group_id': 'mygroup',
990 'disks': [{'pool': 'rbd', 'image': 'lun2'}],
991 'members': ['iqn.1994-05.com.redhat:rh7-client2']
994 'target_controls': {},
1001 class IscsiClientMock(object):
1006 self
.gateway_name
= None
1007 self
.service_url
= None
1009 "created": "2019/01/17 08:57:16",
1013 "password_encryption_enabled": False,
1014 "mutual_username": "",
1015 "mutual_password": "",
1016 "mutual_password_encryption_enabled": False
1032 def instance(cls
, gateway_name
=None, service_url
=None):
1033 cls
._instance
.gateway_name
= gateway_name
1034 cls
._instance
.service_url
= service_url
1035 # pylint: disable=unused-argument
1036 return cls
._instance
1043 def get_settings(self
):
1050 "minimum_gateways": 2
1052 "default_backstore": "user:rbd",
1053 "required_rbd_features": {
1057 "unsupported_rbd_features": {
1061 "disk_default_controls": {
1063 "hw_max_sectors": 1024,
1064 "max_data_area_mb": 8,
1065 "osd_op_timeout": 30,
1069 "target_default_controls": {
1071 "dataout_timeout": 20,
1072 "first_burst_length": 262144,
1073 "immediate_data": "Yes",
1074 "initial_r2t": "Yes",
1075 "max_burst_length": 524288,
1076 "max_outstanding_r2t": 1,
1077 "max_recv_data_segment_length": 262144,
1078 "max_xmit_data_segment_length": 262144,
1079 "nopin_response_timeout": 5,
1084 def get_config(self
):
1085 return copy
.deepcopy(self
.config
)
1087 def create_target(self
, target_iqn
, target_controls
):
1088 self
.config
['targets'][target_iqn
] = {
1090 "acl_enabled": True,
1094 "password_encryption_enabled": False,
1095 "mutual_username": "",
1096 "mutual_password": "",
1097 "mutual_password_encryption_enabled": False
1099 "controls": target_controls
,
1100 "created": "2019/01/17 09:22:34",
1106 def create_gateway(self
, target_iqn
, gateway_name
, ip_addresses
):
1107 target_config
= self
.config
['targets'][target_iqn
]
1108 if 'ip_list' not in target_config
:
1109 target_config
['ip_list'] = []
1110 target_config
['ip_list'] += ip_addresses
1111 target_config
['portals'][gateway_name
] = {
1112 "portal_ip_addresses": ip_addresses
1115 def delete_gateway(self
, target_iqn
, gateway_name
):
1116 target_config
= self
.config
['targets'][target_iqn
]
1117 portal_config
= target_config
['portals'][gateway_name
]
1118 for ip
in portal_config
['portal_ip_addresses']:
1119 target_config
['ip_list'].remove(ip
)
1120 target_config
['portals'].pop(gateway_name
)
1122 def create_disk(self
, pool
, image
, backstore
, wwn
):
1124 wwn
= '64af6678-9694-4367-bacc-f8eb0baa' + str(len(self
.config
['disks']))
1125 image_id
= '{}/{}'.format(pool
, image
)
1126 self
.config
['disks'][image_id
] = {
1129 "backstore": backstore
,
1134 def create_target_lun(self
, target_iqn
, image_id
, lun
):
1135 target_config
= self
.config
['targets'][target_iqn
]
1137 lun
= len(target_config
['disks'])
1138 target_config
['disks'][image_id
] = {
1141 self
.config
['disks'][image_id
]['owner'] = list(target_config
['portals'].keys())[0]
1143 def reconfigure_disk(self
, pool
, image
, controls
):
1144 image_id
= '{}/{}'.format(pool
, image
)
1145 settings
= self
.get_settings()
1146 backstore
= self
.config
['disks'][image_id
]['backstore']
1147 disk_default_controls
= settings
['disk_default_controls'][backstore
]
1149 for control_k
, control_v
in controls
.items():
1150 if control_v
!= disk_default_controls
[control_k
]:
1151 new_controls
[control_k
] = control_v
1152 self
.config
['disks'][image_id
]['controls'] = new_controls
1154 def create_client(self
, target_iqn
, client_iqn
):
1155 target_config
= self
.config
['targets'][target_iqn
]
1156 target_config
['clients'][client_iqn
] = {
1160 "password_encryption_enabled": False,
1161 "mutual_username": "",
1162 "mutual_password": "",
1163 "mutual_password_encryption_enabled": False
1169 def create_client_lun(self
, target_iqn
, client_iqn
, image_id
):
1170 target_config
= self
.config
['targets'][target_iqn
]
1171 target_config
['clients'][client_iqn
]['luns'][image_id
] = {}
1173 def delete_client_lun(self
, target_iqn
, client_iqn
, image_id
):
1174 target_config
= self
.config
['targets'][target_iqn
]
1175 del target_config
['clients'][client_iqn
]['luns'][image_id
]
1177 def create_client_auth(self
, target_iqn
, client_iqn
, user
, password
, m_user
, m_password
):
1178 target_config
= self
.config
['targets'][target_iqn
]
1179 target_config
['clients'][client_iqn
]['auth']['username'] = user
1180 target_config
['clients'][client_iqn
]['auth']['password'] = password
1181 target_config
['clients'][client_iqn
]['auth']['mutual_username'] = m_user
1182 target_config
['clients'][client_iqn
]['auth']['mutual_password'] = m_password
1184 def create_group(self
, target_iqn
, group_name
, members
, image_ids
):
1185 target_config
= self
.config
['targets'][target_iqn
]
1186 target_config
['groups'][group_name
] = {
1190 for image_id
in image_ids
:
1191 target_config
['groups'][group_name
]['disks'][image_id
] = {}
1192 target_config
['groups'][group_name
]['members'] = members
1194 def update_group(self
, target_iqn
, group_name
, members
, image_ids
):
1195 target_config
= self
.config
['targets'][target_iqn
]
1196 group
= target_config
['groups'][group_name
]
1197 old_members
= group
['members']
1198 disks
= group
['disks']
1199 target_config
['groups'][group_name
] = {
1204 for image_id
in disks
.keys():
1205 if image_id
not in image_ids
:
1206 target_config
['groups'][group_name
]['disks'][image_id
] = {}
1209 for member_iqn
in old_members
:
1210 if member_iqn
not in members
:
1211 new_members
.append(member_iqn
)
1212 target_config
['groups'][group_name
]['members'] = new_members
1214 def delete_group(self
, target_iqn
, group_name
):
1215 target_config
= self
.config
['targets'][target_iqn
]
1216 del target_config
['groups'][group_name
]
1218 def delete_client(self
, target_iqn
, client_iqn
):
1219 target_config
= self
.config
['targets'][target_iqn
]
1220 del target_config
['clients'][client_iqn
]
1222 def delete_target_lun(self
, target_iqn
, image_id
):
1223 target_config
= self
.config
['targets'][target_iqn
]
1224 target_config
['disks'].pop(image_id
)
1225 del self
.config
['disks'][image_id
]['owner']
1227 def delete_disk(self
, pool
, image
):
1228 image_id
= '{}/{}'.format(pool
, image
)
1229 del self
.config
['disks'][image_id
]
1231 def delete_target(self
, target_iqn
):
1232 del self
.config
['targets'][target_iqn
]
1234 def get_ip_addresses(self
):
1236 'node1': ['192.168.100.201'],
1237 'node2': ['192.168.100.202', '10.0.2.15'],
1238 'node3': ['192.168.100.203']
1240 return {'data': ips
[self
.gateway_name
]}
1242 def get_hostname(self
):
1244 'https://admin:admin@10.17.5.1:5001': 'node1',
1245 'https://admin:admin@10.17.5.2:5001': 'node2',
1246 'https://admin:admin@10.17.5.3:5001': 'node3'
1248 if self
.service_url
not in hostnames
:
1249 raise RequestException('No route to host')
1250 return {'data': hostnames
[self
.service_url
]}
1252 def update_discoveryauth(self
, user
, password
, mutual_user
, mutual_password
):
1253 self
.config
['discovery_auth']['username'] = user
1254 self
.config
['discovery_auth']['password'] = password
1255 self
.config
['discovery_auth']['mutual_username'] = mutual_user
1256 self
.config
['discovery_auth']['mutual_password'] = mutual_password
1258 def update_targetacl(self
, target_iqn
, action
):
1259 self
.config
['targets'][target_iqn
]['acl_enabled'] = (action
== 'enable_acl')
1261 def update_targetauth(self
, target_iqn
, user
, password
, mutual_user
, mutual_password
):
1262 target_config
= self
.config
['targets'][target_iqn
]
1263 target_config
['auth']['username'] = user
1264 target_config
['auth']['password'] = password
1265 target_config
['auth']['mutual_username'] = mutual_user
1266 target_config
['auth']['mutual_password'] = mutual_password
1268 def get_targetinfo(self
, target_iqn
):
1269 # pylint: disable=unused-argument
1274 def get_clientinfo(self
, target_iqn
, client_iqn
):
1275 # pylint: disable=unused-argument
1276 return self
.clientinfo