1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import { uniqBy } from 'lodash';
- import { Labels } from '@grafana/data';
- import { Matcher, MatcherOperator } from 'app/plugins/datasource/alertmanager/types';
- import { Alert } from 'app/types/unified-alerting';
- import { MatcherFieldValue } from '../types/silence-form';
- import { parseMatcher } from './alertmanager';
- // Parses a list of entries like like "['foo=bar', 'baz=~bad*']" into SilenceMatcher[]
- export function parseQueryParamMatchers(matcherPairs: string[]): Matcher[] {
- const parsedMatchers = matcherPairs.filter((x) => !!x.trim()).map((x) => parseMatcher(x.trim()));
- // Due to migration, old alert rules might have a duplicated alertname label
- // To handle that case want to filter out duplicates and make sure there are only unique labels
- return uniqBy(parsedMatchers, (matcher) => matcher.name);
- }
- export const getMatcherQueryParams = (labels: Labels) => {
- const validMatcherLabels = Object.entries(labels).filter(
- ([labelKey]) => !(labelKey.startsWith('__') && labelKey.endsWith('__'))
- );
- const matcherUrlParams = new URLSearchParams();
- validMatcherLabels.forEach(([labelKey, labelValue]) =>
- matcherUrlParams.append('matcher', `${labelKey}=${labelValue}`)
- );
- return matcherUrlParams;
- };
- interface MatchedInstance {
- id: string;
- data: {
- matchedInstance: Alert;
- };
- }
- export const findAlertInstancesWithMatchers = (
- instances: Alert[],
- matchers: MatcherFieldValue[]
- ): MatchedInstance[] => {
- const anchorRegex = (regexpString: string): RegExp => {
- // Silence matchers are always fully anchored in the Alertmanager: https://github.com/prometheus/alertmanager/pull/748
- if (!regexpString.startsWith('^')) {
- regexpString = '^' + regexpString;
- }
- if (!regexpString.endsWith('$')) {
- regexpString = regexpString + '$';
- }
- return new RegExp(regexpString);
- };
- const matchesInstance = (instance: Alert, matcher: MatcherFieldValue) => {
- return Object.entries(instance.labels).some(([key, value]) => {
- if (!matcher.name || !matcher.value) {
- return false;
- }
- if (matcher.name !== key) {
- return false;
- }
- switch (matcher.operator) {
- case MatcherOperator.equal:
- return matcher.value === value;
- case MatcherOperator.notEqual:
- return matcher.value !== value;
- case MatcherOperator.regex:
- const regex = anchorRegex(matcher.value);
- return regex.test(value);
- case MatcherOperator.notRegex:
- const negregex = anchorRegex(matcher.value);
- return !negregex.test(value);
- default:
- return false;
- }
- });
- };
- const filteredInstances = instances.filter((instance) => {
- return matchers.every((matcher) => matchesInstance(instance, matcher));
- });
- const mappedInstances = filteredInstances.map((instance) => ({
- id: `${instance.activeAt}-${instance.value}`,
- data: { matchedInstance: instance },
- }));
- return mappedInstances;
- };
|