]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/tests/test_iscsi.py
1 # pylint: disable=too-many-public-methods
8 from . import CmdException
, ControllerTestCase
, CLICommandTestMixin
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
16 class IscsiTest(ControllerTestCase
, CLICommandTestMixin
):
19 def setup_server(cls
):
20 OrchClient
.instance().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
])
29 # pylint: disable=protected-access
30 IscsiClientMock
._instance
= IscsiClientMock()
31 IscsiClient
.instance
= IscsiClientMock
.instance
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')
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]'.")
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'], {
51 'service_url': 'https://admin:admin@10.17.5.1:5001'
54 'service_url': 'https://admin:admin@10.17.5.2:5001'
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'], {
64 'service_url': 'https://admin:admin@10.17.5.2:5001'
68 def test_enable_discoveryauth(self
):
70 'user': 'myiscsiusername',
71 'password': 'myiscsipassword',
72 'mutual_user': 'myiscsiusername2',
73 'mutual_password': 'myiscsipassword2'
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
)
82 def test_disable_discoveryauth(self
):
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
)
96 def test_list_empty(self
):
97 self
._get
('/api/iscsi/target')
98 self
.assertStatus(200)
99 self
.assertJsonBody([])
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
._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
])
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
._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
)
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
._post
('/api/iscsi/target', request
)
133 self
.assertStatus(201)
134 self
._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([])
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(
149 "luns": [{"image": "lun1", "pool": "rbd"}],
150 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
152 "password": "myiscsipassword5",
153 "user": "myiscsiusername5",
154 "mutual_password": "myiscsipassword6",
155 "mutual_user": "myiscsiusername6"}
157 response
= copy
.deepcopy(iscsi_target_response
)
158 response
['target_iqn'] = target_iqn
159 response
['clients'].append(
161 "luns": [{"image": "lun1", "pool": "rbd"}],
162 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
164 "password": "myiscsipassword5",
165 "user": "myiscsiusername5",
166 "mutual_password": "myiscsipassword6",
167 "mutual_user": "myiscsiusername6"}
169 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
171 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
172 def test_change_client_password(self
, _validate_image_mock
):
173 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw5"
174 create_request
= copy
.deepcopy(iscsi_target_request
)
175 create_request
['target_iqn'] = target_iqn
176 update_request
= copy
.deepcopy(create_request
)
177 update_request
['new_target_iqn'] = target_iqn
178 update_request
['clients'][0]['auth']['password'] = 'mynewiscsipassword'
179 response
= copy
.deepcopy(iscsi_target_response
)
180 response
['target_iqn'] = target_iqn
181 response
['clients'][0]['auth']['password'] = 'mynewiscsipassword'
182 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
184 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
185 def test_rename_client(self
, _validate_image_mock
):
186 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw6"
187 create_request
= copy
.deepcopy(iscsi_target_request
)
188 create_request
['target_iqn'] = target_iqn
189 update_request
= copy
.deepcopy(create_request
)
190 update_request
['new_target_iqn'] = target_iqn
191 update_request
['clients'][0]['client_iqn'] = 'iqn.1994-05.com.redhat:rh7-client0'
192 response
= copy
.deepcopy(iscsi_target_response
)
193 response
['target_iqn'] = target_iqn
194 response
['clients'][0]['client_iqn'] = 'iqn.1994-05.com.redhat:rh7-client0'
195 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
197 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
198 def test_add_disk(self
, _validate_image_mock
):
199 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw7"
200 create_request
= copy
.deepcopy(iscsi_target_request
)
201 create_request
['target_iqn'] = target_iqn
202 update_request
= copy
.deepcopy(create_request
)
203 update_request
['new_target_iqn'] = target_iqn
204 update_request
['disks'].append(
209 "backstore": "user:rbd"
211 update_request
['clients'][0]['luns'].append({"image": "lun3", "pool": "rbd"})
212 response
= copy
.deepcopy(iscsi_target_response
)
213 response
['target_iqn'] = target_iqn
214 response
['disks'].append(
219 "backstore": "user:rbd"
221 response
['clients'][0]['luns'].append({"image": "lun3", "pool": "rbd"})
222 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
224 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
225 def test_change_disk_image(self
, _validate_image_mock
):
226 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw8"
227 create_request
= copy
.deepcopy(iscsi_target_request
)
228 create_request
['target_iqn'] = target_iqn
229 update_request
= copy
.deepcopy(create_request
)
230 update_request
['new_target_iqn'] = target_iqn
231 update_request
['disks'][0]['image'] = 'lun0'
232 update_request
['clients'][0]['luns'][0]['image'] = 'lun0'
233 response
= copy
.deepcopy(iscsi_target_response
)
234 response
['target_iqn'] = target_iqn
235 response
['disks'][0]['image'] = 'lun0'
236 response
['clients'][0]['luns'][0]['image'] = 'lun0'
237 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
239 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
240 def test_change_disk_controls(self
, _validate_image_mock
):
241 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw9"
242 create_request
= copy
.deepcopy(iscsi_target_request
)
243 create_request
['target_iqn'] = target_iqn
244 update_request
= copy
.deepcopy(create_request
)
245 update_request
['new_target_iqn'] = target_iqn
246 update_request
['disks'][0]['controls'] = {"qfull_timeout": 15}
247 response
= copy
.deepcopy(iscsi_target_response
)
248 response
['target_iqn'] = target_iqn
249 response
['disks'][0]['controls'] = {"qfull_timeout": 15}
250 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
252 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
253 def test_rename_target(self
, _validate_image_mock
):
254 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw10"
255 new_target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw11"
256 create_request
= copy
.deepcopy(iscsi_target_request
)
257 create_request
['target_iqn'] = target_iqn
258 update_request
= copy
.deepcopy(create_request
)
259 update_request
['new_target_iqn'] = new_target_iqn
260 response
= copy
.deepcopy(iscsi_target_response
)
261 response
['target_iqn'] = new_target_iqn
262 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
264 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
265 def test_rename_group(self
, _validate_image_mock
):
266 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw12"
267 create_request
= copy
.deepcopy(iscsi_target_request
)
268 create_request
['target_iqn'] = target_iqn
269 update_request
= copy
.deepcopy(create_request
)
270 update_request
['new_target_iqn'] = target_iqn
271 update_request
['groups'][0]['group_id'] = 'mygroup0'
272 response
= copy
.deepcopy(iscsi_target_response
)
273 response
['target_iqn'] = target_iqn
274 response
['groups'][0]['group_id'] = 'mygroup0'
275 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
277 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
278 def test_add_client_to_group(self
, _validate_image_mock
):
279 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw13"
280 create_request
= copy
.deepcopy(iscsi_target_request
)
281 create_request
['target_iqn'] = target_iqn
282 update_request
= copy
.deepcopy(create_request
)
283 update_request
['new_target_iqn'] = target_iqn
284 update_request
['clients'].append(
287 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
291 "mutual_password": None,
294 update_request
['groups'][0]['members'].append('iqn.1994-05.com.redhat:rh7-client3')
295 response
= copy
.deepcopy(iscsi_target_response
)
296 response
['target_iqn'] = target_iqn
297 response
['clients'].append(
300 "client_iqn": "iqn.1994-05.com.redhat:rh7-client3",
304 "mutual_password": None,
307 response
['groups'][0]['members'].append('iqn.1994-05.com.redhat:rh7-client3')
308 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
310 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
311 def test_remove_client_from_group(self
, _validate_image_mock
):
312 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw14"
313 create_request
= copy
.deepcopy(iscsi_target_request
)
314 create_request
['target_iqn'] = target_iqn
315 update_request
= copy
.deepcopy(create_request
)
316 update_request
['new_target_iqn'] = target_iqn
317 update_request
['groups'][0]['members'].remove('iqn.1994-05.com.redhat:rh7-client2')
318 response
= copy
.deepcopy(iscsi_target_response
)
319 response
['target_iqn'] = target_iqn
320 response
['groups'][0]['members'].remove('iqn.1994-05.com.redhat:rh7-client2')
321 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
323 @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image')
324 def test_remove_groups(self
, _validate_image_mock
):
325 target_iqn
= "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw15"
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'] = []
331 response
= copy
.deepcopy(iscsi_target_response
)
332 response
['target_iqn'] = target_iqn
333 response
['groups'] = []
334 self
._update
_iscsi
_target
(create_request
, update_request
, response
)
336 def _update_iscsi_target(self
, create_request
, update_request
, response
):
337 self
._post
('/api/iscsi/target', create_request
)
338 self
.assertStatus(201)
339 self
._put
('/api/iscsi/target/{}'.format(create_request
['target_iqn']), update_request
)
340 self
.assertStatus(200)
341 self
._get
('/api/iscsi/target/{}'.format(update_request
['new_target_iqn']))
342 self
.assertStatus(200)
343 self
.assertJsonBody(response
)
346 iscsi_target_request
= {
347 "target_iqn": "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw",
349 {"ip": "192.168.100.202", "host": "node2"},
350 {"ip": "10.0.2.15", "host": "node2"},
351 {"ip": "192.168.100.203", "host": "node3"}
354 {"image": "lun1", "pool": "rbd", "backstore": "user:rbd",
355 "controls": {"max_data_area_mb": 128}},
356 {"image": "lun2", "pool": "rbd", "backstore": "user:rbd",
357 "controls": {"max_data_area_mb": 128}}
361 "luns": [{"image": "lun1", "pool": "rbd"}],
362 "client_iqn": "iqn.1994-05.com.redhat:rh7-client",
364 "password": "myiscsipassword1",
365 "user": "myiscsiusername1",
366 "mutual_password": "myiscsipassword2",
367 "mutual_user": "myiscsiusername2"}
371 "client_iqn": "iqn.1994-05.com.redhat:rh7-client2",
373 "password": "myiscsipassword3",
374 "user": "myiscsiusername3",
375 "mutual_password": "myiscsipassword4",
376 "mutual_user": "myiscsiusername4"
381 "target_controls": {},
384 "group_id": "mygroup",
385 "disks": [{"pool": "rbd", "image": "lun2"}],
386 "members": ["iqn.1994-05.com.redhat:rh7-client2"]
391 iscsi_target_response
= {
392 'target_iqn': 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw',
394 {'host': 'node2', 'ip': '10.0.2.15'},
395 {'host': 'node2', 'ip': '192.168.100.202'},
396 {'host': 'node3', 'ip': '192.168.100.203'}
399 {'pool': 'rbd', 'image': 'lun1', 'backstore': 'user:rbd',
400 'controls': {'max_data_area_mb': 128}},
401 {'pool': 'rbd', 'image': 'lun2', 'backstore': 'user:rbd',
402 'controls': {'max_data_area_mb': 128}}
406 'client_iqn': 'iqn.1994-05.com.redhat:rh7-client',
407 'luns': [{'pool': 'rbd', 'image': 'lun1'}],
409 'user': 'myiscsiusername1',
410 'password': 'myiscsipassword1',
411 'mutual_password': 'myiscsipassword2',
412 'mutual_user': 'myiscsiusername2'
416 'client_iqn': 'iqn.1994-05.com.redhat:rh7-client2',
419 'user': 'myiscsiusername3',
420 'password': 'myiscsipassword3',
421 'mutual_password': 'myiscsipassword4',
422 'mutual_user': 'myiscsiusername4'
429 'group_id': 'mygroup',
430 'disks': [{'pool': 'rbd', 'image': 'lun2'}],
431 'members': ['iqn.1994-05.com.redhat:rh7-client2']
434 'target_controls': {},
441 class IscsiClientMock(object):
446 self
.gateway_name
= None
447 self
.service_url
= None
449 "created": "2019/01/17 08:57:16",
453 "password_encryption_enabled": False,
454 "mutual_username": "",
455 "mutual_password": "",
456 "mutual_password_encryption_enabled": False
467 def instance(cls
, gateway_name
=None, service_url
=None):
468 cls
._instance
.gateway_name
= gateway_name
469 cls
._instance
.service_url
= service_url
470 # pylint: disable=unused-argument
478 def get_settings(self
):
484 "minimum_gateways": 2
486 "default_backstore": "user:rbd",
487 "required_rbd_features": {
491 "supported_rbd_features": {
495 "disk_default_controls": {
497 "hw_max_sectors": 1024,
498 "max_data_area_mb": 8,
499 "osd_op_timeout": 30,
503 "target_default_controls": {
505 "dataout_timeout": 20,
506 "first_burst_length": 262144,
507 "immediate_data": "Yes",
508 "initial_r2t": "Yes",
509 "max_burst_length": 524288,
510 "max_outstanding_r2t": 1,
511 "max_recv_data_segment_length": 262144,
512 "max_xmit_data_segment_length": 262144,
513 "nopin_response_timeout": 5,
518 def get_config(self
):
521 def create_target(self
, target_iqn
, target_controls
):
522 self
.config
['targets'][target_iqn
] = {
525 "controls": target_controls
,
526 "created": "2019/01/17 09:22:34",
532 def create_gateway(self
, target_iqn
, gateway_name
, ip_address
):
533 target_config
= self
.config
['targets'][target_iqn
]
534 if 'ip_list' not in target_config
:
535 target_config
['ip_list'] = []
536 target_config
['ip_list'] += ip_address
537 target_config
['portals'][gateway_name
] = {
538 "portal_ip_address": ip_address
[0]
541 def create_disk(self
, pool
, image
, backstore
):
542 image_id
= '{}/{}'.format(pool
, image
)
543 self
.config
['disks'][image_id
] = {
546 "backstore": backstore
,
550 def create_target_lun(self
, target_iqn
, image_id
):
551 target_config
= self
.config
['targets'][target_iqn
]
552 target_config
['disks'].append(image_id
)
553 self
.config
['disks'][image_id
]['owner'] = list(target_config
['portals'].keys())[0]
555 def reconfigure_disk(self
, pool
, image
, controls
):
556 image_id
= '{}/{}'.format(pool
, image
)
557 self
.config
['disks'][image_id
]['controls'] = controls
559 def create_client(self
, target_iqn
, client_iqn
):
560 target_config
= self
.config
['targets'][target_iqn
]
561 target_config
['clients'][client_iqn
] = {
565 "password_encryption_enabled": False,
566 "mutual_username": "",
567 "mutual_password": "",
568 "mutual_password_encryption_enabled": False
574 def create_client_lun(self
, target_iqn
, client_iqn
, image_id
):
575 target_config
= self
.config
['targets'][target_iqn
]
576 target_config
['clients'][client_iqn
]['luns'][image_id
] = {}
578 def create_client_auth(self
, target_iqn
, client_iqn
, user
, password
, m_user
, m_password
):
579 target_config
= self
.config
['targets'][target_iqn
]
580 target_config
['clients'][client_iqn
]['auth']['username'] = user
581 target_config
['clients'][client_iqn
]['auth']['password'] = password
582 target_config
['clients'][client_iqn
]['auth']['mutual_username'] = m_user
583 target_config
['clients'][client_iqn
]['auth']['mutual_password'] = m_password
585 def create_group(self
, target_iqn
, group_name
, members
, image_ids
):
586 target_config
= self
.config
['targets'][target_iqn
]
587 target_config
['groups'][group_name
] = {
591 for image_id
in image_ids
:
592 target_config
['groups'][group_name
]['disks'][image_id
] = {}
593 target_config
['groups'][group_name
]['members'] = members
595 def delete_group(self
, target_iqn
, group_name
):
596 target_config
= self
.config
['targets'][target_iqn
]
597 del target_config
['groups'][group_name
]
599 def delete_client(self
, target_iqn
, client_iqn
):
600 target_config
= self
.config
['targets'][target_iqn
]
601 del target_config
['clients'][client_iqn
]
603 def delete_target_lun(self
, target_iqn
, image_id
):
604 target_config
= self
.config
['targets'][target_iqn
]
605 target_config
['disks'].remove(image_id
)
606 del self
.config
['disks'][image_id
]['owner']
608 def delete_disk(self
, pool
, image
):
609 image_id
= '{}/{}'.format(pool
, image
)
610 del self
.config
['disks'][image_id
]
612 def delete_target(self
, target_iqn
):
613 del self
.config
['targets'][target_iqn
]
615 def get_ip_addresses(self
):
617 'node1': ['192.168.100.201'],
618 'node2': ['192.168.100.202', '10.0.2.15'],
619 'node3': ['192.168.100.203']
621 return {'data': ips
[self
.gateway_name
]}
623 def get_hostname(self
):
625 'https://admin:admin@10.17.5.1:5001': 'node1',
626 'https://admin:admin@10.17.5.2:5001': 'node2',
627 'https://admin:admin@10.17.5.3:5001': 'node3'
629 if self
.service_url
not in hostnames
:
630 raise RequestException('No route to host')
631 return {'data': hostnames
[self
.service_url
]}
633 def update_discoveryauth(self
, user
, password
, mutual_user
, mutual_password
):
634 self
.config
['discovery_auth']['username'] = user
635 self
.config
['discovery_auth']['password'] = password
636 self
.config
['discovery_auth']['mutual_username'] = mutual_user
637 self
.config
['discovery_auth']['mutual_password'] = mutual_password
639 def update_targetauth(self
, target_iqn
, action
):
640 self
.config
['targets'][target_iqn
]['acl_enabled'] = (action
== 'enable_acl')
642 def get_targetinfo(self
, _
):