1 import { Component, OnInit } from '@angular/core';
2 import { FormArray, FormBuilder, FormControl, NgForm, Validators } from '@angular/forms';
3 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
4 import _ from 'lodash';
5 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
6 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
7 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
8 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
9 import { CdValidators } from '~/app/shared/forms/cd-validators';
10 import { NotificationService } from '~/app/shared/services/notification.service';
11 import { RgwRealm, RgwZone, RgwZonegroup } from '../models/rgw-multisite';
12 import { Icons } from '~/app/shared/enum/icons.enum';
13 import { SelectOption } from '~/app/shared/components/select/select-option.model';
16 selector: 'cd-rgw-multisite-zonegroup-form',
17 templateUrl: './rgw-multisite-zonegroup-form.component.html',
18 styleUrls: ['./rgw-multisite-zonegroup-form.component.scss']
20 export class RgwMultisiteZonegroupFormComponent implements OnInit {
21 readonly endpoints = /^((https?:\/\/)|(www.))(?:([a-zA-Z]+)|(\d+\.\d+.\d+.\d+)):\d{2,4}$/;
22 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;
23 readonly ipv6Rgx = /^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i;
26 multisiteZonegroupForm: CdFormGroup;
30 zonegroup: RgwZonegroup;
32 defaultsInfo: string[] = [];
33 multisiteInfo: object[] = [];
34 realmList: RgwRealm[] = [];
35 zonegroupList: RgwZonegroup[] = [];
36 zonegroupNames: string[];
38 placementTargets: FormArray;
39 newZonegroupName: string;
40 zonegroupZoneNames: string[];
41 labelsOption: Array<SelectOption> = [];
42 zoneList: RgwZone[] = [];
43 allZoneNames: string[];
44 zgZoneNames: string[];
46 removedZones: string[];
47 isRemoveMasterZone = false;
49 disableDefault = false;
50 disableMaster = false;
53 public activeModal: NgbActiveModal,
54 public actionLabels: ActionLabelsI18n,
55 public rgwZonegroupService: RgwZonegroupService,
56 public notificationService: NotificationService,
57 private formBuilder: FormBuilder
59 this.action = this.editing
60 ? this.actionLabels.EDIT + this.resource
61 : this.actionLabels.CREATE + this.resource;
66 this.multisiteZonegroupForm = new CdFormGroup({
67 default_zonegroup: new FormControl(false),
68 zonegroupName: new FormControl(null, {
71 CdValidators.custom('uniqueName', (zonegroupName: string) => {
73 this.action === 'create' &&
74 this.zonegroupNames &&
75 this.zonegroupNames.indexOf(zonegroupName) !== -1
80 master_zonegroup: new FormControl(false),
81 selectedRealm: new FormControl(null),
82 zonegroup_endpoints: new FormControl(null, [
83 CdValidators.custom('endpoint', (value: string) => {
84 if (_.isEmpty(value)) {
87 if (value.includes(',')) {
88 value.split(',').forEach((url: string) => {
90 !this.endpoints.test(url) && !this.ipv4Rgx.test(url) && !this.ipv6Rgx.test(url)
95 !this.endpoints.test(value) &&
96 !this.ipv4Rgx.test(value) &&
97 !this.ipv6Rgx.test(value)
105 placementTargets: this.formBuilder.array([])
110 _.forEach(this.multisiteZonegroupForm.get('placementTargets'), (placementTarget) => {
111 const fg = this.addPlacementTarget();
112 fg.patchValue(placementTarget);
114 this.placementTargets = this.multisiteZonegroupForm.get('placementTargets') as FormArray;
116 this.multisiteInfo[0] !== undefined && this.multisiteInfo[0].hasOwnProperty('realms')
117 ? this.multisiteInfo[0]['realms']
120 this.multisiteInfo[1] !== undefined && this.multisiteInfo[1].hasOwnProperty('zonegroups')
121 ? this.multisiteInfo[1]['zonegroups']
123 this.zonegroupList.forEach((zgp: any) => {
124 if (zgp.is_master === true && !_.isEmpty(zgp.realm_id)) {
125 this.isMaster = true;
126 this.disableMaster = true;
129 if (!this.isMaster) {
130 this.multisiteZonegroupForm.get('master_zonegroup').setValue(true);
131 this.multisiteZonegroupForm.get('master_zonegroup').disable();
134 this.multisiteInfo[2] !== undefined && this.multisiteInfo[2].hasOwnProperty('zones')
135 ? this.multisiteInfo[2]['zones']
137 this.zonegroupNames = this.zonegroupList.map((zonegroup) => {
138 return zonegroup['name'];
140 this.allZoneNames = this.zoneList.map((zone: RgwZone) => {
143 if (this.action === 'create' && this.defaultsInfo['defaultRealmName'] !== null) {
144 this.multisiteZonegroupForm
145 .get('selectedRealm')
146 .setValue(this.defaultsInfo['defaultRealmName']);
147 if (this.disableMaster) {
148 this.multisiteZonegroupForm.get('master_zonegroup').disable();
151 if (this.action === 'edit') {
152 this.multisiteZonegroupForm.get('zonegroupName').setValue(this.info.data.name);
153 this.multisiteZonegroupForm.get('selectedRealm').setValue(this.info.data.parent);
154 this.multisiteZonegroupForm.get('default_zonegroup').setValue(this.info.data.is_default);
155 this.multisiteZonegroupForm.get('master_zonegroup').setValue(this.info.data.is_master);
156 this.multisiteZonegroupForm.get('zonegroup_endpoints').setValue(this.info.data.endpoints);
158 if (this.info.data.is_default) {
159 this.multisiteZonegroupForm.get('default_zonegroup').disable();
162 !this.info.data.is_default &&
163 this.multisiteZonegroupForm.getValue('selectedRealm') !==
164 this.defaultsInfo['defaultRealmName']
166 this.multisiteZonegroupForm.get('default_zonegroup').disable();
167 this.disableDefault = true;
169 if (this.info.data.is_master || this.disableMaster) {
170 this.multisiteZonegroupForm.get('master_zonegroup').disable();
173 this.zonegroupZoneNames = this.info.data.zones.map((zone: { [x: string]: any }) => {
176 this.zgZoneNames = this.info.data.zones.map((zone: { [x: string]: any }) => {
179 this.zgZoneIds = this.info.data.zones.map((zone: { [x: string]: any }) => {
182 const uniqueZones = new Set(this.allZoneNames);
183 this.labelsOption = Array.from(uniqueZones).map((zone) => {
184 return { enabled: true, name: zone, selected: false, description: null };
187 this.info.data.placement_targets.forEach((target: object) => {
188 const fg = this.addPlacementTarget();
190 placement_id: target['name'],
191 tags: target['tags'].join(','),
193 typeof target['storage_classes'] === 'string'
194 ? target['storage_classes']
195 : target['storage_classes'].join(',')
203 const values = this.multisiteZonegroupForm.getRawValue();
204 if (this.action === 'create') {
205 this.realm = new RgwRealm();
206 this.realm.name = values['selectedRealm'];
207 this.zonegroup = new RgwZonegroup();
208 this.zonegroup.name = values['zonegroupName'];
209 this.zonegroup.endpoints = this.checkUrlArray(values['zonegroup_endpoints']);
210 this.rgwZonegroupService
211 .create(this.realm, this.zonegroup, values['default_zonegroup'], values['master_zonegroup'])
214 this.notificationService.show(
215 NotificationType.success,
216 $localize`Zonegroup: '${values['zonegroupName']}' created successfully`
218 this.activeModal.close();
221 this.multisiteZonegroupForm.setErrors({ cdSubmitButton: true });
224 } else if (this.action === 'edit') {
225 this.removedZones = _.difference(this.zgZoneNames, this.zonegroupZoneNames);
226 const masterZoneName = this.info.data.zones.filter(
227 (zone: any) => zone.id === this.info.data.master_zone
229 this.isRemoveMasterZone = this.removedZones.includes(masterZoneName[0].name);
230 if (this.isRemoveMasterZone) {
231 this.multisiteZonegroupForm.setErrors({ cdSubmitButton: true });
234 this.addedZones = _.difference(this.zonegroupZoneNames, this.zgZoneNames);
235 this.realm = new RgwRealm();
236 this.realm.name = values['selectedRealm'];
237 this.zonegroup = new RgwZonegroup();
238 this.zonegroup.name = this.info.data.name;
239 this.newZonegroupName = values['zonegroupName'];
240 this.zonegroup.endpoints =
241 values['zonegroup_endpoints'] === this.info.data.endpoints
242 ? values['zonegroup_endpoints']
243 : this.checkUrlArray(values['zonegroup_endpoints']);
244 this.zonegroup.placement_targets = values['placementTargets'];
245 this.rgwZonegroupService
249 this.newZonegroupName,
250 values['default_zonegroup'],
251 values['master_zonegroup'],
257 this.notificationService.show(
258 NotificationType.success,
259 $localize`Zonegroup: '${values['zonegroupName']}' updated successfully`
261 this.activeModal.close();
264 this.multisiteZonegroupForm.setErrors({ cdSubmitButton: true });
270 checkUrlArray(endpoints: string) {
271 let endpointsArray = [];
272 if (endpoints.includes(',')) {
273 endpointsArray = endpoints.split(',');
275 endpointsArray.push(endpoints);
277 return endpointsArray;
280 addPlacementTarget() {
281 this.placementTargets = this.multisiteZonegroupForm.get('placementTargets') as FormArray;
282 const fg = new CdFormGroup({
283 placement_id: new FormControl('', {
284 validators: [Validators.required]
286 tags: new FormControl(''),
287 storage_class: new FormControl([])
289 this.placementTargets.push(fg);
293 trackByFn(index: number) {
297 removePlacementTarget(index: number) {
298 this.placementTargets = this.multisiteZonegroupForm.get('placementTargets') as FormArray;
299 this.placementTargets.removeAt(index);
302 showError(index: number, control: string, formDir: NgForm, x: string) {
303 return (<any>this.multisiteZonegroupForm.controls.placementTargets).controls[index].showError(