]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
8b64b2480ada3f4b722a21152e13641a68e353d5
[ceph-ci.git] /
1 import { TitleCasePipe } from '@angular/common';
2 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
3 import { Router } from '@angular/router';
4 import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs';
5 import { RgwDaemonService } from '~/app/shared/api/rgw-daemon.service';
6 import { RgwMultisiteService } from '~/app/shared/api/rgw-multisite.service';
7 import { ListWithDetails } from '~/app/shared/classes/list-with-details.class';
8 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
9 import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
10 import { TableComponent } from '~/app/shared/datatable/table/table.component';
11 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
12 import { Icons } from '~/app/shared/enum/icons.enum';
13 import { CdTableAction } from '~/app/shared/models/cd-table-action';
14 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
15 import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
16 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
17 import { FinishedTask } from '~/app/shared/models/finished-task';
18 import { Permission } from '~/app/shared/models/permissions';
19 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
20 import { ModalService } from '~/app/shared/services/modal.service';
21 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
22 import { URLBuilderService } from '~/app/shared/services/url-builder.service';
23
24 const BASE_URL = 'rgw/multisite/sync-policy';
25
26 @Component({
27   selector: 'cd-rgw-multisite-sync-policy',
28   templateUrl: './rgw-multisite-sync-policy.component.html',
29   styleUrls: ['./rgw-multisite-sync-policy.component.scss'],
30   providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
31 })
32 export class RgwMultisiteSyncPolicyComponent extends ListWithDetails implements OnInit {
33   @ViewChild(TableComponent, { static: true })
34   table: TableComponent;
35   @ViewChild('deleteTpl', { static: true })
36   deleteTpl: TemplateRef<any>;
37
38   columns: Array<CdTableColumn> = [];
39   syncPolicyData: any = [];
40   tableActions: CdTableAction[];
41   selection = new CdTableSelection();
42   permission: Permission;
43
44   constructor(
45     private rgwMultisiteService: RgwMultisiteService,
46     private titleCasePipe: TitleCasePipe,
47     private actionLabels: ActionLabelsI18n,
48     private authStorageService: AuthStorageService,
49     private modalService: ModalService,
50     private taskWrapper: TaskWrapperService,
51     private router: Router,
52     private rgwDaemonService: RgwDaemonService
53   ) {
54     super();
55   }
56
57   ngOnInit(): void {
58     this.permission = this.authStorageService.getPermissions().rgw;
59     this.columns = [
60       {
61         prop: 'uniqueId',
62         isInvisible: true,
63         isHidden: true
64       },
65       {
66         name: $localize`Group Name`,
67         prop: 'groupName',
68         flexGrow: 1
69       },
70       {
71         name: $localize`Status`,
72         prop: 'status',
73         flexGrow: 1,
74         cellTransformation: CellTemplate.tooltip,
75         customTemplateConfig: {
76           map: {
77             Enabled: { class: 'badge-success', tooltip: 'sync is allowed and enabled' },
78             Allowed: { class: 'badge-info', tooltip: 'sync is allowed' },
79             Forbidden: {
80               class: 'badge-warning',
81               tooltip:
82                 'sync (as defined by this group) is not allowed and can override other groups'
83             }
84           }
85         },
86         pipe: this.titleCasePipe
87       },
88       {
89         name: $localize`Zonegroup`,
90         prop: 'zonegroup',
91         flexGrow: 1
92       },
93       {
94         name: $localize`Bucket`,
95         prop: 'bucket',
96         flexGrow: 1
97       }
98     ];
99     this.rgwDaemonService.list().subscribe();
100     const getEditURL = () => {
101       if (this.selection.first().groupName && this.selection.first().bucket) {
102         return `${URLVerbs.EDIT}/${this.selection.first().groupName}/${
103           this.selection.first().bucket
104         }`;
105       }
106       return `${URLVerbs.EDIT}/${this.selection.first().groupName}`;
107     };
108     const addAction: CdTableAction = {
109       permission: 'create',
110       icon: Icons.add,
111       click: () => this.router.navigate([BASE_URL, { outlets: { modal: URLVerbs.CREATE } }]),
112       name: this.actionLabels.CREATE,
113       canBePrimary: (selection: CdTableSelection) => !selection.hasSelection
114     };
115     const editAction: CdTableAction = {
116       permission: 'update',
117       icon: Icons.edit,
118       click: () => this.router.navigate([BASE_URL, { outlets: { modal: getEditURL() } }]),
119       name: this.actionLabels.EDIT
120     };
121     const deleteAction: CdTableAction = {
122       permission: 'delete',
123       icon: Icons.destroy,
124       click: () => this.deleteAction(),
125       disable: () => !this.selection.hasSelection,
126       name: this.actionLabels.DELETE,
127       canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection
128     };
129     this.tableActions = [addAction, editAction, deleteAction];
130   }
131
132   transformSyncPolicyData(allSyncPolicyData: any) {
133     if (allSyncPolicyData && allSyncPolicyData.length > 0) {
134       allSyncPolicyData.forEach((policy: any) => {
135         this.syncPolicyData.push({
136           uniqueId: policy['id'] + (policy['bucketName'] ? policy['bucketName'] : ''),
137           groupName: policy['id'],
138           status: policy['status'],
139           bucket: policy['bucketName'],
140           zonegroup: ''
141         });
142       });
143       this.syncPolicyData = [...this.syncPolicyData];
144     }
145   }
146
147   updateSelection(selection: CdTableSelection) {
148     this.selection = selection;
149   }
150
151   getPolicyList(context?: CdTableFetchDataContext) {
152     this.rgwMultisiteService.getSyncPolicy('', '', true).subscribe(
153       (resp: object[]) => {
154         this.syncPolicyData = [];
155         this.transformSyncPolicyData(resp);
156       },
157       () => {
158         if (context) {
159           context.error();
160         }
161       }
162     );
163   }
164
165   deleteAction() {
166     const groupNames = this.selection.selected.map((policy: any) => policy.groupName);
167     this.modalService.show(CriticalConfirmationModalComponent, {
168       itemDescription: this.selection.hasSingleSelection
169         ? $localize`Policy Group`
170         : $localize`Policy Groups`,
171       itemNames: groupNames,
172       bodyTemplate: this.deleteTpl,
173       submitActionObservable: () => {
174         return new Observable((observer: Subscriber<any>) => {
175           this.taskWrapper
176             .wrapTaskAroundCall({
177               task: new FinishedTask('rgw/multisite/sync-policy/delete', {
178                 group_names: groupNames
179               }),
180               call: observableForkJoin(
181                 this.selection.selected.map((policy: any) => {
182                   return this.rgwMultisiteService.removeSyncPolicyGroup(
183                     policy.groupName,
184                     policy.bucket
185                   );
186                 })
187               )
188             })
189             .subscribe({
190               error: (error: any) => {
191                 // Forward the error to the observer.
192                 observer.error(error);
193                 // Reload the data table content because some deletions might
194                 // have been executed successfully in the meanwhile.
195                 this.table.refreshBtn();
196               },
197               complete: () => {
198                 // Notify the observer that we are done.
199                 observer.complete();
200                 // Reload the data table content.
201                 this.table.refreshBtn();
202               }
203             });
204         });
205       }
206     });
207   }
208 }