mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Azure monitor: Make sure alert rule editor is not enabled when template variables are being used (#41335)
* check if variable exist in query * add tests * pr feedback
This commit is contained in:
parent
cbc00babe4
commit
07754351b7
@ -0,0 +1,51 @@
|
|||||||
|
import { CustomVariableModel, initialVariableModelState, VariableHide } from 'app/features/variables/types';
|
||||||
|
|
||||||
|
export const subscriptionsVariable: CustomVariableModel = {
|
||||||
|
...initialVariableModelState,
|
||||||
|
id: 'subs',
|
||||||
|
name: 'subs',
|
||||||
|
index: 3,
|
||||||
|
current: { value: ['sub-foo', 'sub-baz'], text: 'sub-foo + sub-baz', selected: true },
|
||||||
|
options: [
|
||||||
|
{ selected: true, value: 'sub-foo', text: 'sub-foo' },
|
||||||
|
{ selected: false, value: 'sub-bar', text: 'sub-bar' },
|
||||||
|
{ selected: true, value: 'sub-baz', text: 'sub-baz' },
|
||||||
|
],
|
||||||
|
multi: true,
|
||||||
|
includeAll: false,
|
||||||
|
query: '',
|
||||||
|
hide: VariableHide.dontHide,
|
||||||
|
type: 'custom',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const singleVariable: CustomVariableModel = {
|
||||||
|
...initialVariableModelState,
|
||||||
|
id: 'var1',
|
||||||
|
name: 'var1',
|
||||||
|
index: 0,
|
||||||
|
current: { value: 'var1-foo', text: 'var1-foo', selected: true },
|
||||||
|
options: [{ value: 'var1-foo', text: 'var1-foo', selected: true }],
|
||||||
|
multi: false,
|
||||||
|
includeAll: false,
|
||||||
|
query: '',
|
||||||
|
hide: VariableHide.dontHide,
|
||||||
|
type: 'custom',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const multiVariable: CustomVariableModel = {
|
||||||
|
...initialVariableModelState,
|
||||||
|
id: 'var3',
|
||||||
|
name: 'var3',
|
||||||
|
index: 2,
|
||||||
|
current: { value: ['var3-foo', 'var3-baz'], text: 'var3-foo + var3-baz', selected: true },
|
||||||
|
options: [
|
||||||
|
{ selected: true, value: 'var3-foo', text: 'var3-foo' },
|
||||||
|
{ selected: false, value: 'var3-bar', text: 'var3-bar' },
|
||||||
|
{ selected: true, value: 'var3-baz', text: 'var3-baz' },
|
||||||
|
],
|
||||||
|
multi: true,
|
||||||
|
includeAll: false,
|
||||||
|
query: '',
|
||||||
|
hide: VariableHide.dontHide,
|
||||||
|
type: 'custom',
|
||||||
|
};
|
@ -2,8 +2,10 @@ import AzureMonitorDatasource from '../datasource';
|
|||||||
import AzureLogAnalyticsDatasource from './azure_log_analytics_datasource';
|
import AzureLogAnalyticsDatasource from './azure_log_analytics_datasource';
|
||||||
import FakeSchemaData from './__mocks__/schema';
|
import FakeSchemaData from './__mocks__/schema';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { AzureMonitorQuery, DatasourceValidationResult } from '../types';
|
import { AzureMonitorQuery, AzureQueryType, DatasourceValidationResult } from '../types';
|
||||||
import { toUtc } from '@grafana/data';
|
import { toUtc } from '@grafana/data';
|
||||||
|
import createMockQuery from '../__mocks__/query';
|
||||||
|
import { singleVariable } from '../__mocks__/variables';
|
||||||
|
|
||||||
const templateSrv = new TemplateSrv();
|
const templateSrv = new TemplateSrv();
|
||||||
|
|
||||||
@ -227,6 +229,37 @@ describe('AzureLogAnalyticsDatasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('When performing targetContainsTemplate', () => {
|
||||||
|
it('should return false when no variable is being used', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings);
|
||||||
|
query.queryType = AzureQueryType.LogAnalytics;
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true when resource field is using a variable', () => {
|
||||||
|
const templateSrv = new TemplateSrv();
|
||||||
|
const query = createMockQuery();
|
||||||
|
templateSrv.init([singleVariable]);
|
||||||
|
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings, templateSrv);
|
||||||
|
query.queryType = AzureQueryType.LogAnalytics;
|
||||||
|
query.azureLogAnalytics = { resource: `$${singleVariable.name}` };
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when a variable is used in a different part of the query', () => {
|
||||||
|
const templateSrv = new TemplateSrv();
|
||||||
|
const query = createMockQuery();
|
||||||
|
templateSrv.init([singleVariable]);
|
||||||
|
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings, templateSrv);
|
||||||
|
query.queryType = AzureQueryType.LogAnalytics;
|
||||||
|
query.azureResourceGraph = { query: `$${singleVariable.name}` };
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('When performing filterQuery', () => {
|
describe('When performing filterQuery', () => {
|
||||||
const ctx: any = {};
|
const ctx: any = {};
|
||||||
let laDatasource: AzureLogAnalyticsDatasource;
|
let laDatasource: AzureLogAnalyticsDatasource;
|
||||||
|
@ -2,7 +2,9 @@ import AzureMonitorDatasource from '../datasource';
|
|||||||
|
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||||
import { AzureDataSourceJsonData, DatasourceValidationResult } from '../types';
|
import { AzureDataSourceJsonData, AzureQueryType, DatasourceValidationResult } from '../types';
|
||||||
|
import createMockQuery from '../__mocks__/query';
|
||||||
|
import { singleVariable, subscriptionsVariable } from '../__mocks__/variables';
|
||||||
|
|
||||||
const templateSrv = new TemplateSrv();
|
const templateSrv = new TemplateSrv();
|
||||||
|
|
||||||
@ -485,6 +487,36 @@ describe('AzureMonitorDatasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('When performing targetContainsTemplate', () => {
|
||||||
|
it('should return false when no variable is being used', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
query.queryType = AzureQueryType.AzureMonitor;
|
||||||
|
expect(ctx.ds.targetContainsTemplate(query)).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true when subscriptions field is using a variable', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
const templateSrv = new TemplateSrv();
|
||||||
|
templateSrv.init([subscriptionsVariable]);
|
||||||
|
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings, templateSrv);
|
||||||
|
query.queryType = AzureQueryType.AzureMonitor;
|
||||||
|
query.subscription = `$${subscriptionsVariable.name}`;
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when a variable is used in a different part of the query', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
const templateSrv = new TemplateSrv();
|
||||||
|
templateSrv.init([singleVariable]);
|
||||||
|
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings, templateSrv);
|
||||||
|
query.queryType = AzureQueryType.AzureMonitor;
|
||||||
|
query.azureLogAnalytics = { resource: `$${singleVariable.name}` };
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should return an empty array for a Metric that does not have dimensions', () => {
|
it('should return an empty array for a Metric that does not have dimensions', () => {
|
||||||
return ctx.ds
|
return ctx.ds
|
||||||
.getMetricMetadata(
|
.getMetricMetadata(
|
||||||
|
@ -1,64 +1,17 @@
|
|||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { backendSrv } from 'app/core/services/backend_srv';
|
import { backendSrv } from 'app/core/services/backend_srv';
|
||||||
import AzureResourceGraphDatasource from './azure_resource_graph_datasource';
|
import AzureResourceGraphDatasource from './azure_resource_graph_datasource';
|
||||||
import { CustomVariableModel, initialVariableModelState, VariableHide } from 'app/features/variables/types';
|
import { multiVariable, singleVariable, subscriptionsVariable } from '../__mocks__/variables';
|
||||||
|
import { AzureQueryType } from '../types';
|
||||||
const single: CustomVariableModel = {
|
import AzureMonitorDatasource from '../datasource';
|
||||||
...initialVariableModelState,
|
import createMockQuery from '../__mocks__/query';
|
||||||
id: 'var1',
|
|
||||||
name: 'var1',
|
|
||||||
index: 0,
|
|
||||||
current: { value: 'var1-foo', text: 'var1-foo', selected: true },
|
|
||||||
options: [{ value: 'var1-foo', text: 'var1-foo', selected: true }],
|
|
||||||
multi: false,
|
|
||||||
includeAll: false,
|
|
||||||
query: '',
|
|
||||||
hide: VariableHide.dontHide,
|
|
||||||
type: 'custom',
|
|
||||||
};
|
|
||||||
|
|
||||||
const multi: CustomVariableModel = {
|
|
||||||
...initialVariableModelState,
|
|
||||||
id: 'var3',
|
|
||||||
name: 'var3',
|
|
||||||
index: 2,
|
|
||||||
current: { value: ['var3-foo', 'var3-baz'], text: 'var3-foo + var3-baz', selected: true },
|
|
||||||
options: [
|
|
||||||
{ selected: true, value: 'var3-foo', text: 'var3-foo' },
|
|
||||||
{ selected: false, value: 'var3-bar', text: 'var3-bar' },
|
|
||||||
{ selected: true, value: 'var3-baz', text: 'var3-baz' },
|
|
||||||
],
|
|
||||||
multi: true,
|
|
||||||
includeAll: false,
|
|
||||||
query: '',
|
|
||||||
hide: VariableHide.dontHide,
|
|
||||||
type: 'custom',
|
|
||||||
};
|
|
||||||
|
|
||||||
const subs: CustomVariableModel = {
|
|
||||||
...initialVariableModelState,
|
|
||||||
id: 'subs',
|
|
||||||
name: 'subs',
|
|
||||||
index: 3,
|
|
||||||
current: { value: ['sub-foo', 'sub-baz'], text: 'sub-foo + sub-baz', selected: true },
|
|
||||||
options: [
|
|
||||||
{ selected: true, value: 'sub-foo', text: 'sub-foo' },
|
|
||||||
{ selected: false, value: 'sub-bar', text: 'sub-bar' },
|
|
||||||
{ selected: true, value: 'sub-baz', text: 'sub-baz' },
|
|
||||||
],
|
|
||||||
multi: true,
|
|
||||||
includeAll: false,
|
|
||||||
query: '',
|
|
||||||
hide: VariableHide.dontHide,
|
|
||||||
type: 'custom',
|
|
||||||
};
|
|
||||||
|
|
||||||
const templateSrv = new TemplateSrv({
|
const templateSrv = new TemplateSrv({
|
||||||
getVariables: () => [subs, single, multi],
|
getVariables: () => [subscriptionsVariable, singleVariable, multiVariable],
|
||||||
getVariableWithName: jest.fn(),
|
getVariableWithName: jest.fn(),
|
||||||
getFilteredVariables: jest.fn(),
|
getFilteredVariables: jest.fn(),
|
||||||
});
|
});
|
||||||
templateSrv.init([subs, single, multi]);
|
templateSrv.init([subscriptionsVariable, singleVariable, multiVariable]);
|
||||||
|
|
||||||
jest.mock('app/core/services/backend_srv');
|
jest.mock('app/core/services/backend_srv');
|
||||||
jest.mock('@grafana/runtime', () => ({
|
jest.mock('@grafana/runtime', () => ({
|
||||||
@ -80,6 +33,7 @@ describe('AzureResourceGraphDatasource', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ctx.instanceSettings = {
|
ctx.instanceSettings = {
|
||||||
url: 'http://azureresourcegraphapi',
|
url: 'http://azureresourcegraphapi',
|
||||||
|
jsonData: { subscriptionId: '9935389e-9122-4ef9-95f9-1513dd24753f', cloudName: 'azuremonitor' },
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.ds = new AzureResourceGraphDatasource(ctx.instanceSettings);
|
ctx.ds = new AzureResourceGraphDatasource(ctx.instanceSettings);
|
||||||
@ -138,4 +92,47 @@ describe('AzureResourceGraphDatasource', () => {
|
|||||||
subscriptions: ['sub-foo', 'sub-baz'],
|
subscriptions: ['sub-foo', 'sub-baz'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('When performing targetContainsTemplate', () => {
|
||||||
|
it('should return false when no variable is being used', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings, templateSrv);
|
||||||
|
query.queryType = AzureQueryType.AzureResourceGraph;
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true when resource field is using a variable', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
const templateSrv = new TemplateSrv();
|
||||||
|
templateSrv.init([singleVariable]);
|
||||||
|
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings, templateSrv);
|
||||||
|
query.queryType = AzureQueryType.AzureResourceGraph;
|
||||||
|
query.azureResourceGraph = { query: `$${singleVariable.name}` };
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true when resource field is using a variable in the subscriptions field', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
const templateSrv = new TemplateSrv();
|
||||||
|
templateSrv.init([multiVariable]);
|
||||||
|
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings, templateSrv);
|
||||||
|
query.queryType = AzureQueryType.AzureResourceGraph;
|
||||||
|
query.subscriptions = [multiVariable.name];
|
||||||
|
query.azureResourceGraph = { query: `$${multiVariable.name}` };
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when a variable is used in a different part of the query', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
const templateSrv = new TemplateSrv();
|
||||||
|
templateSrv.init([singleVariable]);
|
||||||
|
|
||||||
|
const ds = new AzureMonitorDatasource(ctx.instanceSettings, templateSrv);
|
||||||
|
query.queryType = AzureQueryType.AzureResourceGraph;
|
||||||
|
query.azureMonitor = { metricName: `$${singleVariable.name}` };
|
||||||
|
expect(ds.targetContainsTemplate(query)).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ import {
|
|||||||
ScopedVars,
|
ScopedVars,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { forkJoin, Observable, of } from 'rxjs';
|
import { forkJoin, Observable, of } from 'rxjs';
|
||||||
import { getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import InsightsAnalyticsDatasource from './insights_analytics/insights_analytics_datasource';
|
import InsightsAnalyticsDatasource from './insights_analytics/insights_analytics_datasource';
|
||||||
import { datasourceMigrations } from './utils/migrateQuery';
|
import { datasourceMigrations } from './utils/migrateQuery';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
@ -131,6 +131,23 @@ export default class Datasource extends DataSourceApi<AzureMonitorQuery, AzureDa
|
|||||||
return of({ state: LoadingState.Done, data: [] });
|
return of({ state: LoadingState.Done, data: [] });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetContainsTemplate(query: AzureMonitorQuery) {
|
||||||
|
if (query.subscription && this.templateSrv.variableExists(query.subscription)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let subQuery;
|
||||||
|
if (query.queryType === AzureQueryType.AzureMonitor) {
|
||||||
|
subQuery = JSON.stringify(query.azureMonitor);
|
||||||
|
} else if (query.queryType === AzureQueryType.LogAnalytics) {
|
||||||
|
subQuery = JSON.stringify(query.azureLogAnalytics);
|
||||||
|
} else if (query.queryType === AzureQueryType.AzureResourceGraph) {
|
||||||
|
subQuery = JSON.stringify([query.azureResourceGraph, query.subscriptions]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!subQuery && this.templateSrv.variableExists(subQuery);
|
||||||
|
}
|
||||||
|
|
||||||
async annotationQuery(options: any) {
|
async annotationQuery(options: any) {
|
||||||
return this.azureLogAnalyticsDatasource.annotationQuery(options);
|
return this.azureLogAnalyticsDatasource.annotationQuery(options);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user