From: Sagar Gopale Date: Wed, 18 Feb 2026 14:12:28 +0000 (+0530) Subject: mgr/dashboard: Nvmeof add hosts(Add Initiator) in subsystem details X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e84d51e04779855943b238d22405f2c6f4e739ed;p=ceph.git mgr/dashboard: Nvmeof add hosts(Add Initiator) in subsystem details Fixes: https://tracker.ceph.com/issues/75006 Signed-off-by: Sagar Gopale (cherry picked from commit bdacb3d7ab3507300c51b01b1728e66dd8b04147) Conflicts: src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.html --- diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts index 72ac8dc87fd5..5347979c3dac 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts @@ -443,6 +443,11 @@ const routes: Routes = [ { path: 'performance', component: NvmeofSubsystemPerformanceComponent + }, + { + path: `${URLVerbs.ADD}/initiator`, + component: NvmeofInitiatorsFormComponent, + outlet: 'modal' } ] } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvme-subsystem-view/nvme-subsystem-view.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvme-subsystem-view/nvme-subsystem-view.component.html index 7b63beee3a60..296351107ec2 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvme-subsystem-view/nvme-subsystem-view.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvme-subsystem-view/nvme-subsystem-view.component.html @@ -2,3 +2,5 @@ [title]="subsystemNQN" [items]="sidebarItems" > + + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvme-subsystem-view/nvme-subsystem-view.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvme-subsystem-view/nvme-subsystem-view.component.spec.ts index 254b68841348..f055b715a85b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvme-subsystem-view/nvme-subsystem-view.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvme-subsystem-view/nvme-subsystem-view.component.spec.ts @@ -4,6 +4,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { SideNavModule, ThemeModule } from 'carbon-components-angular'; import { NvmeSubsystemViewComponent } from './nvme-subsystem-view.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; describe('NvmeSubsystemViewComponent', () => { let component: NvmeSubsystemViewComponent; @@ -13,7 +14,7 @@ describe('NvmeSubsystemViewComponent', () => { waitForAsync(() => { TestBed.configureTestingModule({ declarations: [NvmeSubsystemViewComponent], - imports: [RouterTestingModule, SideNavModule, ThemeModule], + imports: [RouterTestingModule, SideNavModule, ThemeModule, HttpClientTestingModule], schemas: [CUSTOM_ELEMENTS_SCHEMA] }).compileComponents(); }) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.html index a0a61d7ae480..a6183a8acf08 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.html @@ -1,104 +1,17 @@ - - {{ action | titlecase }} {{ resource | upperFirst }} - -
- - -
-
-
+ + + + + + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.spec.ts index 7df77e1b99d9..e01943f65335 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.spec.ts @@ -2,6 +2,9 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ActivatedRoute } from '@angular/router'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { of } from 'rxjs'; import { ToastrModule } from 'ngx-toastr'; @@ -9,6 +12,7 @@ import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; import { SharedModule } from '~/app/shared/shared.module'; import { NvmeofService } from '~/app/shared/api/nvmeof.service'; +import { HOST_TYPE } from '~/app/shared/models/nvmeof'; import { NvmeofInitiatorsFormComponent } from './nvmeof-initiators-form.component'; @@ -22,7 +26,20 @@ describe('NvmeofInitiatorsFormComponent', () => { spyOn(Date, 'now').and.returnValue(mockTimestamp); await TestBed.configureTestingModule({ declarations: [NvmeofInitiatorsFormComponent], - providers: [NgbActiveModal], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + NgbActiveModal, + { + provide: ActivatedRoute, + useValue: { + queryParams: of({ group: 'test-group' }), + params: of({ subsystem_nqn: 'nqn.test' }), + parent: { + params: of({ subsystem_nqn: 'nqn.test' }) + } + } + } + ], imports: [ HttpClientTestingModule, NgbTypeaheadModule, @@ -46,15 +63,23 @@ describe('NvmeofInitiatorsFormComponent', () => { describe('should test form', () => { beforeEach(() => { nvmeofService = TestBed.inject(NvmeofService); - spyOn(nvmeofService, 'addSubsystemInitiators').and.stub(); + spyOn(nvmeofService, 'addInitiators').and.stub(); }); it('should be creating request correctly', () => { - const subsystemNQN = 'nqn.2001-07.com.ceph:' + mockTimestamp; + const subsystemNQN = 'nqn.test'; component.subsystemNQN = subsystemNQN; - component.onSubmit(); - expect(nvmeofService.addSubsystemInitiators).toHaveBeenCalledWith(subsystemNQN, { - host_nqn: '' + component.group = 'test-group'; + + const payload: any = { + hostType: HOST_TYPE.SPECIFIC, + addedHosts: ['host1'] + }; + + component.onSubmit(payload); + expect(nvmeofService.addInitiators).toHaveBeenCalledWith(subsystemNQN, { + host_nqn: 'host1', + gw_group: 'test-group' }); }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.ts index 2d2d93d3a1e9..329d08b9bd29 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-form/nvmeof-initiators-form.component.ts @@ -1,17 +1,11 @@ import { Component, OnInit } from '@angular/core'; -import { UntypedFormArray, UntypedFormControl, Validators } from '@angular/forms'; - -import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder'; -import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants'; -import { Icons } from '~/app/shared/enum/icons.enum'; -import { CdFormGroup } from '~/app/shared/forms/cd-form-group'; -import { CdValidators } from '~/app/shared/forms/cd-validators'; -import { Permission } from '~/app/shared/models/permissions'; -import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; -import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; +import { Step } from 'carbon-components-angular'; +import { InitiatorRequest, NvmeofService } from '~/app/shared/api/nvmeof.service'; import { FinishedTask } from '~/app/shared/models/finished-task'; +import { HOST_TYPE, NvmeofSubsystemInitiator } from '~/app/shared/models/nvmeof'; +import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; import { ActivatedRoute, Router } from '@angular/router'; -import { InitiatorRequest, NvmeofService } from '~/app/shared/api/nvmeof.service'; +import { SubsystemPayload } from '../nvmeof-subsystems-form/nvmeof-subsystems-form.component'; @Component({ selector: 'cd-nvmeof-initiators-form', @@ -19,123 +13,82 @@ import { InitiatorRequest, NvmeofService } from '~/app/shared/api/nvmeof.service styleUrls: ['./nvmeof-initiators-form.component.scss'] }) export class NvmeofInitiatorsFormComponent implements OnInit { - icons = Icons; - permission: Permission; - initiatorForm: CdFormGroup; - action: string; - resource: string; - pageURL: string; - remove: boolean = false; - subsystemNQN: string; - removeHosts: { name: string; value: boolean; id: number }[] = []; - group: string; + group!: string; + subsystemNQN!: string; + isSubmitLoading = false; + existingHosts: string[] = []; + + steps: Step[] = [ + { + label: $localize`Host access control`, + invalid: false + } + ]; + + title = $localize`Add Initiator`; + description = $localize`Allow specific hosts to run NVMe/TCP commands to the NVMe subsystem.`; + pageURL = 'block/nvmeof/subsystems'; constructor( - private authStorageService: AuthStorageService, - public actionLabels: ActionLabelsI18n, private nvmeofService: NvmeofService, private taskWrapperService: TaskWrapperService, private router: Router, - private route: ActivatedRoute, - private formBuilder: CdFormBuilder - ) { - this.permission = this.authStorageService.getPermissions().nvmeof; - this.resource = $localize`Initiator`; - this.pageURL = 'block/nvmeof/subsystems'; - } - - NQN_REGEX = /^nqn\.(19|20)\d\d-(0[1-9]|1[0-2])\.\D{2,3}(\.[A-Za-z0-9-]+)+(:[A-Za-z0-9-\.]+(:[A-Za-z0-9-\.]+)*)$/; - NQN_REGEX_UUID = /^nqn\.2014-08\.org\.nvmexpress:uuid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/; - ALLOW_ALL_HOST = '*'; - - customNQNValidator = CdValidators.custom( - 'pattern', - (nqnInput: string) => - !!nqnInput && !(this.NQN_REGEX.test(nqnInput) || this.NQN_REGEX_UUID.test(nqnInput)) - ); + private route: ActivatedRoute + ) {} ngOnInit() { this.route.queryParams.subscribe((params) => { this.group = params?.['group']; }); - this.createForm(); - this.action = this.actionLabels.ADD; - this.route.params.subscribe((params: { subsystem_nqn: string }) => { - this.subsystemNQN = params.subsystem_nqn; + this.route.parent.params.subscribe((params: any) => { + if (params.subsystem_nqn) { + this.subsystemNQN = params.subsystem_nqn; + } }); - } - - createForm() { - this.initiatorForm = new CdFormGroup({ - allowAnyHost: new UntypedFormControl(false), - addHost: new CdFormGroup({ - addHostCheck: new UntypedFormControl(false), - addedHosts: this.formBuilder.array( - [], - [ - CdValidators.custom( - 'duplicate', - (hosts: string[]) => !!hosts.length && new Set(hosts)?.size !== hosts.length - ) - ] - ) - }) + this.route.params.subscribe((params: any) => { + if (!this.subsystemNQN && params.subsystem_nqn) { + this.subsystemNQN = params.subsystem_nqn; + } + this.fetchExistingHosts(); }); } - get addedHosts(): UntypedFormArray { - return this.initiatorForm.get('addHost.addedHosts') as UntypedFormArray; - } - - addHost() { - let newHostFormGroup; - newHostFormGroup = this.formBuilder.control('', [this.customNQNValidator, Validators.required]); - this.addedHosts.push(newHostFormGroup); - } - - removeHost(index: number) { - this.addedHosts.removeAt(index); - } - - setAddHostCheck() { - const addHostCheck = this.initiatorForm.get('addHost.addHostCheck').value; - if (!addHostCheck) { - while (this.addedHosts.length !== 0) { - this.addedHosts.removeAt(0); - } - } else { - this.addHost(); - } + fetchExistingHosts() { + if (!this.subsystemNQN || !this.group) return; + this.nvmeofService + .getInitiators(this.subsystemNQN, this.group) + .subscribe((response: NvmeofSubsystemInitiator[] | { hosts: NvmeofSubsystemInitiator[] }) => { + const initiators = Array.isArray(response) ? response : response?.hosts || []; + this.existingHosts = initiators.map((i) => i.nqn); + }); } - onSubmit() { - const component = this; - const allowAnyHost: boolean = this.initiatorForm.getValue('allowAnyHost'); - const hosts: string[] = this.addedHosts.value; - let taskUrl = `nvmeof/initiator/${URLVerbs.ADD}`; + onSubmit(payload: SubsystemPayload) { + this.isSubmitLoading = true; + const taskUrl = `nvmeof/initiator/add`; const request: InitiatorRequest = { - host_nqn: hosts.join(','), + host_nqn: payload.hostType === HOST_TYPE.ALL ? '*' : payload.addedHosts.join(','), gw_group: this.group }; - - if (allowAnyHost) { - hosts.push('*'); - request['host_nqn'] = hosts.join(','); - } this.taskWrapperService .wrapTaskAroundCall({ task: new FinishedTask(taskUrl, { nqn: this.subsystemNQN }), - call: this.nvmeofService.addSubsystemInitiators(this.subsystemNQN, request) + call: this.nvmeofService.addInitiators(this.subsystemNQN, request) }) .subscribe({ - error() { - component.initiatorForm.setErrors({ cdSubmitButton: true }); + error: (err) => { + this.isSubmitLoading = false; + err.preventDefault(); }, complete: () => { - this.router.navigate([this.pageURL, { outlets: { modal: null } }]); + this.isSubmitLoading = false; + this.router.navigate([{ outlets: { modal: null } }], { + relativeTo: this.route.parent, + queryParamsHandling: 'preserve' + }); } }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.ts index 2c077f6ad47f..ebc58dcb18aa 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.ts @@ -92,10 +92,10 @@ export class NvmeofInitiatorsListComponent implements OnInit { permission: 'create', icon: Icons.add, click: () => - this.router.navigate( - [BASE_URL, { outlets: { modal: [URLVerbs.ADD, this.subsystemNQN, 'initiator'] } }], - { queryParams: { group: this.group } } - ), + this.router.navigate([{ outlets: { modal: [URLVerbs.ADD, 'initiator'] } }], { + queryParams: { group: this.group }, + relativeTo: this.route.parent + }), canBePrimary: (selection: CdTableSelection) => !selection.hasSelection, disable: () => this.hasAllHostsAllowed() }, @@ -205,7 +205,7 @@ export class NvmeofInitiatorsListComponent implements OnInit { nqn: this.subsystemNQN, plural: itemNames.length > 1 }), - call: this.nvmeofService.removeSubsystemInitiators(this.subsystemNQN, { + call: this.nvmeofService.removeInitiators(this.subsystemNQN, { host_nqn, gw_group: this.group }) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-listeners-form/nvmeof-listeners-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-listeners-form/nvmeof-listeners-form.component.ts index 81f639a57130..39393d5580cd 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-listeners-form/nvmeof-listeners-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-listeners-form/nvmeof-listeners-form.component.ts @@ -146,7 +146,9 @@ export class NvmeofListenersFormComponent implements OnInit { component.listenerForm.setErrors({ cdSubmitButton: true }); }, complete: () => { - this.router.navigate([this.pageURL, { outlets: { modal: null } }]); + this.router.navigate([this.pageURL, { outlets: { modal: null } }], { + queryParamsHandling: 'preserve' + }); } }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.html index 43e755f27bee..9dce1e45f3b3 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.html @@ -23,6 +23,7 @@ orientation="vertical"> Allow all hosts Any host can connect to this subsystem without verification. @@ -30,13 +31,18 @@ Allowing all hosts grants access to every initiator on the network. Authentication is not supported in this mode, which may expose the subsystem to unauthorized access. } - - Restrict to specific hosts + + Restrict to specific hosts - Add the specific hosts permitted to connect. diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.scss index 28149d5bd677..9cf1e5193146 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.scss @@ -15,7 +15,6 @@ &-specific-hosts-tag { max-inline-size: 17rem; - margin: 0 var(--cds-spacing-01); } &-influencer { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.ts index 254f09f6cc8d..9708e92ec56c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.ts @@ -17,6 +17,7 @@ import { TearsheetStep } from '~/app/shared/models/tearsheet-step'; }) export class NvmeofSubsystemsStepTwoComponent implements OnInit, TearsheetStep { @Input() group!: string; + @Input() existingHosts: string[] = []; @ViewChild('rightInfluencer', { static: true }) rightInfluencer?: TemplateRef; formGroup: CdFormGroup; @@ -37,6 +38,9 @@ export class NvmeofSubsystemsStepTwoComponent implements OnInit, TearsheetStep { ngOnInit() { this.createForm(); + this.formGroup.get('hostType').valueChanges.subscribe(() => { + this.formGroup.get('hostname').updateValueAndValidity(); + }); } isValidNQN = CdValidators.custom( @@ -46,7 +50,10 @@ export class NvmeofSubsystemsStepTwoComponent implements OnInit, TearsheetStep { isDuplicate = CdValidators.custom( 'duplicate', - (input: string) => !!input && this.formGroup?.get('addedHosts')?.value.includes(input) + (input: string) => + !!input && + (this.formGroup?.get('addedHosts')?.value.includes(input) || + this.existingHosts.includes(input)) ); isRequired = CdValidators.custom( diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystems-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystems-form.component.spec.ts index 78aae18c0f9c..4c7e3d6c3f0f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystems-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystems-form.component.spec.ts @@ -73,7 +73,7 @@ describe('NvmeofSubsystemsFormComponent', () => { beforeEach(() => { nvmeofService = TestBed.inject(NvmeofService); spyOn(nvmeofService, 'createSubsystem').and.returnValue(of({})); - spyOn(nvmeofService, 'addSubsystemInitiators').and.returnValue(of({})); + spyOn(nvmeofService, 'addInitiators').and.returnValue(of({})); }); it('should be creating request correctly', () => { @@ -100,7 +100,7 @@ describe('NvmeofSubsystemsFormComponent', () => { component.group = mockGroupName; component.onSubmit(payload); - expect(nvmeofService.addSubsystemInitiators).toHaveBeenCalledWith('test-nqn.default', { + expect(nvmeofService.addInitiators).toHaveBeenCalledWith('test-nqn.default', { host_nqn: '*', gw_group: mockGroupName }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystems-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystems-form.component.ts index 9845c96d4848..866452eb9d11 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystems-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystems-form.component.ts @@ -95,10 +95,7 @@ export class NvmeofSubsystemsFormComponent implements OnInit { { step: this.steps[1].label, call: () => - this.nvmeofService.addSubsystemInitiators( - `${payload.nqn}.${this.group}`, - initiatorRequest - ) + this.nvmeofService.addInitiators(`${payload.nqn}.${this.group}`, initiatorRequest) } ], stepResults diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nvmeof.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nvmeof.service.spec.ts index 44cc2b4db8d5..ede904c2f646 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nvmeof.service.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nvmeof.service.spec.ts @@ -198,13 +198,13 @@ describe('NvmeofService', () => { ); expect(req.request.method).toBe('GET'); }); - it('should call addSubsystemInitiators', () => { - service.addSubsystemInitiators(mockNQN, request).subscribe(); + it('should call addInitiators', () => { + service.addInitiators(mockNQN, request).subscribe(); const req = httpTesting.expectOne(`${UI_API_PATH}/subsystem/${mockNQN}/host`); expect(req.request.method).toBe('POST'); }); - it('should call removeSubsystemInitiators', () => { - service.removeSubsystemInitiators(mockNQN, request).subscribe(); + it('should call removeInitiators', () => { + service.removeInitiators(mockNQN, request).subscribe(); const req = httpTesting.expectOne( `${UI_API_PATH}/subsystem/${mockNQN}/host/${request.host_nqn}/${mockGroupName}` ); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nvmeof.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nvmeof.service.ts index 920e78c417a7..12641a0f2784 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nvmeof.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/nvmeof.service.ts @@ -182,7 +182,7 @@ export class NvmeofService { return this.http.get(`${API_PATH}/subsystem/${subsystemNQN}/host?gw_group=${group}`); } - addSubsystemInitiators(subsystemNQN: string, request: InitiatorRequest) { + addInitiators(subsystemNQN: string, request: InitiatorRequest) { return this.http.post(`${UI_API_PATH}/subsystem/${subsystemNQN}/host`, request, { observe: 'response' }); @@ -204,7 +204,7 @@ export class NvmeofService { }); } - removeSubsystemInitiators(subsystemNQN: string, request: InitiatorRequest) { + removeInitiators(subsystemNQN: string, request: InitiatorRequest) { return this.http.delete( `${UI_API_PATH}/subsystem/${subsystemNQN}/host/${request.host_nqn}/${request.gw_group}`, { @@ -213,15 +213,6 @@ export class NvmeofService { ); } - removeNamespaceInitiators(nsid: string, request: NamespaceInitiatorRequest) { - return this.http.delete( - `${UI_API_PATH}/namespace/${nsid}/host/${request.subsystem_nqn}/${request.host_nqn}/${request.gw_group}`, - { - observe: 'response' - } - ); - } - // Listeners listListeners(subsystemNQN: string, group: string) { return this.http.get(`${API_PATH}/subsystem/${subsystemNQN}/listener?gw_group=${group}`); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/tearsheet/tearsheet.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/tearsheet/tearsheet.component.html index 4b49eda01373..1c4f562d1473 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/tearsheet/tearsheet.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/tearsheet/tearsheet.component.html @@ -50,11 +50,13 @@ (click)="closeTearsheet()" size="xl" i18n>Cancel + @if (steps.length > 1) { + } @if (currentStep === lastStep) { + @if (steps.length > 1) { + } @if (currentStep === lastStep) {