From 2c57ecc08517aa3d03c23fcdb972d91d6edb7643 Mon Sep 17 00:00:00 2001 From: Tom Ratcliffe Date: Mon, 4 Nov 2024 14:20:35 +0000 Subject: [PATCH] Alerting: Only show "misconfigured" warning for templates if AM is not Grafana (#95596) --- .../contact-points/ContactPoints.test.tsx | 62 ++++++++++++------- .../alertmanager.mimir.config.mock.json | 33 ++++++++-- .../components/receivers/TemplatesTable.tsx | 4 +- 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/public/app/features/alerting/unified/components/contact-points/ContactPoints.test.tsx b/public/app/features/alerting/unified/components/contact-points/ContactPoints.test.tsx index dea25168694..91a71361a37 100644 --- a/public/app/features/alerting/unified/components/contact-points/ContactPoints.test.tsx +++ b/public/app/features/alerting/unified/components/contact-points/ContactPoints.test.tsx @@ -91,7 +91,26 @@ const attemptDeleteContactPoint = async (name: string) => { return user.click(await screen.findByRole('button', { name: /delete contact point/i })); }; +const alertManager = mockDataSource({ + name: VANILLA_ALERTMANAGER_DATASOURCE_UID, + uid: VANILLA_ALERTMANAGER_DATASOURCE_UID, + type: DataSourceType.Alertmanager, + jsonData: { + implementation: AlertManagerImplementation.prometheus, + handleGrafanaManagedAlerts: true, + }, +}); + +const mimirDatasource = mockDataSource({ + type: DataSourceType.Alertmanager, + name: MIMIR_DATASOURCE_UID, + uid: MIMIR_DATASOURCE_UID, +}); + describe('contact points', () => { + beforeEach(() => { + setupDataSources(alertManager, mimirDatasource); + }); describe('Contact points with Grafana managed alertmanager', () => { beforeEach(() => { grantUserPermissions([ @@ -127,9 +146,14 @@ describe('contact points', () => { }); describe('templates tab', () => { - it('shows a warning when a template is misconfigured', async () => { - renderWithProvider(, { initialEntries: ['/?tab=templates'] }); - expect((await screen.findAllByText(/^misconfigured$/i))[0]).toBeInTheDocument(); + it('does not show a warning for a "misconfigured" template', async () => { + renderWithProvider( + , + { initialEntries: ['/?tab=templates'] }, + { alertmanagerSourceName: GRAFANA_RULES_SOURCE_NAME } + ); + await screen.findByText(/create notification templates/i); + expect(screen.queryByText(/^misconfigured$/i)).not.toBeInTheDocument(); }); }); @@ -328,13 +352,6 @@ describe('contact points', () => { AccessControlAction.AlertingNotificationsExternalRead, AccessControlAction.AlertingNotificationsExternalWrite, ]); - setupDataSources( - mockDataSource({ - type: DataSourceType.Alertmanager, - name: MIMIR_DATASOURCE_UID, - uid: MIMIR_DATASOURCE_UID, - }) - ); }); it('should show / hide loading states, have the right actions enabled', async () => { @@ -367,6 +384,17 @@ describe('contact points', () => { expect(button).toBeEnabled(); }); }); + + describe('templates tab', () => { + it('shows a warning when a template is misconfigured', async () => { + renderWithProvider( + , + { initialEntries: ['/?tab=templates'] }, + { alertmanagerSourceName: MIMIR_DATASOURCE_UID } + ); + expect((await screen.findAllByText(/^misconfigured$/i))[0]).toBeInTheDocument(); + }); + }); }); describe('Vanilla Alertmanager ', () => { @@ -376,23 +404,11 @@ describe('contact points', () => { AccessControlAction.AlertingNotificationsExternalRead, AccessControlAction.AlertingNotificationsExternalWrite, ]); - - const alertManager = mockDataSource({ - name: VANILLA_ALERTMANAGER_DATASOURCE_UID, - uid: VANILLA_ALERTMANAGER_DATASOURCE_UID, - type: DataSourceType.Alertmanager, - jsonData: { - implementation: AlertManagerImplementation.prometheus, - handleGrafanaManagedAlerts: true, - }, - }); - - setupDataSources(alertManager); }); it("should not allow any editing because it's not supported", async () => { const { user } = renderWithProvider(, undefined, { - alertmanagerSourceName: VANILLA_ALERTMANAGER_DATASOURCE_UID, + alertmanagerSourceName: alertManager.name, }); await waitForElementToBeRemoved(screen.queryByText('Loading...')); diff --git a/public/app/features/alerting/unified/components/contact-points/__mocks__/alertmanager.mimir.config.mock.json b/public/app/features/alerting/unified/components/contact-points/__mocks__/alertmanager.mimir.config.mock.json index 46501c9a0d5..c35a120d4f4 100644 --- a/public/app/features/alerting/unified/components/contact-points/__mocks__/alertmanager.mimir.config.mock.json +++ b/public/app/features/alerting/unified/components/contact-points/__mocks__/alertmanager.mimir.config.mock.json @@ -1,18 +1,41 @@ { - "template_files": {}, + "template_files": { + "misconfigured-template": "{{ define 'misconfigured template' }} Template that is defined in template_files but not templates {{ end }}" + }, "alertmanager_config": { "global": {}, "mute_time_intervals": [], "receivers": [ { "email_configs": [ - { "require_tls": false, "send_resolved": true, "to": "foo@bar.com" }, - { "require_tls": false, "send_resolved": true, "to": "foo@bar.com" } + { + "require_tls": false, + "send_resolved": true, + "to": "foo@bar.com" + }, + { + "require_tls": false, + "send_resolved": true, + "to": "foo@bar.com" + } ], "name": "mixed", - "webhook_configs": [{ "send_resolved": true, "url": "https://foo.bar/" }] + "webhook_configs": [ + { + "send_resolved": true, + "url": "https://foo.bar/" + } + ] }, - { "name": "some webhook", "webhook_configs": [{ "send_resolved": true, "url": "https://foo.bar/" }] } + { + "name": "some webhook", + "webhook_configs": [ + { + "send_resolved": true, + "url": "https://foo.bar/" + } + ] + } ], "route": { "continue": false, diff --git a/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx b/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx index c644a3b5fb7..7debc6c7f16 100644 --- a/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx +++ b/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx @@ -5,6 +5,7 @@ import { Badge, ConfirmModal, Tooltip, useStyles2 } from '@grafana/ui'; import { useAppNotification } from 'app/core/copy/appNotification'; import { t, Trans } from 'app/core/internationalization'; import { CodeText } from 'app/features/alerting/unified/components/common/TextVariants'; +import { GRAFANA_RULES_SOURCE_NAME } from 'app/features/alerting/unified/utils/datasource'; import { Authorize } from '../../components/Authorize'; import { AlertmanagerAction } from '../../hooks/useAbilities'; @@ -114,6 +115,7 @@ interface TemplateRowProps { function TemplateRow({ notificationTemplate, idx, alertManagerName, onDeleteClick }: TemplateRowProps) { const tableStyles = useStyles2(getAlertTableStyles); + const isGrafanaAlertmanager = alertManagerName === GRAFANA_RULES_SOURCE_NAME; const [isExpanded, setIsExpanded] = useState(false); const { isProvisioned } = useNotificationTemplateMetadata(notificationTemplate); @@ -128,7 +130,7 @@ function TemplateRow({ notificationTemplate, idx, alertManagerName, onDeleteClic {name} {isProvisioned && }{' '} - {missing && ( + {missing && !isGrafanaAlertmanager && (