]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
2f41dbd23c843d925b86c82d2d1f6828fa75ab1f
[ceph-ci.git] /
1 import { Component, OnInit } from '@angular/core';
2 import { UntypedFormControl, Validators } from '@angular/forms';
3 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
4 import { RgwZonegroup, Zone } from '../models/rgw-multisite';
5 import { SelectOption } from '~/app/shared/components/select/select-option.model';
6 import { catchError, switchMap } from 'rxjs/operators';
7 import { of } from 'rxjs';
8 import { RgwDaemon } from '../models/rgw-daemon';
9 import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
10 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
11 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
12 import _ from 'lodash';
13 import { Icons } from '~/app/shared/enum/icons.enum';
14 import { RgwMultisiteService } from '~/app/shared/api/rgw-multisite.service';
15 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
16 import { NotificationService } from '~/app/shared/services/notification.service';
17 import { ZoneData } from '../models/rgw-multisite-zone-selector';
18 import { SucceededActionLabelsI18n } from '~/app/shared/constants/app.constants';
19
20 const ALL_ZONES = $localize`All zones (*)`;
21
22 @Component({
23   selector: 'cd-rgw-multisite-sync-pipe-modal',
24   templateUrl: './rgw-multisite-sync-pipe-modal.component.html',
25   styleUrls: ['./rgw-multisite-sync-pipe-modal.component.scss']
26 })
27 export class RgwMultisiteSyncPipeModalComponent implements OnInit {
28   groupExpandedRow: any;
29   pipeSelectedRow: any;
30   pipeForm: CdFormGroup;
31   action: string;
32   editing: boolean;
33   sourceZones = new ZoneData(false, 'Filter Zones');
34   destZones = new ZoneData(false, 'Filter Zones');
35   icons = Icons;
36
37   constructor(
38     public activeModal: NgbActiveModal,
39     private rgwDaemonService: RgwDaemonService,
40     private rgwZonegroupService: RgwZonegroupService,
41     private rgwMultisiteService: RgwMultisiteService,
42     private notificationService: NotificationService,
43     private succeededLabels: SucceededActionLabelsI18n
44   ) {}
45
46   ngOnInit(): void {
47     if (this.pipeSelectedRow) {
48       this.pipeSelectedRow.source.zones = this.replaceAsteriskWithString(
49         this.pipeSelectedRow.source.zones
50       );
51       this.pipeSelectedRow.dest.zones = this.replaceAsteriskWithString(
52         this.pipeSelectedRow.dest.zones
53       );
54     }
55     this.editing = this.action === 'create' ? false : true;
56     this.pipeForm = new CdFormGroup({
57       pipe_id: new UntypedFormControl('', {
58         validators: [Validators.required]
59       }),
60       group_id: new UntypedFormControl(this.groupExpandedRow?.groupName || '', {
61         validators: [Validators.required]
62       }),
63       bucket_name: new UntypedFormControl(this.groupExpandedRow?.bucket || ''),
64       source_bucket: new UntypedFormControl(''),
65       source_zones: new UntypedFormControl('', {
66         validators: [Validators.required]
67       }),
68       destination_bucket: new UntypedFormControl(''),
69       destination_zones: new UntypedFormControl('', {
70         validators: [Validators.required]
71       })
72     });
73     this.pipeForm.get('bucket_name').disable();
74     this.rgwDaemonService.selectedDaemon$
75       .pipe(
76         switchMap((daemon: RgwDaemon) => {
77           if (daemon) {
78             const zonegroupObj = new RgwZonegroup();
79             zonegroupObj.name = daemon.zonegroup_name;
80             return this.rgwZonegroupService.get(zonegroupObj).pipe(
81               catchError(() => {
82                 return of([]);
83               })
84             );
85           } else {
86             return of([]);
87           }
88         })
89       )
90       .subscribe((zonegroupData: any) => {
91         if (zonegroupData && zonegroupData?.zones?.length > 0) {
92           let zones: any[] = [];
93           zones.push(new SelectOption(false, ALL_ZONES, ''));
94           zonegroupData.zones.forEach((zone: any) => {
95             zones.push(new SelectOption(false, zone.name, ''));
96           });
97           this.sourceZones.data.available = JSON.parse(JSON.stringify(zones));
98           this.destZones.data.available = JSON.parse(JSON.stringify(zones));
99           if (this.editing) {
100             this.pipeForm.get('pipe_id').disable();
101             this.sourceZones.data.selected = [...this.pipeSelectedRow.source.zones];
102             this.destZones.data.selected = [...this.pipeSelectedRow.dest.zones];
103             const availableDestZone: SelectOption[] = [];
104             this.pipeSelectedRow.dest.zones.forEach((zone: string) => {
105               availableDestZone.push(new SelectOption(true, zone, ''));
106             });
107             this.pipeForm.patchValue({
108               pipe_id: this.pipeSelectedRow.id,
109               source_zones: this.pipeSelectedRow.source.zones,
110               destination_zones: this.pipeSelectedRow.dest.zones,
111               source_bucket: this.pipeSelectedRow.source.bucket,
112               destination_bucket: this.pipeSelectedRow.dest.bucket
113             });
114           }
115         }
116       });
117   }
118
119   replaceWithAsterisk(zones: string[]) {
120     return zones.map((str) => str.replace(ALL_ZONES, '*'));
121   }
122
123   replaceAsteriskWithString(zones: string[]) {
124     return zones.map((str) => str.replace('*', ALL_ZONES));
125   }
126
127   onZoneSelection(zoneType: string) {
128     if (zoneType === 'source_zones') {
129       this.pipeForm.patchValue({
130         source_zones: this.sourceZones.data.selected
131       });
132     } else {
133       this.pipeForm.patchValue({
134         destination_zones: this.destZones.data.selected
135       });
136     }
137   }
138
139   getZoneData(zoneDataToFilter: string[], zoneDataForCondition: string[]) {
140     return zoneDataToFilter.filter((zone: string) => !zoneDataForCondition.includes(zone));
141   }
142
143   assignZoneValue(zone: string[], selectedZone: string[]) {
144     return zone.length > 0
145       ? this.replaceWithAsterisk(zone)
146       : this.replaceWithAsterisk(selectedZone);
147   }
148
149   submit() {
150     const sourceZones: Zone = { added: [], removed: [] };
151     const destZones: Zone = { added: [], removed: [] };
152
153     if (this.pipeForm.invalid) {
154       return;
155     }
156     // Ensure that no validation is pending
157     if (this.pipeForm.pending) {
158       this.pipeForm.setErrors({ cdSubmitButton: true });
159       return;
160     }
161
162     if (this.editing) {
163       destZones.removed = this.getZoneData(
164         this.pipeSelectedRow.dest.zones,
165         this.destZones.data.selected
166       );
167       destZones.added = this.getZoneData(
168         this.destZones.data.selected,
169         this.pipeSelectedRow.dest.zones
170       );
171       sourceZones.removed = this.getZoneData(
172         this.pipeSelectedRow.source.zones,
173         this.sourceZones.data.selected
174       );
175       sourceZones.added = this.getZoneData(
176         this.sourceZones.data.selected,
177         this.pipeSelectedRow.source.zones
178       );
179     }
180     sourceZones.added = this.assignZoneValue(sourceZones.added, this.sourceZones.data.selected);
181     destZones.added = this.assignZoneValue(destZones.added, this.destZones.data.selected);
182
183     sourceZones.removed = this.replaceWithAsterisk(sourceZones.removed);
184     destZones.removed = this.replaceWithAsterisk(destZones.removed);
185
186     this.rgwMultisiteService
187       .createEditSyncPipe({
188         ...this.pipeForm.getRawValue(),
189         source_zones: sourceZones,
190         destination_zones: destZones
191       })
192       .subscribe(
193         () => {
194           const action = this.editing ? this.succeededLabels.EDITED : this.succeededLabels.CREATED;
195           this.notificationService.show(
196             NotificationType.success,
197             $localize`${action} Sync Pipe '${this.pipeForm.getValue('pipe_id')}'`
198           );
199           this.activeModal.close(NotificationType.success);
200         },
201         () => {
202           // Reset the 'Submit' button.
203           this.pipeForm.setErrors({ cdSubmitButton: true });
204           this.activeModal.dismiss();
205         }
206       );
207   }
208 }