]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: NVMe-oF – Subsystem Resource page enhancements 69815/head
authorpujashahu <pshahu@redhat.com>
Fri, 3 Jul 2026 21:53:05 +0000 (03:23 +0530)
committerpujashahu <pshahu@redhat.com>
Fri, 3 Jul 2026 21:53:05 +0000 (03:23 +0530)
fixes:https://tracker.ceph.com/issues/77789

Signed-off-by: pujaoshahu <pshahu@redhat.com>
# 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

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-group-form/nvmeof-group-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.ts
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
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts

index b14b435e9dfb5287588b05fa39a3793c5fd8fb36..94cf5fc5b587b7be4e79cdd40ba9acbdc393f79d 100644 (file)
@@ -52,7 +52,7 @@
            class="form-item">
         <div cdsCol>
           <cds-checkbox id="enableCds"
-                        formControlName="enableEncryption"
+                        formControlName="enable_auth"
                         i18n>Enable encryption
           </cds-checkbox>
         </div>
                       cdValidate
                       #encryptionConfigRef="cdValidate"
                       [invalid]="encryptionConfigRef.isInvalid"
-                      formControlName="encryptionConfig"
+                      formControlName="encryptionKey"
                       cols="100"
                       rows="4"></textarea>
           </cds-textarea-label>
           <span
             class="invalid-feedback"
-            *ngIf="groupForm.showError('encryptionConfig', formDir, 'required')"
+            *ngIf="groupForm.showError('encryptionKey', formDir, 'required')"
             i18n>This field is required.</span>
         </div>
       </div>
index 640d7a7d0bc1ef405d43ed26eb92f552ea58f898..5b77ae89ceb200b68e3f481c58332f1577befa4e 100644 (file)
@@ -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(
index ac97aa3a3b8ee54c14c4c5bb786cdb8384d9f294..7053bbbe9f9a99555707279f7c757cc7effffdac 100644 (file)
@@ -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<string, any> = {
       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)
       })
index 4b4dc82ecf974d7fc1c2712a2acddbbad3fcb5e2..f86a3acb95df88242768319d276d57b17562ca70 100644 (file)
@@ -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');
index 1abf3c48262598ac1a4f1aedf960765a89d128a8..acb97b9a4e8ac273d28ed57d7028fb4e651f134f 100644 (file)
@@ -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,
index 3b56e8df9bd56fa0f5ca898a35ae2a1410894f2f..18fe82a0959b341ef8f1486948b8afb868dcb980 100644 (file)
@@ -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',
index c52f488b031727f7651cdb248df5e480eda72784..33f6d602c4cea26398c748df2c0c0e788c0fce56 100644 (file)
@@ -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'];
index feed57940b8c59cc5deb1a10dd3dff32c6b43287..51485d12c04f6652d2feb7c03869b0522cdd6532 100644 (file)
           }}
           @if (customFilter) {
           @for (filter of stagedCustomFilters; track filter.id; let i = $index) {
-            @if (isCustomFilterLabel()) {
+            @if (isCustomFilterString) {
               <div cdsRow
                    class="cds-mt-4 cds--type-body-02">
                 Filter {{ customFilter }}:
index d44f5f053b45fefaac200d35486be4b844ef270a..975905b9d37178048ea2c2752568d556f61e5ba4 100644 (file)
@@ -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';