summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts')
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts
new file mode 100644
index 000000000..bdd616ce9
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts
@@ -0,0 +1,107 @@
+import { Component, EventEmitter, Output, ViewChild } from '@angular/core';
+import { FormControl, Validators } from '@angular/forms';
+
+import { NgbActiveModal, NgbTypeahead } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
+import { merge, Observable, Subject } from 'rxjs';
+import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators';
+
+import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import {
+ AlertmanagerSilenceMatcher,
+ AlertmanagerSilenceMatcherMatch
+} from '~/app/shared/models/alertmanager-silence';
+import { PrometheusRule } from '~/app/shared/models/prometheus-alerts';
+import { PrometheusSilenceMatcherService } from '~/app/shared/services/prometheus-silence-matcher.service';
+
+@Component({
+ selector: 'cd-silence-matcher-modal',
+ templateUrl: './silence-matcher-modal.component.html',
+ styleUrls: ['./silence-matcher-modal.component.scss']
+})
+export class SilenceMatcherModalComponent {
+ @ViewChild(NgbTypeahead, { static: true })
+ typeahead: NgbTypeahead;
+ @Output()
+ submitAction = new EventEmitter();
+
+ form: CdFormGroup;
+ editMode = false;
+ rules: PrometheusRule[];
+ nameAttributes = ['alertname', 'instance', 'job', 'severity'];
+ possibleValues: string[] = [];
+ matcherMatch: AlertmanagerSilenceMatcherMatch = undefined;
+
+ // For typeahead usage
+ valueClick = new Subject<string>();
+ valueFocus = new Subject<string>();
+ search = (text$: Observable<string>) => {
+ return merge(
+ text$.pipe(debounceTime(200), distinctUntilChanged()),
+ this.valueFocus,
+ this.valueClick.pipe(filter(() => !this.typeahead.isPopupOpen()))
+ ).pipe(
+ map((term) =>
+ (term === ''
+ ? this.possibleValues
+ : this.possibleValues.filter((v) => v.toLowerCase().indexOf(term.toLowerCase()) > -1)
+ ).slice(0, 10)
+ )
+ );
+ };
+
+ constructor(
+ private formBuilder: CdFormBuilder,
+ private silenceMatcher: PrometheusSilenceMatcherService,
+ public activeModal: NgbActiveModal,
+ public actionLabels: ActionLabelsI18n
+ ) {
+ this.createForm();
+ this.subscribeToChanges();
+ }
+
+ private createForm() {
+ this.form = this.formBuilder.group({
+ name: [null, [Validators.required]],
+ value: [{ value: '', disabled: true }, [Validators.required]],
+ isRegex: new FormControl(false)
+ });
+ }
+
+ private subscribeToChanges() {
+ this.form.get('name').valueChanges.subscribe((name) => {
+ if (name === null) {
+ this.form.get('value').disable();
+ return;
+ }
+ this.setPossibleValues(name);
+ this.form.get('value').enable();
+ });
+ this.form.get('value').valueChanges.subscribe((value) => {
+ const values = this.form.value;
+ values.value = value; // Isn't the current value at this stage
+ this.matcherMatch = this.silenceMatcher.singleMatch(values, this.rules);
+ });
+ }
+
+ private setPossibleValues(name: string) {
+ this.possibleValues = _.sortedUniq(
+ this.rules.map((r) => _.get(r, this.silenceMatcher.getAttributePath(name))).filter((x) => x)
+ );
+ }
+
+ getMode() {
+ return this.editMode ? this.actionLabels.EDIT : this.actionLabels.ADD;
+ }
+
+ preFillControls(matcher: AlertmanagerSilenceMatcher) {
+ this.form.setValue(matcher);
+ }
+
+ onSubmit() {
+ this.submitAction.emit(this.form.value);
+ this.activeModal.close();
+ }
+}