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