fix template variable handling
This commit is contained in:
@@ -9,7 +9,11 @@ import { CustomVariableModel } from 'app/features/variables/types';
|
||||
import { TemplateSrvMock } from '../../../../features/templating/template_srv.mock';
|
||||
import { CloudWatchDatasource } from '../datasource';
|
||||
|
||||
export function setupMockedDataSource({ data = [], variables }: { data?: any; variables?: any } = {}) {
|
||||
export function setupMockedDataSource({
|
||||
data = [],
|
||||
variables,
|
||||
mockGetVariableName = true,
|
||||
}: { data?: any; variables?: any; mockGetVariableName?: boolean } = {}) {
|
||||
let templateService = new TemplateSrvMock({
|
||||
region: 'templatedRegion',
|
||||
fields: 'templatedField',
|
||||
@@ -19,7 +23,9 @@ export function setupMockedDataSource({ data = [], variables }: { data?: any; va
|
||||
templateService = new TemplateSrv();
|
||||
templateService.init(variables);
|
||||
templateService.getVariables = jest.fn().mockReturnValue(variables);
|
||||
templateService.getVariableName = (name: string) => name;
|
||||
if (mockGetVariableName) {
|
||||
templateService.getVariableName = (name: string) => name;
|
||||
}
|
||||
}
|
||||
|
||||
const datasource = new CloudWatchDatasource(
|
||||
@@ -125,3 +131,19 @@ export const aggregationvariable: CustomVariableModel = {
|
||||
],
|
||||
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,
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ArrayVector, DataFrame, dataFrameToJSON, dateTime, Field, MutableDataFr
|
||||
import { setDataSourceSrv } from '@grafana/runtime';
|
||||
|
||||
import {
|
||||
dimensionVariable,
|
||||
labelsVariable,
|
||||
limitVariable,
|
||||
metricVariable,
|
||||
@@ -398,6 +399,19 @@ describe('datasource', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('convertMultiFiltersFormat', () => {
|
||||
const ds = setupMockedDataSource({ variables: [labelsVariable, dimensionVariable], mockGetVariableName: false });
|
||||
it('converts keys and values correctly', () => {
|
||||
// the json in this line doesn't matter, but it makes sure that old queries will be parsed
|
||||
const filters = { $dimension: ['b'], a: ['${labels:json}', 'bar'] };
|
||||
const result = ds.datasource.convertMultiFilterFormat(filters);
|
||||
expect(result).toStrictEqual({
|
||||
env: ['b'],
|
||||
a: ['InstanceId', 'InstanceType', 'bar'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLogGroupFields', () => {
|
||||
it('passes region correctly', async () => {
|
||||
const { datasource, fetchMock } = setupMockedDataSource();
|
||||
|
||||
@@ -54,6 +54,7 @@ import {
|
||||
MetricQuery,
|
||||
MetricQueryType,
|
||||
MetricRequest,
|
||||
MultiFilters,
|
||||
StartQueryRequest,
|
||||
TSDBResponse,
|
||||
} from './types';
|
||||
@@ -720,7 +721,7 @@ export class CloudWatchDatasource
|
||||
return this.doMetricResourceRequest('ec2-instance-attribute', {
|
||||
region: this.templateSrv.replace(this.getActualRegion(region)),
|
||||
attributeName: this.templateSrv.replace(attributeName),
|
||||
filters: JSON.stringify(filters),
|
||||
filters: JSON.stringify(this.convertMultiFilterFormat(filters, 'filter key')),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -728,7 +729,7 @@ export class CloudWatchDatasource
|
||||
return this.doMetricResourceRequest('resource-arns', {
|
||||
region: this.templateSrv.replace(this.getActualRegion(region)),
|
||||
resourceType: this.templateSrv.replace(resourceType),
|
||||
tags: JSON.stringify(tags),
|
||||
tags: JSON.stringify(this.convertMultiFilterFormat(tags, 'tag name')),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -836,18 +837,40 @@ export class CloudWatchDatasource
|
||||
return { ...result, [key]: null };
|
||||
}
|
||||
|
||||
const valueVar = this.templateSrv
|
||||
.getVariables()
|
||||
.find(({ name }) => name === this.templateSrv.getVariableName(value));
|
||||
if (valueVar) {
|
||||
if ((valueVar as unknown as VariableWithMultiSupport).multi) {
|
||||
const values = this.templateSrv.replace(value, scopedVars, 'pipe').split('|');
|
||||
return { ...result, [key]: values };
|
||||
}
|
||||
return { ...result, [key]: [this.templateSrv.replace(value, scopedVars)] };
|
||||
}
|
||||
const newValues = this.getVariableValue(value, scopedVars);
|
||||
return { ...result, [key]: newValues };
|
||||
}, {});
|
||||
}
|
||||
|
||||
return { ...result, [key]: [value] };
|
||||
// get the value for a given template variable
|
||||
getVariableValue(value: string, scopedVars: ScopedVars): string[] {
|
||||
const variableName = this.templateSrv.getVariableName(value);
|
||||
const valueVar = this.templateSrv.getVariables().find(({ name }) => {
|
||||
return name === variableName;
|
||||
});
|
||||
if (variableName && valueVar) {
|
||||
if ((valueVar as unknown as VariableWithMultiSupport).multi) {
|
||||
// rebuild the variable name to handle old migrated queries
|
||||
const values = this.templateSrv.replace('$' + variableName, scopedVars, 'pipe').split('|');
|
||||
return values;
|
||||
}
|
||||
return [this.templateSrv.replace(value, scopedVars)];
|
||||
}
|
||||
return [value];
|
||||
}
|
||||
|
||||
convertMultiFilterFormat(multiFilters: MultiFilters, fieldName?: string) {
|
||||
return Object.entries(multiFilters).reduce((result, [key, values]) => {
|
||||
key = this.replace(key, {}, true, fieldName);
|
||||
if (!values) {
|
||||
return { ...result, [key]: null };
|
||||
}
|
||||
const initialVal: string[] = [];
|
||||
const newValues = values.reduce((result, value) => {
|
||||
const vals = this.getVariableValue(value, {});
|
||||
return [...result, ...vals];
|
||||
}, initialVal);
|
||||
return { ...result, [key]: newValues };
|
||||
}, {});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user