mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: for cortex am, load default config from status if theres no user config (#35769)
This commit is contained in:
parent
15171ffa3b
commit
d480bbf262
@ -7,8 +7,14 @@ import { locationService, setDataSourceSrv } from '@grafana/runtime';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import { getAllDataSources } from './utils/config';
|
||||
import { typeAsJestMock } from 'test/helpers/typeAsJestMock';
|
||||
import { updateAlertManagerConfig, fetchAlertManagerConfig } from './api/alertmanager';
|
||||
import { mockDataSource, MockDataSourceSrv, someCloudAlertManagerConfig, someGrafanaAlertManagerConfig } from './mocks';
|
||||
import { updateAlertManagerConfig, fetchAlertManagerConfig, fetchStatus } from './api/alertmanager';
|
||||
import {
|
||||
mockDataSource,
|
||||
MockDataSourceSrv,
|
||||
someCloudAlertManagerConfig,
|
||||
someCloudAlertManagerStatus,
|
||||
someGrafanaAlertManagerConfig,
|
||||
} from './mocks';
|
||||
import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
|
||||
import { fetchNotifiers } from './api/grafana';
|
||||
import { grafanaNotifiersMock } from './mocks/grafana-notifiers';
|
||||
@ -27,6 +33,7 @@ const mocks = {
|
||||
|
||||
api: {
|
||||
fetchConfig: typeAsJestMock(fetchAlertManagerConfig),
|
||||
fetchStatus: typeAsJestMock(fetchStatus),
|
||||
updateConfig: typeAsJestMock(updateAlertManagerConfig),
|
||||
fetchNotifiers: typeAsJestMock(fetchNotifiers),
|
||||
},
|
||||
@ -302,4 +309,25 @@ describe('Receivers', () => {
|
||||
},
|
||||
});
|
||||
}, 10000);
|
||||
|
||||
it('Loads config from status endpoint if there is no user config', async () => {
|
||||
// loading an empty config with make it fetch config from status endpoint
|
||||
mocks.api.fetchConfig.mockResolvedValue({
|
||||
template_files: {},
|
||||
alertmanager_config: {},
|
||||
});
|
||||
mocks.api.fetchStatus.mockResolvedValue(someCloudAlertManagerStatus);
|
||||
await renderReceivers('CloudManager');
|
||||
|
||||
// check that receiver from the default config is represented
|
||||
const receiversTable = await ui.receiversTable.find();
|
||||
const receiverRows = receiversTable.querySelectorAll<HTMLTableRowElement>('tbody tr');
|
||||
expect(receiverRows[0]).toHaveTextContent('default-email');
|
||||
|
||||
// check that both config and status endpoints were called
|
||||
expect(mocks.api.fetchConfig).toHaveBeenCalledTimes(1);
|
||||
expect(mocks.api.fetchConfig).toHaveBeenLastCalledWith('CloudManager');
|
||||
expect(mocks.api.fetchStatus).toHaveBeenCalledTimes(1);
|
||||
expect(mocks.api.fetchStatus).toHaveBeenLastCalledWith('CloudManager');
|
||||
});
|
||||
});
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
Silence,
|
||||
SilenceCreatePayload,
|
||||
Matcher,
|
||||
AlertmanagerStatus,
|
||||
} from 'app/plugins/datasource/alertmanager/types';
|
||||
import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';
|
||||
|
||||
@ -131,6 +132,18 @@ export async function fetchAlertGroups(alertmanagerSourceName: string): Promise<
|
||||
return result.data;
|
||||
}
|
||||
|
||||
export async function fetchStatus(alertManagerSourceName: string): Promise<AlertmanagerStatus> {
|
||||
const result = await getBackendSrv()
|
||||
.fetch<AlertmanagerStatus>({
|
||||
url: `/api/alertmanager/${getDatasourceAPIId(alertManagerSourceName)}/api/v2/status`,
|
||||
showErrorAlert: false,
|
||||
showSuccessAlert: false,
|
||||
})
|
||||
.toPromise();
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
function escapeQuotes(value: string): string {
|
||||
return value.replace(/"/g, '\\"');
|
||||
}
|
||||
|
@ -3,7 +3,11 @@ import { PromAlertingRuleState, PromRuleType } from 'app/types/unified-alerting-
|
||||
import { AlertingRule, Alert, RecordingRule, RuleGroup, RuleNamespace } from 'app/types/unified-alerting';
|
||||
import DatasourceSrv from 'app/features/plugins/datasource_srv';
|
||||
import { DataSourceSrv, GetDataSourceListFilters } from '@grafana/runtime';
|
||||
import { AlertManagerCortexConfig, GrafanaManagedReceiverConfig } from 'app/plugins/datasource/alertmanager/types';
|
||||
import {
|
||||
AlertManagerCortexConfig,
|
||||
AlertmanagerStatus,
|
||||
GrafanaManagedReceiverConfig,
|
||||
} from 'app/plugins/datasource/alertmanager/types';
|
||||
|
||||
let nextDataSourceId = 1;
|
||||
|
||||
@ -176,6 +180,37 @@ export const someGrafanaAlertManagerConfig: AlertManagerCortexConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
export const someCloudAlertManagerStatus: AlertmanagerStatus = {
|
||||
cluster: {
|
||||
peers: [],
|
||||
status: 'ok',
|
||||
},
|
||||
uptime: '10 hours',
|
||||
versionInfo: {
|
||||
branch: '',
|
||||
version: '',
|
||||
goVersion: '',
|
||||
buildDate: '',
|
||||
buildUser: '',
|
||||
revision: '',
|
||||
},
|
||||
config: {
|
||||
route: {
|
||||
receiver: 'default-email',
|
||||
},
|
||||
receivers: [
|
||||
{
|
||||
name: 'default-email',
|
||||
email_configs: [
|
||||
{
|
||||
to: 'example@example.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const someCloudAlertManagerConfig: AlertManagerCortexConfig = {
|
||||
template_files: {
|
||||
'foo template': 'foo content',
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
fetchSilences,
|
||||
createOrUpdateSilence,
|
||||
updateAlertManagerConfig,
|
||||
fetchStatus,
|
||||
} from '../api/alertmanager';
|
||||
import { fetchRules } from '../api/prometheus';
|
||||
import {
|
||||
@ -47,6 +48,7 @@ import {
|
||||
} from '../utils/rules';
|
||||
import { addDefaultsToAlertmanagerConfig } from '../utils/alertmanager';
|
||||
import { backendSrv } from 'app/core/services/backend_srv';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
export const fetchPromRulesAction = createAsyncThunk(
|
||||
'unifiedalerting/fetchPromRules',
|
||||
@ -56,7 +58,18 @@ export const fetchPromRulesAction = createAsyncThunk(
|
||||
export const fetchAlertManagerConfigAction = createAsyncThunk(
|
||||
'unifiedalerting/fetchAmConfig',
|
||||
(alertManagerSourceName: string): Promise<AlertManagerCortexConfig> =>
|
||||
withSerializedError(fetchAlertManagerConfig(alertManagerSourceName))
|
||||
withSerializedError(
|
||||
fetchAlertManagerConfig(alertManagerSourceName).then((result) => {
|
||||
// if user config is empty for cortex alertmanager, try to get config from status endpoint
|
||||
if (isEmpty(result.alertmanager_config) && alertManagerSourceName !== GRAFANA_RULES_SOURCE_NAME) {
|
||||
return fetchStatus(alertManagerSourceName).then((status) => ({
|
||||
alertmanager_config: status.config,
|
||||
template_files: {},
|
||||
}));
|
||||
}
|
||||
return result;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
export const fetchRulerRulesAction = createAsyncThunk(
|
||||
|
@ -5,13 +5,6 @@ export type AlertManagerCortexConfig = {
|
||||
alertmanager_config: AlertmanagerConfig;
|
||||
};
|
||||
|
||||
// NOTE - This type is incomplete! But currently, we don't need more.
|
||||
export type AlertmanagerStatusPayload = {
|
||||
config: {
|
||||
original: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type TLSConfig = {
|
||||
ca_file: string;
|
||||
cert_file: string;
|
||||
@ -217,3 +210,20 @@ export type AlertmanagerGroup = {
|
||||
alerts: AlertmanagerAlert[];
|
||||
id: string;
|
||||
};
|
||||
|
||||
export interface AlertmanagerStatus {
|
||||
cluster: {
|
||||
peers: unknown;
|
||||
status: string;
|
||||
};
|
||||
config: AlertmanagerConfig;
|
||||
uptime: string;
|
||||
versionInfo: {
|
||||
branch: string;
|
||||
buildDate: string;
|
||||
buildUser: string;
|
||||
goVersion: string;
|
||||
revision: string;
|
||||
version: string;
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user