Files
grafana/public/app/features/alerting/unified/api/alertmanager.ts
Nathan Rodman 1913d304a3 Alerting: Add silences table (#33138)
* Create table for silences

* Style table to figma designs

* Add rules table to silences

* Rebase with new rules table

* Remove redundant reducer

* fetch alertmanager alerts (#33142)

* fetch alertmanager alerts

* show the alerts json

* Use matching alerts from alertmanager api

* Add handle to expire silence

* Get silenced alerts closer to figma designs

* fix expire silence endpoint typo

* Style affected alerts table

* Add default empty string for alertmanager source

Co-authored-by: Domas <domasx2@gmail.com>
2021-04-27 13:46:34 -07:00

132 lines
4.0 KiB
TypeScript

import { urlUtil } from '@grafana/data';
import { getBackendSrv } from '@grafana/runtime';
import {
AlertmanagerAlert,
AlertManagerCortexConfig,
AlertmanagerGroup,
Silence,
SilenceCreatePayload,
SilenceMatcher,
} from 'app/plugins/datasource/alertmanager/types';
import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';
// "grafana" for grafana-managed, otherwise a datasource name
export async function fetchAlertManagerConfig(alertManagerSourceName: string): Promise<AlertManagerCortexConfig> {
try {
const result = await getBackendSrv()
.fetch<AlertManagerCortexConfig>({
url: `/api/alertmanager/${getDatasourceAPIId(alertManagerSourceName)}/config/api/v1/alerts`,
showErrorAlert: false,
showSuccessAlert: false,
})
.toPromise();
return {
template_files: result.data.template_files ?? {},
alertmanager_config: result.data.alertmanager_config ?? {},
};
} catch (e) {
// if no config has been uploaded to grafana, it returns error instead of latest config
if (
alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME &&
e.data?.message?.includes('failed to get latest configuration')
) {
return {
template_files: {},
alertmanager_config: {},
};
}
throw e;
}
}
export async function updateAlertmanagerConfig(
alertManagerSourceName: string,
config: AlertManagerCortexConfig
): Promise<void> {
await getBackendSrv()
.fetch({
method: 'POST',
url: `/api/alertmanager/${getDatasourceAPIId(alertManagerSourceName)}/config/api/v1/alerts`,
data: config,
showErrorAlert: false,
showSuccessAlert: false,
})
.toPromise();
}
export async function fetchSilences(alertManagerSourceName: string): Promise<Silence[]> {
const result = await getBackendSrv()
.fetch<Silence[]>({
url: `/api/alertmanager/${getDatasourceAPIId(alertManagerSourceName)}/api/v2/silences`,
showErrorAlert: false,
showSuccessAlert: false,
})
.toPromise();
return result.data;
}
// returns the new silence ID. Even in the case of an update, a new silence is created and the previous one expired.
export async function createOrUpdateSilence(
alertmanagerSourceName: string,
payload: SilenceCreatePayload
): Promise<string> {
const result = await getBackendSrv().post(
`/api/alertmanager/${getDatasourceAPIId(alertmanagerSourceName)}/api/v2/silences`,
payload
);
return result.data.silenceID;
}
export async function expireSilence(alertmanagerSourceName: string, silenceID: string): Promise<void> {
await getBackendSrv().delete(
`/api/alertmanager/${getDatasourceAPIId(alertmanagerSourceName)}/api/v2/silence/${encodeURIComponent(silenceID)}`
);
}
export async function fetchAlerts(
alertmanagerSourceName: string,
matchers?: SilenceMatcher[],
silenced = true,
active = true,
inhibited = true
): Promise<AlertmanagerAlert[]> {
const filters =
urlUtil.toUrlParams({ silenced, active, inhibited }) +
matchers
?.map(
(matcher) =>
`filter=${encodeURIComponent(
`${escapeQuotes(matcher.name)}=${matcher.isRegex ? '~' : ''}"${escapeQuotes(matcher.value)}"`
)}`
)
.join('&') || '';
const result = await getBackendSrv()
.fetch<AlertmanagerAlert[]>({
url:
`/api/alertmanager/${getDatasourceAPIId(alertmanagerSourceName)}/api/v2/alerts` +
(filters ? '?' + filters : ''),
showErrorAlert: false,
showSuccessAlert: false,
})
.toPromise();
return result.data;
}
export async function fetchAlertGroups(alertmanagerSourceName: string): Promise<AlertmanagerGroup[]> {
const result = await getBackendSrv()
.fetch<AlertmanagerGroup[]>({
url: `/api/alertmanager/${getDatasourceAPIId(alertmanagerSourceName)}/api/v2/alerts/groups`,
showErrorAlert: false,
showSuccessAlert: false,
})
.toPromise();
return result.data;
}
function escapeQuotes(value: string): string {
return value.replace(/"/g, '\\"');
}