1 import { Component, OnInit } from '@angular/core';
8 } from '@angular/forms';
9 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
10 import _ from 'lodash';
11 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
12 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
13 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
14 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
15 import { CdValidators } from '~/app/shared/forms/cd-validators';
16 import { NotificationService } from '~/app/shared/services/notification.service';
17 import { RgwRealm, RgwZone, RgwZonegroup } from '../models/rgw-multisite';
18 import { Icons } from '~/app/shared/enum/icons.enum';
19 import { SelectOption } from '~/app/shared/components/select/select-option.model';
22 selector: 'cd-rgw-multisite-zonegroup-form',
23 templateUrl: './rgw-multisite-zonegroup-form.component.html',
24 styleUrls: ['./rgw-multisite-zonegroup-form.component.scss']
26 export class RgwMultisiteZonegroupFormComponent implements OnInit {
27 readonly endpoints = /^((https?:\/\/)|(www.))(?:([a-zA-Z]+)|(\d+\.\d+.\d+.\d+)):\d{2,4}$/;
28 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;
29 readonly ipv6Rgx = /^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i;
32 multisiteZonegroupForm: CdFormGroup;
36 zonegroup: RgwZonegroup;
38 defaultsInfo: string[] = [];
39 multisiteInfo: object[] = [];
40 realmList: RgwRealm[] = [];
41 zonegroupList: RgwZonegroup[] = [];
42 zonegroupNames: string[];
44 placementTargets: UntypedFormArray;
45 newZonegroupName: string;
46 zonegroupZoneNames: string[];
47 labelsOption: Array<SelectOption> = [];
48 zoneList: RgwZone[] = [];
49 allZoneNames: string[];
50 zgZoneNames: string[];
52 removedZones: string[];
53 isRemoveMasterZone = false;
55 disableDefault = false;
56 disableMaster = false;
59 public activeModal: NgbActiveModal,
60 public actionLabels: ActionLabelsI18n,
61 public rgwZonegroupService: RgwZonegroupService,
62 public notificationService: NotificationService,
63 private formBuilder: UntypedFormBuilder
65 this.action = this.editing
66 ? this.actionLabels.EDIT + this.resource
67 : this.actionLabels.CREATE + this.resource;
72 this.multisiteZonegroupForm = new CdFormGroup({
73 default_zonegroup: new UntypedFormControl(false),
74 zonegroupName: new UntypedFormControl(null, {
77 CdValidators.custom('uniqueName', (zonegroupName: string) => {
79 this.action === 'create' &&
80 this.zonegroupNames &&
81 this.zonegroupNames.indexOf(zonegroupName) !== -1
86 master_zonegroup: new UntypedFormControl(false),
87 selectedRealm: new UntypedFormControl(null),
88 zonegroup_endpoints: new UntypedFormControl(null, [
89 CdValidators.custom('endpoint', (value: string) => {
90 if (_.isEmpty(value)) {
93 if (value.includes(',')) {
94 value.split(',').forEach((url: string) => {
96 !this.endpoints.test(url) && !this.ipv4Rgx.test(url) && !this.ipv6Rgx.test(url)
101 !this.endpoints.test(value) &&
102 !this.ipv4Rgx.test(value) &&
103 !this.ipv6Rgx.test(value)
111 placementTargets: this.formBuilder.array([])
116 _.forEach(this.multisiteZonegroupForm.get('placementTargets'), (placementTarget) => {
117 const fg = this.addPlacementTarget();
118 fg.patchValue(placementTarget);
120 this.placementTargets = this.multisiteZonegroupForm.get('placementTargets') as UntypedFormArray;
122 this.multisiteInfo[0] !== undefined && this.multisiteInfo[0].hasOwnProperty('realms')
123 ? this.multisiteInfo[0]['realms']
126 this.multisiteInfo[1] !== undefined && this.multisiteInfo[1].hasOwnProperty('zonegroups')
127 ? this.multisiteInfo[1]['zonegroups']
129 this.zonegroupList.forEach((zgp: any) => {
130 if (zgp.is_master === true && !_.isEmpty(zgp.realm_id)) {
131 this.isMaster = true;
132 this.disableMaster = true;
135 if (!this.isMaster) {
136 this.multisiteZonegroupForm.get('master_zonegroup').setValue(true);
137 this.multisiteZonegroupForm.get('master_zonegroup').disable();
140 this.multisiteInfo[2] !== undefined && this.multisiteInfo[2].hasOwnProperty('zones')
141 ? this.multisiteInfo[2]['zones']
143 this.zonegroupNames = this.zonegroupList.map((zonegroup) => {
144 return zonegroup['name'];
146 let allZonegroupZonesList = this.zonegroupList.map((zonegroup: RgwZonegroup) => {
147 return zonegroup['zones'];
149 const allZonegroupZonesInfo = allZonegroupZonesList.reduce(
150 (accumulator, value) => accumulator.concat(value),
153 const allZonegroupZonesNames = allZonegroupZonesInfo.map((zone) => {
156 this.allZoneNames = this.zoneList.map((zone: RgwZone) => {
159 this.allZoneNames = _.difference(this.allZoneNames, allZonegroupZonesNames);
160 if (this.action === 'create' && this.defaultsInfo['defaultRealmName'] !== null) {
161 this.multisiteZonegroupForm
162 .get('selectedRealm')
163 .setValue(this.defaultsInfo['defaultRealmName']);
164 if (this.disableMaster) {
165 this.multisiteZonegroupForm.get('master_zonegroup').disable();
168 if (this.action === 'edit') {
169 this.multisiteZonegroupForm.get('zonegroupName').setValue(this.info.data.name);
170 this.multisiteZonegroupForm.get('selectedRealm').setValue(this.info.data.parent);
171 this.multisiteZonegroupForm.get('default_zonegroup').setValue(this.info.data.is_default);
172 this.multisiteZonegroupForm.get('master_zonegroup').setValue(this.info.data.is_master);
173 this.multisiteZonegroupForm.get('zonegroup_endpoints').setValue(this.info.data.endpoints);
175 if (this.info.data.is_default) {
176 this.multisiteZonegroupForm.get('default_zonegroup').disable();
179 !this.info.data.is_default &&
180 this.multisiteZonegroupForm.getValue('selectedRealm') !==
181 this.defaultsInfo['defaultRealmName']
183 this.multisiteZonegroupForm.get('default_zonegroup').disable();
184 this.disableDefault = true;
186 if (this.info.data.is_master || this.disableMaster) {
187 this.multisiteZonegroupForm.get('master_zonegroup').disable();
190 this.zonegroupZoneNames = this.info.data.zones.map((zone: { [x: string]: any }) => {
193 this.zgZoneNames = this.info.data.zones.map((zone: { [x: string]: any }) => {
196 this.zgZoneIds = this.info.data.zones.map((zone: { [x: string]: any }) => {
199 const uniqueZones = new Set(this.allZoneNames);
200 this.labelsOption = Array.from(uniqueZones).map((zone) => {
201 return { enabled: true, name: zone, selected: false, description: null };
204 this.info.data.placement_targets.forEach((target: object) => {
205 const fg = this.addPlacementTarget();
207 placement_id: target['name'],
208 tags: target['tags'].join(','),
210 typeof target['storage_classes'] === 'string'
211 ? target['storage_classes']
212 : target['storage_classes'].join(',')
220 const values = this.multisiteZonegroupForm.getRawValue();
221 if (this.action === 'create') {
222 this.realm = new RgwRealm();
223 this.realm.name = values['selectedRealm'];
224 this.zonegroup = new RgwZonegroup();
225 this.zonegroup.name = values['zonegroupName'];
226 this.zonegroup.endpoints = values['zonegroup_endpoints'];
227 this.rgwZonegroupService
228 .create(this.realm, this.zonegroup, values['default_zonegroup'], values['master_zonegroup'])
231 this.notificationService.show(
232 NotificationType.success,
233 $localize`Zonegroup: '${values['zonegroupName']}' created successfully`
235 this.activeModal.close();
238 this.multisiteZonegroupForm.setErrors({ cdSubmitButton: true });
241 } else if (this.action === 'edit') {
242 this.removedZones = _.difference(this.zgZoneNames, this.zonegroupZoneNames);
243 const masterZoneName = this.info.data.zones.filter(
244 (zone: any) => zone.id === this.info.data.master_zone
246 this.isRemoveMasterZone = this.removedZones.includes(masterZoneName[0].name);
247 if (this.isRemoveMasterZone) {
248 this.multisiteZonegroupForm.setErrors({ cdSubmitButton: true });
251 this.addedZones = _.difference(this.zonegroupZoneNames, this.zgZoneNames);
252 this.realm = new RgwRealm();
253 this.realm.name = values['selectedRealm'];
254 this.zonegroup = new RgwZonegroup();
255 this.zonegroup.name = this.info.data.name;
256 this.newZonegroupName = values['zonegroupName'];
257 this.zonegroup.endpoints = values['zonegroup_endpoints'].toString();
258 this.zonegroup.placement_targets = values['placementTargets'];
259 this.rgwZonegroupService
263 this.newZonegroupName,
264 values['default_zonegroup'],
265 values['master_zonegroup'],
271 this.notificationService.show(
272 NotificationType.success,
273 $localize`Zonegroup: '${values['zonegroupName']}' updated successfully`
275 this.activeModal.close();
278 this.multisiteZonegroupForm.setErrors({ cdSubmitButton: true });
284 addPlacementTarget() {
285 this.placementTargets = this.multisiteZonegroupForm.get('placementTargets') as UntypedFormArray;
286 const fg = new CdFormGroup({
287 placement_id: new UntypedFormControl('', {
288 validators: [Validators.required]
290 tags: new UntypedFormControl(''),
291 storage_class: new UntypedFormControl([])
293 this.placementTargets.push(fg);
297 trackByFn(index: number) {
301 removePlacementTarget(index: number) {
302 this.placementTargets = this.multisiteZonegroupForm.get('placementTargets') as UntypedFormArray;
303 this.placementTargets.removeAt(index);
306 showError(index: number, control: string, formDir: NgForm, x: string) {
307 return (<any>this.multisiteZonegroupForm.controls.placementTargets).controls[index].showError(