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:
@@ -7,8 +7,14 @@ import { locationService, setDataSourceSrv } from '@grafana/runtime';
|
|||||||
import { act, render } from '@testing-library/react';
|
import { act, render } from '@testing-library/react';
|
||||||
import { getAllDataSources } from './utils/config';
|
import { getAllDataSources } from './utils/config';
|
||||||
import { typeAsJestMock } from 'test/helpers/typeAsJestMock';
|
import { typeAsJestMock } from 'test/helpers/typeAsJestMock';
|
||||||
import { updateAlertManagerConfig, fetchAlertManagerConfig } from './api/alertmanager';
|
import { updateAlertManagerConfig, fetchAlertManagerConfig, fetchStatus } from './api/alertmanager';
|
||||||
import { mockDataSource, MockDataSourceSrv, someCloudAlertManagerConfig, someGrafanaAlertManagerConfig } from './mocks';
|
import {
|
||||||
|
mockDataSource,
|
||||||
|
MockDataSourceSrv,
|
||||||
|
someCloudAlertManagerConfig,
|
||||||
|
someCloudAlertManagerStatus,
|
||||||
|
someGrafanaAlertManagerConfig,
|
||||||
|
} from './mocks';
|
||||||
import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
|
import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
|
||||||
import { fetchNotifiers } from './api/grafana';
|
import { fetchNotifiers } from './api/grafana';
|
||||||
import { grafanaNotifiersMock } from './mocks/grafana-notifiers';
|
import { grafanaNotifiersMock } from './mocks/grafana-notifiers';
|
||||||
@@ -27,6 +33,7 @@ const mocks = {
|
|||||||
|
|
||||||
api: {
|
api: {
|
||||||
fetchConfig: typeAsJestMock(fetchAlertManagerConfig),
|
fetchConfig: typeAsJestMock(fetchAlertManagerConfig),
|
||||||
|
fetchStatus: typeAsJestMock(fetchStatus),
|
||||||
updateConfig: typeAsJestMock(updateAlertManagerConfig),
|
updateConfig: typeAsJestMock(updateAlertManagerConfig),
|
||||||
fetchNotifiers: typeAsJestMock(fetchNotifiers),
|
fetchNotifiers: typeAsJestMock(fetchNotifiers),
|
||||||
},
|
},
|
||||||
@@ -302,4 +309,25 @@ describe('Receivers', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}, 10000);
|
}, 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,
|
Silence,
|
||||||
SilenceCreatePayload,
|
SilenceCreatePayload,
|
||||||
Matcher,
|
Matcher,
|
||||||
|
AlertmanagerStatus,
|
||||||
} from 'app/plugins/datasource/alertmanager/types';
|
} from 'app/plugins/datasource/alertmanager/types';
|
||||||
import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';
|
import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';
|
||||||
|
|
||||||
@@ -131,6 +132,18 @@ export async function fetchAlertGroups(alertmanagerSourceName: string): Promise<
|
|||||||
return result.data;
|
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 {
|
function escapeQuotes(value: string): string {
|
||||||
return value.replace(/"/g, '\\"');
|
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 { AlertingRule, Alert, RecordingRule, RuleGroup, RuleNamespace } from 'app/types/unified-alerting';
|
||||||
import DatasourceSrv from 'app/features/plugins/datasource_srv';
|
import DatasourceSrv from 'app/features/plugins/datasource_srv';
|
||||||
import { DataSourceSrv, GetDataSourceListFilters } from '@grafana/runtime';
|
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;
|
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 = {
|
export const someCloudAlertManagerConfig: AlertManagerCortexConfig = {
|
||||||
template_files: {
|
template_files: {
|
||||||
'foo template': 'foo content',
|
'foo template': 'foo content',
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
fetchSilences,
|
fetchSilences,
|
||||||
createOrUpdateSilence,
|
createOrUpdateSilence,
|
||||||
updateAlertManagerConfig,
|
updateAlertManagerConfig,
|
||||||
|
fetchStatus,
|
||||||
} from '../api/alertmanager';
|
} from '../api/alertmanager';
|
||||||
import { fetchRules } from '../api/prometheus';
|
import { fetchRules } from '../api/prometheus';
|
||||||
import {
|
import {
|
||||||
@@ -47,6 +48,7 @@ import {
|
|||||||
} from '../utils/rules';
|
} from '../utils/rules';
|
||||||
import { addDefaultsToAlertmanagerConfig } from '../utils/alertmanager';
|
import { addDefaultsToAlertmanagerConfig } from '../utils/alertmanager';
|
||||||
import { backendSrv } from 'app/core/services/backend_srv';
|
import { backendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
export const fetchPromRulesAction = createAsyncThunk(
|
export const fetchPromRulesAction = createAsyncThunk(
|
||||||
'unifiedalerting/fetchPromRules',
|
'unifiedalerting/fetchPromRules',
|
||||||
@@ -56,7 +58,18 @@ export const fetchPromRulesAction = createAsyncThunk(
|
|||||||
export const fetchAlertManagerConfigAction = createAsyncThunk(
|
export const fetchAlertManagerConfigAction = createAsyncThunk(
|
||||||
'unifiedalerting/fetchAmConfig',
|
'unifiedalerting/fetchAmConfig',
|
||||||
(alertManagerSourceName: string): Promise<AlertManagerCortexConfig> =>
|
(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(
|
export const fetchRulerRulesAction = createAsyncThunk(
|
||||||
|
|||||||
@@ -5,13 +5,6 @@ export type AlertManagerCortexConfig = {
|
|||||||
alertmanager_config: AlertmanagerConfig;
|
alertmanager_config: AlertmanagerConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE - This type is incomplete! But currently, we don't need more.
|
|
||||||
export type AlertmanagerStatusPayload = {
|
|
||||||
config: {
|
|
||||||
original: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TLSConfig = {
|
export type TLSConfig = {
|
||||||
ca_file: string;
|
ca_file: string;
|
||||||
cert_file: string;
|
cert_file: string;
|
||||||
@@ -217,3 +210,20 @@ export type AlertmanagerGroup = {
|
|||||||
alerts: AlertmanagerAlert[];
|
alerts: AlertmanagerAlert[];
|
||||||
id: string;
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user