]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
25d994cc2cad1f810ef46178adb9aa685541c6f5
[ceph-ci.git] /
1 import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
2 import {
3   TreeComponent,
4   ITreeOptions,
5   TreeModel,
6   TreeNode,
7   TREE_ACTIONS
8 } from '@circlon/angular-tree-component';
9 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
10 import { forkJoin, Subscription } from 'rxjs';
11 import { RgwRealmService } from '~/app/shared/api/rgw-realm.service';
12 import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
13 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
14 import { ActionLabelsI18n, TimerServiceInterval } from '~/app/shared/constants/app.constants';
15 import { Icons } from '~/app/shared/enum/icons.enum';
16 import { CdTableAction } from '~/app/shared/models/cd-table-action';
17 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
18 import { Permission } from '~/app/shared/models/permissions';
19 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
20 import { ModalService } from '~/app/shared/services/modal.service';
21 import { TimerService } from '~/app/shared/services/timer.service';
22 import { RgwRealm, RgwZone, RgwZonegroup } from '../models/rgw-multisite';
23 import { RgwMultisiteRealmFormComponent } from '../rgw-multisite-realm-form/rgw-multisite-realm-form.component';
24 import { RgwMultisiteZoneFormComponent } from '../rgw-multisite-zone-form/rgw-multisite-zone-form.component';
25 import { RgwMultisiteZonegroupFormComponent } from '../rgw-multisite-zonegroup-form/rgw-multisite-zonegroup-form.component';
26
27 @Component({
28   selector: 'cd-rgw-multisite-details',
29   templateUrl: './rgw-multisite-details.component.html',
30   styleUrls: ['./rgw-multisite-details.component.scss']
31 })
32 export class RgwMultisiteDetailsComponent implements OnDestroy, OnInit {
33   private sub = new Subscription();
34
35   @ViewChild('tree') tree: TreeComponent;
36
37   messages = {
38     noDefaultRealm: $localize`Please create a default realm first to enable this feature`
39   };
40
41   icons = Icons;
42   permission: Permission;
43   selection = new CdTableSelection();
44   createTableActions: CdTableAction[];
45   loadingIndicator = true;
46   nodes: object[] = [];
47   treeOptions: ITreeOptions = {
48     useVirtualScroll: true,
49     nodeHeight: 22,
50     levelPadding: 20,
51     actionMapping: {
52       mouse: {
53         click: this.onNodeSelected.bind(this)
54       }
55     }
56   };
57
58   realms: RgwRealm[] = [];
59   zonegroups: RgwZonegroup[] = [];
60   zones: RgwZone[] = [];
61   metadata: any;
62   metadataTitle: string;
63   bsModalRef: NgbModalRef;
64   realmIds: string[] = [];
65   zoneIds: string[] = [];
66   defaultRealmId = '';
67   defaultZonegroupId = '';
68   defaultZoneId = '';
69   multisiteInfo: object[] = [];
70   defaultsInfo: string[] = [];
71
72   constructor(
73     private modalService: ModalService,
74     private timerService: TimerService,
75     private authStorageService: AuthStorageService,
76     public actionLabels: ActionLabelsI18n,
77     public timerServiceVariable: TimerServiceInterval,
78     public rgwRealmService: RgwRealmService,
79     public rgwZonegroupService: RgwZonegroupService,
80     public rgwZoneService: RgwZoneService
81   ) {
82     this.permission = this.authStorageService.getPermissions().rgw;
83     const createRealmAction: CdTableAction = {
84       permission: 'create',
85       icon: Icons.add,
86       name: this.actionLabels.CREATE + ' Realm',
87       click: () => this.openModal('realm')
88     };
89     const createZonegroupAction: CdTableAction = {
90       permission: 'create',
91       icon: Icons.add,
92       name: this.actionLabels.CREATE + ' Zonegroup',
93       click: () => this.openModal('zonegroup'),
94       disable: () => this.getDisable()
95     };
96     const createZoneAction: CdTableAction = {
97       permission: 'create',
98       icon: Icons.add,
99       name: this.actionLabels.CREATE + ' Zone',
100       click: () => this.openModal('zone')
101     };
102     this.createTableActions = [createRealmAction, createZonegroupAction, createZoneAction];
103   }
104
105   openModal(entity: any, edit = false) {
106     const entityName = edit ? entity.data.type : entity;
107     const action = edit ? 'edit' : 'create';
108     const initialState = {
109       resource: entityName,
110       action: action,
111       info: entity,
112       defaultsInfo: this.defaultsInfo,
113       multisiteInfo: this.multisiteInfo
114     };
115     if (entityName === 'realm') {
116       this.bsModalRef = this.modalService.show(RgwMultisiteRealmFormComponent, initialState, {
117         size: 'lg'
118       });
119     } else if (entityName === 'zonegroup') {
120       this.bsModalRef = this.modalService.show(RgwMultisiteZonegroupFormComponent, initialState, {
121         size: 'lg'
122       });
123     } else {
124       this.bsModalRef = this.modalService.show(RgwMultisiteZoneFormComponent, initialState, {
125         size: 'lg'
126       });
127     }
128   }
129
130   ngOnInit() {
131     const observables = [
132       this.rgwRealmService.getAllRealmsInfo(),
133       this.rgwZonegroupService.getAllZonegroupsInfo(),
134       this.rgwZoneService.getAllZonesInfo()
135     ];
136     this.sub = this.timerService
137       .get(() => forkJoin(observables), this.timerServiceVariable.TIMER_SERVICE_PERIOD * 2)
138       .subscribe(
139         (multisiteInfo: [object, object, object]) => {
140           this.multisiteInfo = multisiteInfo;
141           this.loadingIndicator = false;
142           this.nodes = this.abstractTreeData(multisiteInfo);
143         },
144         (_error) => {}
145       );
146   }
147
148   ngOnDestroy() {
149     this.sub.unsubscribe();
150   }
151
152   private abstractTreeData(multisiteInfo: [object, object, object]): any[] {
153     let allNodes: object[] = [];
154     let rootNodes = {};
155     let firstChildNodes = {};
156     let allFirstChildNodes = [];
157     let secondChildNodes = {};
158     let allSecondChildNodes: {}[] = [];
159     this.realms = multisiteInfo[0]['realms'];
160     this.zonegroups = multisiteInfo[1]['zonegroups'];
161     this.zones = multisiteInfo[2]['zones'];
162     this.defaultRealmId = multisiteInfo[0]['default_realm'];
163     this.defaultZonegroupId = multisiteInfo[1]['default_zonegroup'];
164     this.defaultZoneId = multisiteInfo[2]['default_zone'];
165     this.defaultsInfo = this.getDefaultsEntities(
166       this.defaultRealmId,
167       this.defaultZonegroupId,
168       this.defaultZoneId
169     );
170     if (this.realms.length > 0) {
171       // get tree for realm -> zonegroup -> zone
172       for (const realm of this.realms) {
173         const result = this.rgwRealmService.getRealmTree(realm, this.defaultRealmId);
174         rootNodes = result['nodes'];
175         this.realmIds = this.realmIds.concat(result['realmIds']);
176         for (const zonegroup of this.zonegroups) {
177           if (zonegroup.realm_id === realm.id) {
178             firstChildNodes = this.rgwZonegroupService.getZonegroupTree(
179               zonegroup,
180               this.defaultZonegroupId,
181               realm
182             );
183             for (const zone of zonegroup.zones) {
184               const zoneResult = this.rgwZoneService.getZoneTree(
185                 zone,
186                 this.defaultZoneId,
187                 zonegroup,
188                 realm
189               );
190               secondChildNodes = zoneResult['nodes'];
191               this.zoneIds = this.zoneIds.concat(zoneResult['zoneIds']);
192               allSecondChildNodes.push(secondChildNodes);
193               secondChildNodes = {};
194             }
195             firstChildNodes['children'] = allSecondChildNodes;
196             allSecondChildNodes = [];
197             allFirstChildNodes.push(firstChildNodes);
198             firstChildNodes = {};
199           }
200         }
201         rootNodes['children'] = allFirstChildNodes;
202         allNodes.push(rootNodes);
203         firstChildNodes = {};
204         secondChildNodes = {};
205         rootNodes = {};
206         allFirstChildNodes = [];
207         allSecondChildNodes = [];
208       }
209     }
210     if (this.zonegroups.length > 0) {
211       // get tree for zonegroup -> zone (standalone zonegroups that don't match a realm eg(initial default))
212       for (const zonegroup of this.zonegroups) {
213         if (!this.realmIds.includes(zonegroup.realm_id)) {
214           rootNodes = this.rgwZonegroupService.getZonegroupTree(zonegroup, this.defaultZonegroupId);
215           for (const zone of zonegroup.zones) {
216             const zoneResult = this.rgwZoneService.getZoneTree(zone, this.defaultZoneId, zonegroup);
217             firstChildNodes = zoneResult['nodes'];
218             this.zoneIds = this.zoneIds.concat(zoneResult['zoneIds']);
219             allFirstChildNodes.push(firstChildNodes);
220             firstChildNodes = {};
221           }
222           rootNodes['children'] = allFirstChildNodes;
223           allNodes.push(rootNodes);
224           firstChildNodes = {};
225           rootNodes = {};
226           allFirstChildNodes = [];
227         }
228       }
229     }
230     if (this.zones.length > 0) {
231       // get tree for standalone zones(zones that do not belong to a zonegroup)
232       for (const zone of this.zones) {
233         if (this.zoneIds.length > 0 && !this.zoneIds.includes(zone.id)) {
234           const zoneResult = this.rgwZoneService.getZoneTree(zone, this.defaultZoneId);
235           rootNodes = zoneResult['nodes'];
236           allNodes.push(rootNodes);
237           rootNodes = {};
238         }
239       }
240     }
241     if (this.realms.length < 1 && this.zonegroups.length < 1 && this.zones.length < 1) {
242       return [
243         {
244           name: 'No nodes!'
245         }
246       ];
247     }
248     this.realmIds = [];
249     this.zoneIds = [];
250     return allNodes;
251   }
252
253   getDefaultsEntities(
254     defaultRealmId: string,
255     defaultZonegroupId: string,
256     defaultZoneId: string
257   ): any {
258     const defaultRealm = this.realms.find((x: { id: string }) => x.id === defaultRealmId);
259     const defaultZonegroup = this.zonegroups.find(
260       (x: { id: string }) => x.id === defaultZonegroupId
261     );
262     const defaultZone = this.zones.find((x: { id: string }) => x.id === defaultZoneId);
263     const defaultRealmName = defaultRealm !== undefined ? defaultRealm.name : null;
264     const defaultZonegroupName = defaultZonegroup !== undefined ? defaultZonegroup.name : null;
265     const defaultZoneName = defaultZone !== undefined ? defaultZone.name : null;
266     return {
267       defaultRealmName: defaultRealmName,
268       defaultZonegroupName: defaultZonegroupName,
269       defaultZoneName: defaultZoneName
270     };
271   }
272
273   onNodeSelected(tree: TreeModel, node: TreeNode) {
274     TREE_ACTIONS.ACTIVATE(tree, node, true);
275     this.metadataTitle = node.data.name;
276     this.metadata = node.data.info;
277     node.data.show = true;
278   }
279
280   onUpdateData() {
281     this.tree.treeModel.expandAll();
282   }
283
284   getDisable() {
285     if (this.defaultRealmId === '') {
286       return this.messages.noDefaultRealm;
287     } else {
288       return false;
289     }
290   }
291 }