]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
af48f5fdba69f3f5d32d279689be5df5752ce902
[ceph.git] /
1 import { Component, Inject } from '@angular/core';
2
3 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
4 import { SortDirection, SortPropDir } from '@swimlane/ngx-datatable';
5 import { Observable, Subscriber } from 'rxjs';
6
7 import { PrometheusService } from '../../../../shared/api/prometheus.service';
8 import { CriticalConfirmationModalComponent } from '../../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
9 import {
10   ActionLabelsI18n,
11   SucceededActionLabelsI18n
12 } from '../../../../shared/constants/app.constants';
13 import { CellTemplate } from '../../../../shared/enum/cell-template.enum';
14 import { Icons } from '../../../../shared/enum/icons.enum';
15 import { NotificationType } from '../../../../shared/enum/notification-type.enum';
16 import { AlertmanagerSilence } from '../../../../shared/models/alertmanager-silence';
17 import { CdTableAction } from '../../../../shared/models/cd-table-action';
18 import { CdTableColumn } from '../../../../shared/models/cd-table-column';
19 import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
20 import { Permission } from '../../../../shared/models/permissions';
21 import { CdDatePipe } from '../../../../shared/pipes/cd-date.pipe';
22 import { CephReleaseNamePipe } from '../../../../shared/pipes/ceph-release-name.pipe';
23 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
24 import { ModalService } from '../../../../shared/services/modal.service';
25 import { NotificationService } from '../../../../shared/services/notification.service';
26 import { SummaryService } from '../../../../shared/services/summary.service';
27 import { URLBuilderService } from '../../../../shared/services/url-builder.service';
28 import { PrometheusListHelper } from '../prometheus-list-helper';
29
30 const BASE_URL = 'monitoring/silences';
31
32 @Component({
33   providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }],
34   selector: 'cd-silences-list',
35   templateUrl: './silence-list.component.html',
36   styleUrls: ['./silence-list.component.scss']
37 })
38 export class SilenceListComponent extends PrometheusListHelper {
39   silences: AlertmanagerSilence[] = [];
40   columns: CdTableColumn[];
41   tableActions: CdTableAction[];
42   permission: Permission;
43   selection = new CdTableSelection();
44   modalRef: NgbModalRef;
45   customCss = {
46     'badge badge-danger': 'active',
47     'badge badge-warning': 'pending',
48     'badge badge-default': 'expired'
49   };
50   sorts: SortPropDir[] = [{ prop: 'endsAt', dir: SortDirection.desc }];
51
52   constructor(
53     private authStorageService: AuthStorageService,
54     private cdDatePipe: CdDatePipe,
55     private modalService: ModalService,
56     private notificationService: NotificationService,
57     private urlBuilder: URLBuilderService,
58     private actionLabels: ActionLabelsI18n,
59     private succeededLabels: SucceededActionLabelsI18n,
60     @Inject(PrometheusService) prometheusService: PrometheusService,
61     @Inject(SummaryService) summaryService: SummaryService,
62     @Inject(CephReleaseNamePipe) cephReleaseNamePipe: CephReleaseNamePipe
63   ) {
64     super(prometheusService, summaryService, cephReleaseNamePipe);
65     this.permission = this.authStorageService.getPermissions().prometheus;
66     const selectionExpired = (selection: CdTableSelection) =>
67       selection.first() && selection.first().status && selection.first().status.state === 'expired';
68     this.tableActions = [
69       {
70         permission: 'create',
71         icon: Icons.add,
72         routerLink: () => this.urlBuilder.getCreate(),
73         canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
74         name: this.actionLabels.CREATE
75       },
76       {
77         permission: 'create',
78         canBePrimary: (selection: CdTableSelection) =>
79           selection.hasSingleSelection && selectionExpired(selection),
80         disable: (selection: CdTableSelection) =>
81           !selection.hasSingleSelection ||
82           selection.first().cdExecuting ||
83           (selection.first().cdExecuting && selectionExpired(selection)) ||
84           !selectionExpired(selection),
85         icon: Icons.copy,
86         routerLink: () => this.urlBuilder.getRecreate(this.selection.first().id),
87         name: this.actionLabels.RECREATE
88       },
89       {
90         permission: 'update',
91         icon: Icons.edit,
92         canBePrimary: (selection: CdTableSelection) =>
93           selection.hasSingleSelection && !selectionExpired(selection),
94         disable: (selection: CdTableSelection) =>
95           !selection.hasSingleSelection ||
96           selection.first().cdExecuting ||
97           (selection.first().cdExecuting && !selectionExpired(selection)) ||
98           selectionExpired(selection),
99         routerLink: () => this.urlBuilder.getEdit(this.selection.first().id),
100         name: this.actionLabels.EDIT
101       },
102       {
103         permission: 'delete',
104         icon: Icons.trash,
105         canBePrimary: (selection: CdTableSelection) =>
106           selection.hasSingleSelection && !selectionExpired(selection),
107         disable: (selection: CdTableSelection) =>
108           !selection.hasSingleSelection ||
109           selection.first().cdExecuting ||
110           selectionExpired(selection),
111         click: () => this.expireSilence(),
112         name: this.actionLabels.EXPIRE
113       }
114     ];
115     this.columns = [
116       {
117         name: $localize`ID`,
118         prop: 'id',
119         flexGrow: 3
120       },
121       {
122         name: $localize`Created by`,
123         prop: 'createdBy',
124         flexGrow: 2
125       },
126       {
127         name: $localize`Started`,
128         prop: 'startsAt',
129         pipe: this.cdDatePipe
130       },
131       {
132         name: $localize`Updated`,
133         prop: 'updatedAt',
134         pipe: this.cdDatePipe
135       },
136       {
137         name: $localize`Ends`,
138         prop: 'endsAt',
139         pipe: this.cdDatePipe
140       },
141       {
142         name: $localize`Status`,
143         prop: 'status.state',
144         cellTransformation: CellTemplate.classAdding
145       }
146     ];
147   }
148
149   refresh() {
150     this.prometheusService.ifAlertmanagerConfigured(() => {
151       this.prometheusService.getSilences().subscribe(
152         (silences) => {
153           this.silences = silences;
154         },
155         () => {
156           this.prometheusService.disableAlertmanagerConfig();
157         }
158       );
159     });
160   }
161
162   updateSelection(selection: CdTableSelection) {
163     this.selection = selection;
164   }
165
166   expireSilence() {
167     const id = this.selection.first().id;
168     const i18nSilence = $localize`Silence`;
169     const applicationName = 'Prometheus';
170     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
171       itemDescription: i18nSilence,
172       itemNames: [id],
173       actionDescription: this.actionLabels.EXPIRE,
174       submitActionObservable: () =>
175         new Observable((observer: Subscriber<any>) => {
176           this.prometheusService.expireSilence(id).subscribe(
177             () => {
178               this.notificationService.show(
179                 NotificationType.success,
180                 `${this.succeededLabels.EXPIRED} ${i18nSilence} ${id}`,
181                 undefined,
182                 undefined,
183                 applicationName
184               );
185             },
186             (resp) => {
187               resp['application'] = applicationName;
188               observer.error(resp);
189             },
190             () => {
191               observer.complete();
192               this.refresh();
193             }
194           );
195         })
196     });
197   }
198 }