Cloudwatch: fix template variables in variable queries (#48140)

This commit is contained in:
Isabella Siu 2022-04-25 10:33:49 -04:00 committed by GitHub
parent ea25f7e1ca
commit 801a2a240a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 12 deletions

View File

@ -47,7 +47,7 @@ export function setupMockedDataSource({ data = [], variables }: { data?: any; va
const fetchMock = jest.fn().mockReturnValue(of({ data })); const fetchMock = jest.fn().mockReturnValue(of({ data }));
setBackendSrv({ fetch: fetchMock } as any); setBackendSrv({ fetch: fetchMock } as any);
return { datasource, fetchMock }; return { datasource, fetchMock, templateService };
} }
export const metricVariable: CustomVariableModel = { export const metricVariable: CustomVariableModel = {
@ -125,3 +125,19 @@ export const aggregationvariable: CustomVariableModel = {
], ],
multi: false, multi: false,
}; };
export const dimensionVariable: CustomVariableModel = {
...initialCustomVariableModelState,
id: 'dimension',
name: 'dimension',
current: {
value: 'env',
text: 'env',
selected: true,
},
options: [
{ value: 'env', text: 'env', selected: false },
{ value: 'tag', text: 'tag', selected: false },
],
multi: false,
};

View File

@ -125,7 +125,7 @@ export class CloudWatchDatasource
this.logsTimeout = instanceSettings.jsonData.logsTimeout || '15m'; this.logsTimeout = instanceSettings.jsonData.logsTimeout || '15m';
this.sqlCompletionItemProvider = new SQLCompletionItemProvider(this, this.templateSrv); this.sqlCompletionItemProvider = new SQLCompletionItemProvider(this, this.templateSrv);
this.metricMathCompletionItemProvider = new MetricMathCompletionItemProvider(this, this.templateSrv); this.metricMathCompletionItemProvider = new MetricMathCompletionItemProvider(this, this.templateSrv);
this.variables = new CloudWatchVariableSupport(this); this.variables = new CloudWatchVariableSupport(this, this.templateSrv);
} }
query(options: DataQueryRequest<CloudWatchQuery>): Observable<DataQueryResponse> { query(options: DataQueryRequest<CloudWatchQuery>): Observable<DataQueryResponse> {

View File

@ -1,4 +1,4 @@
import { setupMockedDataSource } from './__mocks__/CloudWatchDataSource'; import { dimensionVariable, labelsVariable, setupMockedDataSource } from './__mocks__/CloudWatchDataSource';
import { VariableQuery, VariableQueryType } from './types'; import { VariableQuery, VariableQueryType } from './types';
import { CloudWatchVariableSupport } from './variables'; import { CloudWatchVariableSupport } from './variables';
@ -16,7 +16,7 @@ const defaultQuery: VariableQuery = {
refId: '', refId: '',
}; };
const ds = setupMockedDataSource(); const ds = setupMockedDataSource({ variables: [labelsVariable, dimensionVariable] });
ds.datasource.getRegions = jest.fn().mockResolvedValue([{ label: 'a', value: 'a' }]); ds.datasource.getRegions = jest.fn().mockResolvedValue([{ label: 'a', value: 'a' }]);
ds.datasource.getNamespaces = jest.fn().mockResolvedValue([{ label: 'b', value: 'b' }]); ds.datasource.getNamespaces = jest.fn().mockResolvedValue([{ label: 'b', value: 'b' }]);
ds.datasource.getMetrics = jest.fn().mockResolvedValue([{ label: 'c', value: 'c' }]); ds.datasource.getMetrics = jest.fn().mockResolvedValue([{ label: 'c', value: 'c' }]);
@ -26,7 +26,7 @@ const getEbsVolumeIds = jest.fn().mockResolvedValue([{ label: 'f', value: 'f' }]
const getEc2InstanceAttribute = jest.fn().mockResolvedValue([{ label: 'g', value: 'g' }]); const getEc2InstanceAttribute = jest.fn().mockResolvedValue([{ label: 'g', value: 'g' }]);
const getResourceARNs = jest.fn().mockResolvedValue([{ label: 'h', value: 'h' }]); const getResourceARNs = jest.fn().mockResolvedValue([{ label: 'h', value: 'h' }]);
const variables = new CloudWatchVariableSupport(ds.datasource); const variables = new CloudWatchVariableSupport(ds.datasource, ds.templateService);
describe('variables', () => { describe('variables', () => {
it('should run regions', async () => { it('should run regions', async () => {
@ -114,7 +114,7 @@ describe('variables', () => {
...defaultQuery, ...defaultQuery,
queryType: VariableQueryType.EC2InstanceAttributes, queryType: VariableQueryType.EC2InstanceAttributes,
attributeName: 'abc', attributeName: 'abc',
ec2Filters: '{"a":["b"]}', ec2Filters: '{"$dimension":["b"]}',
}; };
beforeEach(() => { beforeEach(() => {
ds.datasource.getEc2InstanceAttribute = getEc2InstanceAttribute; ds.datasource.getEc2InstanceAttribute = getEc2InstanceAttribute;
@ -129,7 +129,7 @@ describe('variables', () => {
it('should run if instance id set', async () => { it('should run if instance id set', async () => {
const result = await variables.execute(query); const result = await variables.execute(query);
expect(getEc2InstanceAttribute).toBeCalledWith(query.region, query.attributeName, { a: ['b'] }); expect(getEc2InstanceAttribute).toBeCalledWith(query.region, query.attributeName, { env: ['b'] });
expect(result).toEqual([{ text: 'g', value: 'g', expandable: true }]); expect(result).toEqual([{ text: 'g', value: 'g', expandable: true }]);
}); });
}); });
@ -139,7 +139,7 @@ describe('variables', () => {
...defaultQuery, ...defaultQuery,
queryType: VariableQueryType.ResourceArns, queryType: VariableQueryType.ResourceArns,
resourceType: 'abc', resourceType: 'abc',
tags: '{"a":["b"]}', tags: '{"a":${labels:json}}',
}; };
beforeEach(() => { beforeEach(() => {
ds.datasource.getResourceARNs = getResourceARNs; ds.datasource.getResourceARNs = getResourceARNs;
@ -154,7 +154,7 @@ describe('variables', () => {
it('should run if instance id set', async () => { it('should run if instance id set', async () => {
const result = await variables.execute(query); const result = await variables.execute(query);
expect(getResourceARNs).toBeCalledWith(query.region, query.resourceType, { a: ['b'] }); expect(getResourceARNs).toBeCalledWith(query.region, query.resourceType, { a: ['InstanceId', 'InstanceType'] });
expect(result).toEqual([{ text: 'h', value: 'h', expandable: true }]); expect(result).toEqual([{ text: 'h', value: 'h', expandable: true }]);
}); });
}); });

View File

@ -2,6 +2,7 @@ import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data'; import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data';
import { getTemplateSrv, TemplateSrv } from '@grafana/runtime';
import { VariableQueryEditor } from './components/VariableQueryEditor/VariableQueryEditor'; import { VariableQueryEditor } from './components/VariableQueryEditor/VariableQueryEditor';
import { CloudWatchDatasource } from './datasource'; import { CloudWatchDatasource } from './datasource';
@ -10,10 +11,12 @@ import { VariableQuery, VariableQueryType } from './types';
export class CloudWatchVariableSupport extends CustomVariableSupport<CloudWatchDatasource, VariableQuery> { export class CloudWatchVariableSupport extends CustomVariableSupport<CloudWatchDatasource, VariableQuery> {
private readonly datasource: CloudWatchDatasource; private readonly datasource: CloudWatchDatasource;
private readonly templateSrv: TemplateSrv;
constructor(datasource: CloudWatchDatasource) { constructor(datasource: CloudWatchDatasource, templateSrv: TemplateSrv = getTemplateSrv()) {
super(); super();
this.datasource = datasource; this.datasource = datasource;
this.templateSrv = templateSrv;
this.query = this.query.bind(this); this.query = this.query.bind(this);
} }
@ -124,7 +127,7 @@ export class CloudWatchVariableSupport extends CustomVariableSupport<CloudWatchD
} }
let filterJson = {}; let filterJson = {};
if (ec2Filters) { if (ec2Filters) {
filterJson = JSON.parse(ec2Filters); filterJson = JSON.parse(this.templateSrv.replace(ec2Filters));
} }
const values = await this.datasource.getEc2InstanceAttribute(region, attributeName, filterJson); const values = await this.datasource.getEc2InstanceAttribute(region, attributeName, filterJson);
return values.map((s: { label: string; value: string }) => ({ return values.map((s: { label: string; value: string }) => ({
@ -140,7 +143,7 @@ export class CloudWatchVariableSupport extends CustomVariableSupport<CloudWatchD
} }
let tagJson = {}; let tagJson = {};
if (tags) { if (tags) {
tagJson = JSON.parse(tags); tagJson = JSON.parse(this.templateSrv.replace(tags));
} }
const keys = await this.datasource.getResourceARNs(region, resourceType, tagJson); const keys = await this.datasource.getResourceARNs(region, resourceType, tagJson);
return keys.map((s: { label: string; value: string }) => ({ return keys.map((s: { label: string; value: string }) => ({