mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AzureMonitor: Ensure original query properties are included unchanged (#49642)
* Ensure original query properties are included unchanged * Remove refId from pseudo datasources * Include testing for interpolateVariablesInQueries - Add util function to create template variables - Update mock query with missing props - Additional tests on each ds for template variables * Correct typo and add explicit check for datasource
This commit is contained in:
parent
1308e28d8b
commit
c8094b33cd
@ -7,10 +7,12 @@ export default function createMockQuery(): AzureMonitorQuery {
|
|||||||
'//change this example to create your own time series query\n<table name> //the table to query (e.g. Usage, Heartbeat, Perf)\n| where $__timeFilter(TimeGenerated) //this is a macro used to show the full chart’s time range, choose the datetime column here\n| summarize count() by <group by column>, bin(TimeGenerated, $__interval) //change “group by column” to a column in your table, such as “Computer”. The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.\n| order by TimeGenerated asc',
|
'//change this example to create your own time series query\n<table name> //the table to query (e.g. Usage, Heartbeat, Perf)\n| where $__timeFilter(TimeGenerated) //this is a macro used to show the full chart’s time range, choose the datetime column here\n| summarize count() by <group by column>, bin(TimeGenerated, $__interval) //change “group by column” to a column in your table, such as “Computer”. The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.\n| order by TimeGenerated asc',
|
||||||
resultFormat: 'time_series',
|
resultFormat: 'time_series',
|
||||||
workspace: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2',
|
workspace: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2',
|
||||||
|
resource: 'test-resource',
|
||||||
},
|
},
|
||||||
|
|
||||||
azureResourceGraph: {
|
azureResourceGraph: {
|
||||||
query: 'Resources | summarize count()',
|
query: 'Resources | summarize count()',
|
||||||
|
resultFormat: 'table',
|
||||||
},
|
},
|
||||||
|
|
||||||
azureMonitor: {
|
azureMonitor: {
|
||||||
@ -36,5 +38,9 @@ export default function createMockQuery(): AzureMonitorQuery {
|
|||||||
refId: 'A',
|
refId: 'A',
|
||||||
subscription: '99999999-cccc-bbbb-aaaa-9106972f9572',
|
subscription: '99999999-cccc-bbbb-aaaa-9106972f9572',
|
||||||
subscriptions: ['99999999-cccc-bbbb-aaaa-9106972f9572'],
|
subscriptions: ['99999999-cccc-bbbb-aaaa-9106972f9572'],
|
||||||
|
datasource: {
|
||||||
|
type: 'grafana-azure-monitor-datasource',
|
||||||
|
uid: 'AAAAA11111BBBBB22222CCCC',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
import { VariableType } from '@grafana/data';
|
||||||
|
import { LoadingState } from '@grafana/data/src/types/data';
|
||||||
|
import { VariableWithOptions } from 'app/features/variables/types';
|
||||||
|
|
||||||
|
interface TemplateableValue {
|
||||||
|
variableName: string;
|
||||||
|
templateVariable: VariableWithOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createTemplateVariables(templateableProps: string[]): Map<string, TemplateableValue> {
|
||||||
|
const templateVariables = new Map<string, TemplateableValue>();
|
||||||
|
templateableProps.map((prop) => {
|
||||||
|
const variableName = prop.replace(/[\[\].]/g, '');
|
||||||
|
const templateVariable = {
|
||||||
|
current: {
|
||||||
|
selected: false,
|
||||||
|
text: `${variableName}-template-variable`,
|
||||||
|
value: `${variableName}-template-variable`,
|
||||||
|
},
|
||||||
|
id: variableName,
|
||||||
|
name: variableName,
|
||||||
|
type: 'textbox' as VariableType,
|
||||||
|
options: [],
|
||||||
|
query: '',
|
||||||
|
rootStateKey: null,
|
||||||
|
global: false,
|
||||||
|
hide: 0,
|
||||||
|
skipUrlSync: false,
|
||||||
|
index: 0,
|
||||||
|
state: 'Done' as LoadingState,
|
||||||
|
error: null,
|
||||||
|
description: null,
|
||||||
|
};
|
||||||
|
templateVariables.set(prop, {
|
||||||
|
variableName,
|
||||||
|
templateVariable,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return templateVariables;
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
|
import { get, set } from 'lodash';
|
||||||
|
|
||||||
import { toUtc } from '@grafana/data';
|
import { toUtc } from '@grafana/data';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
import createMockQuery from '../__mocks__/query';
|
import createMockQuery from '../__mocks__/query';
|
||||||
|
import { createTemplateVariables } from '../__mocks__/utils';
|
||||||
import { singleVariable } from '../__mocks__/variables';
|
import { singleVariable } from '../__mocks__/variables';
|
||||||
import AzureMonitorDatasource from '../datasource';
|
import AzureMonitorDatasource from '../datasource';
|
||||||
import { AzureMonitorQuery, AzureQueryType, DatasourceValidationResult } from '../types';
|
import { AzureMonitorQuery, AzureQueryType, DatasourceValidationResult } from '../types';
|
||||||
@ -369,4 +372,38 @@ describe('AzureLogAnalyticsDatasource', () => {
|
|||||||
expect(laDatasource.filterQuery(query)).toBeFalsy();
|
expect(laDatasource.filterQuery(query)).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('When performing interpolateVariablesInQueries for azure_log_analytics', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
templateSrv.init([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a query unchanged if no template variables are provided', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
query.queryType = AzureQueryType.LogAnalytics;
|
||||||
|
const templatedQuery = ctx.ds.interpolateVariablesInQueries([query], {});
|
||||||
|
expect(templatedQuery[0]).toEqual(query);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a query with any template variables replaced', () => {
|
||||||
|
const templateableProps = ['resource', 'workspace', 'query'];
|
||||||
|
const templateVariables = createTemplateVariables(templateableProps);
|
||||||
|
templateSrv.init(Array.from(templateVariables.values()).map((item) => item.templateVariable));
|
||||||
|
const query = createMockQuery();
|
||||||
|
const azureLogAnalytics: { [index: string]: any } = {};
|
||||||
|
for (const [path, templateVariable] of templateVariables.entries()) {
|
||||||
|
set(azureLogAnalytics, path, `$${templateVariable.variableName}`);
|
||||||
|
}
|
||||||
|
query.queryType = AzureQueryType.LogAnalytics;
|
||||||
|
query.azureLogAnalytics = {
|
||||||
|
...query.azureLogAnalytics,
|
||||||
|
...azureLogAnalytics,
|
||||||
|
};
|
||||||
|
const templatedQuery = ctx.ds.interpolateVariablesInQueries([query], {});
|
||||||
|
expect(templatedQuery[0]).toHaveProperty('datasource');
|
||||||
|
for (const [path, templateVariable] of templateVariables.entries()) {
|
||||||
|
expect(get(templatedQuery[0].azureLogAnalytics, path)).toEqual(templateVariable.templateVariable.current.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -134,7 +134,7 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
|
|||||||
const query = templateSrv.replace(item.query, scopedVars, interpolateVariable);
|
const query = templateSrv.replace(item.query, scopedVars, interpolateVariable);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
refId: target.refId,
|
...target,
|
||||||
queryType: AzureQueryType.LogAnalytics,
|
queryType: AzureQueryType.LogAnalytics,
|
||||||
|
|
||||||
azureLogAnalytics: {
|
azureLogAnalytics: {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { startsWith } from 'lodash';
|
import { startsWith, get, set } from 'lodash';
|
||||||
|
|
||||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
import createMockQuery from '../__mocks__/query';
|
import createMockQuery from '../__mocks__/query';
|
||||||
|
import { createTemplateVariables } from '../__mocks__/utils';
|
||||||
import { singleVariable, subscriptionsVariable } from '../__mocks__/variables';
|
import { singleVariable, subscriptionsVariable } from '../__mocks__/variables';
|
||||||
import AzureMonitorDatasource from '../datasource';
|
import AzureMonitorDatasource from '../datasource';
|
||||||
import { AzureDataSourceJsonData, AzureQueryType, DatasourceValidationResult } from '../types';
|
import { AzureDataSourceJsonData, AzureQueryType, DatasourceValidationResult } from '../types';
|
||||||
@ -259,6 +260,50 @@ describe('AzureMonitorDatasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('When performing interpolateVariablesInQueries for azure_monitor_metrics', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
templateSrv.init([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a query unchanged if no template variables are provided', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
const templatedQuery = ctx.ds.interpolateVariablesInQueries([query], {});
|
||||||
|
expect(templatedQuery[0]).toEqual(query);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a query with any template variables replaced', () => {
|
||||||
|
const templateableProps = [
|
||||||
|
'resourceUri',
|
||||||
|
'resourceGroup',
|
||||||
|
'resourceName',
|
||||||
|
'metricNamespace',
|
||||||
|
'metricDefinition',
|
||||||
|
'timeGrain',
|
||||||
|
'aggregation',
|
||||||
|
'top',
|
||||||
|
'dimensionFilters[0].dimension',
|
||||||
|
'dimensionFilters[0].filters[0]',
|
||||||
|
];
|
||||||
|
const templateVariables = createTemplateVariables(templateableProps);
|
||||||
|
templateSrv.init(Array.from(templateVariables.values()).map((item) => item.templateVariable));
|
||||||
|
const query = createMockQuery();
|
||||||
|
const azureMonitorQuery: { [index: string]: any } = {};
|
||||||
|
for (const [path, templateVariable] of templateVariables.entries()) {
|
||||||
|
set(azureMonitorQuery, path, `$${templateVariable.variableName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
query.azureMonitor = {
|
||||||
|
...query.azureMonitor,
|
||||||
|
...azureMonitorQuery,
|
||||||
|
};
|
||||||
|
const templatedQuery = ctx.ds.interpolateVariablesInQueries([query], {});
|
||||||
|
expect(templatedQuery[0]).toHaveProperty('datasource');
|
||||||
|
for (const [path, templateVariable] of templateVariables.entries()) {
|
||||||
|
expect(get(templatedQuery[0].azureMonitor, path)).toEqual(templateVariable.templateVariable.current.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Legacy Azure Monitor Query Object data fetchers', () => {
|
describe('Legacy Azure Monitor Query Object data fetchers', () => {
|
||||||
describe('When performing getSubscriptions', () => {
|
describe('When performing getSubscriptions', () => {
|
||||||
const response = {
|
const response = {
|
||||||
|
@ -114,7 +114,7 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend<AzureM
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
refId: target.refId,
|
...target,
|
||||||
subscription: subscriptionId,
|
subscription: subscriptionId,
|
||||||
queryType: AzureQueryType.AzureMonitor,
|
queryType: AzureQueryType.AzureMonitor,
|
||||||
azureMonitor: {
|
azureMonitor: {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
import { set, get } from 'lodash';
|
||||||
|
|
||||||
import { backendSrv } from 'app/core/services/backend_srv';
|
import { backendSrv } from 'app/core/services/backend_srv';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
import createMockQuery from '../__mocks__/query';
|
import createMockQuery from '../__mocks__/query';
|
||||||
|
import { createTemplateVariables } from '../__mocks__/utils';
|
||||||
import { multiVariable, singleVariable, subscriptionsVariable } from '../__mocks__/variables';
|
import { multiVariable, singleVariable, subscriptionsVariable } from '../__mocks__/variables';
|
||||||
import AzureMonitorDatasource from '../datasource';
|
import AzureMonitorDatasource from '../datasource';
|
||||||
import { AzureQueryType } from '../types';
|
import { AzureQueryType } from '../types';
|
||||||
@ -13,7 +16,6 @@ const templateSrv = new TemplateSrv({
|
|||||||
getVariableWithName: jest.fn(),
|
getVariableWithName: jest.fn(),
|
||||||
getFilteredVariables: jest.fn(),
|
getFilteredVariables: jest.fn(),
|
||||||
});
|
});
|
||||||
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', () => ({
|
||||||
@ -41,7 +43,48 @@ describe('AzureResourceGraphDatasource', () => {
|
|||||||
ctx.ds = new AzureResourceGraphDatasource(ctx.instanceSettings);
|
ctx.ds = new AzureResourceGraphDatasource(ctx.instanceSettings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('When performing interpolateVariablesInQueries for azure_resource_graph', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
templateSrv.init([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a query unchanged if no template variables are provided', () => {
|
||||||
|
const query = createMockQuery();
|
||||||
|
query.queryType = AzureQueryType.AzureResourceGraph;
|
||||||
|
const templatedQuery = ctx.ds.interpolateVariablesInQueries([query], {});
|
||||||
|
expect(templatedQuery[0]).toEqual(query);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a query with any template variables replaced', () => {
|
||||||
|
const templateableProps = ['query'];
|
||||||
|
const templateVariables = createTemplateVariables(templateableProps);
|
||||||
|
templateSrv.init(Array.from(templateVariables.values()).map((item) => item.templateVariable));
|
||||||
|
const query = createMockQuery();
|
||||||
|
const azureResourceGraph: { [index: string]: any } = {};
|
||||||
|
for (const [path, templateVariable] of templateVariables.entries()) {
|
||||||
|
set(azureResourceGraph, path, `$${templateVariable.variableName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
query.queryType = AzureQueryType.AzureResourceGraph;
|
||||||
|
query.azureResourceGraph = {
|
||||||
|
...query.azureResourceGraph,
|
||||||
|
...azureResourceGraph,
|
||||||
|
};
|
||||||
|
const templatedQuery = ctx.ds.interpolateVariablesInQueries([query], {});
|
||||||
|
expect(templatedQuery[0]).toHaveProperty('datasource');
|
||||||
|
for (const [path, templateVariable] of templateVariables.entries()) {
|
||||||
|
expect(get(templatedQuery[0].azureResourceGraph, path)).toEqual(
|
||||||
|
templateVariable.templateVariable.current.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('When applying template variables', () => {
|
describe('When applying template variables', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
templateSrv.init([subscriptionsVariable, singleVariable, multiVariable]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should expand single value template variable', () => {
|
it('should expand single value template variable', () => {
|
||||||
const target = {
|
const target = {
|
||||||
azureResourceGraph: {
|
azureResourceGraph: {
|
||||||
@ -52,7 +95,6 @@ describe('AzureResourceGraphDatasource', () => {
|
|||||||
expect(ctx.ds.applyTemplateVariables(target)).toStrictEqual({
|
expect(ctx.ds.applyTemplateVariables(target)).toStrictEqual({
|
||||||
azureResourceGraph: { query: 'Resources | var1-foo', resultFormat: 'table' },
|
azureResourceGraph: { query: 'Resources | var1-foo', resultFormat: 'table' },
|
||||||
queryType: 'Azure Resource Graph',
|
queryType: 'Azure Resource Graph',
|
||||||
refId: undefined,
|
|
||||||
subscriptions: [],
|
subscriptions: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -70,7 +112,6 @@ describe('AzureResourceGraphDatasource', () => {
|
|||||||
resultFormat: 'table',
|
resultFormat: 'table',
|
||||||
},
|
},
|
||||||
queryType: 'Azure Resource Graph',
|
queryType: 'Azure Resource Graph',
|
||||||
refId: undefined,
|
|
||||||
subscriptions: [],
|
subscriptions: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -90,7 +131,6 @@ describe('AzureResourceGraphDatasource', () => {
|
|||||||
resultFormat: 'table',
|
resultFormat: 'table',
|
||||||
},
|
},
|
||||||
queryType: 'Azure Resource Graph',
|
queryType: 'Azure Resource Graph',
|
||||||
refId: undefined,
|
|
||||||
subscriptions: ['sub-foo', 'sub-baz'],
|
subscriptions: ['sub-foo', 'sub-baz'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -35,7 +35,7 @@ export default class AzureResourceGraphDatasource extends DataSourceWithBackend<
|
|||||||
const query = templateSrv.replace(item.query, scopedVars, interpolateVariable);
|
const query = templateSrv.replace(item.query, scopedVars, interpolateVariable);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
refId: target.refId,
|
...target,
|
||||||
queryType: AzureQueryType.AzureResourceGraph,
|
queryType: AzureQueryType.AzureResourceGraph,
|
||||||
subscriptions,
|
subscriptions,
|
||||||
azureResourceGraph: {
|
azureResourceGraph: {
|
||||||
|
Loading…
Reference in New Issue
Block a user