2024-03-28 23:19:46 +08:00
|
|
|
import { produce } from 'immer';
|
2024-03-27 01:36:30 +08:00
|
|
|
import React from 'react';
|
|
|
|
|
|
|
|
|
|
import { Menu } from '@grafana/ui';
|
2024-05-14 16:01:08 +08:00
|
|
|
import { useAppNotification } from 'app/core/copy/appNotification';
|
2024-03-27 01:36:30 +08:00
|
|
|
import { alertRuleApi } from 'app/features/alerting/unified/api/alertRuleApi';
|
|
|
|
|
import { isGrafanaRulerRule, isGrafanaRulerRulePaused } from 'app/features/alerting/unified/utils/rules';
|
|
|
|
|
import { CombinedRule } from 'app/types/unified-alerting';
|
|
|
|
|
|
2024-05-14 16:01:08 +08:00
|
|
|
import { grafanaRulerConfig } from '../hooks/useCombinedRule';
|
|
|
|
|
|
2024-03-27 01:36:30 +08:00
|
|
|
interface Props {
|
|
|
|
|
rule: CombinedRule;
|
|
|
|
|
/**
|
|
|
|
|
* Method invoked after the request to change the paused state has completed
|
|
|
|
|
*/
|
2024-03-28 23:20:19 +08:00
|
|
|
onPauseChange?: () => void;
|
2024-03-27 01:36:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Menu item to display correct text for pausing/resuming an alert,
|
|
|
|
|
* and triggering API call to do so
|
|
|
|
|
*/
|
|
|
|
|
const MenuItemPauseRule = ({ rule, onPauseChange }: Props) => {
|
2024-05-14 16:01:08 +08:00
|
|
|
// we need to fetch the group again, as maybe the group has been filtered
|
|
|
|
|
const [getGroup] = alertRuleApi.endpoints.rulerRuleGroup.useLazyQuery();
|
|
|
|
|
const notifyApp = useAppNotification();
|
|
|
|
|
|
|
|
|
|
// Add any dependencies here
|
2024-03-28 23:20:19 +08:00
|
|
|
const [updateRule] = alertRuleApi.endpoints.updateRule.useMutation();
|
2024-03-27 01:36:30 +08:00
|
|
|
const isPaused = isGrafanaRulerRule(rule.rulerRule) && isGrafanaRulerRulePaused(rule.rulerRule);
|
|
|
|
|
const icon = isPaused ? 'play' : 'pause';
|
2024-03-28 23:20:40 +08:00
|
|
|
const title = isPaused ? 'Resume evaluation' : 'Pause evaluation';
|
2024-03-27 01:36:30 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Triggers API call to update the current rule to the new `is_paused` state
|
|
|
|
|
*/
|
|
|
|
|
const setRulePause = async (newIsPaused: boolean) => {
|
|
|
|
|
if (!isGrafanaRulerRule(rule.rulerRule)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const ruleUid = rule.rulerRule.grafana_alert.uid;
|
2024-05-14 16:01:08 +08:00
|
|
|
const targetGroup = await getGroup({
|
|
|
|
|
rulerConfig: grafanaRulerConfig,
|
|
|
|
|
namespace: rule.namespace.uid || rule.rulerRule.grafana_alert.namespace_uid,
|
|
|
|
|
group: rule.group.name,
|
|
|
|
|
}).unwrap();
|
|
|
|
|
|
|
|
|
|
if (!targetGroup) {
|
|
|
|
|
notifyApp.error(
|
|
|
|
|
`Failed to ${newIsPaused ? 'pause' : 'resume'} the rule. Could not get the target group to update the rule.`
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-03-27 01:36:30 +08:00
|
|
|
|
|
|
|
|
// Parse the rules into correct format for API
|
2024-05-14 16:01:08 +08:00
|
|
|
const modifiedRules = targetGroup.rules.map((groupRule) => {
|
|
|
|
|
if (!(isGrafanaRulerRule(groupRule) && groupRule.grafana_alert.uid === ruleUid)) {
|
|
|
|
|
return groupRule;
|
2024-03-27 01:36:30 +08:00
|
|
|
}
|
2024-05-14 16:01:08 +08:00
|
|
|
return produce(groupRule, (updatedGroupRule) => {
|
2024-03-28 23:19:46 +08:00
|
|
|
updatedGroupRule.grafana_alert.is_paused = newIsPaused;
|
|
|
|
|
});
|
2024-03-27 01:36:30 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const payload = {
|
2024-05-14 16:01:08 +08:00
|
|
|
interval: targetGroup.interval!,
|
|
|
|
|
name: targetGroup.name,
|
2024-03-27 01:36:30 +08:00
|
|
|
rules: modifiedRules,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await updateRule({
|
|
|
|
|
nameSpaceUID: rule.namespace.uid || rule.rulerRule.grafana_alert.namespace_uid,
|
|
|
|
|
payload,
|
|
|
|
|
}).unwrap();
|
|
|
|
|
|
|
|
|
|
onPauseChange?.();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Menu.Item
|
|
|
|
|
label={title}
|
|
|
|
|
icon={icon}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setRulePause(!isPaused);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default MenuItemPauseRule;
|