1 import { Component, OnInit } from '@angular/core';
2 import { UntypedFormControl, Validators } from '@angular/forms';
3 import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
4 import _ from 'lodash';
5 import { RgwMultisiteService } from '~/app/shared/api/rgw-multisite.service';
6 import { RgwUserService } from '~/app/shared/api/rgw-user.service';
7 import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
8 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
9 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
10 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
11 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
12 import { CdValidators } from '~/app/shared/forms/cd-validators';
13 import { NotificationService } from '~/app/shared/services/notification.service';
14 import { RgwRealm, RgwZone, RgwZonegroup, SystemKey } from '../models/rgw-multisite';
15 import { ModalService } from '~/app/shared/services/modal.service';
18 selector: 'cd-rgw-multisite-zone-form',
19 templateUrl: './rgw-multisite-zone-form.component.html',
20 styleUrls: ['./rgw-multisite-zone-form.component.scss']
22 export class RgwMultisiteZoneFormComponent implements OnInit {
23 readonly endpoints = /^((https?:\/\/)|(www.))(?:([a-zA-Z]+)|(\d+\.\d+.\d+.\d+)):\d{2,4}$/;
24 readonly ipv4Rgx = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i;
25 readonly ipv6Rgx = /^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i;
28 multisiteZoneForm: CdFormGroup;
32 zonegroup: RgwZonegroup;
34 defaultsInfo: string[] = [];
35 multisiteInfo: object[] = [];
36 zonegroupList: RgwZonegroup[] = [];
37 zoneList: RgwZone[] = [];
40 placementTargets: any;
42 poolList: object[] = [];
43 storageClassList: object[] = [];
44 disableDefault: boolean = false;
45 disableMaster: boolean = false;
46 isMetadataSync: boolean = false;
47 isMasterZone: boolean;
48 isDefaultZone: boolean;
49 syncStatusTimedOut: boolean = false;
50 bsModalRef: NgbModalRef;
51 createSystemUser: boolean = false;
52 master_zone_of_master_zonegroup: RgwZone;
55 master_zonegroup_of_realm: RgwZonegroup;
56 compressionTypes = ['lz4', 'zlib', 'snappy'];
57 userListReady: boolean = false;
60 public activeModal: NgbActiveModal,
61 public actionLabels: ActionLabelsI18n,
62 public rgwMultisiteService: RgwMultisiteService,
63 public rgwZoneService: RgwZoneService,
64 public rgwZoneGroupService: RgwZonegroupService,
65 public notificationService: NotificationService,
66 public rgwUserService: RgwUserService,
67 public modalService: ModalService
69 this.action = this.editing
70 ? this.actionLabels.EDIT + this.resource
71 : this.actionLabels.CREATE + this.resource;
76 this.multisiteZoneForm = new CdFormGroup({
77 zoneName: new UntypedFormControl(null, {
80 CdValidators.custom('uniqueName', (zoneName: string) => {
82 this.action === 'create' && this.zoneNames && this.zoneNames.indexOf(zoneName) !== -1
87 default_zone: new UntypedFormControl(false),
88 master_zone: new UntypedFormControl(false),
89 selectedZonegroup: new UntypedFormControl(null),
90 zone_endpoints: new UntypedFormControl(null, {
92 CdValidators.custom('endpoint', (value: string) => {
93 if (_.isEmpty(value)) {
96 if (value.includes(',')) {
97 value.split(',').forEach((url: string) => {
99 !this.endpoints.test(url) && !this.ipv4Rgx.test(url) && !this.ipv6Rgx.test(url)
104 !this.endpoints.test(value) &&
105 !this.ipv4Rgx.test(value) &&
106 !this.ipv6Rgx.test(value)
115 access_key: new UntypedFormControl(null, Validators.required),
116 secret_key: new UntypedFormControl(null, Validators.required),
117 placementTarget: new UntypedFormControl(null),
118 placementDataPool: new UntypedFormControl(''),
119 placementIndexPool: new UntypedFormControl(null),
120 placementDataExtraPool: new UntypedFormControl(null),
121 storageClass: new UntypedFormControl(null),
122 storageDataPool: new UntypedFormControl(null),
123 storageCompression: new UntypedFormControl(null)
127 onZoneGroupChange(zonegroupName: string) {
128 let zg = new RgwZonegroup();
129 zg.name = zonegroupName;
130 this.rgwZoneGroupService.get(zg).subscribe((zonegroup: RgwZonegroup) => {
131 if (_.isEmpty(zonegroup.master_zone)) {
132 this.multisiteZoneForm.get('master_zone').setValue(true);
133 this.multisiteZoneForm.get('master_zone').disable();
134 this.disableMaster = false;
135 } else if (!_.isEmpty(zonegroup.master_zone) && this.action === 'create') {
136 this.multisiteZoneForm.get('master_zone').setValue(false);
137 this.multisiteZoneForm.get('master_zone').disable();
138 this.disableMaster = true;
142 this.multisiteZoneForm.getValue('selectedZonegroup') !==
143 this.defaultsInfo['defaultZonegroupName']
145 this.disableDefault = true;
146 this.multisiteZoneForm.get('default_zone').disable();
152 this.multisiteInfo[1] !== undefined && this.multisiteInfo[1].hasOwnProperty('zonegroups')
153 ? this.multisiteInfo[1]['zonegroups']
156 this.multisiteInfo[2] !== undefined && this.multisiteInfo[2].hasOwnProperty('zones')
157 ? this.multisiteInfo[2]['zones']
159 this.zoneNames = this.zoneList.map((zone) => {
162 if (this.action === 'create') {
163 if (this.defaultsInfo['defaultZonegroupName'] !== undefined) {
164 this.multisiteZoneForm
165 .get('selectedZonegroup')
166 .setValue(this.defaultsInfo['defaultZonegroupName']);
167 this.onZoneGroupChange(this.defaultsInfo['defaultZonegroupName']);
170 if (this.action === 'edit') {
171 this.placementTargets = this.info.parent ? this.info.parent.data.placement_targets : [];
172 this.rgwZoneService.getPoolNames().subscribe((pools: object[]) => {
173 this.poolList = pools;
175 this.multisiteZoneForm.get('zoneName').setValue(this.info.data.name);
176 this.multisiteZoneForm.get('selectedZonegroup').setValue(this.info.data.parent);
177 this.multisiteZoneForm.get('default_zone').setValue(this.info.data.is_default);
178 this.multisiteZoneForm.get('master_zone').setValue(this.info.data.is_master);
179 this.multisiteZoneForm.get('zone_endpoints').setValue(this.info.data.endpoints.toString());
180 this.multisiteZoneForm.get('access_key').setValue(this.info.data.access_key);
181 this.multisiteZoneForm.get('secret_key').setValue(this.info.data.secret_key);
182 this.multisiteZoneForm
183 .get('placementTarget')
184 .setValue(this.info.parent.data.default_placement);
185 this.getZonePlacementData(this.multisiteZoneForm.getValue('placementTarget'));
186 if (this.info.data.is_default) {
187 this.isDefaultZone = true;
188 this.multisiteZoneForm.get('default_zone').disable();
190 if (this.info.data.is_master) {
191 this.isMasterZone = true;
192 this.multisiteZoneForm.get('master_zone').disable();
194 const zone = new RgwZone();
195 zone.name = this.info.data.name;
196 this.onZoneGroupChange(this.info.data.parent);
199 this.multisiteZoneForm.getValue('selectedZonegroup') !==
200 this.defaultsInfo['defaultZonegroupName']
202 this.disableDefault = true;
203 this.multisiteZoneForm.get('default_zone').disable();
207 getZonePlacementData(placementTarget: string) {
208 this.zone = new RgwZone();
209 this.zone.name = this.info.data.name;
210 if (this.placementTargets) {
211 this.placementTargets.forEach((placement: any) => {
212 if (placement.name === placementTarget) {
213 let storageClasses = placement.storage_classes;
214 this.storageClassList = Object.entries(storageClasses).map(([key, value]) => ({
221 this.rgwZoneService.get(this.zone).subscribe((zoneInfo: RgwZone) => {
222 this.zoneInfo = zoneInfo;
223 if (this.zoneInfo && this.zoneInfo['placement_pools']) {
224 this.zoneInfo['placement_pools'].forEach((plc_pool) => {
225 if (plc_pool.key === placementTarget) {
226 let storageClasses = plc_pool.val.storage_classes;
227 let placementDataPool = storageClasses['STANDARD']
228 ? storageClasses['STANDARD']['data_pool']
230 let placementIndexPool = plc_pool.val.index_pool;
231 let placementDataExtraPool = plc_pool.val.data_extra_pool;
232 this.poolList.push({ poolname: placementDataPool });
233 this.poolList.push({ poolname: placementIndexPool });
234 this.poolList.push({ poolname: placementDataExtraPool });
235 this.multisiteZoneForm.get('storageClass').setValue(this.storageClassList[0]['value']);
236 this.multisiteZoneForm.get('storageDataPool').setValue(placementDataPool);
237 this.multisiteZoneForm.get('storageCompression').setValue(this.compressionTypes[0]);
238 this.multisiteZoneForm.get('placementDataPool').setValue(placementDataPool);
239 this.multisiteZoneForm.get('placementIndexPool').setValue(placementIndexPool);
240 this.multisiteZoneForm.get('placementDataExtraPool').setValue(placementDataExtraPool);
247 getStorageClassData(storageClass: string) {
248 let storageClassSelected = this.storageClassList.find((x) => x['value'] == storageClass)[
251 this.poolList.push({ poolname: storageClassSelected.data_pool });
252 this.multisiteZoneForm.get('storageDataPool').setValue(storageClassSelected.data_pool);
253 this.multisiteZoneForm
254 .get('storageCompression')
255 .setValue(storageClassSelected.compression_type);
259 const values = this.multisiteZoneForm.getRawValue();
260 if (this.action === 'create') {
261 this.zonegroup = new RgwZonegroup();
262 this.zonegroup.name = values['selectedZonegroup'];
263 this.zone = new RgwZone();
264 this.zone.name = values['zoneName'];
265 this.zone.endpoints = values['zone_endpoints'];
266 this.zone.system_key = new SystemKey();
267 this.zone.system_key.access_key = values['access_key'];
268 this.zone.system_key.secret_key = values['secret_key'];
273 values['default_zone'],
274 values['master_zone'],
279 this.notificationService.show(
280 NotificationType.success,
281 $localize`Zone: '${values['zoneName']}' created successfully`
283 this.activeModal.close();
286 this.multisiteZoneForm.setErrors({ cdSubmitButton: true });
289 } else if (this.action === 'edit') {
290 this.zonegroup = new RgwZonegroup();
291 this.zonegroup.name = values['selectedZonegroup'];
292 this.zone = new RgwZone();
293 this.zone.name = this.info.data.name;
294 this.zone.endpoints = values['zone_endpoints'];
295 this.zone.system_key = new SystemKey();
296 this.zone.system_key.access_key = values['access_key'];
297 this.zone.system_key.secret_key = values['secret_key'];
303 values['default_zone'],
304 values['master_zone'],
306 values['placementTarget'],
307 values['placementDataPool'],
308 values['placementIndexPool'],
309 values['placementDataExtraPool'],
310 values['storageClass'],
311 values['storageDataPool'],
312 values['storageCompression']
316 this.notificationService.show(
317 NotificationType.success,
318 $localize`Zone: '${values['zoneName']}' updated successfully`
320 this.activeModal.close();
323 this.multisiteZoneForm.setErrors({ cdSubmitButton: true });