InfluxDB: Fix querying with template variables without using regex operator (#84953)
* remove regex wrappers if the operator is not a regex operator * fix import
This commit is contained in:
@@ -44,7 +44,7 @@ import InfluxQueryModel from './influx_query_model';
|
|||||||
import InfluxSeries from './influx_series';
|
import InfluxSeries from './influx_series';
|
||||||
import { buildMetadataQuery } from './influxql_query_builder';
|
import { buildMetadataQuery } from './influxql_query_builder';
|
||||||
import { prepareAnnotation } from './migrations';
|
import { prepareAnnotation } from './migrations';
|
||||||
import { buildRawQuery } from './queryUtils';
|
import { buildRawQuery, removeRegexWrapper } from './queryUtils';
|
||||||
import ResponseParser from './response_parser';
|
import ResponseParser from './response_parser';
|
||||||
import { DEFAULT_POLICY, InfluxOptions, InfluxQuery, InfluxQueryTag, InfluxVersion } from './types';
|
import { DEFAULT_POLICY, InfluxOptions, InfluxQuery, InfluxQueryTag, InfluxVersion } from './types';
|
||||||
|
|
||||||
@@ -262,6 +262,11 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
|
|||||||
|
|
||||||
if (query.tags) {
|
if (query.tags) {
|
||||||
expandedQuery.tags = query.tags.map((tag) => {
|
expandedQuery.tags = query.tags.map((tag) => {
|
||||||
|
// Remove the regex wrapper if the operator is not a regex operator
|
||||||
|
if (tag.operator !== '=~' && tag.operator !== '!~') {
|
||||||
|
tag.value = removeRegexWrapper(tag.value);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...tag,
|
...tag,
|
||||||
key: this.templateSrv.replace(tag.key, scopedVars),
|
key: this.templateSrv.replace(tag.key, scopedVars),
|
||||||
|
|||||||
@@ -218,7 +218,10 @@ describe('InfluxDataSource Backend Mode', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('variable interpolation with chained variables with backend mode', () => {
|
describe('variable interpolation with chained variables with backend mode', () => {
|
||||||
const variablesMock = [queryBuilder().withId('var1').withName('var1').withCurrent('var1').build()];
|
const variablesMock = [
|
||||||
|
queryBuilder().withId('var1').withName('var1').withCurrent('var1').build(),
|
||||||
|
queryBuilder().withId('path').withName('path').withCurrent('/etc/hosts').build(),
|
||||||
|
];
|
||||||
const mockTemplateService = new TemplateSrv({
|
const mockTemplateService = new TemplateSrv({
|
||||||
getVariables: () => variablesMock,
|
getVariables: () => variablesMock,
|
||||||
getVariableWithName: (name: string) => variablesMock.filter((v) => v.name === name)[0],
|
getVariableWithName: (name: string) => variablesMock.filter((v) => v.name === name)[0],
|
||||||
@@ -309,6 +312,22 @@ describe('InfluxDataSource Backend Mode', () => {
|
|||||||
const expected = `/^.*-var1$/`;
|
const expected = `/^.*-var1$/`;
|
||||||
expect(res.tags?.[0].value).toEqual(expected);
|
expect(res.tags?.[0].value).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should remove regex wrappers when operator is not a regex operator', () => {
|
||||||
|
const query: InfluxQuery = {
|
||||||
|
refId: 'A',
|
||||||
|
tags: [
|
||||||
|
{
|
||||||
|
key: 'key',
|
||||||
|
operator: '=',
|
||||||
|
value: '/^$path$/',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const res = ds.applyVariables(query, {});
|
||||||
|
const expected = `/etc/hosts`;
|
||||||
|
expect(res.tags?.[0].value).toEqual(expected);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('metric find query', () => {
|
describe('metric find query', () => {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { filter, find, indexOf, map } from 'lodash';
|
|||||||
import { escapeRegex, ScopedVars } from '@grafana/data';
|
import { escapeRegex, ScopedVars } from '@grafana/data';
|
||||||
import { TemplateSrv } from '@grafana/runtime';
|
import { TemplateSrv } from '@grafana/runtime';
|
||||||
|
|
||||||
|
import { removeRegexWrapper } from './queryUtils';
|
||||||
import queryPart from './query_part';
|
import queryPart from './query_part';
|
||||||
import { DEFAULT_POLICY, InfluxQuery, InfluxQueryTag } from './types';
|
import { DEFAULT_POLICY, InfluxQuery, InfluxQueryTag } from './types';
|
||||||
|
|
||||||
@@ -141,17 +142,6 @@ export default class InfluxQueryModel {
|
|||||||
this.updatePersistedParts();
|
this.updatePersistedParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeRegexWrapper(str: string) {
|
|
||||||
const regex = /\/\^(.*?)\$\//; // match any string that starts with "/^" and ends with "$/", capturing the characters in between
|
|
||||||
const match = str.match(regex);
|
|
||||||
|
|
||||||
if (match && match.length > 1) {
|
|
||||||
return match[1];
|
|
||||||
} else {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private isOperatorTypeHandler(operator: string, value: string, fieldName: string) {
|
private isOperatorTypeHandler(operator: string, value: string, fieldName: string) {
|
||||||
let textValue;
|
let textValue;
|
||||||
if (operator === 'Is Not') {
|
if (operator === 'Is Not') {
|
||||||
@@ -162,7 +152,7 @@ export default class InfluxQueryModel {
|
|||||||
|
|
||||||
// Tags should always quote
|
// Tags should always quote
|
||||||
if (fieldName.endsWith('::tag')) {
|
if (fieldName.endsWith('::tag')) {
|
||||||
textValue = "'" + this.removeRegexWrapper(value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'")) + "'";
|
textValue = "'" + removeRegexWrapper(value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'")) + "'";
|
||||||
return {
|
return {
|
||||||
operator: operator,
|
operator: operator,
|
||||||
value: textValue,
|
value: textValue,
|
||||||
@@ -180,7 +170,7 @@ export default class InfluxQueryModel {
|
|||||||
textValue = lowerValue;
|
textValue = lowerValue;
|
||||||
} else {
|
} else {
|
||||||
// String or unrecognised: quote
|
// String or unrecognised: quote
|
||||||
textValue = "'" + this.removeRegexWrapper(value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'")) + "'";
|
textValue = "'" + removeRegexWrapper(value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'")) + "'";
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
operator: operator,
|
operator: operator,
|
||||||
@@ -210,7 +200,7 @@ export default class InfluxQueryModel {
|
|||||||
if (interpolate) {
|
if (interpolate) {
|
||||||
value = this.templateSrv.replace(value, this.scopedVars);
|
value = this.templateSrv.replace(value, this.scopedVars);
|
||||||
}
|
}
|
||||||
value = this.removeRegexWrapper(value);
|
value = removeRegexWrapper(value);
|
||||||
if (operator.startsWith('Is')) {
|
if (operator.startsWith('Is')) {
|
||||||
let r = this.isOperatorTypeHandler(operator, value, tag.key);
|
let r = this.isOperatorTypeHandler(operator, value, tag.key);
|
||||||
operator = r.operator;
|
operator = r.operator;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
|
|
||||||
import InfluxQueryModel from './influx_query_model';
|
import InfluxQueryModel from './influx_query_model';
|
||||||
import { InfluxQuery } from './types';
|
import { InfluxQuery } from './types'; // FIXME: these functions are a beginning of a refactoring of influx_query_model.ts
|
||||||
|
|
||||||
// FIXME: these functions are a beginning of a refactoring of influx_query_model.ts
|
// FIXME: these functions are a beginning of a refactoring of influx_query_model.ts
|
||||||
// into a simpler approach with full typescript types.
|
// into a simpler approach with full typescript types.
|
||||||
@@ -90,3 +90,14 @@ export function changeGroupByPart(query: InfluxQuery, partIndex: number, newPara
|
|||||||
};
|
};
|
||||||
return { ...query, groupBy: newGroupBy };
|
return { ...query, groupBy: newGroupBy };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function removeRegexWrapper(str: string) {
|
||||||
|
const regex = /\/\^(.*?)\$\//; // match any string that starts with "/^" and ends with "$/", capturing the characters in between
|
||||||
|
const match = str.match(regex);
|
||||||
|
|
||||||
|
if (match && match.length > 1) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user