]>
Commit | Line | Data |
---|---|---|
f67539c2 | 1 | import { Component, Inject } from '@angular/core'; |
494da23a | 2 | |
f67539c2 TL |
3 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; |
4 | import { SortDirection, SortPropDir } from '@swimlane/ngx-datatable'; | |
494da23a TL |
5 | import { Observable, Subscriber } from 'rxjs'; |
6 | ||
1e59de90 | 7 | import { PrometheusListHelper } from '~/app/shared/helpers/prometheus-list-helper'; |
39ae355f | 8 | import { SilenceFormComponent } from '~/app/ceph/cluster/prometheus/silence-form/silence-form.component'; |
f67539c2 TL |
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'; | |
39ae355f | 20 | import { PrometheusRule } from '~/app/shared/models/prometheus-alerts'; |
f67539c2 TL |
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'; | |
39ae355f | 25 | import { PrometheusSilenceMatcherService } from '~/app/shared/services/prometheus-silence-matcher.service'; |
f67539c2 | 26 | import { URLBuilderService } from '~/app/shared/services/url-builder.service'; |
494da23a | 27 | |
f67539c2 | 28 | const BASE_URL = 'monitoring/silences'; |
494da23a TL |
29 | |
30 | @Component({ | |
39ae355f TL |
31 | providers: [ |
32 | { provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }, | |
33 | SilenceFormComponent | |
34 | ], | |
494da23a TL |
35 | selector: 'cd-silences-list', |
36 | templateUrl: './silence-list.component.html', | |
37 | styleUrls: ['./silence-list.component.scss'] | |
38 | }) | |
f67539c2 | 39 | export class SilenceListComponent extends PrometheusListHelper { |
494da23a TL |
40 | silences: AlertmanagerSilence[] = []; |
41 | columns: CdTableColumn[]; | |
42 | tableActions: CdTableAction[]; | |
43 | permission: Permission; | |
44 | selection = new CdTableSelection(); | |
f67539c2 | 45 | modalRef: NgbModalRef; |
494da23a | 46 | customCss = { |
9f95a23c TL |
47 | 'badge badge-danger': 'active', |
48 | 'badge badge-warning': 'pending', | |
49 | 'badge badge-default': 'expired' | |
494da23a TL |
50 | }; |
51 | sorts: SortPropDir[] = [{ prop: 'endsAt', dir: SortDirection.desc }]; | |
39ae355f TL |
52 | rules: PrometheusRule[]; |
53 | visited: boolean; | |
494da23a TL |
54 | |
55 | constructor( | |
56 | private authStorageService: AuthStorageService, | |
494da23a | 57 | private cdDatePipe: CdDatePipe, |
f67539c2 | 58 | private modalService: ModalService, |
494da23a TL |
59 | private notificationService: NotificationService, |
60 | private urlBuilder: URLBuilderService, | |
61 | private actionLabels: ActionLabelsI18n, | |
f67539c2 | 62 | private succeededLabels: SucceededActionLabelsI18n, |
39ae355f TL |
63 | private silenceFormComponent: SilenceFormComponent, |
64 | private silenceMatcher: PrometheusSilenceMatcherService, | |
f67539c2 | 65 | @Inject(PrometheusService) prometheusService: PrometheusService |
494da23a | 66 | ) { |
f67539c2 | 67 | super(prometheusService); |
494da23a | 68 | this.permission = this.authStorageService.getPermissions().prometheus; |
494da23a | 69 | const selectionExpired = (selection: CdTableSelection) => |
9f95a23c | 70 | selection.first() && selection.first().status && selection.first().status.state === 'expired'; |
494da23a TL |
71 | this.tableActions = [ |
72 | { | |
73 | permission: 'create', | |
74 | icon: Icons.add, | |
75 | routerLink: () => this.urlBuilder.getCreate(), | |
76 | canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection, | |
77 | name: this.actionLabels.CREATE | |
78 | }, | |
79 | { | |
80 | permission: '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), | |
88 | icon: Icons.copy, | |
89 | routerLink: () => this.urlBuilder.getRecreate(this.selection.first().id), | |
90 | name: this.actionLabels.RECREATE | |
91 | }, | |
92 | { | |
93 | permission: 'update', | |
94 | icon: Icons.edit, | |
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 | |
104 | }, | |
105 | { | |
106 | permission: 'delete', | |
107 | icon: Icons.trash, | |
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 | |
116 | } | |
117 | ]; | |
118 | this.columns = [ | |
119 | { | |
f67539c2 | 120 | name: $localize`ID`, |
494da23a TL |
121 | prop: 'id', |
122 | flexGrow: 3 | |
123 | }, | |
39ae355f TL |
124 | { |
125 | name: $localize`Alerts Silenced`, | |
126 | prop: 'silencedAlerts', | |
127 | flexGrow: 3, | |
128 | cellTransformation: CellTemplate.badge | |
129 | }, | |
494da23a | 130 | { |
f67539c2 | 131 | name: $localize`Created by`, |
494da23a TL |
132 | prop: 'createdBy', |
133 | flexGrow: 2 | |
134 | }, | |
135 | { | |
f67539c2 | 136 | name: $localize`Started`, |
494da23a TL |
137 | prop: 'startsAt', |
138 | pipe: this.cdDatePipe | |
139 | }, | |
140 | { | |
f67539c2 | 141 | name: $localize`Updated`, |
494da23a TL |
142 | prop: 'updatedAt', |
143 | pipe: this.cdDatePipe | |
144 | }, | |
145 | { | |
f67539c2 | 146 | name: $localize`Ends`, |
494da23a TL |
147 | prop: 'endsAt', |
148 | pipe: this.cdDatePipe | |
149 | }, | |
150 | { | |
f67539c2 | 151 | name: $localize`Status`, |
494da23a TL |
152 | prop: 'status.state', |
153 | cellTransformation: CellTemplate.classAdding | |
154 | } | |
155 | ]; | |
156 | } | |
157 | ||
158 | refresh() { | |
159 | this.prometheusService.ifAlertmanagerConfigured(() => { | |
160 | this.prometheusService.getSilences().subscribe( | |
161 | (silences) => { | |
162 | this.silences = silences; | |
39ae355f TL |
163 | const activeSilences = silences.filter( |
164 | (silence: AlertmanagerSilence) => silence.status.state !== 'expired' | |
165 | ); | |
166 | this.getAlerts(activeSilences); | |
494da23a TL |
167 | }, |
168 | () => { | |
169 | this.prometheusService.disableAlertmanagerConfig(); | |
170 | } | |
171 | ); | |
172 | }); | |
173 | } | |
174 | ||
175 | updateSelection(selection: CdTableSelection) { | |
176 | this.selection = selection; | |
177 | } | |
178 | ||
39ae355f TL |
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); | |
187 | } | |
188 | silence.silencedAlerts = alertNames; | |
189 | }); | |
190 | }); | |
191 | } | |
192 | ||
494da23a TL |
193 | expireSilence() { |
194 | const id = this.selection.first().id; | |
f67539c2 | 195 | const i18nSilence = $localize`Silence`; |
494da23a TL |
196 | const applicationName = 'Prometheus'; |
197 | this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, { | |
f67539c2 TL |
198 | itemDescription: i18nSilence, |
199 | itemNames: [id], | |
200 | actionDescription: this.actionLabels.EXPIRE, | |
201 | submitActionObservable: () => | |
202 | new Observable((observer: Subscriber<any>) => { | |
203 | this.prometheusService.expireSilence(id).subscribe( | |
204 | () => { | |
205 | this.notificationService.show( | |
206 | NotificationType.success, | |
207 | `${this.succeededLabels.EXPIRED} ${i18nSilence} ${id}`, | |
208 | undefined, | |
209 | undefined, | |
210 | applicationName | |
211 | ); | |
212 | }, | |
213 | (resp) => { | |
214 | resp['application'] = applicationName; | |
215 | observer.error(resp); | |
216 | }, | |
217 | () => { | |
218 | observer.complete(); | |
219 | this.refresh(); | |
220 | } | |
221 | ); | |
222 | }) | |
494da23a TL |
223 | }); |
224 | } | |
225 | } |