Plugins: InfluxDB variable interpolation fix for influxdbBackendMigration feature flag (#51624) (#51834)
(cherry picked from commit 9941e06e22)
Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>
This commit is contained in:
co-authored by
ismail simsek
parent
62e0a2c561
commit
a35e7f0bf5
@@ -5,6 +5,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AnnotationEvent,
|
AnnotationEvent,
|
||||||
|
AnnotationQueryRequest,
|
||||||
ArrayVector,
|
ArrayVector,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
DataQueryError,
|
DataQueryError,
|
||||||
@@ -21,7 +22,6 @@ import {
|
|||||||
TIME_SERIES_TIME_FIELD_NAME,
|
TIME_SERIES_TIME_FIELD_NAME,
|
||||||
TIME_SERIES_VALUE_FIELD_NAME,
|
TIME_SERIES_VALUE_FIELD_NAME,
|
||||||
TimeSeries,
|
TimeSeries,
|
||||||
AnnotationQueryRequest,
|
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import {
|
import {
|
||||||
BackendDataSourceResponse,
|
BackendDataSourceResponse,
|
||||||
@@ -240,7 +240,7 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
|
|||||||
if (this.isFlux) {
|
if (this.isFlux) {
|
||||||
return {
|
return {
|
||||||
...query,
|
...query,
|
||||||
query: this.templateSrv.replace(query.query ?? '', rest), // The raw query text
|
query: this.templateSrv.replace(query.query ?? '', rest, 'regex'), // The raw query text
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
|
|||||||
const target: InfluxQuery = {
|
const target: InfluxQuery = {
|
||||||
refId: 'metricFindQuery',
|
refId: 'metricFindQuery',
|
||||||
datasource: this.getRef(),
|
datasource: this.getRef(),
|
||||||
query: this.templateSrv.replace(options.annotation.query ?? ''),
|
query: this.templateSrv.replace(options.annotation.query ?? '', undefined, 'regex'),
|
||||||
rawQuery: true,
|
rawQuery: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -426,7 +426,7 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
|
|||||||
return {
|
return {
|
||||||
...query,
|
...query,
|
||||||
datasource: this.getRef(),
|
datasource: this.getRef(),
|
||||||
query: this.templateSrv.replace(query.query ?? '', scopedVars), // The raw query text
|
query: this.templateSrv.replace(query.query ?? '', scopedVars, 'regex'), // The raw query text
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,7 +475,7 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...expandedQuery,
|
...expandedQuery,
|
||||||
query: this.templateSrv.replace(query.query ?? '', rest), // The raw query text
|
query: this.templateSrv.replace(query.query ?? '', rest, 'regex'), // The raw query text
|
||||||
alias: this.templateSrv.replace(query.alias ?? '', scopedVars),
|
alias: this.templateSrv.replace(query.alias ?? '', scopedVars),
|
||||||
limit: this.templateSrv.replace(query.limit?.toString() ?? '', scopedVars, 'regex'),
|
limit: this.templateSrv.replace(query.limit?.toString() ?? '', scopedVars, 'regex'),
|
||||||
measurement: this.templateSrv.replace(query.measurement ?? '', scopedVars, 'regex'),
|
measurement: this.templateSrv.replace(query.measurement ?? '', scopedVars, 'regex'),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { lastValueFrom, of } from 'rxjs';
|
import { lastValueFrom, of } from 'rxjs';
|
||||||
import { TemplateSrvStub } from 'test/specs/helpers';
|
import { TemplateSrvStub } from 'test/specs/helpers';
|
||||||
|
|
||||||
|
import { ScopedVars } from '@grafana/data/src';
|
||||||
import { FetchResponse } from '@grafana/runtime';
|
import { FetchResponse } from '@grafana/runtime';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
|
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
|
||||||
@@ -177,15 +178,31 @@ describe('InfluxDataSource', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Variables should be interpolated correctly', () => {
|
describe('Variables should be interpolated correctly', () => {
|
||||||
const templateSrv: any = { replace: jest.fn() };
|
|
||||||
const instanceSettings: any = {};
|
const instanceSettings: any = {};
|
||||||
const ds = new InfluxDatasource(instanceSettings, templateSrv);
|
|
||||||
const text = 'interpolationText';
|
const text = 'interpolationText';
|
||||||
templateSrv.replace.mockReturnValue(text);
|
const text2 = 'interpolationText2';
|
||||||
|
const textWithoutFormatRegex = 'interpolationText,interpolationText2';
|
||||||
|
const textWithFormatRegex = 'interpolationText|interpolationText2';
|
||||||
|
const variableMap: Record<string, string> = {
|
||||||
|
$interpolationVar: text,
|
||||||
|
$interpolationVar2: text2,
|
||||||
|
};
|
||||||
|
const templateSrv: any = {
|
||||||
|
replace: jest.fn((target?: string, scopedVars?: ScopedVars, format?: string | Function): string => {
|
||||||
|
if (!format) {
|
||||||
|
return variableMap[target!] || '';
|
||||||
|
}
|
||||||
|
if (format === 'regex') {
|
||||||
|
return textWithFormatRegex;
|
||||||
|
}
|
||||||
|
return textWithoutFormatRegex;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
const ds = new InfluxDatasource(instanceSettings, templateSrv);
|
||||||
|
|
||||||
const fluxQuery = {
|
const fluxQuery = {
|
||||||
refId: 'x',
|
refId: 'x',
|
||||||
query: '$interpolationVar',
|
query: '$interpolationVar,$interpolationVar2',
|
||||||
};
|
};
|
||||||
|
|
||||||
const influxQuery = {
|
const influxQuery = {
|
||||||
@@ -200,7 +217,7 @@ describe('InfluxDataSource', () => {
|
|||||||
{
|
{
|
||||||
key: 'cpu',
|
key: 'cpu',
|
||||||
operator: '=~',
|
operator: '=~',
|
||||||
value: '/^$interpolationVar$/',
|
value: '/^$interpolationVar,$interpolationVar2$/',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
groupBy: [
|
groupBy: [
|
||||||
@@ -221,20 +238,20 @@ describe('InfluxDataSource', () => {
|
|||||||
|
|
||||||
function fluxChecks(query: any) {
|
function fluxChecks(query: any) {
|
||||||
expect(templateSrv.replace).toBeCalledTimes(1);
|
expect(templateSrv.replace).toBeCalledTimes(1);
|
||||||
expect(query).toBe(text);
|
expect(query).toBe(textWithFormatRegex);
|
||||||
}
|
}
|
||||||
|
|
||||||
function influxChecks(query: any) {
|
function influxChecks(query: any) {
|
||||||
expect(templateSrv.replace).toBeCalledTimes(10);
|
expect(templateSrv.replace).toBeCalledTimes(10);
|
||||||
expect(query.alias).toBe(text);
|
expect(query.alias).toBe(text);
|
||||||
expect(query.measurement).toBe(text);
|
expect(query.measurement).toBe(textWithFormatRegex);
|
||||||
expect(query.policy).toBe(text);
|
expect(query.policy).toBe(textWithFormatRegex);
|
||||||
expect(query.limit).toBe(text);
|
expect(query.limit).toBe(textWithFormatRegex);
|
||||||
expect(query.slimit).toBe(text);
|
expect(query.slimit).toBe(textWithFormatRegex);
|
||||||
expect(query.tz).toBe(text);
|
expect(query.tz).toBe(text);
|
||||||
expect(query.tags![0].value).toBe(text);
|
expect(query.tags![0].value).toBe(textWithFormatRegex);
|
||||||
expect(query.groupBy![0].params![0]).toBe(text);
|
expect(query.groupBy![0].params![0]).toBe(textWithFormatRegex);
|
||||||
expect(query.select![0][0].params![0]).toBe(text);
|
expect(query.select![0][0].params![0]).toBe(textWithFormatRegex);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('when interpolating query variables for dashboard->explore', () => {
|
describe('when interpolating query variables for dashboard->explore', () => {
|
||||||
@@ -242,6 +259,7 @@ describe('InfluxDataSource', () => {
|
|||||||
ds.isFlux = true;
|
ds.isFlux = true;
|
||||||
const queries = ds.interpolateVariablesInQueries([fluxQuery], {
|
const queries = ds.interpolateVariablesInQueries([fluxQuery], {
|
||||||
interpolationVar: { text: text, value: text },
|
interpolationVar: { text: text, value: text },
|
||||||
|
interpolationVar2: { text: text2, value: text2 },
|
||||||
});
|
});
|
||||||
fluxChecks(queries[0].query);
|
fluxChecks(queries[0].query);
|
||||||
});
|
});
|
||||||
@@ -250,6 +268,7 @@ describe('InfluxDataSource', () => {
|
|||||||
ds.isFlux = false;
|
ds.isFlux = false;
|
||||||
const queries = ds.interpolateVariablesInQueries([influxQuery], {
|
const queries = ds.interpolateVariablesInQueries([influxQuery], {
|
||||||
interpolationVar: { text: text, value: text },
|
interpolationVar: { text: text, value: text },
|
||||||
|
interpolationVar2: { text: text2, value: text2 },
|
||||||
});
|
});
|
||||||
influxChecks(queries[0]);
|
influxChecks(queries[0]);
|
||||||
});
|
});
|
||||||
@@ -258,7 +277,12 @@ describe('InfluxDataSource', () => {
|
|||||||
describe('when interpolating template variables', () => {
|
describe('when interpolating template variables', () => {
|
||||||
it('should apply all template variables with Flux mode', () => {
|
it('should apply all template variables with Flux mode', () => {
|
||||||
ds.isFlux = true;
|
ds.isFlux = true;
|
||||||
const query = ds.applyTemplateVariables(fluxQuery, { interpolationVar: { text: text, value: text } });
|
const query = ds.applyTemplateVariables(fluxQuery, {
|
||||||
|
interpolationVar: {
|
||||||
|
text: text,
|
||||||
|
value: text,
|
||||||
|
},
|
||||||
|
});
|
||||||
fluxChecks(query.query);
|
fluxChecks(query.query);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -266,7 +290,10 @@ describe('InfluxDataSource', () => {
|
|||||||
ds.isFlux = false;
|
ds.isFlux = false;
|
||||||
ds.access = 'proxy';
|
ds.access = 'proxy';
|
||||||
config.featureToggles.influxdbBackendMigration = true;
|
config.featureToggles.influxdbBackendMigration = true;
|
||||||
const query = ds.applyTemplateVariables(influxQuery, { interpolationVar: { text: text, value: text } });
|
const query = ds.applyTemplateVariables(influxQuery, {
|
||||||
|
interpolationVar: { text: text, value: text },
|
||||||
|
interpolationVar2: { text: 'interpolationText2', value: 'interpolationText2' },
|
||||||
|
});
|
||||||
influxChecks(query);
|
influxChecks(query);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user