From d83f5dcdb905bd7b1de0ffaba951c7b6d491f467 Mon Sep 17 00:00:00 2001 From: pujashahu Date: Wed, 17 Jun 2026 18:37:24 +0530 Subject: [PATCH] mgr/dashboard: "Any" initiator entry appears in the Initiator table after selecting "All Hosts Allowed" during subsystem creation Fixes: https://tracker.ceph.com/issues/77467 Signed-off-by: pujaoshahu --- .../src/app/ceph/block/block.module.ts | 2 +- .../nvmeof-gateway-node.component.ts | 2 +- .../nvmeof-gateway-subsystem.component.ts | 2 +- .../nvmeof-initiators-list.component.html | 47 ++++++++++--------- .../nvmeof-initiators-list.component.spec.ts | 5 +- .../nvmeof-initiators-list.component.ts | 22 ++++++--- .../nvmeof-subsystems.component.ts | 2 +- .../src/app/shared/enum/nvmeof.enum.ts | 10 ---- .../frontend/src/app/shared/models/nvmeof.ts | 12 +++++ 9 files changed, 62 insertions(+), 42 deletions(-) delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/enum/nvmeof.enum.ts 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 b0852ec9b6b..cadf130be26 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 @@ -97,7 +97,7 @@ import { NvmeofGatewaySubsystemComponent } from './nvmeof-gateway-subsystem/nvme import { NvmeofNamespaceExpandModalComponent } from './nvmeof-namespace-expand-modal/nvmeof-namespace-expand-modal.component'; import { NvmeGatewayViewComponent } from './nvme-gateway-view/nvme-gateway-view.component'; import { NvmeGatewayViewBreadcrumbResolver } from './nvme-gateway-view/nvme-gateway-view-breadcrumb.resolver'; -import { NvmeofGatewayNodeMode } from '~/app/shared/enum/nvmeof.enum'; +import { NvmeofGatewayNodeMode } from '~/app/shared/models/nvmeof'; import { NvmeofGatewayNodeAddModalComponent } from './nvmeof-gateway-node/nvmeof-gateway-node-add-modal/nvmeof-gateway-node-add-modal.component'; import { NvmeofSubsystemNamespacesListComponent } from './nvmeof-subsystem-namespaces-list/nvmeof-subsystem-namespaces-list.component'; import { NvmeofSubsystemOverviewComponent } from './nvmeof-subsystem-overview/nvmeof-subsystem-overview.component'; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-node/nvmeof-gateway-node.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-node/nvmeof-gateway-node.component.ts index 32549d1a828..2de89e3a478 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-node/nvmeof-gateway-node.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-node/nvmeof-gateway-node.component.ts @@ -17,7 +17,6 @@ import _ from 'lodash'; import { TableComponent } from '~/app/shared/datatable/table/table.component'; import { HostStatus } from '~/app/shared/enum/host-status.enum'; import { Icons } from '~/app/shared/enum/icons.enum'; -import { NvmeofGatewayNodeMode } from '~/app/shared/enum/nvmeof.enum'; import { CdTableAction } from '~/app/shared/models/cd-table-action'; import { CdTableColumn } from '~/app/shared/models/cd-table-column'; import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context'; @@ -26,6 +25,7 @@ import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface'; import { Permission } from '~/app/shared/models/permissions'; import { Host } from '~/app/shared/models/host.interface'; +import { NvmeofGatewayNodeMode } from '~/app/shared/models/nvmeof'; import { CephServiceSpec, CephServiceSpecUpdate } from '~/app/shared/models/service.interface'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { CephServiceService } from '~/app/shared/api/ceph-service.service'; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-subsystem/nvmeof-gateway-subsystem.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-subsystem/nvmeof-gateway-subsystem.component.ts index ef6575e47ea..de6732de69e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-subsystem/nvmeof-gateway-subsystem.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-subsystem/nvmeof-gateway-subsystem.component.ts @@ -7,13 +7,13 @@ import { NvmeofSubsystem, NvmeofSubsystemData, NvmeofSubsystemInitiator, + NvmeofSubsystemAuthType, getSubsystemAuthStatus } from '~/app/shared/models/nvmeof'; import { CdTableColumn } from '~/app/shared/models/cd-table-column'; import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; import { ICON_TYPE, EMPTY_STATE_IMAGE } from '~/app/shared/enum/icons.enum'; -import { NvmeofSubsystemAuthType } from '~/app/shared/enum/nvmeof.enum'; @Component({ selector: 'cd-nvmeof-gateway-subsystem', diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.html index 97a520db0c6..8c924ce0152 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.html @@ -1,27 +1,21 @@ - -
+@if (hasAllHostsAllowed()) { +
- Host access: All hosts allowed -

+ gap="1"> + All hosts allowed +

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.

- Edit host access -
-
+ +} - - + + + {{ getDisplayedHostNqn(row.nqn) }} + + +
- {{ authStatus !== authType.NO_AUTH ? 'Yes' : 'No' }} + @if (row.nqn === allowAllHost) { + {{ '-' }} + } @else { + {{ authStatus !== authType.NO_AUTH ? yesLabel : noLabel }} + }
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.spec.ts index 2b42b8c339d..05d956256cb 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.spec.ts @@ -9,12 +9,13 @@ import { NvmeofService } from '~/app/shared/api/nvmeof.service'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { ModalService } from '~/app/shared/services/modal.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; +import { ALLOW_ALL_HOST } from '~/app/shared/models/nvmeof'; import { NvmeofInitiatorsListComponent } from './nvmeof-initiators-list.component'; const mockInitiators = [ { - nqn: '*', + nqn: ALLOW_ALL_HOST, use_dhchap: false } ]; @@ -79,6 +80,8 @@ describe('NvmeofInitiatorsListComponent', () => { expect(component.initiators).toEqual(mockInitiators); expect(component.subsystem).toEqual(mockSubsystem); expect(component.authStatus).toBe('No authentication'); + expect(component.initiatorColumns.length).toBe(2); + expect(component.getDisplayedHostNqn(ALLOW_ALL_HOST)).toBe('Any'); })); it('should update authStatus when initiator has dhchap_key', fakeAsync(() => { 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 e4f4bb14fb2..4aa5fccb460 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 @@ -12,10 +12,11 @@ import { FinishedTask } from '~/app/shared/models/finished-task'; import { NvmeofSubsystem, NvmeofSubsystemInitiator, + ALLOW_ALL_HOST, + NvmeofSubsystemAuthType, getSubsystemAuthStatus } from '~/app/shared/models/nvmeof'; import { Permission } from '~/app/shared/models/permissions'; -import { NvmeofSubsystemAuthType } from '~/app/shared/enum/nvmeof.enum'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { ModalCdsService } from '~/app/shared/services/modal-cds.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; @@ -35,6 +36,8 @@ export class NvmeofInitiatorsListComponent implements OnInit { @ViewChild('dhchapTpl', { static: true }) dhchapTpl: TemplateRef; + @ViewChild('hostNqnTpl', { static: true }) + hostNqnTpl: TemplateRef; initiatorColumns: CdTableColumn[]; tableActions: CdTableAction[]; @@ -44,6 +47,9 @@ export class NvmeofInitiatorsListComponent implements OnInit { subsystem: NvmeofSubsystem; authStatus: string; authType = NvmeofSubsystemAuthType; + allowAllHost = ALLOW_ALL_HOST; + yesLabel = $localize`Yes`; + noLabel = $localize`No`; constructor( public actionLabels: ActionLabelsI18n, @@ -78,7 +84,8 @@ export class NvmeofInitiatorsListComponent implements OnInit { this.initiatorColumns = [ { name: $localize`Host NQN`, - prop: 'nqn' + prop: 'nqn', + cellTemplate: this.hostNqnTpl }, { name: $localize`DHCHAP key`, @@ -96,8 +103,7 @@ export class NvmeofInitiatorsListComponent implements OnInit { queryParams: { group: this.group }, relativeTo: this.route.parent }), - canBePrimary: (selection: CdTableSelection) => !selection.hasSelection, - disable: () => this.hasAllHostsAllowed() + canBePrimary: (selection: CdTableSelection) => !selection.hasSelection }, { name: $localize`Edit host key`, @@ -137,11 +143,11 @@ export class NvmeofInitiatorsListComponent implements OnInit { } getAllowAllHostIndex() { - return this.selection.selected.findIndex((selected) => selected.nqn === '*'); + return this.selection.selected.findIndex((selected) => selected.nqn === ALLOW_ALL_HOST); } hasAllHostsAllowed(): boolean { - return this.initiators.some((initiator) => initiator.nqn === '*'); + return this.initiators.some((initiator) => initiator.nqn === ALLOW_ALL_HOST); } updateSelection(selection: CdTableSelection) { @@ -175,6 +181,10 @@ export class NvmeofInitiatorsListComponent implements OnInit { return this.selection.selected.map((selected) => selected.nqn); } + getDisplayedHostNqn(hostNqn: string): string { + return hostNqn === ALLOW_ALL_HOST ? $localize`Any` : hostNqn; + } + removeInitiatorModal() { const hostNQNs = this.getSelectedNQNs(); const allowAllHostIndex = this.getAllowAllHostIndex(); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems/nvmeof-subsystems.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems/nvmeof-subsystems.component.ts index 71c954d34ae..85590b314b5 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems/nvmeof-subsystems.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems/nvmeof-subsystems.component.ts @@ -5,6 +5,7 @@ import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; import { NvmeofSubsystem, NvmeofSubsystemInitiator, + NvmeofSubsystemAuthType, getSubsystemAuthStatus } from '~/app/shared/models/nvmeof'; import { Permissions } from '~/app/shared/models/permissions'; @@ -14,7 +15,6 @@ import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data import { CdTableAction } from '~/app/shared/models/cd-table-action'; import { Icons } from '~/app/shared/enum/icons.enum'; -import { NvmeofSubsystemAuthType } from '~/app/shared/enum/nvmeof.enum'; import { DeleteConfirmationModalComponent } from '~/app/shared/components/delete-confirmation-modal/delete-confirmation-modal.component'; import { FinishedTask } from '~/app/shared/models/finished-task'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/nvmeof.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/nvmeof.enum.ts deleted file mode 100644 index 816613dc595..00000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/nvmeof.enum.ts +++ /dev/null @@ -1,10 +0,0 @@ -export enum NvmeofSubsystemAuthType { - NO_AUTH = 'No authentication', - UNIDIRECTIONAL = 'Unidirectional', - BIDIRECTIONAL = 'Bi-directional' -} - -export enum NvmeofGatewayNodeMode { - SELECTOR = 'selector', - DETAILS = 'details' -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/nvmeof.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/nvmeof.ts index 11d7edab3b0..ccc43e72499 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/nvmeof.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/nvmeof.ts @@ -72,12 +72,24 @@ export interface NvmeofGatewayGroup extends CephServiceSpec { nodeCount: number; } +export enum NvmeofSubsystemAuthType { + NO_AUTH = 'No authentication', + UNIDIRECTIONAL = 'Unidirectional', + BIDIRECTIONAL = 'Bi-directional' +} + +export enum NvmeofGatewayNodeMode { + SELECTOR = 'selector', + DETAILS = 'details' +} + export enum AUTHENTICATION { Unidirectional = 'unidirectional', Bidirectional = 'bidirectional', None = 'none' } +export const ALLOW_ALL_HOST = '*'; export const NO_AUTH = 'No authentication'; export const HOST_TYPE = { -- 2.47.3