mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Simplified routing part3 (#79941)
* Update alert rule model in FE following BE design doc * Remove unnecessary conditional rendering * Update styles for optional route settings: add indentation * Update test * Add validation for grouBy to include grafana_folder and alertname * Split conversions between FEdataModel/ DTO, in separate functions * Update texts following Brenda's suggestions * Update text
This commit is contained in:
parent
48612063dd
commit
6f8ddac4eb
@ -80,9 +80,9 @@ export const NotificationsStep = ({ alertUid }: NotificationsStepProps) => {
|
||||
* - simplified routing is enabled
|
||||
* - the alert rule is a grafana rule
|
||||
*
|
||||
* This component will render the switch between the manual routing and the notification policy routing.
|
||||
* This component will render the switch between the select contact point routing and the notification policy routing.
|
||||
* It also renders the section body of the NotificationsStep, depending on the routing option selected.
|
||||
* If manual routing is selected, it will render the SimplifiedRouting component.
|
||||
* If select contact point routing is selected, it will render the SimplifiedRouting component.
|
||||
* If notification policy routing is selected, it will render the AutomaticRouting component.
|
||||
*
|
||||
*/
|
||||
@ -93,8 +93,8 @@ function ManualAndAutomaticRouting({ alertUid }: { alertUid?: string }) {
|
||||
const [manualRouting] = watch(['manualRouting']);
|
||||
|
||||
const routingOptions = [
|
||||
{ label: 'Manually select contact point', value: RoutingOptions.ContactPoint },
|
||||
{ label: 'Auto-select contact point', value: RoutingOptions.NotificationPolicy },
|
||||
{ label: 'Select contact point', value: RoutingOptions.ContactPoint },
|
||||
{ label: 'Use notification policy', value: RoutingOptions.NotificationPolicy },
|
||||
];
|
||||
|
||||
const onRoutingOptionChange = (option: RoutingOptions) => {
|
||||
@ -229,7 +229,7 @@ export const RoutingOptionDescription = ({ manualRouting }: NotificationsStepDes
|
||||
<Text variant="bodySmall" color="secondary">
|
||||
{manualRouting
|
||||
? 'Notifications for firing alerts are routed to a selected contact point.'
|
||||
: 'Notifications for firing alerts are routed to contact points based on matching labels.'}
|
||||
: 'Notifications for firing alerts are routed to contact points based on matching labels and the notification policy tree.'}
|
||||
</Text>
|
||||
{manualRouting ? <NeedHelpInfoForContactpoint /> : <NeedHelpInfoForNotificationPolicy />}
|
||||
</div>
|
||||
|
@ -23,7 +23,6 @@ export function AlertManagerManualRouting({ alertManager }: AlertManagerManualRo
|
||||
|
||||
const alertManagerName = alertManager.name;
|
||||
const { isLoading, error: errorInContactPointStatus, contactPoints } = useContactPointsWithStatus();
|
||||
const shouldShowAM = true;
|
||||
const [selectedContactPointWithMetadata, setSelectedContactPointWithMetadata] = useState<
|
||||
ContactPointWithMetadata | undefined
|
||||
>();
|
||||
@ -36,17 +35,15 @@ export function AlertManagerManualRouting({ alertManager }: AlertManagerManualRo
|
||||
}
|
||||
return (
|
||||
<Stack direction="column">
|
||||
{shouldShowAM && (
|
||||
<Stack direction="row" alignItems="center">
|
||||
<div className={styles.firstAlertManagerLine}></div>
|
||||
<div className={styles.alertManagerName}>
|
||||
Alert manager:
|
||||
<img src={alertManager.imgUrl} alt="Alert manager logo" className={styles.img} />
|
||||
{alertManagerName}
|
||||
</div>
|
||||
<div className={styles.secondAlertManagerLine}></div>
|
||||
</Stack>
|
||||
)}
|
||||
<Stack direction="row" alignItems="center">
|
||||
<div className={styles.firstAlertManagerLine}></div>
|
||||
<div className={styles.alertManagerName}>
|
||||
Alert manager:
|
||||
<img src={alertManager.imgUrl} alt="Alert manager logo" className={styles.img} />
|
||||
{alertManagerName}
|
||||
</div>
|
||||
<div className={styles.secondAlertManagerLine}></div>
|
||||
</Stack>
|
||||
<Stack direction="row" gap={1} alignItems="center">
|
||||
<ContactPointSelector
|
||||
alertManager={alertManagerName}
|
||||
@ -59,7 +56,11 @@ export function AlertManagerManualRouting({ alertManager }: AlertManagerManualRo
|
||||
<ContactPointDetails receivers={selectedContactPointWithMetadata.grafana_managed_receiver_configs} />
|
||||
)}
|
||||
<div className={styles.routingSection}>
|
||||
<CollapsableSection label="Muting, grouping and timings" isOpen={false} className={styles.collapsableSection}>
|
||||
<CollapsableSection
|
||||
label="Muting, grouping and timings (optional)"
|
||||
isOpen={false}
|
||||
className={styles.collapsableSection}
|
||||
>
|
||||
<Stack direction="column" gap={1}>
|
||||
<MuteTimingFields alertManager={alertManagerName} />
|
||||
<RoutingSettings alertManager={alertManagerName} />
|
||||
@ -74,7 +75,7 @@ function LinkToContactPoints() {
|
||||
return (
|
||||
<Link target="_blank" href={createUrl(hrefToContactPoints)} rel="noopener" aria-label="View alert rule">
|
||||
<Stack direction="row" gap={1} alignItems="center" justifyContent="center">
|
||||
<Text color="secondary">To browse contact points and create new ones go to</Text>
|
||||
<Text color="secondary">To browse contact points and create new ones, go to</Text>
|
||||
<Text color="link">Contact points</Text>
|
||||
<Icon name={'external-link-alt'} size="sm" color="link" />
|
||||
</Stack>
|
||||
|
@ -24,7 +24,7 @@ export function MuteTimingFields({ alertManager }: MuteTimingFieldsProps) {
|
||||
<Field
|
||||
label="Mute timings"
|
||||
data-testid="am-mute-timing-select"
|
||||
description="Add mute timing to policy"
|
||||
description="Select a mute timing to define when not to send notifications for this alert rule"
|
||||
invalid={!!errors.contactPoints?.[alertManager]?.muteTimeIntervals}
|
||||
>
|
||||
<InputControl
|
||||
@ -35,6 +35,7 @@ export function MuteTimingFields({ alertManager }: MuteTimingFieldsProps) {
|
||||
className={styles.input}
|
||||
onChange={(value) => onChange(mapMultiSelectValueToStrings(value))}
|
||||
options={muteTimingOptions}
|
||||
placeholder="Select mute timings..."
|
||||
/>
|
||||
)}
|
||||
control={control}
|
||||
|
@ -1,7 +1,19 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { Field, FieldValidationMessage, InputControl, MultiSelect, Stack, Switch, Text, useStyles2 } from '@grafana/ui';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import {
|
||||
Field,
|
||||
FieldValidationMessage,
|
||||
InlineField,
|
||||
InputControl,
|
||||
MultiSelect,
|
||||
Stack,
|
||||
Switch,
|
||||
Text,
|
||||
useStyles2,
|
||||
} from '@grafana/ui';
|
||||
import { useAlertmanagerConfig } from 'app/features/alerting/unified/hooks/useAlertmanagerConfig';
|
||||
import { useAlertmanager } from 'app/features/alerting/unified/state/AlertmanagerContext';
|
||||
import { RuleFormValues } from 'app/features/alerting/unified/types/rule-form';
|
||||
@ -32,12 +44,14 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
const { groupBy, groupIntervalValue, groupWaitValue, repeatIntervalValue } = useGetDefaultsForRoutingSettings();
|
||||
const overrideGrouping = watch(`contactPoints.${alertManager}.overrideGrouping`);
|
||||
const overrideTimings = watch(`contactPoints.${alertManager}.overrideTimings`);
|
||||
const requiredFieldsInGroupBy = ['grafana_folder', 'alertname'];
|
||||
const styles = useStyles2(getStyles);
|
||||
return (
|
||||
<Stack direction="column">
|
||||
<Stack direction="row" gap={1} alignItems="center" justifyContent="space-between">
|
||||
<Field label="Override grouping">
|
||||
<InlineField label="Override grouping" transparent={true} className={styles.switchElement}>
|
||||
<Switch id="override-grouping-toggle" {...register(`contactPoints.${alertManager}.overrideGrouping`)} />
|
||||
</Field>
|
||||
</InlineField>
|
||||
{!overrideGrouping && (
|
||||
<Text variant="body" color="secondary">
|
||||
Grouping: <strong>{groupBy.join(', ')}</strong>
|
||||
@ -50,8 +64,22 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
description="Group alerts when you receive a notification based on labels. If empty it will be inherited from the default notification policy."
|
||||
{...register(`contactPoints.${alertManager}.groupBy`, { required: true })}
|
||||
invalid={!!errors.contactPoints?.[alertManager]?.groupBy}
|
||||
className={styles.optionalContent}
|
||||
>
|
||||
<InputControl
|
||||
rules={{
|
||||
validate: (value: string[]) => {
|
||||
if (!value || value.length === 0) {
|
||||
return 'At least one group by option is required.';
|
||||
}
|
||||
// we need to make sure that the required fields are included
|
||||
const requiredFieldsIncluded = requiredFieldsInGroupBy.every((field) => value.includes(field));
|
||||
if (!requiredFieldsIncluded) {
|
||||
return `Group by must include ${requiredFieldsInGroupBy.join(', ')}`;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
}}
|
||||
render={({ field: { onChange, ref, ...field }, fieldState: { error } }) => (
|
||||
<>
|
||||
<MultiSelect
|
||||
@ -68,7 +96,7 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
onChange={(value) => onChange(mapMultiSelectValueToStrings(value))}
|
||||
options={[...commonGroupByOptions, ...groupByOptions]}
|
||||
/>
|
||||
{error && <FieldValidationMessage>{'At least one group by option is required'}</FieldValidationMessage>}
|
||||
{error && <FieldValidationMessage>{error.message}</FieldValidationMessage>}
|
||||
</>
|
||||
)}
|
||||
name={`contactPoints.${alertManager}.groupBy`}
|
||||
@ -77,9 +105,9 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
</Field>
|
||||
)}
|
||||
<Stack direction="row" gap={1} alignItems="center" justifyContent="space-between">
|
||||
<Field label="Override timings">
|
||||
<InlineField label="Override timings" transparent={true} className={styles.switchElement}>
|
||||
<Switch id="override-timings-toggle" {...register(`contactPoints.${alertManager}.overrideTimings`)} />
|
||||
</Field>
|
||||
</InlineField>
|
||||
{!overrideTimings && (
|
||||
<Text variant="body" color="secondary">
|
||||
Group wait: <strong>{groupWaitValue}, </strong>
|
||||
@ -88,7 +116,11 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
{overrideTimings && <RouteTimings alertManager={alertManager} />}
|
||||
{overrideTimings && (
|
||||
<div className={styles.optionalContent}>
|
||||
<RouteTimings alertManager={alertManager} />
|
||||
</div>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@ -106,3 +138,14 @@ function useGetDefaultsForRoutingSettings() {
|
||||
};
|
||||
}, [config]);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
switchElement: css({
|
||||
flexFlow: 'row-reverse',
|
||||
gap: theme.spacing(1),
|
||||
alignItems: 'center',
|
||||
}),
|
||||
optionalContent: css({
|
||||
marginLeft: '49px',
|
||||
}),
|
||||
});
|
||||
|
@ -10,11 +10,11 @@ exports[`formValuesToRulerGrafanaRuleDTO should correctly convert rule form valu
|
||||
"for": "5m",
|
||||
"grafana_alert": {
|
||||
"condition": "A",
|
||||
"contactPoints": undefined,
|
||||
"data": [],
|
||||
"exec_err_state": "Error",
|
||||
"is_paused": false,
|
||||
"no_data_state": "NoData",
|
||||
"notification_settings": undefined,
|
||||
"title": "",
|
||||
},
|
||||
"labels": {
|
||||
@ -33,7 +33,6 @@ exports[`formValuesToRulerGrafanaRuleDTO should not save both instant and range
|
||||
"for": "5m",
|
||||
"grafana_alert": {
|
||||
"condition": "A",
|
||||
"contactPoints": undefined,
|
||||
"data": [
|
||||
{
|
||||
"datasourceUid": "dsuid",
|
||||
@ -54,6 +53,7 @@ exports[`formValuesToRulerGrafanaRuleDTO should not save both instant and range
|
||||
"exec_err_state": "Error",
|
||||
"is_paused": false,
|
||||
"no_data_state": "NoData",
|
||||
"notification_settings": undefined,
|
||||
"title": "",
|
||||
},
|
||||
"labels": {
|
||||
|
@ -1,13 +1,16 @@
|
||||
import { PromQuery } from 'app/plugins/datasource/prometheus/types';
|
||||
import { RulerAlertingRuleDTO } from 'app/types/unified-alerting-dto';
|
||||
import { GrafanaAlertStateDecision, GrafanaRuleDefinition, RulerAlertingRuleDTO } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { RuleFormType, RuleFormValues } from '../types/rule-form';
|
||||
import { AlertManagerManualRouting, RuleFormType, RuleFormValues } from '../types/rule-form';
|
||||
|
||||
import { GRAFANA_RULES_SOURCE_NAME } from './datasource';
|
||||
import {
|
||||
alertingRulerRuleToRuleForm,
|
||||
formValuesToRulerGrafanaRuleDTO,
|
||||
formValuesToRulerRuleDTO,
|
||||
getContactPointsFromDTO,
|
||||
getDefaultFormValues,
|
||||
getNotificationSettingsForDTO,
|
||||
} from './rule-form';
|
||||
|
||||
describe('formValuesToRulerGrafanaRuleDTO', () => {
|
||||
@ -85,3 +88,122 @@ describe('formValuesToRulerGrafanaRuleDTO', () => {
|
||||
expect(alertingRulerRuleToRuleForm(rule)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('getContactPointsFromDTO', () => {
|
||||
it('should return undefined if notification_settings is not defined', () => {
|
||||
const ga: GrafanaRuleDefinition = {
|
||||
uid: '123',
|
||||
title: 'myalert',
|
||||
namespace_uid: '123',
|
||||
condition: 'A',
|
||||
no_data_state: GrafanaAlertStateDecision.Alerting,
|
||||
exec_err_state: GrafanaAlertStateDecision.Alerting,
|
||||
data: [
|
||||
{
|
||||
datasourceUid: '123',
|
||||
refId: 'A',
|
||||
queryType: 'huh',
|
||||
model: { refId: 'A' },
|
||||
},
|
||||
],
|
||||
notification_settings: undefined,
|
||||
};
|
||||
|
||||
const result = getContactPointsFromDTO(ga);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return routingSettings with correct props if notification_settings is defined', () => {
|
||||
const ga: GrafanaRuleDefinition = {
|
||||
uid: '123',
|
||||
title: 'myalert',
|
||||
namespace_uid: '123',
|
||||
condition: 'A',
|
||||
no_data_state: GrafanaAlertStateDecision.Alerting,
|
||||
exec_err_state: GrafanaAlertStateDecision.Alerting,
|
||||
data: [
|
||||
{
|
||||
datasourceUid: '123',
|
||||
refId: 'A',
|
||||
queryType: 'huh',
|
||||
model: { refId: 'A' },
|
||||
},
|
||||
],
|
||||
notification_settings: {
|
||||
receiver: 'receiver',
|
||||
mute_timings: ['mute_timing'],
|
||||
group_by: ['group_by'],
|
||||
group_wait: 'group_wait',
|
||||
group_interval: 'group_interval',
|
||||
repeat_interval: 'repeat_interval',
|
||||
},
|
||||
};
|
||||
|
||||
const result = getContactPointsFromDTO(ga);
|
||||
expect(result).toEqual({
|
||||
[GRAFANA_RULES_SOURCE_NAME]: {
|
||||
selectedContactPoint: 'receiver',
|
||||
muteTimeIntervals: ['mute_timing'],
|
||||
overrideGrouping: true,
|
||||
overrideTimings: true,
|
||||
groupBy: ['group_by'],
|
||||
groupWaitValue: 'group_wait',
|
||||
groupIntervalValue: 'group_interval',
|
||||
repeatIntervalValue: 'repeat_interval',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getNotificationSettingsForDTO', () => {
|
||||
it('should return undefined if manualRouting is false', () => {
|
||||
const manualRouting = false;
|
||||
const contactPoints: AlertManagerManualRouting = {
|
||||
grafana: {
|
||||
selectedContactPoint: 'receiver',
|
||||
muteTimeIntervals: ['mute_timing'],
|
||||
overrideGrouping: true,
|
||||
overrideTimings: true,
|
||||
groupBy: ['group_by'],
|
||||
groupWaitValue: 'group_wait',
|
||||
groupIntervalValue: 'group_interval',
|
||||
repeatIntervalValue: 'repeat_interval',
|
||||
},
|
||||
};
|
||||
|
||||
const result = getNotificationSettingsForDTO(manualRouting, contactPoints);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return undefined if selectedContactPoint is not defined', () => {
|
||||
const manualRouting = true;
|
||||
|
||||
const result = getNotificationSettingsForDTO(manualRouting, undefined);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return notification settings if manualRouting is true and selectedContactPoint is defined', () => {
|
||||
const manualRouting = true;
|
||||
const contactPoints: AlertManagerManualRouting = {
|
||||
grafana: {
|
||||
selectedContactPoint: 'receiver',
|
||||
muteTimeIntervals: ['mute_timing'],
|
||||
overrideGrouping: true,
|
||||
overrideTimings: true,
|
||||
groupBy: ['group_by'],
|
||||
groupWaitValue: 'group_wait',
|
||||
groupIntervalValue: 'group_interval',
|
||||
repeatIntervalValue: 'repeat_interval',
|
||||
},
|
||||
};
|
||||
|
||||
const result = getNotificationSettingsForDTO(manualRouting, contactPoints);
|
||||
expect(result).toEqual({
|
||||
receiver: 'receiver',
|
||||
mute_timings: ['mute_timing'],
|
||||
group_by: ['group_by'],
|
||||
group_wait: 'group_wait',
|
||||
group_interval: 'group_interval',
|
||||
repeat_interval: 'repeat_interval',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -25,6 +25,8 @@ import {
|
||||
AlertQuery,
|
||||
Annotations,
|
||||
GrafanaAlertStateDecision,
|
||||
GrafanaNotificationSettings,
|
||||
GrafanaRuleDefinition,
|
||||
Labels,
|
||||
PostableRuleGrafanaRuleDTO,
|
||||
RulerAlertingRuleDTO,
|
||||
@ -33,11 +35,11 @@ import {
|
||||
} from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { EvalFunction } from '../../state/alertDef';
|
||||
import { RuleFormType, RuleFormValues } from '../types/rule-form';
|
||||
import { AlertManagerManualRouting, ContactPoint, RuleFormType, RuleFormValues } from '../types/rule-form';
|
||||
|
||||
import { getRulesAccess } from './access-control';
|
||||
import { Annotation, defaultAnnotations } from './constants';
|
||||
import { getDefaultOrFirstCompatibleDataSource, isGrafanaRulesSource } from './datasource';
|
||||
import { getDefaultOrFirstCompatibleDataSource, GRAFANA_RULES_SOURCE_NAME, isGrafanaRulesSource } from './datasource';
|
||||
import { arrayToRecord, recordToArray } from './misc';
|
||||
import { isAlertingRulerRule, isGrafanaRulerRule, isRecordingRulerRule } from './rules';
|
||||
import { parseInterval } from './time';
|
||||
@ -138,10 +140,34 @@ export function normalizeDefaultAnnotations(annotations: Array<{ key: string; va
|
||||
return orderedAnnotations;
|
||||
}
|
||||
|
||||
export function getNotificationSettingsForDTO(
|
||||
manualRouting: boolean,
|
||||
contactPoints?: AlertManagerManualRouting
|
||||
): GrafanaNotificationSettings | undefined {
|
||||
if (contactPoints?.grafana?.selectedContactPoint && manualRouting) {
|
||||
return {
|
||||
receiver: contactPoints?.grafana?.selectedContactPoint,
|
||||
mute_timings: contactPoints?.grafana?.muteTimeIntervals,
|
||||
group_by: contactPoints?.grafana?.overrideGrouping ? contactPoints?.grafana?.groupBy : undefined,
|
||||
group_wait: contactPoints?.grafana?.overrideTimings ? contactPoints?.grafana?.groupWaitValue : undefined,
|
||||
group_interval: contactPoints?.grafana?.overrideTimings ? contactPoints?.grafana?.groupIntervalValue : undefined,
|
||||
repeat_interval: contactPoints?.grafana?.overrideTimings
|
||||
? contactPoints?.grafana?.repeatIntervalValue
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function formValuesToRulerGrafanaRuleDTO(values: RuleFormValues): PostableRuleGrafanaRuleDTO {
|
||||
const { name, condition, noDataState, execErrState, evaluateFor, queries, isPaused, contactPoints, manualRouting } =
|
||||
values;
|
||||
if (condition) {
|
||||
const notificationSettings: GrafanaNotificationSettings | undefined = getNotificationSettingsForDTO(
|
||||
manualRouting,
|
||||
contactPoints
|
||||
);
|
||||
|
||||
return {
|
||||
grafana_alert: {
|
||||
title: name,
|
||||
@ -150,7 +176,7 @@ export function formValuesToRulerGrafanaRuleDTO(values: RuleFormValues): Postabl
|
||||
exec_err_state: execErrState,
|
||||
data: queries.map(fixBothInstantAndRangeQuery),
|
||||
is_paused: Boolean(isPaused),
|
||||
contactPoints: manualRouting ? contactPoints : undefined,
|
||||
notification_settings: notificationSettings,
|
||||
},
|
||||
for: evaluateFor,
|
||||
annotations: arrayToRecord(values.annotations || []),
|
||||
@ -160,6 +186,27 @@ export function formValuesToRulerGrafanaRuleDTO(values: RuleFormValues): Postabl
|
||||
throw new Error('Cannot create rule without specifying alert condition');
|
||||
}
|
||||
|
||||
export function getContactPointsFromDTO(ga: GrafanaRuleDefinition): AlertManagerManualRouting | undefined {
|
||||
const contactPoint: ContactPoint | undefined = ga.notification_settings
|
||||
? {
|
||||
selectedContactPoint: ga.notification_settings.receiver,
|
||||
muteTimeIntervals: ga.notification_settings.mute_timings ?? [],
|
||||
overrideGrouping: Boolean(ga.notification_settings?.group_by),
|
||||
overrideTimings: Boolean(ga.notification_settings.group_wait),
|
||||
groupBy: ga.notification_settings.group_by || [],
|
||||
groupWaitValue: ga.notification_settings.group_wait || '',
|
||||
groupIntervalValue: ga.notification_settings.group_interval || '',
|
||||
repeatIntervalValue: ga.notification_settings.repeat_interval || '',
|
||||
}
|
||||
: undefined;
|
||||
const routingSettings: AlertManagerManualRouting | undefined = contactPoint
|
||||
? {
|
||||
[GRAFANA_RULES_SOURCE_NAME]: contactPoint,
|
||||
}
|
||||
: undefined;
|
||||
return routingSettings;
|
||||
}
|
||||
|
||||
export function rulerRuleToFormValues(ruleWithLocation: RuleWithLocation): RuleFormValues {
|
||||
const { ruleSourceName, namespace, group, rule } = ruleWithLocation;
|
||||
|
||||
@ -168,6 +215,8 @@ export function rulerRuleToFormValues(ruleWithLocation: RuleWithLocation): RuleF
|
||||
if (isGrafanaRulerRule(rule)) {
|
||||
const ga = rule.grafana_alert;
|
||||
|
||||
const routingSettings: AlertManagerManualRouting | undefined = getContactPointsFromDTO(ga);
|
||||
|
||||
return {
|
||||
...defaultFormValues,
|
||||
name: ga.title,
|
||||
@ -183,8 +232,9 @@ export function rulerRuleToFormValues(ruleWithLocation: RuleWithLocation): RuleF
|
||||
labels: listifyLabelsOrAnnotations(rule.labels, true),
|
||||
folder: { title: namespace, uid: ga.namespace_uid },
|
||||
isPaused: ga.is_paused,
|
||||
contactPoints: ga.contactPoints,
|
||||
manualRouting: Boolean(ga.contactPoints),
|
||||
|
||||
contactPoints: routingSettings,
|
||||
manualRouting: Boolean(routingSettings),
|
||||
// next line is for testing
|
||||
// manualRouting: true,
|
||||
// contactPoints: {
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Prometheus API DTOs, possibly to be autogenerated from openapi spec in the near future
|
||||
|
||||
import { DataQuery, RelativeTimeRange } from '@grafana/data';
|
||||
import { AlertManagerManualRouting } from 'app/features/alerting/unified/types/rule-form';
|
||||
|
||||
import { AlertGroupTotals } from './unified-alerting';
|
||||
|
||||
@ -198,6 +197,14 @@ export interface AlertQuery {
|
||||
model: AlertDataQuery;
|
||||
}
|
||||
|
||||
export interface GrafanaNotificationSettings {
|
||||
receiver: string;
|
||||
group_by?: string[];
|
||||
group_wait?: string;
|
||||
group_interval?: string;
|
||||
repeat_interval?: string;
|
||||
mute_timings?: string[];
|
||||
}
|
||||
export interface PostableGrafanaRuleDefinition {
|
||||
uid?: string;
|
||||
title: string;
|
||||
@ -206,7 +213,7 @@ export interface PostableGrafanaRuleDefinition {
|
||||
exec_err_state: GrafanaAlertStateDecision;
|
||||
data: AlertQuery[];
|
||||
is_paused?: boolean;
|
||||
contactPoints?: AlertManagerManualRouting;
|
||||
notification_settings?: GrafanaNotificationSettings;
|
||||
}
|
||||
export interface GrafanaRuleDefinition extends PostableGrafanaRuleDefinition {
|
||||
id?: string;
|
||||
|
Loading…
Reference in New Issue
Block a user