1 import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
8 } from '@circlon/angular-tree-component';
9 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
10 import _ from 'lodash';
11 import { forkJoin, Subscription } from 'rxjs';
12 import { RgwRealmService } from '~/app/shared/api/rgw-realm.service';
13 import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
14 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
15 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
16 import { ActionLabelsI18n, TimerServiceInterval } from '~/app/shared/constants/app.constants';
17 import { Icons } from '~/app/shared/enum/icons.enum';
18 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
19 import { CdTableAction } from '~/app/shared/models/cd-table-action';
20 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
21 import { Permission } from '~/app/shared/models/permissions';
22 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
23 import { ModalService } from '~/app/shared/services/modal.service';
24 import { NotificationService } from '~/app/shared/services/notification.service';
25 import { TimerService } from '~/app/shared/services/timer.service';
26 import { RgwRealm, RgwZone, RgwZonegroup } from '../models/rgw-multisite';
27 import { RgwMultisiteMigrateComponent } from '../rgw-multisite-migrate/rgw-multisite-migrate.component';
28 import { RgwMultisiteZoneDeletionFormComponent } from '../models/rgw-multisite-zone-deletion-form/rgw-multisite-zone-deletion-form.component';
29 import { RgwMultisiteZonegroupDeletionFormComponent } from '../models/rgw-multisite-zonegroup-deletion-form/rgw-multisite-zonegroup-deletion-form.component';
30 import { RgwMultisiteRealmFormComponent } from '../rgw-multisite-realm-form/rgw-multisite-realm-form.component';
31 import { RgwMultisiteZoneFormComponent } from '../rgw-multisite-zone-form/rgw-multisite-zone-form.component';
32 import { RgwMultisiteZonegroupFormComponent } from '../rgw-multisite-zonegroup-form/rgw-multisite-zonegroup-form.component';
35 selector: 'cd-rgw-multisite-details',
36 templateUrl: './rgw-multisite-details.component.html',
37 styleUrls: ['./rgw-multisite-details.component.scss']
39 export class RgwMultisiteDetailsComponent implements OnDestroy, OnInit {
40 private sub = new Subscription();
42 @ViewChild('tree') tree: TreeComponent;
45 noDefaultRealm: $localize`Please create a default realm first to enable this feature`,
46 noMasterZone: $localize`Please create a master zone for each zonegroup to enable this feature`,
47 disableMigrate: $localize`Deployment is already migrated to multi-site system.`
51 permission: Permission;
52 selection = new CdTableSelection();
53 createTableActions: CdTableAction[];
54 migrateTableAction: CdTableAction[];
55 loadingIndicator = true;
57 treeOptions: ITreeOptions = {
58 useVirtualScroll: true,
63 click: this.onNodeSelected.bind(this)
67 modalRef: NgbModalRef;
69 realms: RgwRealm[] = [];
70 zonegroups: RgwZonegroup[] = [];
71 zones: RgwZone[] = [];
73 metadataTitle: string;
74 bsModalRef: NgbModalRef;
75 realmIds: string[] = [];
76 zoneIds: string[] = [];
78 defaultZonegroupId = '';
80 multisiteInfo: object[] = [];
81 defaultsInfo: string[] = [];
82 title: string = 'Edit';
83 showMigrateAction: boolean = false;
86 private modalService: ModalService,
87 private timerService: TimerService,
88 private authStorageService: AuthStorageService,
89 public actionLabels: ActionLabelsI18n,
90 public timerServiceVariable: TimerServiceInterval,
91 public rgwRealmService: RgwRealmService,
92 public rgwZonegroupService: RgwZonegroupService,
93 public rgwZoneService: RgwZoneService,
94 private notificationService: NotificationService
96 this.permission = this.authStorageService.getPermissions().rgw;
97 const createRealmAction: CdTableAction = {
100 name: this.actionLabels.CREATE + ' Realm',
101 click: () => this.openModal('realm')
103 const createZonegroupAction: CdTableAction = {
104 permission: 'create',
106 name: this.actionLabels.CREATE + ' Zonegroup',
107 click: () => this.openModal('zonegroup'),
108 disable: () => this.getDisable()
110 const createZoneAction: CdTableAction = {
111 permission: 'create',
113 name: this.actionLabels.CREATE + ' Zone',
114 click: () => this.openModal('zone')
116 const migrateMultsiteAction: CdTableAction = {
118 icon: Icons.exchange,
119 name: this.actionLabels.MIGRATE,
120 click: () => this.openMigrateModal()
122 this.createTableActions = [createRealmAction, createZonegroupAction, createZoneAction];
123 this.migrateTableAction = [migrateMultsiteAction];
126 openModal(entity: any, edit = false) {
127 const entityName = edit ? entity.data.type : entity;
128 const action = edit ? 'edit' : 'create';
129 const initialState = {
130 resource: entityName,
133 defaultsInfo: this.defaultsInfo,
134 multisiteInfo: this.multisiteInfo
136 if (entityName === 'realm') {
137 this.bsModalRef = this.modalService.show(RgwMultisiteRealmFormComponent, initialState, {
140 } else if (entityName === 'zonegroup') {
141 this.bsModalRef = this.modalService.show(RgwMultisiteZonegroupFormComponent, initialState, {
145 this.bsModalRef = this.modalService.show(RgwMultisiteZoneFormComponent, initialState, {
152 const initialState = {
153 multisiteInfo: this.multisiteInfo
155 this.bsModalRef = this.modalService.show(RgwMultisiteMigrateComponent, initialState, {
161 const observables = [
162 this.rgwRealmService.getAllRealmsInfo(),
163 this.rgwZonegroupService.getAllZonegroupsInfo(),
164 this.rgwZoneService.getAllZonesInfo()
166 this.sub = this.timerService
167 .get(() => forkJoin(observables), this.timerServiceVariable.TIMER_SERVICE_PERIOD * 2)
169 (multisiteInfo: [object, object, object]) => {
170 this.multisiteInfo = multisiteInfo;
171 this.loadingIndicator = false;
172 this.nodes = this.abstractTreeData(multisiteInfo);
179 this.sub.unsubscribe();
182 private abstractTreeData(multisiteInfo: [object, object, object]): any[] {
183 let allNodes: object[] = [];
185 let firstChildNodes = {};
186 let allFirstChildNodes = [];
187 let secondChildNodes = {};
188 let allSecondChildNodes: {}[] = [];
189 this.realms = multisiteInfo[0]['realms'];
190 this.zonegroups = multisiteInfo[1]['zonegroups'];
191 this.zones = multisiteInfo[2]['zones'];
192 this.defaultRealmId = multisiteInfo[0]['default_realm'];
193 this.defaultZonegroupId = multisiteInfo[1]['default_zonegroup'];
194 this.defaultZoneId = multisiteInfo[2]['default_zone'];
195 this.defaultsInfo = this.getDefaultsEntities(
197 this.defaultZonegroupId,
200 if (this.realms.length > 0) {
201 // get tree for realm -> zonegroup -> zone
202 for (const realm of this.realms) {
203 const result = this.rgwRealmService.getRealmTree(realm, this.defaultRealmId);
204 rootNodes = result['nodes'];
205 this.realmIds = this.realmIds.concat(result['realmIds']);
206 for (const zonegroup of this.zonegroups) {
207 if (zonegroup.realm_id === realm.id) {
208 firstChildNodes = this.rgwZonegroupService.getZonegroupTree(
210 this.defaultZonegroupId,
213 for (const zone of zonegroup.zones) {
214 const zoneResult = this.rgwZoneService.getZoneTree(
220 secondChildNodes = zoneResult['nodes'];
221 this.zoneIds = this.zoneIds.concat(zoneResult['zoneIds']);
222 allSecondChildNodes.push(secondChildNodes);
223 secondChildNodes = {};
225 firstChildNodes['children'] = allSecondChildNodes;
226 allSecondChildNodes = [];
227 allFirstChildNodes.push(firstChildNodes);
228 firstChildNodes = {};
231 rootNodes['children'] = allFirstChildNodes;
232 allNodes.push(rootNodes);
233 firstChildNodes = {};
234 secondChildNodes = {};
236 allFirstChildNodes = [];
237 allSecondChildNodes = [];
240 if (this.zonegroups.length > 0) {
241 // get tree for zonegroup -> zone (standalone zonegroups that don't match a realm eg(initial default))
242 for (const zonegroup of this.zonegroups) {
243 if (!this.realmIds.includes(zonegroup.realm_id)) {
244 rootNodes = this.rgwZonegroupService.getZonegroupTree(zonegroup, this.defaultZonegroupId);
245 for (const zone of zonegroup.zones) {
246 const zoneResult = this.rgwZoneService.getZoneTree(zone, this.defaultZoneId, zonegroup);
247 firstChildNodes = zoneResult['nodes'];
248 this.zoneIds = this.zoneIds.concat(zoneResult['zoneIds']);
249 allFirstChildNodes.push(firstChildNodes);
250 firstChildNodes = {};
252 rootNodes['children'] = allFirstChildNodes;
253 allNodes.push(rootNodes);
254 firstChildNodes = {};
256 allFirstChildNodes = [];
260 if (this.zones.length > 0) {
261 // get tree for standalone zones(zones that do not belong to a zonegroup)
262 for (const zone of this.zones) {
263 if (this.zoneIds.length > 0 && !this.zoneIds.includes(zone.id)) {
264 const zoneResult = this.rgwZoneService.getZoneTree(zone, this.defaultZoneId);
265 rootNodes = zoneResult['nodes'];
266 allNodes.push(rootNodes);
271 if (this.realms.length < 1 && this.zonegroups.length < 1 && this.zones.length < 1) {
280 this.getDisableMigrate();
285 defaultRealmId: string,
286 defaultZonegroupId: string,
287 defaultZoneId: string
289 const defaultRealm = this.realms.find((x: { id: string }) => x.id === defaultRealmId);
290 const defaultZonegroup = this.zonegroups.find(
291 (x: { id: string }) => x.id === defaultZonegroupId
293 const defaultZone = this.zones.find((x: { id: string }) => x.id === defaultZoneId);
294 const defaultRealmName = defaultRealm !== undefined ? defaultRealm.name : null;
295 const defaultZonegroupName = defaultZonegroup !== undefined ? defaultZonegroup.name : null;
296 const defaultZoneName = defaultZone !== undefined ? defaultZone.name : null;
298 defaultRealmName: defaultRealmName,
299 defaultZonegroupName: defaultZonegroupName,
300 defaultZoneName: defaultZoneName
304 onNodeSelected(tree: TreeModel, node: TreeNode) {
305 TREE_ACTIONS.ACTIVATE(tree, node, true);
306 this.metadataTitle = node.data.name;
307 this.metadata = node.data.info;
308 node.data.show = true;
312 this.tree.treeModel.expandAll();
316 let isMasterZone = true;
317 if (this.defaultRealmId === '') {
318 return this.messages.noDefaultRealm;
320 this.zonegroups.forEach((zgp: any) => {
321 if (_.isEmpty(zgp.master_zone)) {
322 isMasterZone = false;
327 'Please create a master zone for each existing zonegroup to enable this feature';
328 return this.messages.noMasterZone;
336 getDisableMigrate() {
338 this.realms.length === 0 &&
339 this.zonegroups.length === 1 &&
340 this.zonegroups[0].name === 'default' &&
341 this.zones.length === 1 &&
342 this.zones[0].name === 'default'
344 this.showMigrateAction = true;
346 this.showMigrateAction = false;
348 return this.showMigrateAction;
351 delete(node: TreeNode) {
352 if (node.data.type === 'realm') {
353 this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
354 itemDescription: $localize`${node.data.type} ${node.data.name}`,
355 itemNames: [`${node.data.name}`],
356 submitAction: () => {
357 this.rgwRealmService.delete(node.data.name).subscribe(
359 this.modalRef.close();
360 this.notificationService.show(
361 NotificationType.success,
362 $localize`Realm: '${node.data.name}' deleted successfully`
366 this.modalRef.componentInstance.stopLoadingSpinner();
371 } else if (node.data.type === 'zonegroup') {
372 this.modalRef = this.modalService.show(RgwMultisiteZonegroupDeletionFormComponent, {
375 } else if (node.data.type === 'zone') {
376 this.modalRef = this.modalService.show(RgwMultisiteZoneDeletionFormComponent, {