]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/blob
4da1696fffead47c9c4bc9cddf133e9d62f1f9b6
[ceph.git] /
1 import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core';
2 import { ActivatedRoute, Router } from '@angular/router';
3 import { NvmeofService } from '~/app/shared/api/nvmeof.service';
4 import { DeleteConfirmationModalComponent } from '~/app/shared/components/delete-confirmation-modal/delete-confirmation-modal.component';
5 import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
6 import { Icons } from '~/app/shared/enum/icons.enum';
7 import { CdTableAction } from '~/app/shared/models/cd-table-action';
8 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
9 import { FinishedTask } from '~/app/shared/models/finished-task';
10 import {
11   NvmeofSubsystem,
12   NvmeofSubsystemInitiator,
13   getSubsystemAuthStatus
14 } from '~/app/shared/models/nvmeof';
15 import { Permission } from '~/app/shared/models/permissions';
16 import { NvmeofSubsystemAuthType } from '~/app/shared/enum/nvmeof.enum';
17 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
18 import { ModalCdsService } from '~/app/shared/services/modal-cds.service';
19 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
20
21 const BASE_URL = 'block/nvmeof/subsystems';
22
23 @Component({
24   selector: 'cd-nvmeof-initiators-list',
25   templateUrl: './nvmeof-initiators-list.component.html',
26   styleUrls: ['./nvmeof-initiators-list.component.scss'],
27   standalone: false
28 })
29 export class NvmeofInitiatorsListComponent implements OnInit {
30   @Input()
31   subsystemNQN: string;
32   @Input()
33   group: string;
34
35   @ViewChild('dhchapTpl', { static: true })
36   dhchapTpl: TemplateRef<any>;
37
38   initiatorColumns: any;
39   tableActions: CdTableAction[];
40   selection = new CdTableSelection();
41   permission: Permission;
42   initiators: NvmeofSubsystemInitiator[] = [];
43   subsystem: NvmeofSubsystem;
44   authStatus: string;
45   authType = NvmeofSubsystemAuthType;
46
47   constructor(
48     public actionLabels: ActionLabelsI18n,
49     private authStorageService: AuthStorageService,
50     private nvmeofService: NvmeofService,
51     private modalService: ModalCdsService,
52     private router: Router,
53     private taskWrapper: TaskWrapperService,
54     private route: ActivatedRoute
55   ) {
56     this.permission = this.authStorageService.getPermissions().nvmeof;
57   }
58
59   ngOnInit() {
60     if (!this.subsystemNQN || !this.group) {
61       this.route.parent?.params.subscribe((params) => {
62         if (params['subsystem_nqn']) {
63           this.subsystemNQN = params['subsystem_nqn'];
64         }
65         this.fetchIfReady();
66       });
67       this.route.queryParams.subscribe((qp) => {
68         if (qp['group']) {
69           this.group = qp['group'];
70         }
71         this.fetchIfReady();
72       });
73     } else {
74       this.getSubsystem();
75     }
76
77     this.initiatorColumns = [
78       {
79         name: $localize`Host NQN`,
80         prop: 'nqn'
81       },
82       {
83         name: $localize`DHCHAP key`,
84         prop: 'dhchap_key',
85         cellTemplate: this.dhchapTpl
86       }
87     ];
88     this.tableActions = [
89       {
90         name: this.actionLabels.ADD,
91         permission: 'create',
92         icon: Icons.add,
93         click: () =>
94           this.router.navigate(
95             [BASE_URL, { outlets: { modal: [URLVerbs.ADD, this.subsystemNQN, 'initiator'] } }],
96             { queryParams: { group: this.group } }
97           ),
98         canBePrimary: (selection: CdTableSelection) => !selection.hasSelection,
99         disable: () => this.hasAllHostsAllowed()
100       },
101       {
102         name: this.actionLabels.REMOVE,
103         permission: 'delete',
104         icon: Icons.destroy,
105         click: () => this.removeInitiatorModal(),
106         disable: () => !this.selection.hasSelection,
107         canBePrimary: (selection: CdTableSelection) => selection.hasSelection
108       }
109     ];
110   }
111
112   private fetchIfReady() {
113     if (this.subsystemNQN && this.group) {
114       this.listInitiators();
115       this.getSubsystem();
116     }
117   }
118
119   getAllowAllHostIndex() {
120     return this.selection.selected.findIndex((selected) => selected.nqn === '*');
121   }
122
123   hasAllHostsAllowed(): boolean {
124     return this.initiators.some((initiator) => initiator.nqn === '*');
125   }
126
127   editHostAccess() {
128     this.router.navigate(
129       [BASE_URL, { outlets: { modal: [URLVerbs.ADD, this.subsystemNQN, 'initiator'] } }],
130       { queryParams: { group: this.group } }
131     );
132   }
133
134   updateSelection(selection: CdTableSelection) {
135     this.selection = selection;
136   }
137
138   listInitiators() {
139     this.nvmeofService
140       .getInitiators(this.subsystemNQN, this.group)
141       .subscribe((initiators: NvmeofSubsystemInitiator[]) => {
142         this.initiators = initiators;
143         this.updateAuthStatus();
144       });
145   }
146
147   getSubsystem() {
148     this.nvmeofService.getSubsystem(this.subsystemNQN, this.group).subscribe((subsystem: any) => {
149       this.subsystem = subsystem;
150       this.updateAuthStatus();
151     });
152   }
153
154   updateAuthStatus() {
155     if (this.subsystem && this.initiators) {
156       this.authStatus = getSubsystemAuthStatus(this.subsystem, this.initiators);
157     }
158   }
159
160   getSelectedNQNs() {
161     return this.selection.selected.map((selected) => selected.nqn);
162   }
163
164   removeInitiatorModal() {
165     const hostNQNs = this.getSelectedNQNs();
166     const allowAllHostIndex = this.getAllowAllHostIndex();
167     const host_nqn = hostNQNs.join(',');
168     let itemNames = hostNQNs;
169     if (allowAllHostIndex !== -1) {
170       hostNQNs.splice(allowAllHostIndex, 1);
171       itemNames = [...hostNQNs, $localize`Allow any host(*)`];
172     }
173     this.modalService.show(DeleteConfirmationModalComponent, {
174       itemDescription: 'Initiator',
175       itemNames,
176       actionDescription: 'remove',
177       submitActionObservable: () =>
178         this.taskWrapper.wrapTaskAroundCall({
179           task: new FinishedTask('nvmeof/initiator/remove', {
180             nqn: this.subsystemNQN,
181             plural: itemNames.length > 1
182           }),
183           call: this.nvmeofService.removeSubsystemInitiators(this.subsystemNQN, {
184             host_nqn,
185             gw_group: this.group
186           })
187         })
188     });
189   }
190 }