]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts
import 15.2.4
[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 { 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 }