]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/tests/test_iscsi.py
import ceph 14.2.5
[ceph.git] / ceph / src / pybind / mgr / dashboard / tests / test_iscsi.py
1 # pylint: disable=too-many-public-methods
2
3 import copy
4 import errno
5 import json
6 import mock
7
8 from . import CmdException, ControllerTestCase, CLICommandTestMixin
9 from .. import mgr
10 from ..controllers.iscsi import Iscsi, IscsiTarget
11 from ..services.iscsi_client import IscsiClient
12 from ..services.orchestrator import OrchClient
13 from ..rest_client import RequestException
14
15
16 class IscsiTest(ControllerTestCase, CLICommandTestMixin):
17
18 @classmethod
19 def setup_server(cls):
20 OrchClient().available = lambda: False
21 mgr.rados.side_effect = None
22 # pylint: disable=protected-access
23 Iscsi._cp_config['tools.authenticate.on'] = False
24 IscsiTarget._cp_config['tools.authenticate.on'] = False
25 cls.setup_controllers([Iscsi, IscsiTarget])
26
27 def setUp(self):
28 self.mock_kv_store()
29 # pylint: disable=protected-access
30 IscsiClientMock._instance = IscsiClientMock()
31 IscsiClient.instance = IscsiClientMock.instance
32
33 def test_cli_add_gateway_invalid_url(self):
34 with self.assertRaises(CmdException) as ctx:
35 self.exec_cmd('iscsi-gateway-add', name='node1',
36 service_url='http:/hello.com')
37
38 self.assertEqual(ctx.exception.retcode, -errno.EINVAL)
39 self.assertEqual(str(ctx.exception),
40 "Invalid service URL 'http:/hello.com'. Valid format: "
41 "'<scheme>://<username>:<password>@<host>[:port]'.")
42
43 def test_cli_add_gateway(self):
44 self.exec_cmd('iscsi-gateway-add', name='node1',
45 service_url='https://admin:admin@10.17.5.1:5001')
46 self.exec_cmd('iscsi-gateway-add', name='node2',
47 service_url='https://admin:admin@10.17.5.2:5001')
48 iscsi_config = json.loads(self.get_key("_iscsi_config"))
49 self.assertEqual(iscsi_config['gateways'], {
50 'node1': {
51 'service_url': 'https://admin:admin@10.17.5.1:5001'
52 },
53 'node2': {
54 'service_url': 'https://admin:admin@10.17.5.2:5001'
55 }
56 })
57
58 def test_cli_remove_gateway(self):
59 self.test_cli_add_gateway()
60 self.exec_cmd('iscsi-gateway-rm', name='node1')
61 iscsi_config = json.loads(self.get_key("_iscsi_config"))
62 self.assertEqual(iscsi_config['gateways'], {
63 'node2': {
64 'service_url': 'https://admin:admin@10.17.5.2:5001'
65 }
66 })
67
68 def test_enable_discoveryauth(self):
69 discoveryauth = {
70 'user': 'myiscsiusername',
71 'password': 'myiscsipassword',
72 'mutual_user': 'myiscsiusername2',
73 'mutual_password': 'myiscsipassword2'
74 }
75 self._put('/api/iscsi/discoveryauth', discoveryauth)
76 self.assertStatus(200)
77 self.assertJsonBody(discoveryauth)
78 self._get('/api/iscsi/discoveryauth')
79 self.assertStatus(200)
80 self.assertJsonBody(discoveryauth)
81
82 def test_disable_discoveryauth(self):
83 discoveryauth = {
84 'user': '',
85 'password': '',
86 'mutual_user': '',
87 'mutual_password': ''
88 }
89 self._put('/api/iscsi/discoveryauth', discoveryauth)
90 self.assertStatus(200)
91 self.assertJsonBody(discoveryauth)
92 self._get('/api/iscsi/discoveryauth')
93 self.assertStatus(200)
94 self.assertJsonBody(discoveryauth)
95
96 def test_list_empty(self):
97 self._get('/api/iscsi/target')
98 self.assertStatus(200)
99 self.assertJsonBody([])
100
101 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
102 def test_list(self, _validate_image_mock):
103 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw1"
104 request = copy.deepcopy(iscsi_target_request)
105 request['target_iqn'] = target_iqn
106 self._task_post('/api/iscsi/target', request)
107 self.assertStatus(201)
108 self._get('/api/iscsi/target')
109 self.assertStatus(200)
110 response = copy.deepcopy(iscsi_target_response)
111 response['target_iqn'] = target_iqn
112 self.assertJsonBody([response])
113
114 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
115 def test_create(self, _validate_image_mock):
116 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw2"
117 request = copy.deepcopy(iscsi_target_request)
118 request['target_iqn'] = target_iqn
119 self._task_post('/api/iscsi/target', request)
120 self.assertStatus(201)
121 self._get('/api/iscsi/target/{}'.format(request['target_iqn']))
122 self.assertStatus(200)
123 response = copy.deepcopy(iscsi_target_response)
124 response['target_iqn'] = target_iqn
125 self.assertJsonBody(response)
126
127 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
128 def test_delete(self, _validate_image_mock):
129 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw3"
130 request = copy.deepcopy(iscsi_target_request)
131 request['target_iqn'] = target_iqn
132 self._task_post('/api/iscsi/target', request)
133 self.assertStatus(201)
134 self._task_delete('/api/iscsi/target/{}'.format(request['target_iqn']))
135 self.assertStatus(204)
136 self._get('/api/iscsi/target')
137 self.assertStatus(200)
138 self.assertJsonBody([])
139
140 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
141 def test_add_client(self, _validate_image_mock):
142 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw4"
143 create_request = copy.deepcopy(iscsi_target_request)
144 create_request['target_iqn'] = target_iqn
145 update_request = copy.deepcopy(create_request)
146 update_request['new_target_iqn'] = target_iqn
147 update_request['clients'].append(
148 {
149 "luns": [{"image": "lun1", "pool": "rbd"}],
150 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
151 "auth": {
152 "password": "myiscsipassword5",
153 "user": "myiscsiusername5",
154 "mutual_password": "myiscsipassword6",
155 "mutual_user": "myiscsiusername6"}
156 })
157 response = copy.deepcopy(iscsi_target_response)
158 response['target_iqn'] = target_iqn
159 response['clients'].append(
160 {
161 "luns": [{"image": "lun1", "pool": "rbd"}],
162 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
163 "auth": {
164 "password": "myiscsipassword5",
165 "user": "myiscsiusername5",
166 "mutual_password": "myiscsipassword6",
167 "mutual_user": "myiscsiusername6"},
168 "info": {
169 "alias": "",
170 "ip_address": [],
171 "state": {}
172 }
173 })
174 self._update_iscsi_target(create_request, update_request, response)
175
176 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
177 def test_change_client_password(self, _validate_image_mock):
178 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw5"
179 create_request = copy.deepcopy(iscsi_target_request)
180 create_request['target_iqn'] = target_iqn
181 update_request = copy.deepcopy(create_request)
182 update_request['new_target_iqn'] = target_iqn
183 update_request['clients'][0]['auth']['password'] = 'mynewiscsipassword'
184 response = copy.deepcopy(iscsi_target_response)
185 response['target_iqn'] = target_iqn
186 response['clients'][0]['auth']['password'] = 'mynewiscsipassword'
187 self._update_iscsi_target(create_request, update_request, response)
188
189 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
190 def test_rename_client(self, _validate_image_mock):
191 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw6"
192 create_request = copy.deepcopy(iscsi_target_request)
193 create_request['target_iqn'] = target_iqn
194 update_request = copy.deepcopy(create_request)
195 update_request['new_target_iqn'] = target_iqn
196 update_request['clients'][0]['client_iqn'] = 'iqn.1994-05.com.redhat:rh7-client0'
197 response = copy.deepcopy(iscsi_target_response)
198 response['target_iqn'] = target_iqn
199 response['clients'][0]['client_iqn'] = 'iqn.1994-05.com.redhat:rh7-client0'
200 self._update_iscsi_target(create_request, update_request, response)
201
202 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
203 def test_add_disk(self, _validate_image_mock):
204 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw7"
205 create_request = copy.deepcopy(iscsi_target_request)
206 create_request['target_iqn'] = target_iqn
207 update_request = copy.deepcopy(create_request)
208 update_request['new_target_iqn'] = target_iqn
209 update_request['disks'].append(
210 {
211 "image": "lun3",
212 "pool": "rbd",
213 "controls": {},
214 "backstore": "user:rbd"
215 })
216 update_request['clients'][0]['luns'].append({"image": "lun3", "pool": "rbd"})
217 response = copy.deepcopy(iscsi_target_response)
218 response['target_iqn'] = target_iqn
219 response['disks'].append(
220 {
221 "image": "lun3",
222 "pool": "rbd",
223 "controls": {},
224 "backstore": "user:rbd",
225 "wwn": "64af6678-9694-4367-bacc-f8eb0baa2",
226 "lun": 2
227
228 })
229 response['clients'][0]['luns'].append({"image": "lun3", "pool": "rbd"})
230 self._update_iscsi_target(create_request, update_request, response)
231
232 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
233 def test_change_disk_image(self, _validate_image_mock):
234 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw8"
235 create_request = copy.deepcopy(iscsi_target_request)
236 create_request['target_iqn'] = target_iqn
237 update_request = copy.deepcopy(create_request)
238 update_request['new_target_iqn'] = target_iqn
239 update_request['disks'][0]['image'] = 'lun0'
240 update_request['clients'][0]['luns'][0]['image'] = 'lun0'
241 response = copy.deepcopy(iscsi_target_response)
242 response['target_iqn'] = target_iqn
243 response['disks'][0]['image'] = 'lun0'
244 response['clients'][0]['luns'][0]['image'] = 'lun0'
245 self._update_iscsi_target(create_request, update_request, response)
246
247 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
248 def test_change_disk_controls(self, _validate_image_mock):
249 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw9"
250 create_request = copy.deepcopy(iscsi_target_request)
251 create_request['target_iqn'] = target_iqn
252 update_request = copy.deepcopy(create_request)
253 update_request['new_target_iqn'] = target_iqn
254 update_request['disks'][0]['controls'] = {"qfull_timeout": 15}
255 response = copy.deepcopy(iscsi_target_response)
256 response['target_iqn'] = target_iqn
257 response['disks'][0]['controls'] = {"qfull_timeout": 15}
258 self._update_iscsi_target(create_request, update_request, response)
259
260 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
261 def test_rename_target(self, _validate_image_mock):
262 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw10"
263 new_target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw11"
264 create_request = copy.deepcopy(iscsi_target_request)
265 create_request['target_iqn'] = target_iqn
266 update_request = copy.deepcopy(create_request)
267 update_request['new_target_iqn'] = new_target_iqn
268 response = copy.deepcopy(iscsi_target_response)
269 response['target_iqn'] = new_target_iqn
270 self._update_iscsi_target(create_request, update_request, response)
271
272 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
273 def test_rename_group(self, _validate_image_mock):
274 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw12"
275 create_request = copy.deepcopy(iscsi_target_request)
276 create_request['target_iqn'] = target_iqn
277 update_request = copy.deepcopy(create_request)
278 update_request['new_target_iqn'] = target_iqn
279 update_request['groups'][0]['group_id'] = 'mygroup0'
280 response = copy.deepcopy(iscsi_target_response)
281 response['target_iqn'] = target_iqn
282 response['groups'][0]['group_id'] = 'mygroup0'
283 self._update_iscsi_target(create_request, update_request, response)
284
285 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
286 def test_add_client_to_group(self, _validate_image_mock):
287 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw13"
288 create_request = copy.deepcopy(iscsi_target_request)
289 create_request['target_iqn'] = target_iqn
290 update_request = copy.deepcopy(create_request)
291 update_request['new_target_iqn'] = target_iqn
292 update_request['clients'].append(
293 {
294 "luns": [],
295 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
296 "auth": {
297 "password": None,
298 "user": None,
299 "mutual_password": None,
300 "mutual_user": None}
301 })
302 update_request['groups'][0]['members'].append('iqn.1994-05.com.redhat:rh7-client3')
303 response = copy.deepcopy(iscsi_target_response)
304 response['target_iqn'] = target_iqn
305 response['clients'].append(
306 {
307 "luns": [],
308 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
309 "auth": {
310 "password": None,
311 "user": None,
312 "mutual_password": None,
313 "mutual_user": None},
314 "info": {
315 "alias": "",
316 "ip_address": [],
317 "state": {}
318 }
319 })
320 response['groups'][0]['members'].append('iqn.1994-05.com.redhat:rh7-client3')
321 self._update_iscsi_target(create_request, update_request, response)
322
323 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
324 def test_remove_client_from_group(self, _validate_image_mock):
325 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw14"
326 create_request = copy.deepcopy(iscsi_target_request)
327 create_request['target_iqn'] = target_iqn
328 update_request = copy.deepcopy(create_request)
329 update_request['new_target_iqn'] = target_iqn
330 update_request['groups'][0]['members'].remove('iqn.1994-05.com.redhat:rh7-client2')
331 response = copy.deepcopy(iscsi_target_response)
332 response['target_iqn'] = target_iqn
333 response['groups'][0]['members'].remove('iqn.1994-05.com.redhat:rh7-client2')
334 self._update_iscsi_target(create_request, update_request, response)
335
336 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
337 def test_remove_groups(self, _validate_image_mock):
338 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw15"
339 create_request = copy.deepcopy(iscsi_target_request)
340 create_request['target_iqn'] = target_iqn
341 update_request = copy.deepcopy(create_request)
342 update_request['new_target_iqn'] = target_iqn
343 update_request['groups'] = []
344 response = copy.deepcopy(iscsi_target_response)
345 response['target_iqn'] = target_iqn
346 response['groups'] = []
347 self._update_iscsi_target(create_request, update_request, response)
348
349 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
350 def test_add_client_to_multiple_groups(self, _validate_image_mock):
351 target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw16"
352 create_request = copy.deepcopy(iscsi_target_request)
353 create_request['target_iqn'] = target_iqn
354 create_request['groups'].append(copy.deepcopy(create_request['groups'][0]))
355 create_request['groups'][1]['group_id'] = 'mygroup2'
356 self._task_post('/api/iscsi/target', create_request)
357 self.assertStatus(400)
358 self.assertJsonBody({
359 'detail': 'Each initiator can only be part of 1 group at a time',
360 'code': 'initiator_in_multiple_groups',
361 'component': 'iscsi'
362 })
363
364 def _update_iscsi_target(self, create_request, update_request, response):
365 self._task_post('/api/iscsi/target', create_request)
366 self.assertStatus(201)
367 self._task_put('/api/iscsi/target/{}'.format(create_request['target_iqn']), update_request)
368 self.assertStatus(200)
369 self._get('/api/iscsi/target/{}'.format(update_request['new_target_iqn']))
370 self.assertStatus(200)
371 self.assertJsonBody(response)
372
373
374 iscsi_target_request = {
375 "target_iqn": "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw",
376 "portals": [
377 {"ip": "192.168.100.202", "host": "node2"},
378 {"ip": "10.0.2.15", "host": "node2"},
379 {"ip": "192.168.100.203", "host": "node3"}
380 ],
381 "disks": [
382 {"image": "lun1", "pool": "rbd", "backstore": "user:rbd",
383 "controls": {"max_data_area_mb": 128}},
384 {"image": "lun2", "pool": "rbd", "backstore": "user:rbd",
385 "controls": {"max_data_area_mb": 128}}
386 ],
387 "clients": [
388 {
389 "luns": [{"image": "lun1", "pool": "rbd"}],
390 "client_iqn": "iqn.1994-05.com.redhat:rh7-client",
391 "auth": {
392 "password": "myiscsipassword1",
393 "user": "myiscsiusername1",
394 "mutual_password": "myiscsipassword2",
395 "mutual_user": "myiscsiusername2"}
396 },
397 {
398 "luns": [],
399 "client_iqn": "iqn.1994-05.com.redhat:rh7-client2",
400 "auth": {
401 "password": "myiscsipassword3",
402 "user": "myiscsiusername3",
403 "mutual_password": "myiscsipassword4",
404 "mutual_user": "myiscsiusername4"
405 }
406 }
407 ],
408 "acl_enabled": True,
409 "auth": {
410 "password": "",
411 "user": "",
412 "mutual_password": "",
413 "mutual_user": ""},
414 "target_controls": {},
415 "groups": [
416 {
417 "group_id": "mygroup",
418 "disks": [{"pool": "rbd", "image": "lun2"}],
419 "members": ["iqn.1994-05.com.redhat:rh7-client2"]
420 }
421 ]
422 }
423
424 iscsi_target_response = {
425 'target_iqn': 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw',
426 'portals': [
427 {'host': 'node2', 'ip': '10.0.2.15'},
428 {'host': 'node2', 'ip': '192.168.100.202'},
429 {'host': 'node3', 'ip': '192.168.100.203'}
430 ],
431 'disks': [
432 {'pool': 'rbd', 'image': 'lun1', 'backstore': 'user:rbd',
433 'wwn': '64af6678-9694-4367-bacc-f8eb0baa0', 'lun': 0,
434 'controls': {'max_data_area_mb': 128}},
435 {'pool': 'rbd', 'image': 'lun2', 'backstore': 'user:rbd',
436 'wwn': '64af6678-9694-4367-bacc-f8eb0baa1', 'lun': 1,
437 'controls': {'max_data_area_mb': 128}}
438 ],
439 'clients': [
440 {
441 'client_iqn': 'iqn.1994-05.com.redhat:rh7-client',
442 'luns': [{'pool': 'rbd', 'image': 'lun1'}],
443 'auth': {
444 'user': 'myiscsiusername1',
445 'password': 'myiscsipassword1',
446 'mutual_password': 'myiscsipassword2',
447 'mutual_user': 'myiscsiusername2'
448 },
449 'info': {
450 'alias': '',
451 'ip_address': [],
452 'state': {}
453 }
454 },
455 {
456 'client_iqn': 'iqn.1994-05.com.redhat:rh7-client2',
457 'luns': [],
458 'auth': {
459 'user': 'myiscsiusername3',
460 'password': 'myiscsipassword3',
461 'mutual_password': 'myiscsipassword4',
462 'mutual_user': 'myiscsiusername4'
463 },
464 'info': {
465 'alias': '',
466 'ip_address': [],
467 'state': {}
468 }
469 }
470 ],
471 "acl_enabled": True,
472 "auth": {
473 "password": "",
474 "user": "",
475 "mutual_password": "",
476 "mutual_user": ""},
477 'groups': [
478 {
479 'group_id': 'mygroup',
480 'disks': [{'pool': 'rbd', 'image': 'lun2'}],
481 'members': ['iqn.1994-05.com.redhat:rh7-client2']
482 }
483 ],
484 'target_controls': {},
485 'info': {
486 'num_sessions': 0
487 }
488 }
489
490
491 class IscsiClientMock(object):
492
493 _instance = None
494
495 def __init__(self):
496 self.gateway_name = None
497 self.service_url = None
498 self.config = {
499 "created": "2019/01/17 08:57:16",
500 "discovery_auth": {
501 "username": "",
502 "password": "",
503 "password_encryption_enabled": False,
504 "mutual_username": "",
505 "mutual_password": "",
506 "mutual_password_encryption_enabled": False
507 },
508 "disks": {},
509 "epoch": 0,
510 "gateways": {},
511 "targets": {},
512 "updated": "",
513 "version": 11
514 }
515
516 @classmethod
517 def instance(cls, gateway_name=None, service_url=None):
518 cls._instance.gateway_name = gateway_name
519 cls._instance.service_url = service_url
520 # pylint: disable=unused-argument
521 return cls._instance
522
523 def ping(self):
524 return {
525 "message": "pong"
526 }
527
528 def get_settings(self):
529 return {
530 "backstores": [
531 "user:rbd"
532 ],
533 "config": {
534 "minimum_gateways": 2
535 },
536 "default_backstore": "user:rbd",
537 "required_rbd_features": {
538 "rbd": 0,
539 "user:rbd": 4,
540 },
541 "unsupported_rbd_features": {
542 "rbd": 88,
543 "user:rbd": 0,
544 },
545 "disk_default_controls": {
546 "user:rbd": {
547 "hw_max_sectors": 1024,
548 "max_data_area_mb": 8,
549 "osd_op_timeout": 30,
550 "qfull_timeout": 5
551 }
552 },
553 "target_default_controls": {
554 "cmdsn_depth": 128,
555 "dataout_timeout": 20,
556 "first_burst_length": 262144,
557 "immediate_data": "Yes",
558 "initial_r2t": "Yes",
559 "max_burst_length": 524288,
560 "max_outstanding_r2t": 1,
561 "max_recv_data_segment_length": 262144,
562 "max_xmit_data_segment_length": 262144,
563 "nopin_response_timeout": 5,
564 "nopin_timeout": 5
565 }
566 }
567
568 def get_config(self):
569 return copy.deepcopy(self.config)
570
571 def create_target(self, target_iqn, target_controls):
572 self.config['targets'][target_iqn] = {
573 "clients": {},
574 "acl_enabled": True,
575 "auth": {
576 "username": "",
577 "password": "",
578 "password_encryption_enabled": False,
579 "mutual_username": "",
580 "mutual_password": "",
581 "mutual_password_encryption_enabled": False
582 },
583 "controls": target_controls,
584 "created": "2019/01/17 09:22:34",
585 "disks": {},
586 "groups": {},
587 "portals": {}
588 }
589
590 def create_gateway(self, target_iqn, gateway_name, ip_addresses):
591 target_config = self.config['targets'][target_iqn]
592 if 'ip_list' not in target_config:
593 target_config['ip_list'] = []
594 target_config['ip_list'] += ip_addresses
595 target_config['portals'][gateway_name] = {
596 "portal_ip_addresses": ip_addresses
597 }
598
599 def delete_gateway(self, target_iqn, gateway_name):
600 target_config = self.config['targets'][target_iqn]
601 portal_config = target_config['portals'][gateway_name]
602 for ip in portal_config['portal_ip_addresses']:
603 target_config['ip_list'].remove(ip)
604 target_config['portals'].pop(gateway_name)
605
606 def create_disk(self, pool, image, backstore, wwn):
607 if wwn is None:
608 wwn = '64af6678-9694-4367-bacc-f8eb0baa' + str(len(self.config['disks']))
609 image_id = '{}/{}'.format(pool, image)
610 self.config['disks'][image_id] = {
611 "pool": pool,
612 "image": image,
613 "backstore": backstore,
614 "controls": {},
615 "wwn": wwn
616 }
617
618 def create_target_lun(self, target_iqn, image_id, lun):
619 target_config = self.config['targets'][target_iqn]
620 if lun is None:
621 lun = len(target_config['disks'])
622 target_config['disks'][image_id] = {
623 "lun_id": lun
624 }
625 self.config['disks'][image_id]['owner'] = list(target_config['portals'].keys())[0]
626
627 def reconfigure_disk(self, pool, image, controls):
628 image_id = '{}/{}'.format(pool, image)
629 settings = self.get_settings()
630 backstore = self.config['disks'][image_id]['backstore']
631 disk_default_controls = settings['disk_default_controls'][backstore]
632 new_controls = {}
633 for control_k, control_v in controls.items():
634 if control_v != disk_default_controls[control_k]:
635 new_controls[control_k] = control_v
636 self.config['disks'][image_id]['controls'] = new_controls
637
638 def create_client(self, target_iqn, client_iqn):
639 target_config = self.config['targets'][target_iqn]
640 target_config['clients'][client_iqn] = {
641 "auth": {
642 "username": "",
643 "password": "",
644 "password_encryption_enabled": False,
645 "mutual_username": "",
646 "mutual_password": "",
647 "mutual_password_encryption_enabled": False
648 },
649 "group_name": "",
650 "luns": {}
651 }
652
653 def create_client_lun(self, target_iqn, client_iqn, image_id):
654 target_config = self.config['targets'][target_iqn]
655 target_config['clients'][client_iqn]['luns'][image_id] = {}
656
657 def delete_client_lun(self, target_iqn, client_iqn, image_id):
658 target_config = self.config['targets'][target_iqn]
659 del target_config['clients'][client_iqn]['luns'][image_id]
660
661 def create_client_auth(self, target_iqn, client_iqn, user, password, m_user, m_password):
662 target_config = self.config['targets'][target_iqn]
663 target_config['clients'][client_iqn]['auth']['username'] = user
664 target_config['clients'][client_iqn]['auth']['password'] = password
665 target_config['clients'][client_iqn]['auth']['mutual_username'] = m_user
666 target_config['clients'][client_iqn]['auth']['mutual_password'] = m_password
667
668 def create_group(self, target_iqn, group_name, members, image_ids):
669 target_config = self.config['targets'][target_iqn]
670 target_config['groups'][group_name] = {
671 "disks": {},
672 "members": []
673 }
674 for image_id in image_ids:
675 target_config['groups'][group_name]['disks'][image_id] = {}
676 target_config['groups'][group_name]['members'] = members
677
678 def delete_group(self, target_iqn, group_name):
679 target_config = self.config['targets'][target_iqn]
680 del target_config['groups'][group_name]
681
682 def delete_client(self, target_iqn, client_iqn):
683 target_config = self.config['targets'][target_iqn]
684 del target_config['clients'][client_iqn]
685
686 def delete_target_lun(self, target_iqn, image_id):
687 target_config = self.config['targets'][target_iqn]
688 target_config['disks'].pop(image_id)
689 del self.config['disks'][image_id]['owner']
690
691 def delete_disk(self, pool, image):
692 image_id = '{}/{}'.format(pool, image)
693 del self.config['disks'][image_id]
694
695 def delete_target(self, target_iqn):
696 del self.config['targets'][target_iqn]
697
698 def get_ip_addresses(self):
699 ips = {
700 'node1': ['192.168.100.201'],
701 'node2': ['192.168.100.202', '10.0.2.15'],
702 'node3': ['192.168.100.203']
703 }
704 return {'data': ips[self.gateway_name]}
705
706 def get_hostname(self):
707 hostnames = {
708 'https://admin:admin@10.17.5.1:5001': 'node1',
709 'https://admin:admin@10.17.5.2:5001': 'node2',
710 'https://admin:admin@10.17.5.3:5001': 'node3'
711 }
712 if self.service_url not in hostnames:
713 raise RequestException('No route to host')
714 return {'data': hostnames[self.service_url]}
715
716 def update_discoveryauth(self, user, password, mutual_user, mutual_password):
717 self.config['discovery_auth']['username'] = user
718 self.config['discovery_auth']['password'] = password
719 self.config['discovery_auth']['mutual_username'] = mutual_user
720 self.config['discovery_auth']['mutual_password'] = mutual_password
721
722 def update_targetacl(self, target_iqn, action):
723 self.config['targets'][target_iqn]['acl_enabled'] = (action == 'enable_acl')
724
725 def update_targetauth(self, target_iqn, user, password, mutual_user, mutual_password):
726 target_config = self.config['targets'][target_iqn]
727 target_config['auth']['username'] = user
728 target_config['auth']['password'] = password
729 target_config['auth']['mutual_username'] = mutual_user
730 target_config['auth']['mutual_password'] = mutual_password
731
732 def get_targetinfo(self, target_iqn):
733 # pylint: disable=unused-argument
734 return {
735 'num_sessions': 0
736 }
737
738 def get_clientinfo(self, target_iqn, client_iqn):
739 # pylint: disable=unused-argument
740 return {
741 'alias': '',
742 'ip_address': [],
743 'state': {}
744 }