1 import { Component, Inject } from '@angular/core';
3 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
4 import { Observable, Subscriber } from 'rxjs';
6 import { PrometheusListHelper } from '~/app/shared/helpers/prometheus-list-helper';
7 import { SilenceFormComponent } from '~/app/ceph/cluster/prometheus/silence-form/silence-form.component';
8 import { PrometheusService } from '~/app/shared/api/prometheus.service';
9 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
10 import { ActionLabelsI18n, SucceededActionLabelsI18n } from '~/app/shared/constants/app.constants';
11 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
12 import { Icons } from '~/app/shared/enum/icons.enum';
13 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
14 import { AlertmanagerSilence } from '~/app/shared/models/alertmanager-silence';
15 import { CdTableAction } from '~/app/shared/models/cd-table-action';
16 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
17 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
18 import { Permission } from '~/app/shared/models/permissions';
19 import { PrometheusRule } from '~/app/shared/models/prometheus-alerts';
20 import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
21 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
22 import { ModalService } from '~/app/shared/services/modal.service';
23 import { NotificationService } from '~/app/shared/services/notification.service';
24 import { PrometheusSilenceMatcherService } from '~/app/shared/services/prometheus-silence-matcher.service';
25 import { URLBuilderService } from '~/app/shared/services/url-builder.service';
26 import { CdSortDirection } from '~/app/shared/enum/cd-sort-direction';
27 import { CdSortPropDir } from '~/app/shared/models/cd-sort-prop-dir';
29 const BASE_URL = 'monitoring/silences';
33 { provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) },
36 selector: 'cd-silences-list',
37 templateUrl: './silence-list.component.html',
38 styleUrls: ['./silence-list.component.scss']
40 export class SilenceListComponent extends PrometheusListHelper {
41 silences: AlertmanagerSilence[] = [];
42 columns: CdTableColumn[];
43 tableActions: CdTableAction[];
44 permission: Permission;
45 selection = new CdTableSelection();
46 modalRef: NgbModalRef;
48 'badge badge-danger': 'active',
49 'badge badge-warning': 'pending',
50 'badge badge-default': 'expired'
52 sorts: CdSortPropDir[] = [{ prop: 'endsAt', dir: CdSortDirection.desc }];
53 rules: PrometheusRule[];
57 private authStorageService: AuthStorageService,
58 private cdDatePipe: CdDatePipe,
59 private modalService: ModalService,
60 private notificationService: NotificationService,
61 private urlBuilder: URLBuilderService,
62 private actionLabels: ActionLabelsI18n,
63 private succeededLabels: SucceededActionLabelsI18n,
64 private silenceFormComponent: SilenceFormComponent,
65 private silenceMatcher: PrometheusSilenceMatcherService,
66 @Inject(PrometheusService) prometheusService: PrometheusService
68 super(prometheusService);
69 this.permission = this.authStorageService.getPermissions().prometheus;
70 const selectionExpired = (selection: CdTableSelection) =>
71 selection.first() && selection.first().status && selection.first().status.state === 'expired';
76 routerLink: () => this.urlBuilder.getCreate(),
77 canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
78 name: this.actionLabels.CREATE
82 canBePrimary: (selection: CdTableSelection) =>
83 selection.hasSingleSelection && selectionExpired(selection),
84 disable: (selection: CdTableSelection) =>
85 !selection.hasSingleSelection ||
86 selection.first().cdExecuting ||
87 (selection.first().cdExecuting && selectionExpired(selection)) ||
88 !selectionExpired(selection),
90 routerLink: () => this.urlBuilder.getRecreate(this.selection.first().id),
91 name: this.actionLabels.RECREATE
96 canBePrimary: (selection: CdTableSelection) =>
97 selection.hasSingleSelection && !selectionExpired(selection),
98 disable: (selection: CdTableSelection) =>
99 !selection.hasSingleSelection ||
100 selection.first().cdExecuting ||
101 (selection.first().cdExecuting && !selectionExpired(selection)) ||
102 selectionExpired(selection),
103 routerLink: () => this.urlBuilder.getEdit(this.selection.first().id),
104 name: this.actionLabels.EDIT
107 permission: 'delete',
109 canBePrimary: (selection: CdTableSelection) =>
110 selection.hasSingleSelection && !selectionExpired(selection),
111 disable: (selection: CdTableSelection) =>
112 !selection.hasSingleSelection ||
113 selection.first().cdExecuting ||
114 selectionExpired(selection),
115 click: () => this.expireSilence(),
116 name: this.actionLabels.EXPIRE
126 name: $localize`Alerts Silenced`,
127 prop: 'silencedAlerts',
129 cellTransformation: CellTemplate.badge
132 name: $localize`Created by`,
137 name: $localize`Started`,
139 pipe: this.cdDatePipe
142 name: $localize`Updated`,
144 pipe: this.cdDatePipe
147 name: $localize`Ends`,
149 pipe: this.cdDatePipe
152 name: $localize`Status`,
153 prop: 'status.state',
154 cellTransformation: CellTemplate.classAdding
160 this.prometheusService.ifAlertmanagerConfigured(() => {
161 this.prometheusService.getSilences().subscribe(
163 this.silences = silences;
164 const activeSilences = silences.filter(
165 (silence: AlertmanagerSilence) => silence.status.state !== 'expired'
167 this.getAlerts(activeSilences);
170 this.prometheusService.disableAlertmanagerConfig();
176 updateSelection(selection: CdTableSelection) {
177 this.selection = selection;
180 getAlerts(silences: any) {
181 const rules = this.silenceFormComponent.getRules();
182 silences.forEach((silence: any) => {
183 silence.matchers.forEach((matcher: any) => {
184 this.rules = this.silenceMatcher.getMatchedRules(matcher, rules);
185 const alertNames: string[] = [];
186 for (const rule of this.rules) {
187 alertNames.push(rule.name);
189 silence.silencedAlerts = alertNames;
195 const id = this.selection.first().id;
196 const i18nSilence = $localize`Silence`;
197 const applicationName = 'Prometheus';
198 this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
199 itemDescription: i18nSilence,
201 actionDescription: this.actionLabels.EXPIRE,
202 submitActionObservable: () =>
203 new Observable((observer: Subscriber<any>) => {
204 this.prometheusService.expireSilence(id).subscribe(
206 this.notificationService.show(
207 NotificationType.success,
208 `${this.succeededLabels.EXPIRED} ${i18nSilence} ${id}`,
215 resp['application'] = applicationName;
216 observer.error(resp);