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 { RgwMultisiteZoneDeletionFormComponent } from '../models/rgw-multisite-zone-deletion-form/rgw-multisite-zone-deletion-form.component';
28 import { RgwMultisiteZonegroupDeletionFormComponent } from '../models/rgw-multisite-zonegroup-deletion-form/rgw-multisite-zonegroup-deletion-form.component';
29 import { RgwMultisiteRealmFormComponent } from '../rgw-multisite-realm-form/rgw-multisite-realm-form.component';
30 import { RgwMultisiteZoneFormComponent } from '../rgw-multisite-zone-form/rgw-multisite-zone-form.component';
31 import { RgwMultisiteZonegroupFormComponent } from '../rgw-multisite-zonegroup-form/rgw-multisite-zonegroup-form.component';
34 selector: 'cd-rgw-multisite-details',
35 templateUrl: './rgw-multisite-details.component.html',
36 styleUrls: ['./rgw-multisite-details.component.scss']
38 export class RgwMultisiteDetailsComponent implements OnDestroy, OnInit {
39 private sub = new Subscription();
41 @ViewChild('tree') tree: TreeComponent;
44 noDefaultRealm: $localize`Please create a default realm first to enable this feature`,
45 noMasterZone: $localize`Please create a master zone for each zonegroups to enable this feature`
49 permission: Permission;
50 selection = new CdTableSelection();
51 createTableActions: CdTableAction[];
52 loadingIndicator = true;
54 treeOptions: ITreeOptions = {
55 useVirtualScroll: true,
60 click: this.onNodeSelected.bind(this)
64 modalRef: NgbModalRef;
66 realms: RgwRealm[] = [];
67 zonegroups: RgwZonegroup[] = [];
68 zones: RgwZone[] = [];
70 metadataTitle: string;
71 bsModalRef: NgbModalRef;
72 realmIds: string[] = [];
73 zoneIds: string[] = [];
75 defaultZonegroupId = '';
77 multisiteInfo: object[] = [];
78 defaultsInfo: string[] = [];
79 title: string = 'Edit';
82 private modalService: ModalService,
83 private timerService: TimerService,
84 private authStorageService: AuthStorageService,
85 public actionLabels: ActionLabelsI18n,
86 public timerServiceVariable: TimerServiceInterval,
87 public rgwRealmService: RgwRealmService,
88 public rgwZonegroupService: RgwZonegroupService,
89 public rgwZoneService: RgwZoneService,
90 private notificationService: NotificationService
92 this.permission = this.authStorageService.getPermissions().rgw;
93 const createRealmAction: CdTableAction = {
96 name: this.actionLabels.CREATE + ' Realm',
97 click: () => this.openModal('realm')
99 const createZonegroupAction: CdTableAction = {
100 permission: 'create',
102 name: this.actionLabels.CREATE + ' Zonegroup',
103 click: () => this.openModal('zonegroup'),
104 disable: () => this.getDisable()
106 const createZoneAction: CdTableAction = {
107 permission: 'create',
109 name: this.actionLabels.CREATE + ' Zone',
110 click: () => this.openModal('zone')
112 this.createTableActions = [createRealmAction, createZonegroupAction, createZoneAction];
115 openModal(entity: any, edit = false) {
116 const entityName = edit ? entity.data.type : entity;
117 const action = edit ? 'edit' : 'create';
118 const initialState = {
119 resource: entityName,
122 defaultsInfo: this.defaultsInfo,
123 multisiteInfo: this.multisiteInfo
125 if (entityName === 'realm') {
126 this.bsModalRef = this.modalService.show(RgwMultisiteRealmFormComponent, initialState, {
129 } else if (entityName === 'zonegroup') {
130 this.bsModalRef = this.modalService.show(RgwMultisiteZonegroupFormComponent, initialState, {
134 this.bsModalRef = this.modalService.show(RgwMultisiteZoneFormComponent, initialState, {
141 const observables = [
142 this.rgwRealmService.getAllRealmsInfo(),
143 this.rgwZonegroupService.getAllZonegroupsInfo(),
144 this.rgwZoneService.getAllZonesInfo()
146 this.sub = this.timerService
147 .get(() => forkJoin(observables), this.timerServiceVariable.TIMER_SERVICE_PERIOD * 2)
149 (multisiteInfo: [object, object, object]) => {
150 this.multisiteInfo = multisiteInfo;
151 this.loadingIndicator = false;
152 this.nodes = this.abstractTreeData(multisiteInfo);
159 this.sub.unsubscribe();
162 private abstractTreeData(multisiteInfo: [object, object, object]): any[] {
163 let allNodes: object[] = [];
165 let firstChildNodes = {};
166 let allFirstChildNodes = [];
167 let secondChildNodes = {};
168 let allSecondChildNodes: {}[] = [];
169 this.realms = multisiteInfo[0]['realms'];
170 this.zonegroups = multisiteInfo[1]['zonegroups'];
171 this.zones = multisiteInfo[2]['zones'];
172 this.defaultRealmId = multisiteInfo[0]['default_realm'];
173 this.defaultZonegroupId = multisiteInfo[1]['default_zonegroup'];
174 this.defaultZoneId = multisiteInfo[2]['default_zone'];
175 this.defaultsInfo = this.getDefaultsEntities(
177 this.defaultZonegroupId,
180 if (this.realms.length > 0) {
181 // get tree for realm -> zonegroup -> zone
182 for (const realm of this.realms) {
183 const result = this.rgwRealmService.getRealmTree(realm, this.defaultRealmId);
184 rootNodes = result['nodes'];
185 this.realmIds = this.realmIds.concat(result['realmIds']);
186 for (const zonegroup of this.zonegroups) {
187 if (zonegroup.realm_id === realm.id) {
188 firstChildNodes = this.rgwZonegroupService.getZonegroupTree(
190 this.defaultZonegroupId,
193 for (const zone of zonegroup.zones) {
194 const zoneResult = this.rgwZoneService.getZoneTree(
200 secondChildNodes = zoneResult['nodes'];
201 this.zoneIds = this.zoneIds.concat(zoneResult['zoneIds']);
202 allSecondChildNodes.push(secondChildNodes);
203 secondChildNodes = {};
205 firstChildNodes['children'] = allSecondChildNodes;
206 allSecondChildNodes = [];
207 allFirstChildNodes.push(firstChildNodes);
208 firstChildNodes = {};
211 rootNodes['children'] = allFirstChildNodes;
212 allNodes.push(rootNodes);
213 firstChildNodes = {};
214 secondChildNodes = {};
216 allFirstChildNodes = [];
217 allSecondChildNodes = [];
220 if (this.zonegroups.length > 0) {
221 // get tree for zonegroup -> zone (standalone zonegroups that don't match a realm eg(initial default))
222 for (const zonegroup of this.zonegroups) {
223 if (!this.realmIds.includes(zonegroup.realm_id)) {
224 rootNodes = this.rgwZonegroupService.getZonegroupTree(zonegroup, this.defaultZonegroupId);
225 for (const zone of zonegroup.zones) {
226 const zoneResult = this.rgwZoneService.getZoneTree(zone, this.defaultZoneId, zonegroup);
227 firstChildNodes = zoneResult['nodes'];
228 this.zoneIds = this.zoneIds.concat(zoneResult['zoneIds']);
229 allFirstChildNodes.push(firstChildNodes);
230 firstChildNodes = {};
232 rootNodes['children'] = allFirstChildNodes;
233 allNodes.push(rootNodes);
234 firstChildNodes = {};
236 allFirstChildNodes = [];
240 if (this.zones.length > 0) {
241 // get tree for standalone zones(zones that do not belong to a zonegroup)
242 for (const zone of this.zones) {
243 if (this.zoneIds.length > 0 && !this.zoneIds.includes(zone.id)) {
244 const zoneResult = this.rgwZoneService.getZoneTree(zone, this.defaultZoneId);
245 rootNodes = zoneResult['nodes'];
246 allNodes.push(rootNodes);
251 if (this.realms.length < 1 && this.zonegroups.length < 1 && this.zones.length < 1) {
264 defaultRealmId: string,
265 defaultZonegroupId: string,
266 defaultZoneId: string
268 const defaultRealm = this.realms.find((x: { id: string }) => x.id === defaultRealmId);
269 const defaultZonegroup = this.zonegroups.find(
270 (x: { id: string }) => x.id === defaultZonegroupId
272 const defaultZone = this.zones.find((x: { id: string }) => x.id === defaultZoneId);
273 const defaultRealmName = defaultRealm !== undefined ? defaultRealm.name : null;
274 const defaultZonegroupName = defaultZonegroup !== undefined ? defaultZonegroup.name : null;
275 const defaultZoneName = defaultZone !== undefined ? defaultZone.name : null;
277 defaultRealmName: defaultRealmName,
278 defaultZonegroupName: defaultZonegroupName,
279 defaultZoneName: defaultZoneName
283 onNodeSelected(tree: TreeModel, node: TreeNode) {
284 TREE_ACTIONS.ACTIVATE(tree, node, true);
285 this.metadataTitle = node.data.name;
286 this.metadata = node.data.info;
287 node.data.show = true;
291 this.tree.treeModel.expandAll();
295 let isMasterZone = true;
296 if (this.defaultRealmId === '') {
297 return this.messages.noDefaultRealm;
299 this.zonegroups.forEach((zgp: any) => {
300 if (_.isEmpty(zgp.master_zone)) {
301 isMasterZone = false;
306 'Please create a master zone for each existing zonegroup to enable this feature';
307 return this.messages.noMasterZone;
315 delete(node: TreeNode) {
316 if (node.data.type === 'realm') {
317 this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
318 itemDescription: $localize`${node.data.type} ${node.data.name}`,
319 itemNames: [`${node.data.name}`],
320 submitAction: () => {
321 this.rgwRealmService.delete(node.data.name).subscribe(
323 this.modalRef.close();
324 this.notificationService.show(
325 NotificationType.success,
326 $localize`Realm: '${node.data.name}' deleted successfully`
330 this.modalRef.componentInstance.stopLoadingSpinner();
335 } else if (node.data.type === 'zonegroup') {
336 this.modalRef = this.modalService.show(RgwMultisiteZonegroupDeletionFormComponent, {
339 } else if (node.data.type === 'zone') {
340 this.modalRef = this.modalService.show(RgwMultisiteZoneDeletionFormComponent, {