From 6cc6e8d5dba658ebfa87fe2ab9ec6e375cb11665 Mon Sep 17 00:00:00 2001 From: Ricardo Marques Date: Thu, 29 Aug 2019 15:28:23 +0100 Subject: [PATCH] mgr/dashboard: Support iSCSI target-level CHAP auth Requires `ceph-iscsi` config v11 Fixes: https://tracker.ceph.com/issues/41576 Signed-off-by: Ricardo Marques --- src/pybind/mgr/dashboard/controllers/iscsi.py | 81 +++++++++-- .../iscsi-target-details.component.ts | 19 ++- .../iscsi-target-form.component.html | 129 ++++++++++++++++++ .../iscsi-target-form.component.spec.ts | 33 ++++- .../iscsi-target-form.component.ts | 87 +++++++++--- .../iscsi-target-list.component.html | 1 + .../iscsi-target-list.component.spec.ts | 1 + .../iscsi-target-list.component.ts | 22 +-- .../src/app/shared/api/iscsi.service.ts | 4 + .../mgr/dashboard/services/iscsi_client.py | 16 ++- src/pybind/mgr/dashboard/tests/test_iscsi.py | 29 +++- 11 files changed, 372 insertions(+), 50 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/iscsi.py b/src/pybind/mgr/dashboard/controllers/iscsi.py index 300535dcac7..1714f9ae66f 100644 --- a/src/pybind/mgr/dashboard/controllers/iscsi.py +++ b/src/pybind/mgr/dashboard/controllers/iscsi.py @@ -25,7 +25,8 @@ from ..tools import TaskManager @UiApiController('/iscsi', Scope.ISCSI) class IscsiUi(BaseController): - REQUIRED_CEPH_ISCSI_CONFIG_VERSION = 10 + REQUIRED_CEPH_ISCSI_CONFIG_MIN_VERSION = 10 + REQUIRED_CEPH_ISCSI_CONFIG_MAX_VERSION = 11 @Endpoint() @ReadPermission @@ -43,10 +44,13 @@ class IscsiUi(BaseController): status['message'] = 'Gateway {} is inaccessible'.format(gateway) return status config = IscsiClient.instance().get_config() - if config['version'] != IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_VERSION: - status['message'] = 'Unsupported `ceph-iscsi` config version. Expected {} but ' \ - 'found {}.'.format(IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_VERSION, - config['version']) + if config['version'] < IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_MIN_VERSION or \ + config['version'] > IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_MAX_VERSION: + status['message'] = 'Unsupported `ceph-iscsi` config version. ' \ + 'Expected >= {} and <= {} but found' \ + ' {}.'.format(IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_MIN_VERSION, + IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_MAX_VERSION, + config['version']) return status status['available'] = True except RequestException as e: @@ -61,6 +65,13 @@ class IscsiUi(BaseController): return status + @Endpoint() + @ReadPermission + def version(self): + return { + 'ceph_iscsi_config_version': IscsiClient.instance().get_config()['version'] + } + @Endpoint() @ReadPermission def settings(self): @@ -216,7 +227,7 @@ class IscsiTarget(RESTController): @iscsi_target_task('create', {'target_iqn': '{target_iqn}'}) def create(self, target_iqn=None, target_controls=None, acl_enabled=None, - portals=None, disks=None, clients=None, groups=None): + auth=None, portals=None, disks=None, clients=None, groups=None): target_controls = target_controls or {} portals = portals or [] disks = disks or [] @@ -230,12 +241,13 @@ class IscsiTarget(RESTController): component='iscsi') settings = IscsiClient.instance().get_settings() IscsiTarget._validate(target_iqn, target_controls, portals, disks, groups, settings) - IscsiTarget._create(target_iqn, target_controls, acl_enabled, portals, disks, clients, - groups, 0, 100, config, settings) + + IscsiTarget._create(target_iqn, target_controls, acl_enabled, auth, portals, disks, + clients, groups, 0, 100, config, settings) @iscsi_target_task('edit', {'target_iqn': '{target_iqn}'}) def set(self, target_iqn, new_target_iqn=None, target_controls=None, acl_enabled=None, - portals=None, disks=None, clients=None, groups=None): + auth=None, portals=None, disks=None, clients=None, groups=None): target_controls = target_controls or {} portals = IscsiTarget._sorted_portals(portals) disks = IscsiTarget._sorted_disks(disks) @@ -255,8 +267,8 @@ class IscsiTarget(RESTController): IscsiTarget._validate(new_target_iqn, target_controls, portals, disks, groups, settings) config = IscsiTarget._delete(target_iqn, config, 0, 50, new_target_iqn, target_controls, portals, disks, clients, groups) - IscsiTarget._create(new_target_iqn, target_controls, acl_enabled, portals, disks, clients, - groups, 50, 100, config, settings) + IscsiTarget._create(new_target_iqn, target_controls, acl_enabled, auth, portals, disks, + clients, groups, 50, 100, config, settings) @staticmethod def _delete(target_iqn, config, task_progress_begin, task_progress_end, new_target_iqn=None, @@ -543,9 +555,30 @@ class IscsiTarget(RESTController): code='pool_does_not_exist', component='iscsi') + @staticmethod + def _update_targetauth(config, target_iqn, auth, gateway_name): + # Target level authentication was introduced in ceph-iscsi config v11 + if config['version'] > 10: + user = auth['user'] + password = auth['password'] + mutual_user = auth['mutual_user'] + mutual_password = auth['mutual_password'] + IscsiClient.instance(gateway_name=gateway_name).update_targetauth(target_iqn, + user, + password, + mutual_user, + mutual_password) + + @staticmethod + def _update_targetacl(target_config, target_iqn, acl_enabled, gateway_name): + if not target_config or target_config['acl_enabled'] != acl_enabled: + targetauth_action = ('enable_acl' if acl_enabled else 'disable_acl') + IscsiClient.instance(gateway_name=gateway_name).update_targetacl(target_iqn, + targetauth_action) + @staticmethod def _create(target_iqn, target_controls, acl_enabled, - portals, disks, clients, groups, + auth, portals, disks, clients, groups, task_progress_begin, task_progress_end, config, settings): target_config = config['targets'].get(target_iqn, None) TaskManager.current_task().set_progress(task_progress_begin) @@ -569,9 +602,15 @@ class IscsiTarget(RESTController): host, ip_list) TaskManager.current_task().inc_progress(task_progress_inc) - targetauth_action = ('enable_acl' if acl_enabled else 'disable_acl') - IscsiClient.instance(gateway_name=gateway_name).update_targetauth(target_iqn, - targetauth_action) + + if acl_enabled: + IscsiTarget._update_targetauth(config, target_iqn, auth, gateway_name) + IscsiTarget._update_targetacl(target_config, target_iqn, acl_enabled, gateway_name) + + else: + IscsiTarget._update_targetacl(target_config, target_iqn, acl_enabled, gateway_name) + IscsiTarget._update_targetauth(config, target_iqn, auth, gateway_name) + for disk in disks: pool = disk['pool'] image = disk['image'] @@ -721,6 +760,18 @@ class IscsiTarget(RESTController): 'target_controls': target_controls, 'acl_enabled': acl_enabled } + # Target level authentication was introduced in ceph-iscsi config v11 + if config['version'] > 10: + target_user = target_config['auth']['username'] + target_password = target_config['auth']['password'] + target_mutual_user = target_config['auth']['mutual_username'] + target_mutual_password = target_config['auth']['mutual_password'] + target['auth'] = { + 'user': target_user, + 'password': target_password, + 'mutual_user': target_mutual_user, + 'mutual_password': target_mutual_password + } return target @staticmethod diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts index 73af8e927ce..a3a9c2dd253 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts @@ -20,6 +20,8 @@ export class IscsiTargetDetailsComponent implements OnChanges, OnInit { selection: CdTableSelection; @Input() settings: any; + @Input() + cephIscsiConfigVersion: number; @ViewChild('highlightTpl', { static: true }) highlightTpl: TemplateRef; @@ -75,7 +77,12 @@ export class IscsiTargetDetailsComponent implements OnChanges, OnInit { } private generateTree() { - this.metadata = { root: this.selectedItem.target_controls }; + const target_meta = _.cloneDeep(this.selectedItem.target_controls); + // Target level authentication was introduced in ceph-iscsi config v11 + if (this.cephIscsiConfigVersion > 10) { + _.extend(target_meta, _.cloneDeep(this.selectedItem.auth)); + } + this.metadata = { root: target_meta }; const cssClasses = { target: { expanded: _.join( @@ -256,6 +263,16 @@ export class IscsiTargetDetailsComponent implements OnChanges, OnInit { current: tempData[key] || value }; }); + // Target level authentication was introduced in ceph-iscsi config v11 + if (this.cephIscsiConfigVersion > 10) { + ['user', 'password', 'mutual_user', 'mutual_password'].forEach((key) => { + this.data.push({ + displayName: key, + default: null, + current: tempData[key] + }); + }); + } } else if (e.node.id.toString().startsWith('disk_')) { this.columns[2].isHidden = false; this.data = _.map(this.settings.disk_default_controls[tempData.backstore], (value, key) => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html index cc9a27e71b4..bebb6e1b033 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html @@ -185,6 +185,135 @@ + +
+ + +
+ +
+ + + This field is required. + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. +
+
+ + +
+ +
+
+ + + + + + +
+ + This field is required. + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. +
+
+ + +
+ +
+ + + This field is required. + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. +
+
+ + +
+ +
+
+ + + + + + +
+ + This field is required. + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. +
+
+ +
+
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts index c4eb15dd40b..320afbd0af3 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts @@ -72,6 +72,10 @@ describe('IscsiTargetFormComponent', () => { { name: 'node2', ip_addresses: ['192.168.100.202'] } ]; + const VERSION = { + ceph_iscsi_config_version: 11 + }; + const RBD_LIST = [ { status: 0, value: [], pool_name: 'ganesha' }, { @@ -152,6 +156,7 @@ describe('IscsiTargetFormComponent', () => { httpTesting.expectOne('ui-api/iscsi/settings').flush(SETTINGS); httpTesting.expectOne('ui-api/iscsi/portals').flush(PORTALS); + httpTesting.expectOne('ui-api/iscsi/version').flush(VERSION); httpTesting.expectOne('api/summary').flush({}); httpTesting.expectOne('api/block/image').flush(RBD_LIST); httpTesting.expectOne('api/iscsi/target').flush(LIST_TARGET); @@ -183,6 +188,12 @@ describe('IscsiTargetFormComponent', () => { groups: [], initiators: [], acl_enabled: false, + auth: { + password: '', + user: '', + mutual_password: '', + mutual_user: '' + }, portals: [], target_controls: {}, target_iqn: component.targetForm.value.target_iqn @@ -386,7 +397,13 @@ describe('IscsiTargetFormComponent', () => { ], target_controls: {}, target_iqn: component.target_iqn, - acl_enabled: true + acl_enabled: true, + auth: { + password: '', + user: '', + mutual_password: '', + mutual_user: '' + } }); }); @@ -417,7 +434,13 @@ describe('IscsiTargetFormComponent', () => { ], target_controls: {}, target_iqn: component.targetForm.value.target_iqn, - acl_enabled: true + acl_enabled: true, + auth: { + password: '', + user: '', + mutual_password: '', + mutual_user: '' + } }); }); @@ -432,6 +455,12 @@ describe('IscsiTargetFormComponent', () => { disks: [{ backstore: 'backstore:1', controls: {}, image: 'disk_2', pool: 'rbd' }], groups: [], acl_enabled: false, + auth: { + password: '', + user: '', + mutual_password: '', + mutual_user: '' + }, portals: [ { host: 'node1', ip: '192.168.100.201' }, { host: 'node2', ip: '192.168.100.202' } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts index 576752539dc..96f5b84ad2b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts @@ -26,6 +26,7 @@ import { IscsiTargetIqnSettingsModalComponent } from '../iscsi-target-iqn-settin styleUrls: ['./iscsi-target-form.component.scss'] }) export class IscsiTargetFormComponent implements OnInit { + cephIscsiConfigVersion: number; targetForm: CdFormGroup; modalRef: BsModalRef; minimum_gateways = 1; @@ -103,7 +104,8 @@ export class IscsiTargetFormComponent implements OnInit { this.iscsiService.listTargets(), this.rbdService.list(), this.iscsiService.portals(), - this.iscsiService.settings() + this.iscsiService.settings(), + this.iscsiService.version() ]; if (this.router.url.startsWith('/block/iscsi/targets/edit')) { @@ -163,11 +165,14 @@ export class IscsiTargetFormComponent implements OnInit { }); this.portalsSelections = [...portals]; + // iscsiService.version() + this.cephIscsiConfigVersion = data[4]['ceph_iscsi_config_version']; + this.createForm(); // iscsiService.getTarget() - if (data[4]) { - this.resolveModel(data[4]); + if (data[5]) { + this.resolveModel(data[5]); } }); } @@ -191,6 +196,17 @@ export class IscsiTargetFormComponent implements OnInit { groups: new FormArray([]), acl_enabled: new FormControl(false) }); + // Target level authentication was introduced in ceph-iscsi config v11 + if (this.cephIscsiConfigVersion > 10) { + const authFormGroup = new CdFormGroup({ + user: new FormControl(''), + password: new FormControl(''), + mutual_user: new FormControl(''), + mutual_password: new FormControl('') + }); + this.setAuthValidator(authFormGroup); + this.targetForm.addControl('auth', authFormGroup); + } } resolveModel(res) { @@ -199,7 +215,12 @@ export class IscsiTargetFormComponent implements OnInit { target_controls: res.target_controls, acl_enabled: res.acl_enabled }); - + // Target level authentication was introduced in ceph-iscsi config v11 + if (this.cephIscsiConfigVersion > 10) { + this.targetForm.patchValue({ + auth: res.auth + }); + } const portals = []; _.forEach(res.portals, (portal) => { const id = `${portal.host}:${portal.ip}`; @@ -372,6 +393,25 @@ export class IscsiTargetFormComponent implements OnInit { cdIsInGroup: new FormControl(false) }); + this.setAuthValidator(fg); + + this.initiators.push(fg); + + _.forEach(this.groupMembersSelections, (selections, i) => { + selections.push(new SelectOption(false, '', '')); + this.groupMembersSelections[i] = [...selections]; + }); + + const disks = _.map( + this.targetForm.getValue('disks'), + (disk) => new SelectOption(false, disk, '') + ); + this.imagesInitiatorSelections.push(disks); + + return fg; + } + + setAuthValidator(fg: CdFormGroup) { CdValidators.validateIf( fg.get('user'), () => fg.getValue('password') || fg.getValue('mutual_user') || fg.getValue('mutual_password'), @@ -403,21 +443,6 @@ export class IscsiTargetFormComponent implements OnInit { [Validators.pattern(this.PASSWORD_REGEX)], [fg.get('user'), fg.get('password'), fg.get('mutual_user')] ); - - this.initiators.push(fg); - - _.forEach(this.groupMembersSelections, (selections, i) => { - selections.push(new SelectOption(false, '', '')); - this.groupMembersSelections[i] = [...selections]; - }); - - const disks = _.map( - this.targetForm.getValue('disks'), - (disk) => new SelectOption(false, disk, '') - ); - this.imagesInitiatorSelections.push(disks); - - return fg; } removeInitiator(index) { @@ -570,6 +595,30 @@ export class IscsiTargetFormComponent implements OnInit { groups: [] }; + // Target level authentication was introduced in ceph-iscsi config v11 + if (this.cephIscsiConfigVersion > 10) { + const targetAuth: CdFormGroup = this.targetForm.get('auth') as CdFormGroup; + if (!targetAuth.getValue('user')) { + targetAuth.get('user').setValue(''); + } + if (!targetAuth.getValue('password')) { + targetAuth.get('password').setValue(''); + } + if (!targetAuth.getValue('mutual_user')) { + targetAuth.get('mutual_user').setValue(''); + } + if (!targetAuth.getValue('mutual_password')) { + targetAuth.get('mutual_password').setValue(''); + } + const acl_enabled = this.targetForm.getValue('acl_enabled'); + request['auth'] = { + user: acl_enabled ? '' : targetAuth.getValue('user'), + password: acl_enabled ? '' : targetAuth.getValue('password'), + mutual_user: acl_enabled ? '' : targetAuth.getValue('mutual_user'), + mutual_password: acl_enabled ? '' : targetAuth.getValue('mutual_password') + }; + } + // Disks formValue.disks.forEach((disk) => { const imageSplit = disk.split('/'); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html index e5e7677d2b4..50ec0599d23 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html @@ -42,6 +42,7 @@ diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts index 3a4a845e31d..3c4a7227d48 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts @@ -57,6 +57,7 @@ describe('IscsiTargetListComponent', () => { summaryService['summaryData$'] = summaryService['summaryDataSource'].asObservable(); spyOn(iscsiService, 'status').and.returnValue(of({ available: true })); + spyOn(iscsiService, 'version').and.returnValue(of({ ceph_iscsi_config_version: 11 })); }); it('should create', () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts index 01c373f1630..7a06de5a023 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts @@ -39,6 +39,7 @@ export class IscsiTargetListComponent implements OnInit, OnDestroy { modalRef: BsModalRef; permission: Permission; selection = new CdTableSelection(); + cephIscsiConfigVersion: number; settings: any; status: string; summaryDataSubscription: Subscription; @@ -120,15 +121,18 @@ export class IscsiTargetListComponent implements OnInit, OnDestroy { this.available = result.available; if (result.available) { - this.taskListService.init( - () => this.iscsiService.listTargets(), - (resp) => this.prepareResponse(resp), - (targets) => (this.targets = targets), - () => this.onFetchError(), - this.taskFilter, - this.itemFilter, - this.builders - ); + this.iscsiService.version().subscribe((res: any) => { + this.cephIscsiConfigVersion = res['ceph_iscsi_config_version']; + this.taskListService.init( + () => this.iscsiService.listTargets(), + (resp) => this.prepareResponse(resp), + (targets) => (this.targets = targets), + () => this.onFetchError(), + this.taskFilter, + this.itemFilter, + this.builders + ); + }); this.iscsiService.settings().subscribe((settings: any) => { this.settings = settings; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts index 0c1ec456552..ff2794bf90f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts @@ -82,6 +82,10 @@ export class IscsiService { return this.http.get(`ui-api/iscsi/settings`); } + version() { + return this.http.get(`ui-api/iscsi/version`); + } + portals() { return this.http.get(`ui-api/iscsi/portals`); } diff --git a/src/pybind/mgr/dashboard/services/iscsi_client.py b/src/pybind/mgr/dashboard/services/iscsi_client.py index 773b4cef87b..40f6bf9b87c 100644 --- a/src/pybind/mgr/dashboard/services/iscsi_client.py +++ b/src/pybind/mgr/dashboard/services/iscsi_client.py @@ -209,12 +209,24 @@ class IscsiClient(RestClient): }) @RestClient.api_put('/api/targetauth/{target_iqn}') - def update_targetauth(self, target_iqn, action, request=None): - logger.debug("iSCSI[%s] Updating targetauth: %s/%s", self.gateway_name, target_iqn, action) + def update_targetacl(self, target_iqn, action, request=None): + logger.debug("iSCSI[%s] Updating targetacl: %s/%s", self.gateway_name, target_iqn, action) return request({ 'action': action }) + @RestClient.api_put('/api/targetauth/{target_iqn}') + def update_targetauth(self, target_iqn, user, password, mutual_user, mutual_password, + request=None): + logger.debug("iSCSI[%s] Updating targetauth: %s/%s/%s/%s/%s", self.gateway_name, + target_iqn, user, password, mutual_user, mutual_password) + return request({ + 'username': user, + 'password': password, + 'mutual_username': mutual_user, + 'mutual_password': mutual_password + }) + @RestClient.api_get('/api/targetinfo/{target_iqn}') def get_targetinfo(self, target_iqn, request=None): # pylint: disable=unused-argument diff --git a/src/pybind/mgr/dashboard/tests/test_iscsi.py b/src/pybind/mgr/dashboard/tests/test_iscsi.py index 4b59155b70a..9fa669a3bac 100644 --- a/src/pybind/mgr/dashboard/tests/test_iscsi.py +++ b/src/pybind/mgr/dashboard/tests/test_iscsi.py @@ -407,6 +407,11 @@ iscsi_target_request = { } ], "acl_enabled": True, + "auth": { + "password": "", + "user": "", + "mutual_password": "", + "mutual_user": ""}, "target_controls": {}, "groups": [ { @@ -463,6 +468,11 @@ iscsi_target_response = { } ], "acl_enabled": True, + "auth": { + "password": "", + "user": "", + "mutual_password": "", + "mutual_user": ""}, 'groups': [ { 'group_id': 'mygroup', @@ -499,7 +509,7 @@ class IscsiClientMock(object): "gateways": {}, "targets": {}, "updated": "", - "version": 9 + "version": 11 } @classmethod @@ -561,6 +571,14 @@ class IscsiClientMock(object): self.config['targets'][target_iqn] = { "clients": {}, "acl_enabled": True, + "auth": { + "username": "", + "password": "", + "password_encryption_enabled": False, + "mutual_username": "", + "mutual_password": "", + "mutual_password_encryption_enabled": False + }, "controls": target_controls, "created": "2019/01/17 09:22:34", "disks": [], @@ -689,9 +707,16 @@ class IscsiClientMock(object): self.config['discovery_auth']['mutual_username'] = mutual_user self.config['discovery_auth']['mutual_password'] = mutual_password - def update_targetauth(self, target_iqn, action): + def update_targetacl(self, target_iqn, action): self.config['targets'][target_iqn]['acl_enabled'] = (action == 'enable_acl') + def update_targetauth(self, target_iqn, user, password, mutual_user, mutual_password): + target_config = self.config['targets'][target_iqn] + target_config['auth']['username'] = user + target_config['auth']['password'] = password + target_config['auth']['mutual_username'] = mutual_user + target_config['auth']['mutual_password'] = mutual_password + def get_targetinfo(self, target_iqn): # pylint: disable=unused-argument return { -- 2.39.5