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[] = [];
81 private modalService: ModalService,
82 private timerService: TimerService,
83 private authStorageService: AuthStorageService,
84 public actionLabels: ActionLabelsI18n,
85 public timerServiceVariable: TimerServiceInterval,
86 public rgwRealmService: RgwRealmService,
87 public rgwZonegroupService: RgwZonegroupService,
88 public rgwZoneService: RgwZoneService,
89 private notificationService: NotificationService
91 this.permission = this.authStorageService.getPermissions().rgw;
92 const createRealmAction: CdTableAction = {
95 name: this.actionLabels.CREATE + ' Realm',
96 click: () => this.openModal('realm')
98 const createZonegroupAction: CdTableAction = {
101 name: this.actionLabels.CREATE + ' Zonegroup',
102 click: () => this.openModal('zonegroup'),
103 disable: () => this.getDisable()
105 const createZoneAction: CdTableAction = {
106 permission: 'create',
108 name: this.actionLabels.CREATE + ' Zone',
109 click: () => this.openModal('zone')
111 this.createTableActions = [createRealmAction, createZonegroupAction, createZoneAction];
114 openModal(entity: any, edit = false) {
115 const entityName = edit ? entity.data.type : entity;
116 const action = edit ? 'edit' : 'create';
117 const initialState = {
118 resource: entityName,
121 defaultsInfo: this.defaultsInfo,
122 multisiteInfo: this.multisiteInfo
124 if (entityName === 'realm') {
125 this.bsModalRef = this.modalService.show(RgwMultisiteRealmFormComponent, initialState, {
128 } else if (entityName === 'zonegroup') {
129 this.bsModalRef = this.modalService.show(RgwMultisiteZonegroupFormComponent, initialState, {
133 this.bsModalRef = this.modalService.show(RgwMultisiteZoneFormComponent, initialState, {
140 const observables = [
141 this.rgwRealmService.getAllRealmsInfo(),
142 this.rgwZonegroupService.getAllZonegroupsInfo(),
143 this.rgwZoneService.getAllZonesInfo()
145 this.sub = this.timerService
146 .get(() => forkJoin(observables), this.timerServiceVariable.TIMER_SERVICE_PERIOD * 2)
148 (multisiteInfo: [object, object, object]) => {
149 this.multisiteInfo = multisiteInfo;
150 this.loadingIndicator = false;
151 this.nodes = this.abstractTreeData(multisiteInfo);
158 this.sub.unsubscribe();
161 private abstractTreeData(multisiteInfo: [object, object, object]): any[] {
162 let allNodes: object[] = [];
164 let firstChildNodes = {};
165 let allFirstChildNodes = [];
166 let secondChildNodes = {};
167 let allSecondChildNodes: {}[] = [];
168 this.realms = multisiteInfo[0]['realms'];
169 this.zonegroups = multisiteInfo[1]['zonegroups'];
170 this.zones = multisiteInfo[2]['zones'];
171 this.defaultRealmId = multisiteInfo[0]['default_realm'];
172 this.defaultZonegroupId = multisiteInfo[1]['default_zonegroup'];
173 this.defaultZoneId = multisiteInfo[2]['default_zone'];
174 this.defaultsInfo = this.getDefaultsEntities(
176 this.defaultZonegroupId,
179 if (this.realms.length > 0) {
180 // get tree for realm -> zonegroup -> zone
181 for (const realm of this.realms) {
182 const result = this.rgwRealmService.getRealmTree(realm, this.defaultRealmId);
183 rootNodes = result['nodes'];
184 this.realmIds = this.realmIds.concat(result['realmIds']);
185 for (const zonegroup of this.zonegroups) {
186 if (zonegroup.realm_id === realm.id) {
187 firstChildNodes = this.rgwZonegroupService.getZonegroupTree(
189 this.defaultZonegroupId,
192 for (const zone of zonegroup.zones) {
193 const zoneResult = this.rgwZoneService.getZoneTree(
199 secondChildNodes = zoneResult['nodes'];
200 this.zoneIds = this.zoneIds.concat(zoneResult['zoneIds']);
201 allSecondChildNodes.push(secondChildNodes);
202 secondChildNodes = {};
204 firstChildNodes['children'] = allSecondChildNodes;
205 allSecondChildNodes = [];
206 allFirstChildNodes.push(firstChildNodes);
207 firstChildNodes = {};
210 rootNodes['children'] = allFirstChildNodes;
211 allNodes.push(rootNodes);
212 firstChildNodes = {};
213 secondChildNodes = {};
215 allFirstChildNodes = [];
216 allSecondChildNodes = [];
219 if (this.zonegroups.length > 0) {
220 // get tree for zonegroup -> zone (standalone zonegroups that don't match a realm eg(initial default))
221 for (const zonegroup of this.zonegroups) {
222 if (!this.realmIds.includes(zonegroup.realm_id)) {
223 rootNodes = this.rgwZonegroupService.getZonegroupTree(zonegroup, this.defaultZonegroupId);
224 for (const zone of zonegroup.zones) {
225 const zoneResult = this.rgwZoneService.getZoneTree(zone, this.defaultZoneId, zonegroup);
226 firstChildNodes = zoneResult['nodes'];
227 this.zoneIds = this.zoneIds.concat(zoneResult['zoneIds']);
228 allFirstChildNodes.push(firstChildNodes);
229 firstChildNodes = {};
231 rootNodes['children'] = allFirstChildNodes;
232 allNodes.push(rootNodes);
233 firstChildNodes = {};
235 allFirstChildNodes = [];
239 if (this.zones.length > 0) {
240 // get tree for standalone zones(zones that do not belong to a zonegroup)
241 for (const zone of this.zones) {
242 if (this.zoneIds.length > 0 && !this.zoneIds.includes(zone.id)) {
243 const zoneResult = this.rgwZoneService.getZoneTree(zone, this.defaultZoneId);
244 rootNodes = zoneResult['nodes'];
245 allNodes.push(rootNodes);
250 if (this.realms.length < 1 && this.zonegroups.length < 1 && this.zones.length < 1) {
263 defaultRealmId: string,
264 defaultZonegroupId: string,
265 defaultZoneId: string
267 const defaultRealm = this.realms.find((x: { id: string }) => x.id === defaultRealmId);
268 const defaultZonegroup = this.zonegroups.find(
269 (x: { id: string }) => x.id === defaultZonegroupId
271 const defaultZone = this.zones.find((x: { id: string }) => x.id === defaultZoneId);
272 const defaultRealmName = defaultRealm !== undefined ? defaultRealm.name : null;
273 const defaultZonegroupName = defaultZonegroup !== undefined ? defaultZonegroup.name : null;
274 const defaultZoneName = defaultZone !== undefined ? defaultZone.name : null;
276 defaultRealmName: defaultRealmName,
277 defaultZonegroupName: defaultZonegroupName,
278 defaultZoneName: defaultZoneName
282 onNodeSelected(tree: TreeModel, node: TreeNode) {
283 TREE_ACTIONS.ACTIVATE(tree, node, true);
284 this.metadataTitle = node.data.name;
285 this.metadata = node.data.info;
286 node.data.show = true;
290 this.tree.treeModel.expandAll();
294 if (this.defaultRealmId === '') {
295 return this.messages.noDefaultRealm;
297 let isMasterZone = true;
298 this.zonegroups.forEach((zgp: any) => {
299 if (_.isEmpty(zgp.master_zone)) {
300 isMasterZone = false;
304 return this.messages.noMasterZone;
311 delete(node: TreeNode) {
312 if (node.data.type === 'realm') {
313 this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
314 itemDescription: $localize`${node.data.type} ${node.data.name}`,
315 itemNames: [`${node.data.name}`],
316 submitAction: () => {
317 this.rgwRealmService.delete(node.data.name).subscribe(
319 this.modalRef.close();
320 this.notificationService.show(
321 NotificationType.success,
322 $localize`Realm: '${node.data.name}' deleted successfully`
326 this.modalRef.componentInstance.stopLoadingSpinner();
331 } else if (node.data.type === 'zonegroup') {
332 this.modalRef = this.modalService.show(RgwMultisiteZonegroupDeletionFormComponent, {
335 } else if (node.data.type === 'zone') {
336 this.modalRef = this.modalService.show(RgwMultisiteZoneDeletionFormComponent, {