]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
d2b36f6af75498d791d53d80301f244d1f2794ef
[ceph.git] /
1 import { Component } from '@angular/core';
2
3 import { I18n } from '@ngx-translate/i18n-polyfill';
4 import { SortDirection, SortPropDir } from '@swimlane/ngx-datatable';
5 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
6 import { Observable, Subscriber } from 'rxjs';
7
8 import { PrometheusService } from '../../../../shared/api/prometheus.service';
9 import { ListWithDetails } from '../../../../shared/classes/list-with-details.class';
10 import { CriticalConfirmationModalComponent } from '../../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
11 import {
12   ActionLabelsI18n,
13   SucceededActionLabelsI18n
14 } from '../../../../shared/constants/app.constants';
15 import { CellTemplate } from '../../../../shared/enum/cell-template.enum';
16 import { Icons } from '../../../../shared/enum/icons.enum';
17 import { NotificationType } from '../../../../shared/enum/notification-type.enum';
18 import { AlertmanagerSilence } from '../../../../shared/models/alertmanager-silence';
19 import { CdTableAction } from '../../../../shared/models/cd-table-action';
20 import { CdTableColumn } from '../../../../shared/models/cd-table-column';
21 import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
22 import { Permission } from '../../../../shared/models/permissions';
23 import { CdDatePipe } from '../../../../shared/pipes/cd-date.pipe';
24 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
25 import { NotificationService } from '../../../../shared/services/notification.service';
26 import { URLBuilderService } from '../../../../shared/services/url-builder.service';
27
28 const BASE_URL = 'monitoring/silence';
29
30 @Component({
31   providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }],
32   selector: 'cd-silences-list',
33   templateUrl: './silence-list.component.html',
34   styleUrls: ['./silence-list.component.scss']
35 })
36 export class SilenceListComponent extends ListWithDetails {
37   silences: AlertmanagerSilence[] = [];
38   columns: CdTableColumn[];
39   tableActions: CdTableAction[];
40   permission: Permission;
41   selection = new CdTableSelection();
42   modalRef: BsModalRef;
43   customCss = {
44     'badge badge-danger': 'active',
45     'badge badge-warning': 'pending',
46     'badge badge-default': 'expired'
47   };
48   sorts: SortPropDir[] = [{ prop: 'endsAt', dir: SortDirection.desc }];
49
50   constructor(
51     private authStorageService: AuthStorageService,
52     private i18n: I18n,
53     private cdDatePipe: CdDatePipe,
54     private prometheusService: PrometheusService,
55     private modalService: BsModalService,
56     private notificationService: NotificationService,
57     private urlBuilder: URLBuilderService,
58     private actionLabels: ActionLabelsI18n,
59     private succeededLabels: SucceededActionLabelsI18n
60   ) {
61     super();
62     this.permission = this.authStorageService.getPermissions().prometheus;
63     const selectionExpired = (selection: CdTableSelection) =>
64       selection.first() && selection.first().status && selection.first().status.state === 'expired';
65     this.tableActions = [
66       {
67         permission: 'create',
68         icon: Icons.add,
69         routerLink: () => this.urlBuilder.getCreate(),
70         preserveFragment: true,
71         canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
72         name: this.actionLabels.CREATE
73       },
74       {
75         permission: 'create',
76         canBePrimary: (selection: CdTableSelection) =>
77           selection.hasSingleSelection && selectionExpired(selection),
78         disable: (selection: CdTableSelection) =>
79           !selection.hasSingleSelection ||
80           selection.first().cdExecuting ||
81           (selection.first().cdExecuting && selectionExpired(selection)) ||
82           !selectionExpired(selection),
83         icon: Icons.copy,
84         routerLink: () => this.urlBuilder.getRecreate(this.selection.first().id),
85         preserveFragment: true,
86         name: this.actionLabels.RECREATE
87       },
88       {
89         permission: 'update',
90         icon: Icons.edit,
91         canBePrimary: (selection: CdTableSelection) =>
92           selection.hasSingleSelection && !selectionExpired(selection),
93         disable: (selection: CdTableSelection) =>
94           !selection.hasSingleSelection ||
95           selection.first().cdExecuting ||
96           (selection.first().cdExecuting && !selectionExpired(selection)) ||
97           selectionExpired(selection),
98         routerLink: () => this.urlBuilder.getEdit(this.selection.first().id),
99         preserveFragment: true,
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: this.i18n('ID'),
118         prop: 'id',
119         flexGrow: 3
120       },
121       {
122         name: this.i18n('Created by'),
123         prop: 'createdBy',
124         flexGrow: 2
125       },
126       {
127         name: this.i18n('Started'),
128         prop: 'startsAt',
129         pipe: this.cdDatePipe
130       },
131       {
132         name: this.i18n('Updated'),
133         prop: 'updatedAt',
134         pipe: this.cdDatePipe
135       },
136       {
137         name: this.i18n('Ends'),
138         prop: 'endsAt',
139         pipe: this.cdDatePipe
140       },
141       {
142         name: this.i18n('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 = this.i18n('Silence');
169     const applicationName = 'Prometheus';
170     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
171       initialState: {
172         itemDescription: i18nSilence,
173         itemNames: [id],
174         actionDescription: this.actionLabels.EXPIRE,
175         submitActionObservable: () =>
176           new Observable((observer: Subscriber<any>) => {
177             this.prometheusService.expireSilence(id).subscribe(
178               () => {
179                 this.notificationService.show(
180                   NotificationType.success,
181                   `${this.succeededLabels.EXPIRED} ${i18nSilence} ${id}`,
182                   undefined,
183                   undefined,
184                   applicationName
185                 );
186               },
187               (resp) => {
188                 resp['application'] = applicationName;
189                 observer.error(resp);
190               },
191               () => {
192                 observer.complete();
193                 this.refresh();
194               }
195             );
196           })
197       }
198     });
199   }
200 }