1import { AlertState } from '@grafana/data'; 2import { 3 GrafanaAlertState, 4 PromAlertingRuleState, 5 PromRuleType, 6 RulerAlertingRuleDTO, 7 RulerGrafanaRuleDTO, 8 RulerRecordingRuleDTO, 9 RulerRuleDTO, 10} from 'app/types/unified-alerting-dto'; 11import { 12 Alert, 13 AlertingRule, 14 CloudRuleIdentifier, 15 GrafanaRuleIdentifier, 16 PrometheusRuleIdentifier, 17 PromRuleWithLocation, 18 RecordingRule, 19 Rule, 20 RuleIdentifier, 21 RuleNamespace, 22} from 'app/types/unified-alerting'; 23import { AsyncRequestState } from './redux'; 24import { RULER_NOT_SUPPORTED_MSG } from './constants'; 25import { capitalize } from 'lodash'; 26import { State } from '../components/StateTag'; 27 28export function isAlertingRule(rule: Rule | undefined): rule is AlertingRule { 29 return typeof rule === 'object' && rule.type === PromRuleType.Alerting; 30} 31 32export function isRecordingRule(rule: Rule): rule is RecordingRule { 33 return rule.type === PromRuleType.Recording; 34} 35 36export function isAlertingRulerRule(rule?: RulerRuleDTO): rule is RulerAlertingRuleDTO { 37 return typeof rule === 'object' && 'alert' in rule; 38} 39 40export function isRecordingRulerRule(rule?: RulerRuleDTO): rule is RulerRecordingRuleDTO { 41 return typeof rule === 'object' && 'record' in rule; 42} 43 44export function isGrafanaRulerRule(rule?: RulerRuleDTO): rule is RulerGrafanaRuleDTO { 45 return typeof rule === 'object' && 'grafana_alert' in rule; 46} 47 48export function alertInstanceKey(alert: Alert): string { 49 return JSON.stringify(alert.labels); 50} 51 52export function isRulerNotSupportedResponse(resp: AsyncRequestState<any>) { 53 return resp.error && resp.error?.message?.includes(RULER_NOT_SUPPORTED_MSG); 54} 55 56export function isGrafanaRuleIdentifier(identifier: RuleIdentifier): identifier is GrafanaRuleIdentifier { 57 return 'uid' in identifier; 58} 59 60export function isCloudRuleIdentifier(identifier: RuleIdentifier): identifier is CloudRuleIdentifier { 61 return 'rulerRuleHash' in identifier; 62} 63 64export function isPrometheusRuleIdentifier(identifier: RuleIdentifier): identifier is PrometheusRuleIdentifier { 65 return 'ruleHash' in identifier; 66} 67 68export function alertStateToReadable(state: PromAlertingRuleState | GrafanaAlertState | AlertState): string { 69 if (state === PromAlertingRuleState.Inactive) { 70 return 'Normal'; 71 } 72 return capitalize(state); 73} 74 75export const flattenRules = (rules: RuleNamespace[]) => { 76 return rules.reduce<PromRuleWithLocation[]>((acc, { dataSourceName, name: namespaceName, groups }) => { 77 groups.forEach(({ name: groupName, rules }) => { 78 rules.forEach((rule) => { 79 if (isAlertingRule(rule)) { 80 acc.push({ dataSourceName, namespaceName, groupName, rule }); 81 } 82 }); 83 }); 84 return acc; 85 }, []); 86}; 87 88export const alertStateToState: Record<PromAlertingRuleState | GrafanaAlertState | AlertState, State> = { 89 [PromAlertingRuleState.Inactive]: 'good', 90 [PromAlertingRuleState.Firing]: 'bad', 91 [PromAlertingRuleState.Pending]: 'warning', 92 [GrafanaAlertState.Alerting]: 'bad', 93 [GrafanaAlertState.Error]: 'bad', 94 [GrafanaAlertState.NoData]: 'info', 95 [GrafanaAlertState.Normal]: 'good', 96 [GrafanaAlertState.Pending]: 'warning', 97 [AlertState.NoData]: 'info', 98 [AlertState.Paused]: 'warning', 99 [AlertState.Alerting]: 'bad', 100 [AlertState.OK]: 'good', 101 [AlertState.Pending]: 'warning', 102 [AlertState.Unknown]: 'info', 103}; 104 105export function getFirstActiveAt(promRule: AlertingRule) { 106 if (!promRule.alerts) { 107 return null; 108 } 109 return promRule.alerts.reduce((prev, alert) => { 110 if (alert.activeAt && alert.state !== GrafanaAlertState.Normal) { 111 const activeAt = new Date(alert.activeAt); 112 if (prev === null || prev.getTime() > activeAt.getTime()) { 113 return activeAt; 114 } 115 } 116 return prev; 117 }, null as Date | null); 118} 119