From e6a2a8d996b12eb2e3b23884355905f523a64672 Mon Sep 17 00:00:00 2001 From: pujashahu Date: Sat, 4 Jul 2026 03:23:05 +0530 Subject: [PATCH] =?utf8?q?mgr/dashboard:=20NVMe-oF=20=E2=80=93=20Subsystem?= =?utf8?q?=20Resource=20page=20enhancements?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit fixes:https://tracker.ceph.com/issues/77789 Signed-off-by: pujaoshahu # Conflicts: # src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.html # src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.html # src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.spec.ts # src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.ts --- .../nvmeof-group-form.component.html | 6 +++--- .../nvmeof-group-form.component.spec.ts | 6 ++++-- .../nvmeof-group-form.component.ts | 10 +++++----- .../nvmeof-subsystem-overview.component.spec.ts | 2 ++ .../nvmeof-subsystem-overview.component.ts | 6 ++++++ .../service-form/service-form.component.spec.ts | 3 ++- .../service-form/service-form.component.ts | 15 ++++++++++----- .../shared/datatable/table/table.component.html | 2 +- .../app/shared/datatable/table/table.component.ts | 3 +++ 9 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.html index b14b435e9df..94cf5fc5b58 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.html @@ -52,7 +52,7 @@ class="form-item">
Enable encryption
@@ -74,13 +74,13 @@ cdValidate #encryptionConfigRef="cdValidate" [invalid]="encryptionConfigRef.isInvalid" - formControlName="encryptionConfig" + formControlName="encryptionKey" cols="100" rows="4"> This field is required. diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.spec.ts index 640d7a7d0bc..5b77ae89ceb 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.spec.ts @@ -43,7 +43,9 @@ describe('NvmeofGroupFormComponent', () => { SelectModule ], schemas: [CUSTOM_ELEMENTS_SCHEMA] - }).compileComponents(); + }) + .overrideTemplate(NvmeofGroupFormComponent, '') + .compileComponents(); fixture = TestBed.createComponent(NvmeofGroupFormComponent); component = fixture.componentInstance; @@ -159,7 +161,7 @@ describe('NvmeofGroupFormComponent', () => { component.groupForm.get('groupName').setValue('encrypted-group'); component.groupForm.get('enableEncryption').setValue(true); - component.groupForm.get('encryptionConfig').setValue('encryption-key-123'); + component.groupForm.get('encryptionKey').setValue('encryption-key-123'); component.onSubmit(); expect(cephServiceService.create).toHaveBeenCalledWith( diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.ts index ac97aa3a3b8..7053bbbe9f9 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.ts @@ -145,12 +145,12 @@ export class NvmeofGroupFormComponent extends CdForm implements OnInit { this.groupForm.setErrors({ cdSubmitButton: true }); return; } - let taskUrl = `service/${URLVerbs.CREATE}`; - const serviceName = `${formValues.groupName}`; + const taskUrl = `service/${URLVerbs.CREATE}`; + const serviceId = `${formValues.groupName}`; const serviceSpec: Record = { service_type: 'nvmeof', - service_id: serviceName, + service_id: serviceId, group: formValues.groupName, placement: { hosts: selectedHostnames @@ -173,7 +173,7 @@ export class NvmeofGroupFormComponent extends CdForm implements OnInit { if (formValues.pool) { serviceSpec['pool'] = formValues.pool; - serviceSpec['service_id'] = `${formValues.pool}.${serviceName}`; + serviceSpec['service_id'] = `${formValues.pool}.${formValues.groupName}`; } if ( @@ -195,7 +195,7 @@ export class NvmeofGroupFormComponent extends CdForm implements OnInit { this.taskWrapperService .wrapTaskAroundCall({ task: new FinishedTask(taskUrl, { - service_name: `nvmeof.${serviceName}` + service_name: `nvmeof.${serviceId}` }), call: this.cephServiceService.create(serviceSpec) }) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.spec.ts index 4b4dc82ecf9..f86a3acb95d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.spec.ts @@ -130,6 +130,7 @@ describe('NvmeofSubsystemOverviewComponent', () => { expect(component.subsystem.namespace_count).toBe(3); expect(component.subsystem.max_namespaces).toBe(256); expect(component.subsystem.gw_group).toBe('gateway-prod'); + expect(component.subsystem.subtype).toBe('NVMe'); })); it('should not fetch when subsystemNQN is missing', fakeAsync(async () => { @@ -152,6 +153,7 @@ describe('NvmeofSubsystemOverviewComponent', () => { expect(labelTexts).toContain('Serial number'); expect(labelTexts).toContain('Model Number'); expect(labelTexts).toContain('Gateway group'); + expect(labelTexts).toContain('Subsystem Type'); expect(labelTexts).toContain('Host access'); expect(labelTexts).toContain('Authentication'); expect(labelTexts).toContain('Listeners'); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.ts index 1abf3c48262..acb97b9a4e8 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.ts @@ -84,6 +84,12 @@ export class NvmeofSubsystemOverviewComponent implements OnInit { type: 'text', row: 1 }, + { + label: $localize`Subsystem Type`, + value: this.subsystem.subtype, + type: 'text', + row: 2 + }, { label: $localize`Host access`, value: this.subsystem.allow_any_host ?? false, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts index 3b56e8df9bd..18fe82a0959 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts @@ -597,12 +597,13 @@ x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA== component.onSubmit(); expect(cephServiceService.create).toHaveBeenCalledWith({ service_type: 'nvmeof', - service_id: 'default', + service_id: 'rbd.default', placement: {}, unmanaged: false, group: 'default', enable_auth: true, ssl: true, + pool: 'rbd', certificate_source: 'inline', root_ca_cert: 'root_ca_cert', client_cert: 'client_cert', diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts index c52f488b031..33f6d602c4c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts @@ -1198,6 +1198,10 @@ export class ServiceFormComponent extends CdForm implements OnInit { this.getDefaultPlacementCount(selectedServiceType); + if (selectedServiceType === 'nvmeof' && this.rbdPools?.length > 0) { + this.serviceForm.get('pool').setValue(this.rbdPools[0].pool_name); + } + if (selectedServiceType === 'rgw') { this.setRgwFields(); } @@ -1374,13 +1378,14 @@ export class ServiceFormComponent extends CdForm implements OnInit { serviceSpec['ssl'] = true; serviceSpec['certificate_source'] = values['certificateType'] === CertificateType.internal ? 'cephadm-signed' : 'inline'; - if ( - values['certificateType'] === CertificateType.internal && - values['custom_sans']?.length > 0 - ) { - serviceSpec['custom_sans'] = values['custom_sans']; + if (values['certificateType'] === CertificateType.internal) { + if (values['custom_sans']?.length > 0) { + serviceSpec['custom_sans'] = values['custom_sans']; + } } if (values['certificateType'] === CertificateType.external) { + serviceSpec['pool'] = values['pool']; + serviceSpec['service_id'] = `${values['pool']}.${values['group']}`; serviceSpec['root_ca_cert'] = values['root_ca_cert']; serviceSpec['client_cert'] = values['client_cert']; serviceSpec['client_key'] = values['client_key']; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html index feed57940b8..51485d12c04 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html @@ -127,7 +127,7 @@ }} @if (customFilter) { @for (filter of stagedCustomFilters; track filter.id; let i = $index) { - @if (isCustomFilterLabel()) { + @if (isCustomFilterString) {
Filter {{ customFilter }}: diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts index d44f5f053b4..975905b9d37 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts @@ -206,6 +206,9 @@ export class TableComponent implements AfterViewInit, OnInit, OnChanges, OnDestr */ @Input() customFilter: boolean | string = false; + get isCustomFilterString(): boolean { + return typeof this.customFilter === 'string'; + } isCustomFilterLabel(): boolean { return typeof this.customFilter === 'string'; -- 2.47.3