Alerting: Fall back to "range" query type for unified alerting when "both" is specified (#57288)

reporting/upload-user-per-org
Gilles De Mey 3 years ago committed by GitHub
parent 616db7f68b
commit 2a36301817
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .betterer.results
  2. 59
      public/app/features/alerting/unified/utils/__snapshots__/rule-form.test.ts.snap
  3. 36
      public/app/features/alerting/unified/utils/rule-form.test.ts
  4. 23
      public/app/features/alerting/unified/utils/rule-form.ts
  5. 17
      public/app/plugins/datasource/prometheus/querybuilder/state.test.ts
  6. 6
      public/app/plugins/datasource/prometheus/querybuilder/state.ts

@ -6916,8 +6916,7 @@ exports[`better eslint`] = {
],
"public/app/plugins/datasource/prometheus/querybuilder/state.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/prometheus/querybuilder/state.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]

@ -0,0 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`formValuesToRulerGrafanaRuleDTO should correctly convert rule form values 1`] = `
Object {
"annotations": Object {
"description": "",
"runbook_url": "",
"summary": "",
},
"for": "5m",
"grafana_alert": Object {
"condition": "A",
"data": Array [],
"exec_err_state": "Error",
"no_data_state": "NoData",
"title": "",
},
"labels": Object {
"": "",
},
}
`;
exports[`formValuesToRulerGrafanaRuleDTO should not save both instant and range type queries 1`] = `
Object {
"annotations": Object {
"description": "",
"runbook_url": "",
"summary": "",
},
"for": "5m",
"grafana_alert": Object {
"condition": "A",
"data": Array [
Object {
"datasourceUid": "dsuid",
"model": Object {
"expr": "",
"instant": false,
"range": true,
"refId": "A",
},
"queryType": "query",
"refId": "A",
"relativeTimeRange": Object {
"from": 900,
"to": 1000,
},
},
],
"exec_err_state": "Error",
"no_data_state": "NoData",
"title": "",
},
"labels": Object {
"": "",
},
}
`;

@ -0,0 +1,36 @@
import { PromQuery } from 'app/plugins/datasource/prometheus/types';
import { RuleFormValues } from '../types/rule-form';
import { formValuesToRulerGrafanaRuleDTO, getDefaultFormValues } from './rule-form';
describe('formValuesToRulerGrafanaRuleDTO', () => {
it('should correctly convert rule form values', () => {
const formValues: RuleFormValues = {
...getDefaultFormValues(),
condition: 'A',
};
expect(formValuesToRulerGrafanaRuleDTO(formValues)).toMatchSnapshot();
});
it('should not save both instant and range type queries', () => {
const defaultValues = getDefaultFormValues();
const values: RuleFormValues = {
...defaultValues,
queries: [
{
refId: 'A',
relativeTimeRange: { from: 900, to: 1000 },
datasourceUid: 'dsuid',
model: { refId: 'A', expr: '', instant: true, range: true } as PromQuery,
queryType: 'query',
},
],
condition: 'A',
};
expect(formValuesToRulerGrafanaRuleDTO(values)).toMatchSnapshot();
});
});

@ -14,8 +14,10 @@ import { getNextRefIdChar } from 'app/core/utils/query';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
import { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource';
import { ExpressionQuery, ExpressionQueryType } from 'app/features/expressions/types';
import { PromQuery } from 'app/plugins/datasource/prometheus/types';
import { RuleWithLocation } from 'app/types/unified-alerting';
import {
AlertDataQuery,
AlertQuery,
Annotations,
GrafanaAlertStateDecision,
@ -101,7 +103,7 @@ export function formValuesToRulerGrafanaRuleDTO(values: RuleFormValues): Postabl
condition,
no_data_state: noDataState,
exec_err_state: execErrState,
data: queries,
data: queries.map(fixBothInstantAndRangeQuery),
},
for: evaluateFor,
annotations: arrayToRecord(values.annotations || []),
@ -431,3 +433,22 @@ export function getIntervals(range: TimeRange, lowLimit?: string, resolution?: n
return rangeUtil.calculateInterval(range, resolution, lowLimit);
}
export function fixBothInstantAndRangeQuery(query: AlertQuery) {
const model = query.model;
if (!isPromQuery(model)) {
return query;
}
const isBothInstantAndRange = model.instant && model.range;
if (isBothInstantAndRange) {
return { ...query, model: { ...model, range: true, instant: false } };
}
return query;
}
function isPromQuery(model: AlertDataQuery): model is PromQuery {
return 'expr' in model && 'instant' in model && 'range' in model;
}

@ -1,11 +1,13 @@
import { CoreApp } from '@grafana/data';
import { PromQuery } from '../types';
import { QueryEditorMode } from './shared/types';
import { changeEditorMode, getQueryWithDefaults } from './state';
describe('getQueryWithDefaults(', () => {
it('should set defaults', () => {
expect(getQueryWithDefaults({ refId: 'A' } as any, CoreApp.Dashboard)).toEqual({
expect(getQueryWithDefaults({ refId: 'A' } as PromQuery, CoreApp.Dashboard)).toEqual({
editorMode: 'builder',
expr: '',
legendFormat: '__auto',
@ -25,6 +27,19 @@ describe('getQueryWithDefaults(', () => {
});
});
it('should not set both instant and range for Prometheus queries in Alert Creation', () => {
expect(
getQueryWithDefaults({ refId: 'A', range: true, instant: true } as PromQuery, CoreApp.UnifiedAlerting)
).toEqual({
editorMode: 'builder',
expr: '',
legendFormat: '__auto',
range: true,
instant: false,
refId: 'A',
});
});
it('changing editor mode with blank query should change default', () => {
changeEditorMode({ refId: 'A', expr: '' }, QueryEditorMode.Code, (query) => {
expect(query.editorMode).toBe(QueryEditorMode.Code);

@ -56,5 +56,11 @@ export function getQueryWithDefaults(query: PromQuery, app: CoreApp | undefined)
}
}
// Unified Alerting does not support "both" for query type – fall back to "range".
const isBothInstantAndRange = query.instant && query.range;
if (app === CoreApp.UnifiedAlerting && isBothInstantAndRange) {
result = { ...result, instant: false, range: true };
}
return result;
}

Loading…
Cancel
Save