mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Get oncall metada only when we have alert manager configuration data (#85622)
* Get oncall metada from url in settings only when we have alert manager configuration * Add test in useContactPointsWithStatus hook * Fix tests
This commit is contained in:
parent
8a15ed42ae
commit
e234d098e9
@ -65,7 +65,7 @@ describe('contact points', () => {
|
||||
});
|
||||
|
||||
expect(screen.getByText('grafana-default-email')).toBeInTheDocument();
|
||||
expect(screen.getAllByTestId('contact-point')).toHaveLength(4);
|
||||
expect(screen.getAllByTestId('contact-point')).toHaveLength(5);
|
||||
|
||||
// check for available actions – our mock 4 contact points, 1 of them is provisioned
|
||||
expect(screen.getByRole('link', { name: 'add contact point' })).toBeInTheDocument();
|
||||
@ -73,20 +73,20 @@ describe('contact points', () => {
|
||||
|
||||
// 2 of them are unused by routes in the mock response
|
||||
const unusedBadge = screen.getAllByLabelText('unused');
|
||||
expect(unusedBadge).toHaveLength(2);
|
||||
expect(unusedBadge).toHaveLength(3);
|
||||
|
||||
const viewProvisioned = screen.getByRole('link', { name: 'view-action' });
|
||||
expect(viewProvisioned).toBeInTheDocument();
|
||||
expect(viewProvisioned).not.toBeDisabled();
|
||||
|
||||
const editButtons = screen.getAllByRole('link', { name: 'edit-action' });
|
||||
expect(editButtons).toHaveLength(3);
|
||||
expect(editButtons).toHaveLength(4);
|
||||
editButtons.forEach((button) => {
|
||||
expect(button).not.toBeDisabled();
|
||||
});
|
||||
|
||||
const moreActionsButtons = screen.getAllByRole('button', { name: 'more-actions' });
|
||||
expect(moreActionsButtons).toHaveLength(4);
|
||||
expect(moreActionsButtons).toHaveLength(5);
|
||||
moreActionsButtons.forEach((button) => {
|
||||
expect(button).not.toBeDisabled();
|
||||
});
|
||||
@ -115,11 +115,11 @@ describe('contact points', () => {
|
||||
|
||||
// there should be view buttons though
|
||||
const viewButtons = screen.getAllByRole('link', { name: 'view-action' });
|
||||
expect(viewButtons).toHaveLength(4);
|
||||
expect(viewButtons).toHaveLength(5);
|
||||
|
||||
// delete should be disabled in the "more" actions
|
||||
const moreButtons = screen.queryAllByRole('button', { name: 'more-actions' });
|
||||
expect(moreButtons).toHaveLength(4);
|
||||
expect(moreButtons).toHaveLength(5);
|
||||
|
||||
// check if all of the delete buttons are disabled
|
||||
for await (const button of moreButtons) {
|
||||
|
@ -73,6 +73,19 @@
|
||||
"secureFields": { "token": true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OnCall Conctact point",
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"name": "Oncall-integration",
|
||||
"type": "oncall",
|
||||
"settings": {
|
||||
"url": "https://oncall-endpoint.example.com"
|
||||
},
|
||||
"disableResolveMessage": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -115,6 +115,19 @@ exports[`should be able to test and save a receiver 2`] = `
|
||||
],
|
||||
"name": "Slack with multiple channels",
|
||||
},
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"disableResolveMessage": false,
|
||||
"name": "Oncall-integration",
|
||||
"settings": {
|
||||
"url": "https://oncall-endpoint.example.com",
|
||||
},
|
||||
"type": "oncall",
|
||||
},
|
||||
],
|
||||
"name": "OnCall Conctact point",
|
||||
},
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
|
@ -60,6 +60,32 @@ exports[`useContactPoints should return contact points with status 1`] = `
|
||||
"name": "lotsa-emails",
|
||||
"numberOfPolicies": 0,
|
||||
},
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"disableResolveMessage": false,
|
||||
"name": "Oncall-integration",
|
||||
"settings": {
|
||||
"url": "https://oncall-endpoint.example.com",
|
||||
},
|
||||
"type": "oncall",
|
||||
Symbol(receiver_status): undefined,
|
||||
Symbol(receiver_metadata): {
|
||||
"description": undefined,
|
||||
"name": "Oncall",
|
||||
},
|
||||
Symbol(receiver_plugin_metadata): {
|
||||
"description": "grafana-integration",
|
||||
"externalUrl": "/a/grafana-oncall-app/integrations/ABC123",
|
||||
"icon": "public/img/alerting/oncall_logo.svg",
|
||||
"title": "Grafana OnCall",
|
||||
"warning": undefined,
|
||||
},
|
||||
},
|
||||
],
|
||||
"name": "OnCall Conctact point",
|
||||
"numberOfPolicies": 0,
|
||||
},
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
@ -147,3 +173,174 @@ exports[`useContactPoints should return contact points with status 1`] = `
|
||||
"refetchReceivers": [Function],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`useContactPoints when having oncall plugin installed and no alert manager config data should return contact points with oncall metadata 1`] = `
|
||||
{
|
||||
"contactPoints": [
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"disableResolveMessage": false,
|
||||
"name": "grafana-default-email",
|
||||
"secureFields": {},
|
||||
"settings": {
|
||||
"addresses": "gilles.demey@grafana.com",
|
||||
"singleEmail": false,
|
||||
},
|
||||
"type": "email",
|
||||
"uid": "xeKQrBrnk",
|
||||
Symbol(receiver_status): {
|
||||
"lastNotifyAttempt": "2023-07-02T21:35:34.841+02:00",
|
||||
"lastNotifyAttemptDuration": "1ms",
|
||||
"lastNotifyAttemptError": "failed to send notification to email addresses: gilles.demey@grafana.com: dial tcp 192.168.1.21:1025: connect: connection refused",
|
||||
"name": "email",
|
||||
"sendResolved": true,
|
||||
},
|
||||
Symbol(receiver_metadata): {
|
||||
"description": "Sends notifications using Grafana server configured SMTP settings",
|
||||
"name": "Email",
|
||||
},
|
||||
Symbol(receiver_plugin_metadata): undefined,
|
||||
},
|
||||
],
|
||||
"name": "grafana-default-email",
|
||||
"numberOfPolicies": undefined,
|
||||
},
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"disableResolveMessage": false,
|
||||
"name": "lotsa-emails",
|
||||
"secureFields": {},
|
||||
"settings": {
|
||||
"addresses": "gilles.demey+1@grafana.com, gilles.demey+2@grafana.com, gilles.demey+3@grafana.com, gilles.demey+4@grafana.com",
|
||||
"singleEmail": false,
|
||||
},
|
||||
"type": "email",
|
||||
"uid": "af306c96-35a2-4d6e-908a-4993e245dbb2",
|
||||
Symbol(receiver_status): {
|
||||
"lastNotifyAttempt": "",
|
||||
"lastNotifyAttemptDuration": "",
|
||||
"name": "email",
|
||||
"sendResolved": true,
|
||||
},
|
||||
Symbol(receiver_metadata): {
|
||||
"description": "Sends notifications using Grafana server configured SMTP settings",
|
||||
"name": "Email",
|
||||
},
|
||||
Symbol(receiver_plugin_metadata): undefined,
|
||||
},
|
||||
],
|
||||
"name": "lotsa-emails",
|
||||
"numberOfPolicies": undefined,
|
||||
},
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"disableResolveMessage": false,
|
||||
"name": "Oncall-integration",
|
||||
"settings": {
|
||||
"url": "https://oncall-endpoint.example.com",
|
||||
},
|
||||
"type": "oncall",
|
||||
Symbol(receiver_status): undefined,
|
||||
Symbol(receiver_metadata): {
|
||||
"description": undefined,
|
||||
"name": "Oncall",
|
||||
},
|
||||
Symbol(receiver_plugin_metadata): {
|
||||
"icon": "public/img/alerting/oncall_logo.svg",
|
||||
"title": "Grafana OnCall",
|
||||
},
|
||||
},
|
||||
],
|
||||
"name": "OnCall Conctact point",
|
||||
"numberOfPolicies": undefined,
|
||||
},
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"disableResolveMessage": false,
|
||||
"name": "provisioned-contact-point",
|
||||
"provenance": "api",
|
||||
"secureFields": {},
|
||||
"settings": {
|
||||
"addresses": "gilles.demey@grafana.com",
|
||||
"singleEmail": false,
|
||||
},
|
||||
"type": "email",
|
||||
"uid": "s8SdCVjnk",
|
||||
Symbol(receiver_status): {
|
||||
"lastNotifyAttempt": "",
|
||||
"lastNotifyAttemptDuration": "",
|
||||
"name": "email",
|
||||
"sendResolved": true,
|
||||
},
|
||||
Symbol(receiver_metadata): {
|
||||
"description": "Sends notifications using Grafana server configured SMTP settings",
|
||||
"name": "Email",
|
||||
},
|
||||
Symbol(receiver_plugin_metadata): undefined,
|
||||
},
|
||||
],
|
||||
"name": "provisioned-contact-point",
|
||||
"numberOfPolicies": undefined,
|
||||
},
|
||||
{
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"disableResolveMessage": false,
|
||||
"name": "Slack with multiple channels",
|
||||
"secureFields": {
|
||||
"token": true,
|
||||
},
|
||||
"settings": {
|
||||
"recipient": "test-alerts",
|
||||
},
|
||||
"type": "slack",
|
||||
"uid": "c02ad56a-31da-46b9-becb-4348ec0890fd",
|
||||
Symbol(receiver_status): {
|
||||
"lastNotifyAttempt": "",
|
||||
"lastNotifyAttemptDuration": "",
|
||||
"name": "slack",
|
||||
"sendResolved": true,
|
||||
},
|
||||
Symbol(receiver_metadata): {
|
||||
"description": "Sends notifications to Slack",
|
||||
"name": "Slack",
|
||||
},
|
||||
Symbol(receiver_plugin_metadata): undefined,
|
||||
},
|
||||
{
|
||||
"disableResolveMessage": false,
|
||||
"name": "Slack with multiple channels",
|
||||
"secureFields": {
|
||||
"token": true,
|
||||
},
|
||||
"settings": {
|
||||
"recipient": "test-alerts2",
|
||||
},
|
||||
"type": "slack",
|
||||
"uid": "b286a3be-f690-49e2-8605-b075cbace2df",
|
||||
Symbol(receiver_status): {
|
||||
"lastNotifyAttempt": "",
|
||||
"lastNotifyAttemptDuration": "",
|
||||
"name": "slack",
|
||||
"sendResolved": true,
|
||||
},
|
||||
Symbol(receiver_metadata): {
|
||||
"description": "Sends notifications to Slack",
|
||||
"name": "Slack",
|
||||
},
|
||||
Symbol(receiver_plugin_metadata): undefined,
|
||||
},
|
||||
],
|
||||
"name": "Slack with multiple channels",
|
||||
"numberOfPolicies": undefined,
|
||||
},
|
||||
],
|
||||
"error": undefined,
|
||||
"isLoading": false,
|
||||
"refetchReceivers": [Function],
|
||||
}
|
||||
`;
|
||||
|
@ -2,10 +2,12 @@ import { renderHook, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { TestProvider } from 'test/helpers/TestProvider';
|
||||
|
||||
import alertmanagerMock from 'app/features/alerting/unified/components/contact-points/__mocks__/alertmanager.config.mock.json';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
import { setupMswServer } from '../../mockApi';
|
||||
import { grantUserPermissions } from '../../mocks';
|
||||
import { ONCALL_INTEGRATION_V2_FEATURE } from '../../api/onCallApi';
|
||||
import { mockApi, setupMswServer } from '../../mockApi';
|
||||
import { grantUserPermissions, onCallPluginMetaMock } from '../../mocks';
|
||||
import { AlertmanagerProvider } from '../../state/AlertmanagerContext';
|
||||
|
||||
import setupGrafanaManagedServer from './__mocks__/grafanaManagedServer';
|
||||
@ -23,6 +25,16 @@ describe('useContactPoints', () => {
|
||||
});
|
||||
|
||||
it('should return contact points with status', async () => {
|
||||
mockApi(server).plugins.getPluginSettings({ ...onCallPluginMetaMock, enabled: true });
|
||||
mockApi(server).oncall.features([ONCALL_INTEGRATION_V2_FEATURE]);
|
||||
mockApi(server).oncall.getOnCallIntegrations([
|
||||
{
|
||||
display_name: 'grafana-integration',
|
||||
value: 'ABC123',
|
||||
integration_url: 'https://oncall-endpoint.example.com',
|
||||
},
|
||||
]);
|
||||
mockApi(server).getContactPointsList(receivers);
|
||||
const { result } = renderHook(() => useContactPointsWithStatus(), {
|
||||
wrapper: ({ children }) => (
|
||||
<TestProvider>
|
||||
@ -32,10 +44,42 @@ describe('useContactPoints', () => {
|
||||
</TestProvider>
|
||||
),
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
expect(result.current).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('when having oncall plugin installed and no alert manager config data', () => {
|
||||
it('should return contact points with oncall metadata', async () => {
|
||||
mockApi(server).plugins.getPluginSettings({ ...onCallPluginMetaMock, enabled: true });
|
||||
mockApi(server).oncall.features([ONCALL_INTEGRATION_V2_FEATURE]);
|
||||
mockApi(server).oncall.getOnCallIntegrations([
|
||||
{
|
||||
display_name: 'grafana-integration',
|
||||
value: 'ABC123',
|
||||
integration_url: 'https://oncall-endpoint.example.com',
|
||||
},
|
||||
]);
|
||||
mockApi(server).getContactPointsList(receivers);
|
||||
const { result } = renderHook(
|
||||
() => useContactPointsWithStatus({ includePoliciesCount: false, receiverStatusPollingInterval: 0 }),
|
||||
{
|
||||
wrapper: ({ children }) => (
|
||||
<TestProvider>
|
||||
<AlertmanagerProvider accessType={'notification'} alertmanagerSourceName={'grafana'}>
|
||||
{children}
|
||||
</AlertmanagerProvider>
|
||||
</TestProvider>
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
expect(result.current).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const receivers = JSON.parse(JSON.stringify(alertmanagerMock)).alertmanager_config.receivers;
|
||||
|
@ -137,12 +137,17 @@ export function enhanceContactPointsWithMetadata(
|
||||
alertmanagerConfiguration && usedContactPointsByName && (usedContactPointsByName[contactPoint.name] ?? 0),
|
||||
grafana_managed_receiver_configs: receivers.map((receiver, index) => {
|
||||
const isOnCallReceiver = receiver.type === ReceiverTypes.OnCall;
|
||||
// if we don't have alertmanagerConfiguration we can't get the metadata for oncall receivers,
|
||||
// because we don't have the url, as we are not using the alertmanager configuration
|
||||
// but the contact points returned by the read only permissions contact points endpoint (/api/v1/notifications/receivers)
|
||||
return {
|
||||
...receiver,
|
||||
[RECEIVER_STATUS_KEY]: statusForReceiver?.integrations[index],
|
||||
[RECEIVER_META_KEY]: getNotifierMetadata(notifiers, receiver),
|
||||
// if OnCall plugin is installed, we'll add it to the receiver's plugin metadata
|
||||
[RECEIVER_PLUGIN_META_KEY]: isOnCallReceiver ? getOnCallMetadata(onCallIntegrations, receiver) : undefined,
|
||||
[RECEIVER_PLUGIN_META_KEY]: isOnCallReceiver
|
||||
? getOnCallMetadata(onCallIntegrations, receiver, Boolean(alertmanagerConfiguration))
|
||||
: undefined,
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
@ -16,15 +16,20 @@ export interface ReceiverPluginMetadata {
|
||||
const onCallReceiverICon = GRAFANA_APP_RECEIVERS_SOURCE_IMAGE[SupportedPlugin.OnCall];
|
||||
const onCallReceiverTitle = 'Grafana OnCall';
|
||||
|
||||
const onCallReceiverMeta: ReceiverPluginMetadata = {
|
||||
export const onCallReceiverMeta: ReceiverPluginMetadata = {
|
||||
title: onCallReceiverTitle,
|
||||
icon: onCallReceiverICon,
|
||||
};
|
||||
|
||||
export function getOnCallMetadata(
|
||||
onCallIntegrations: OnCallIntegrationDTO[] | undefined | null,
|
||||
receiver: GrafanaManagedReceiverConfig
|
||||
receiver: GrafanaManagedReceiverConfig,
|
||||
hasAlertManagerConfigData = true
|
||||
): ReceiverPluginMetadata {
|
||||
if (!hasAlertManagerConfigData) {
|
||||
return onCallReceiverMeta;
|
||||
}
|
||||
|
||||
// oncall status is still loading
|
||||
if (onCallIntegrations === undefined) {
|
||||
return onCallReceiverMeta;
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
AlertManagerCortexConfig,
|
||||
AlertmanagerReceiver,
|
||||
EmailConfig,
|
||||
GrafanaManagedContactPoint,
|
||||
GrafanaManagedReceiverConfig,
|
||||
MatcherOperator,
|
||||
Route,
|
||||
@ -218,6 +219,9 @@ export function mockApi(server: SetupServer) {
|
||||
server.use(http.get(`api/plugins/${response.id}/settings`, () => HttpResponse.json(response)));
|
||||
},
|
||||
},
|
||||
getContactPointsList: (response: GrafanaManagedContactPoint[]) => {
|
||||
server.use(http.get(`/api/v1/notifications/receivers`, () => HttpResponse.json(response)));
|
||||
},
|
||||
|
||||
oncall: {
|
||||
getOnCallIntegrations: (response: OnCallIntegrationDTO[]) => {
|
||||
|
Loading…
Reference in New Issue
Block a user