1 import { Component, Inject } from '@angular/core';
3 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
4 import { SortDirection, SortPropDir } from '@swimlane/ngx-datatable';
5 import { Observable, Subscriber } from 'rxjs';
7 import { PrometheusListHelper } from '~/app/ceph/cluster/prometheus/prometheus-list-helper';
8 import { SilenceFormComponent } from '~/app/ceph/cluster/prometheus/silence-form/silence-form.component';
9 import { PrometheusService } from '~/app/shared/api/prometheus.service';
10 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
11 import { ActionLabelsI18n, SucceededActionLabelsI18n } from '~/app/shared/constants/app.constants';
12 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
13 import { Icons } from '~/app/shared/enum/icons.enum';
14 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
15 import { AlertmanagerSilence } from '~/app/shared/models/alertmanager-silence';
16 import { CdTableAction } from '~/app/shared/models/cd-table-action';
17 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
18 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
19 import { Permission } from '~/app/shared/models/permissions';
20 import { PrometheusRule } from '~/app/shared/models/prometheus-alerts';
21 import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
22 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
23 import { ModalService } from '~/app/shared/services/modal.service';
24 import { NotificationService } from '~/app/shared/services/notification.service';
25 import { PrometheusSilenceMatcherService } from '~/app/shared/services/prometheus-silence-matcher.service';
26 import { URLBuilderService } from '~/app/shared/services/url-builder.service';
28 const BASE_URL = 'monitoring/silences';
32 { provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) },
35 selector: 'cd-silences-list',
36 templateUrl: './silence-list.component.html',
37 styleUrls: ['./silence-list.component.scss']
39 export class SilenceListComponent extends PrometheusListHelper {
40 silences: AlertmanagerSilence[] = [];
41 columns: CdTableColumn[];
42 tableActions: CdTableAction[];
43 permission: Permission;
44 selection = new CdTableSelection();
45 modalRef: NgbModalRef;
47 'badge badge-danger': 'active',
48 'badge badge-warning': 'pending',
49 'badge badge-default': 'expired'
51 sorts: SortPropDir[] = [{ prop: 'endsAt', dir: SortDirection.desc }];
52 rules: PrometheusRule[];
56 private authStorageService: AuthStorageService,
57 private cdDatePipe: CdDatePipe,
58 private modalService: ModalService,
59 private notificationService: NotificationService,
60 private urlBuilder: URLBuilderService,
61 private actionLabels: ActionLabelsI18n,
62 private succeededLabels: SucceededActionLabelsI18n,
63 private silenceFormComponent: SilenceFormComponent,
64 private silenceMatcher: PrometheusSilenceMatcherService,
65 @Inject(PrometheusService) prometheusService: PrometheusService
67 super(prometheusService);
68 this.permission = this.authStorageService.getPermissions().prometheus;
69 const selectionExpired = (selection: CdTableSelection) =>
70 selection.first() && selection.first().status && selection.first().status.state === 'expired';
75 routerLink: () => this.urlBuilder.getCreate(),
76 canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
77 name: this.actionLabels.CREATE
81 canBePrimary: (selection: CdTableSelection) =>
82 selection.hasSingleSelection && selectionExpired(selection),
83 disable: (selection: CdTableSelection) =>
84 !selection.hasSingleSelection ||
85 selection.first().cdExecuting ||
86 (selection.first().cdExecuting && selectionExpired(selection)) ||
87 !selectionExpired(selection),
89 routerLink: () => this.urlBuilder.getRecreate(this.selection.first().id),
90 name: this.actionLabels.RECREATE
95 canBePrimary: (selection: CdTableSelection) =>
96 selection.hasSingleSelection && !selectionExpired(selection),
97 disable: (selection: CdTableSelection) =>
98 !selection.hasSingleSelection ||
99 selection.first().cdExecuting ||
100 (selection.first().cdExecuting && !selectionExpired(selection)) ||
101 selectionExpired(selection),
102 routerLink: () => this.urlBuilder.getEdit(this.selection.first().id),
103 name: this.actionLabels.EDIT
106 permission: 'delete',
108 canBePrimary: (selection: CdTableSelection) =>
109 selection.hasSingleSelection && !selectionExpired(selection),
110 disable: (selection: CdTableSelection) =>
111 !selection.hasSingleSelection ||
112 selection.first().cdExecuting ||
113 selectionExpired(selection),
114 click: () => this.expireSilence(),
115 name: this.actionLabels.EXPIRE
125 name: $localize`Alerts Silenced`,
126 prop: 'silencedAlerts',
128 cellTransformation: CellTemplate.badge
131 name: $localize`Created by`,
136 name: $localize`Started`,
138 pipe: this.cdDatePipe
141 name: $localize`Updated`,
143 pipe: this.cdDatePipe
146 name: $localize`Ends`,
148 pipe: this.cdDatePipe
151 name: $localize`Status`,
152 prop: 'status.state',
153 cellTransformation: CellTemplate.classAdding
159 this.prometheusService.ifAlertmanagerConfigured(() => {
160 this.prometheusService.getSilences().subscribe(
162 this.silences = silences;
163 const activeSilences = silences.filter(
164 (silence: AlertmanagerSilence) => silence.status.state !== 'expired'
166 this.getAlerts(activeSilences);
169 this.prometheusService.disableAlertmanagerConfig();
175 updateSelection(selection: CdTableSelection) {
176 this.selection = selection;
179 getAlerts(silences: any) {
180 const rules = this.silenceFormComponent.getRules();
181 silences.forEach((silence: any) => {
182 silence.matchers.forEach((matcher: any) => {
183 this.rules = this.silenceMatcher.getMatchedRules(matcher, rules);
184 const alertNames: string[] = [];
185 for (const rule of this.rules) {
186 alertNames.push(rule.name);
188 silence.silencedAlerts = alertNames;
194 const id = this.selection.first().id;
195 const i18nSilence = $localize`Silence`;
196 const applicationName = 'Prometheus';
197 this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
198 itemDescription: i18nSilence,
200 actionDescription: this.actionLabels.EXPIRE,
201 submitActionObservable: () =>
202 new Observable((observer: Subscriber<any>) => {
203 this.prometheusService.expireSilence(id).subscribe(
205 this.notificationService.show(
206 NotificationType.success,
207 `${this.succeededLabels.EXPIRED} ${i18nSilence} ${id}`,
214 resp['application'] = applicationName;
215 observer.error(resp);