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';
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';
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';
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',
-<cd-alert-panel
- *ngIf="hasAllHostsAllowed()"
- type="info"
- [showTitle]="false">
- <div cdsStack="horizontal"
- gap="2">
+@if (hasAllHostsAllowed()) {
+ <cd-alert-panel
+ class="cds-mb-4"
+ type="warning"
+ [showTitle]="false">
<div cdsStack="vertical"
- gap="2">
- <strong i18n>Host access: All hosts allowed</strong>
- <p
- class="cds-mb-0 cds-mt-1"
- i18n
- >
+ gap="1">
+ <strong class="cds-mb-1"
+ i18n>All hosts allowed</strong>
+ <p class="cds-mb-0"
+ i18n>
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.
</p>
</div>
- <a cdsLink
- class="text-nowrap cds-ml-3 text-muted"
- (click)="editHostAccess()"
- i18n>Edit host access</a>
- </div>
-</cd-alert-panel>
+ </cd-alert-panel>
+}
-<cd-table [data]="hasAllHostsAllowed() ? [] : initiators"
+<cd-table [data]="initiators"
columnMode="flex"
(fetchData)="listInitiators()"
[columns]="initiatorColumns"
</cd-table-actions>
</div>
</cd-table>
-<ng-template #dhchapTpl>
+
+<ng-template #hostNqnTpl
+ let-row="data.row">
+ {{ getDisplayedHostNqn(row.nqn) }}
+</ng-template>
+
+<ng-template #dhchapTpl
+ let-row="data.row">
<div cdsStack="horizontal"
gap="4">
- {{ authStatus !== authType.NO_AUTH ? 'Yes' : 'No' }}
+ @if (row.nqn === allowAllHost) {
+ {{ '-' }}
+ } @else {
+ {{ authStatus !== authType.NO_AUTH ? yesLabel : noLabel }}
+ }
</div>
</ng-template>
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
}
];
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(() => {
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';
@ViewChild('dhchapTpl', { static: true })
dhchapTpl: TemplateRef<any>;
+ @ViewChild('hostNqnTpl', { static: true })
+ hostNqnTpl: TemplateRef<any>;
initiatorColumns: CdTableColumn[];
tableActions: CdTableAction[];
subsystem: NvmeofSubsystem;
authStatus: string;
authType = NvmeofSubsystemAuthType;
+ allowAllHost = ALLOW_ALL_HOST;
+ yesLabel = $localize`Yes`;
+ noLabel = $localize`No`;
constructor(
public actionLabels: ActionLabelsI18n,
this.initiatorColumns = [
{
name: $localize`Host NQN`,
- prop: 'nqn'
+ prop: 'nqn',
+ cellTemplate: this.hostNqnTpl
},
{
name: $localize`DHCHAP key`,
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`,
}
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) {
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();
import {
NvmeofSubsystem,
NvmeofSubsystemInitiator,
+ NvmeofSubsystemAuthType,
getSubsystemAuthStatus
} from '~/app/shared/models/nvmeof';
import { Permissions } from '~/app/shared/models/permissions';
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';
+++ /dev/null
-export enum NvmeofSubsystemAuthType {
- NO_AUTH = 'No authentication',
- UNIDIRECTIONAL = 'Unidirectional',
- BIDIRECTIONAL = 'Bi-directional'
-}
-
-export enum NvmeofGatewayNodeMode {
- SELECTOR = 'selector',
- DETAILS = 'details'
-}
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 = {