]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
07238019c19973969257c241cb60f581a1bc5c9e
[ceph.git] /
1 import { Component, TemplateRef, ViewChild } from '@angular/core';
2 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
3 import { MultiClusterService } from '~/app/shared/api/multi-cluster.service';
4 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
5 import { Icons } from '~/app/shared/enum/icons.enum';
6 import { CdTableAction } from '~/app/shared/models/cd-table-action';
7 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
8 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
9 import { ModalService } from '~/app/shared/services/modal.service';
10 import { MultiClusterFormComponent } from '../multi-cluster-form/multi-cluster-form.component';
11 import { TableComponent } from '~/app/shared/datatable/table/table.component';
12 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
13 import { Permissions } from '~/app/shared/models/permissions';
14 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
15 import { NotificationService } from '~/app/shared/services/notification.service';
16 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
17 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
18 import { MultiCluster } from '~/app/shared/models/multi-cluster';
19 import { SummaryService } from '~/app/shared/services/summary.service';
20 import { Router } from '@angular/router';
21 import { CookiesService } from '~/app/shared/services/cookie.service';
22
23 @Component({
24   selector: 'cd-multi-cluster-list',
25   templateUrl: './multi-cluster-list.component.html',
26   styleUrls: ['./multi-cluster-list.component.scss']
27 })
28 export class MultiClusterListComponent {
29   @ViewChild(TableComponent)
30   table: TableComponent;
31   @ViewChild('urlTpl', { static: true })
32   public urlTpl: TemplateRef<any>;
33
34   permissions: Permissions;
35   tableActions: CdTableAction[];
36   clusterTokenStatus: object = {};
37   columns: Array<CdTableColumn> = [];
38   data: any;
39   selection = new CdTableSelection();
40   bsModalRef: NgbModalRef;
41   clustersTokenMap: Map<string, string> = new Map<string, string>();
42   newData: any;
43   modalRef: NgbModalRef;
44
45   constructor(
46     private multiClusterService: MultiClusterService,
47     private router: Router,
48     private summaryService: SummaryService,
49     public actionLabels: ActionLabelsI18n,
50     private notificationService: NotificationService,
51     private authStorageService: AuthStorageService,
52     private modalService: ModalService,
53     private cookieService: CookiesService
54   ) {
55     this.tableActions = [
56       {
57         permission: 'create',
58         icon: Icons.add,
59         name: this.actionLabels.CONNECT,
60         click: () => this.openRemoteClusterInfoModal('connect')
61       },
62       {
63         permission: 'update',
64         icon: Icons.edit,
65         name: this.actionLabels.EDIT,
66         disable: (selection: CdTableSelection) => this.getDisable('edit', selection),
67         click: () => this.openRemoteClusterInfoModal('edit')
68       },
69       {
70         permission: 'update',
71         icon: Icons.refresh,
72         name: this.actionLabels.RECONNECT,
73         disable: (selection: CdTableSelection) => this.getDisable('reconnect', selection),
74         click: () => this.openRemoteClusterInfoModal('reconnect')
75       },
76       {
77         permission: 'delete',
78         icon: Icons.destroy,
79         name: this.actionLabels.DISCONNECT,
80         disable: (selection: CdTableSelection) => this.getDisable('disconnect', selection),
81         click: () => this.openDeleteClusterModal()
82       }
83     ];
84     this.permissions = this.authStorageService.getPermissions();
85   }
86
87   ngOnInit(): void {
88     this.multiClusterService.subscribe((resp: object) => {
89       if (resp && resp['config']) {
90         const clusterDetailsArray = Object.values(resp['config']).flat();
91         this.data = clusterDetailsArray;
92         this.checkClusterConnectionStatus();
93       }
94     });
95
96     this.columns = [
97       {
98         prop: 'cluster_alias',
99         name: $localize`Alias`,
100         flexGrow: 2
101       },
102       {
103         prop: 'cluster_connection_status',
104         name: $localize`Connection`,
105         flexGrow: 2,
106         cellTransformation: CellTemplate.badge,
107         customTemplateConfig: {
108           map: {
109             1: { value: 'DISCONNECTED', class: 'badge-danger' },
110             0: { value: 'CONNECTED', class: 'badge-success' },
111             2: { value: 'CHECKING..', class: 'badge-info' }
112           }
113         }
114       },
115       {
116         prop: 'name',
117         name: $localize`FSID`,
118         flexGrow: 2
119       },
120       {
121         prop: 'url',
122         name: $localize`URL`,
123         flexGrow: 2,
124         cellTemplate: this.urlTpl
125       },
126       {
127         prop: 'user',
128         name: $localize`User`,
129         flexGrow: 2
130       }
131     ];
132
133     this.multiClusterService.subscribeClusterTokenStatus((resp: object) => {
134       this.clusterTokenStatus = resp;
135       this.checkClusterConnectionStatus();
136     });
137   }
138
139   checkClusterConnectionStatus() {
140     if (this.clusterTokenStatus && this.data) {
141       this.data.forEach((cluster: MultiCluster) => {
142         const clusterStatus = this.clusterTokenStatus[cluster.name];
143
144         if (clusterStatus !== undefined) {
145           cluster.cluster_connection_status = clusterStatus.status;
146         } else {
147           cluster.cluster_connection_status = 2;
148         }
149
150         if (cluster.cluster_alias === 'local-cluster') {
151           cluster.cluster_connection_status = 0;
152         }
153       });
154     }
155   }
156
157   openRemoteClusterInfoModal(action: string) {
158     const initialState = {
159       clustersData: this.data,
160       action: action,
161       cluster: this.selection.first()
162     };
163     this.bsModalRef = this.modalService.show(MultiClusterFormComponent, initialState, {
164       size: 'xl'
165     });
166     this.bsModalRef.componentInstance.submitAction.subscribe(() => {
167       this.multiClusterService.refresh();
168       this.summaryService.refresh();
169       const currentRoute = this.router.url.split('?')[0];
170       if (currentRoute.includes('dashboard')) {
171         this.router.navigateByUrl('/pool', { skipLocationChange: true }).then(() => {
172           this.router.navigate([currentRoute]);
173         });
174       } else {
175         this.router.navigateByUrl('/', { skipLocationChange: true }).then(() => {
176           this.router.navigate([currentRoute]);
177         });
178       }
179     });
180   }
181
182   updateSelection(selection: CdTableSelection) {
183     this.selection = selection;
184   }
185
186   openDeleteClusterModal() {
187     const cluster = this.selection.first();
188     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
189       actionDescription: $localize`Disconnect`,
190       itemDescription: $localize`Cluster`,
191       itemNames: [cluster['cluster_alias'] + ' - ' + cluster['user']],
192       submitAction: () =>
193         this.multiClusterService.deleteCluster(cluster['name'], cluster['user']).subscribe(() => {
194           this.cookieService.deleteToken(`${cluster['name']}-${cluster['user']}`);
195           this.modalRef.close();
196           this.notificationService.show(
197             NotificationType.success,
198             $localize`Disconnected cluster '${cluster['cluster_alias']}'`
199           );
200         })
201     });
202   }
203
204   getDisable(action: string, selection: CdTableSelection): string | boolean {
205     if (!selection.hasSelection) {
206       return $localize`Please select one or more clusters to ${action}`;
207     }
208     if (selection.hasSingleSelection) {
209       const cluster = selection.first();
210       if (cluster['cluster_alias'] === 'local-cluster') {
211         return $localize`Cannot ${action} local cluster`;
212       }
213     }
214     return false;
215   }
216 }