mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: use a single move operation for alert rules (#48125)
This commit is contained in:
parent
1be45d1ed9
commit
9b95d77be9
@ -402,6 +402,9 @@ export const saveRuleFormAction = createAsyncThunk(
|
||||
const newLocation = `/alerting/${encodeURIComponent(stringifiedIdentifier)}/edit`;
|
||||
if (locationService.getLocation().pathname !== newLocation) {
|
||||
locationService.replace(newLocation);
|
||||
} else {
|
||||
// refresh the details of the current editable rule after saving
|
||||
thunkAPI.dispatch(fetchEditableRuleAction(identifier));
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
@ -188,29 +188,23 @@ export function getRulerClient(rulerConfig: RulerDataSourceConfig): RulerClient
|
||||
|
||||
await setRulerRuleGroup(rulerConfig, namespace, payload);
|
||||
|
||||
return { uid: '', ruleSourceName: GRAFANA_RULES_SOURCE_NAME };
|
||||
return { uid: newRule.grafana_alert.uid ?? '', ruleSourceName: GRAFANA_RULES_SOURCE_NAME };
|
||||
};
|
||||
|
||||
// we can't move the rule in a single atomic operation so we have to
|
||||
// 1. add the rule to the new group
|
||||
// 2. remove the rule from the old one
|
||||
// move the rule to another namespace / groupname
|
||||
const moveGrafanaRule = async (
|
||||
namespace: string,
|
||||
group: { name: string; interval: string },
|
||||
existingRule: RuleWithLocation,
|
||||
newRule: PostableRuleGrafanaRuleDTO
|
||||
): Promise<RuleIdentifier> => {
|
||||
// make sure our updated alert has the same UID as before
|
||||
// that way the rule is automatically moved to the new namespace / group name
|
||||
copyGrafanaUID(existingRule, newRule);
|
||||
|
||||
// add the new rule to the requested namespace and group
|
||||
const identifier = await addRuleToNamespaceAndGroup(namespace, group, newRule);
|
||||
|
||||
// remove the rule from the previous namespace and group
|
||||
await deleteRule({
|
||||
ruleSourceName: existingRule.ruleSourceName,
|
||||
namespace: existingRule.namespace,
|
||||
group: existingRule.group,
|
||||
rule: newRule as RulerGrafanaRuleDTO,
|
||||
});
|
||||
|
||||
return identifier;
|
||||
};
|
||||
|
||||
@ -219,19 +213,13 @@ export function getRulerClient(rulerConfig: RulerDataSourceConfig): RulerClient
|
||||
newRule: PostableRuleGrafanaRuleDTO,
|
||||
interval: string
|
||||
): Promise<RuleIdentifier> => {
|
||||
// type guard to make sure we're working with a Grafana managed rule
|
||||
if (!isGrafanaRulerRule(existingRule.rule)) {
|
||||
throw new Error('The rule is not a Grafana managed rule');
|
||||
}
|
||||
|
||||
// make sure our updated alert has the same UID as before
|
||||
const uid = existingRule.rule.grafana_alert.uid;
|
||||
newRule.grafana_alert.uid = uid;
|
||||
copyGrafanaUID(existingRule, newRule);
|
||||
|
||||
// create the new array of rules we want to send to the group
|
||||
const newRules = existingRule.group.rules
|
||||
.filter((rule): rule is RulerGrafanaRuleDTO => isGrafanaRulerRule(rule))
|
||||
.filter((rule) => rule.grafana_alert.uid !== uid)
|
||||
.filter((rule) => rule.grafana_alert.uid !== existingRule.rule.grafana_alert.uid)
|
||||
.concat(newRule as RulerGrafanaRuleDTO);
|
||||
|
||||
await setRulerRuleGroup(rulerConfig, existingRule.namespace, {
|
||||
@ -240,7 +228,7 @@ export function getRulerClient(rulerConfig: RulerDataSourceConfig): RulerClient
|
||||
rules: newRules,
|
||||
});
|
||||
|
||||
return { uid: '', ruleSourceName: GRAFANA_RULES_SOURCE_NAME };
|
||||
return { uid: existingRule.rule.grafana_alert.uid, ruleSourceName: GRAFANA_RULES_SOURCE_NAME };
|
||||
};
|
||||
|
||||
// Would be nice to somehow align checking of ruler type between different methods
|
||||
@ -252,3 +240,17 @@ export function getRulerClient(rulerConfig: RulerDataSourceConfig): RulerClient
|
||||
saveGrafanaRule,
|
||||
};
|
||||
}
|
||||
|
||||
//copy the Grafana rule UID from the old rule to the new rule
|
||||
function copyGrafanaUID(
|
||||
oldRule: RuleWithLocation,
|
||||
newRule: PostableRuleGrafanaRuleDTO
|
||||
): asserts oldRule is RuleWithLocation<RulerGrafanaRuleDTO> {
|
||||
// type guard to make sure we're working with a Grafana managed rule
|
||||
if (!isGrafanaRulerRule(oldRule.rule)) {
|
||||
throw new Error('The rule is not a Grafana managed rule');
|
||||
}
|
||||
|
||||
const uid = oldRule.rule.grafana_alert.uid;
|
||||
newRule.grafana_alert.uid = uid;
|
||||
}
|
||||
|
@ -97,11 +97,11 @@ export interface CombinedRuleNamespace {
|
||||
groups: CombinedRuleGroup[];
|
||||
}
|
||||
|
||||
export interface RuleWithLocation {
|
||||
export interface RuleWithLocation<T = RulerRuleDTO> {
|
||||
ruleSourceName: string;
|
||||
namespace: string;
|
||||
group: RulerRuleGroupDTO;
|
||||
rule: RulerRuleDTO;
|
||||
rule: T;
|
||||
}
|
||||
|
||||
export interface PromRuleWithLocation {
|
||||
|
Loading…
Reference in New Issue
Block a user