mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
MySQL, Postgres, MSSQL: Fix validating query with template variables in alert (#19237)
Adds support for validating query in alert for mysql, postgres and mssql. Fixes #13155
This commit is contained in:
parent
f203e82b40
commit
96046a7ba6
@ -165,4 +165,9 @@ export class MssqlDatasource {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetContainsTemplate(target: any) {
|
||||||
|
const rawSql = target.rawSql.replace('$__', '');
|
||||||
|
return this.templateSrv.variableExists(rawSql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
import { MssqlDatasource } from '../datasource';
|
import { MssqlDatasource } from '../datasource';
|
||||||
import { TemplateSrvStub, TimeSrvStub } from 'test/specs/helpers';
|
import { TimeSrvStub } from 'test/specs/helpers';
|
||||||
import { CustomVariable } from 'app/features/templating/custom_variable';
|
import { CustomVariable } from 'app/features/templating/custom_variable';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import q from 'q';
|
import q from 'q';
|
||||||
import { dateTime } from '@grafana/data';
|
import { dateTime } from '@grafana/data';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
describe('MSSQLDatasource', () => {
|
describe('MSSQLDatasource', () => {
|
||||||
|
const templateSrv: TemplateSrv = new TemplateSrv();
|
||||||
|
|
||||||
const ctx: any = {
|
const ctx: any = {
|
||||||
backendSrv: {},
|
backendSrv: {},
|
||||||
// @ts-ignore
|
|
||||||
templateSrv: new TemplateSrvStub(),
|
|
||||||
timeSrv: new TimeSrvStub(),
|
timeSrv: new TimeSrvStub(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ describe('MSSQLDatasource', () => {
|
|||||||
ctx.$q = q;
|
ctx.$q = q;
|
||||||
ctx.instanceSettings = { name: 'mssql' };
|
ctx.instanceSettings = { name: 'mssql' };
|
||||||
|
|
||||||
ctx.ds = new MssqlDatasource(ctx.instanceSettings, ctx.backendSrv, ctx.$q, ctx.templateSrv, ctx.timeSrv);
|
ctx.ds = new MssqlDatasource(ctx.instanceSettings, ctx.backendSrv, ctx.$q, templateSrv, ctx.timeSrv);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('When performing annotationQuery', () => {
|
describe('When performing annotationQuery', () => {
|
||||||
@ -278,4 +279,51 @@ describe('MSSQLDatasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('targetContainsTemplate', () => {
|
||||||
|
it('given query that contains template variable it should return true', () => {
|
||||||
|
const rawSql = `SELECT
|
||||||
|
$__timeGroup(createdAt,'$summarize') as time,
|
||||||
|
avg(value) as value,
|
||||||
|
hostname as metric
|
||||||
|
FROM
|
||||||
|
grafana_metric
|
||||||
|
WHERE
|
||||||
|
$__timeFilter(createdAt) AND
|
||||||
|
measurement = 'logins.count' AND
|
||||||
|
hostname IN($host)
|
||||||
|
GROUP BY $__timeGroup(createdAt,'$summarize'), hostname
|
||||||
|
ORDER BY 1`;
|
||||||
|
const query = {
|
||||||
|
rawSql,
|
||||||
|
};
|
||||||
|
templateSrv.init([
|
||||||
|
{ type: 'query', name: 'summarize', current: { value: '1m' } },
|
||||||
|
{ type: 'query', name: 'host', current: { value: 'a' } },
|
||||||
|
]);
|
||||||
|
expect(ctx.ds.targetContainsTemplate(query)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('given query that only contains global template variable it should return false', () => {
|
||||||
|
const rawSql = `SELECT
|
||||||
|
$__timeGroup(createdAt,'$__interval') as time,
|
||||||
|
avg(value) as value,
|
||||||
|
hostname as metric
|
||||||
|
FROM
|
||||||
|
grafana_metric
|
||||||
|
WHERE
|
||||||
|
$__timeFilter(createdAt) AND
|
||||||
|
measurement = 'logins.count'
|
||||||
|
GROUP BY $__timeGroup(createdAt,'$summarize'), hostname
|
||||||
|
ORDER BY 1`;
|
||||||
|
const query = {
|
||||||
|
rawSql,
|
||||||
|
};
|
||||||
|
templateSrv.init([
|
||||||
|
{ type: 'query', name: 'summarize', current: { value: '1m' } },
|
||||||
|
{ type: 'query', name: 'host', current: { value: 'a' } },
|
||||||
|
]);
|
||||||
|
expect(ctx.ds.targetContainsTemplate(query)).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -175,4 +175,19 @@ export class MysqlDatasource {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetContainsTemplate(target: any) {
|
||||||
|
let rawSql = '';
|
||||||
|
|
||||||
|
if (target.rawQuery) {
|
||||||
|
rawSql = target.rawSql;
|
||||||
|
} else {
|
||||||
|
const query = new MysqlQuery(target);
|
||||||
|
rawSql = query.buildQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
rawSql = rawSql.replace('$__', '');
|
||||||
|
|
||||||
|
return this.templateSrv.variableExists(rawSql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,12 @@ import { MysqlDatasource } from '../datasource';
|
|||||||
import { CustomVariable } from 'app/features/templating/custom_variable';
|
import { CustomVariable } from 'app/features/templating/custom_variable';
|
||||||
import { toUtc, dateTime } from '@grafana/data';
|
import { toUtc, dateTime } from '@grafana/data';
|
||||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
describe('MySQLDatasource', () => {
|
describe('MySQLDatasource', () => {
|
||||||
const instanceSettings = { name: 'mysql' };
|
const instanceSettings = { name: 'mysql' };
|
||||||
const backendSrv = {};
|
const backendSrv = {};
|
||||||
const templateSrv: any = {
|
const templateSrv: TemplateSrv = new TemplateSrv();
|
||||||
replace: jest.fn(text => text),
|
|
||||||
};
|
|
||||||
|
|
||||||
const raw = {
|
const raw = {
|
||||||
from: toUtc('2018-04-25 10:00'),
|
from: toUtc('2018-04-25 10:00'),
|
||||||
@ -240,4 +239,53 @@ describe('MySQLDatasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('targetContainsTemplate', () => {
|
||||||
|
it('given query that contains template variable it should return true', () => {
|
||||||
|
const rawSql = `SELECT
|
||||||
|
$__timeGroup(createdAt,'$summarize') as time_sec,
|
||||||
|
avg(value) as value,
|
||||||
|
hostname as metric
|
||||||
|
FROM
|
||||||
|
grafana_metric
|
||||||
|
WHERE
|
||||||
|
$__timeFilter(createdAt) AND
|
||||||
|
measurement = 'logins.count' AND
|
||||||
|
hostname IN($host)
|
||||||
|
GROUP BY 1, 3
|
||||||
|
ORDER BY 1`;
|
||||||
|
const query = {
|
||||||
|
rawSql,
|
||||||
|
rawQuery: true,
|
||||||
|
};
|
||||||
|
templateSrv.init([
|
||||||
|
{ type: 'query', name: 'summarize', current: { value: '1m' } },
|
||||||
|
{ type: 'query', name: 'host', current: { value: 'a' } },
|
||||||
|
]);
|
||||||
|
expect(ctx.ds.targetContainsTemplate(query)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('given query that only contains global template variable it should return false', () => {
|
||||||
|
const rawSql = `SELECT
|
||||||
|
$__timeGroup(createdAt,'$__interval') as time_sec,
|
||||||
|
avg(value) as value,
|
||||||
|
hostname as metric
|
||||||
|
FROM
|
||||||
|
grafana_metric
|
||||||
|
WHERE
|
||||||
|
$__timeFilter(createdAt) AND
|
||||||
|
measurement = 'logins.count'
|
||||||
|
GROUP BY 1, 3
|
||||||
|
ORDER BY 1`;
|
||||||
|
const query = {
|
||||||
|
rawSql,
|
||||||
|
rawQuery: true,
|
||||||
|
};
|
||||||
|
templateSrv.init([
|
||||||
|
{ type: 'query', name: 'summarize', current: { value: '1m' } },
|
||||||
|
{ type: 'query', name: 'host', current: { value: 'a' } },
|
||||||
|
]);
|
||||||
|
expect(ctx.ds.targetContainsTemplate(query)).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -160,4 +160,19 @@ export class PostgresDatasource {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetContainsTemplate(target: any) {
|
||||||
|
let rawSql = '';
|
||||||
|
|
||||||
|
if (target.rawQuery) {
|
||||||
|
rawSql = target.rawSql;
|
||||||
|
} else {
|
||||||
|
const query = new PostgresQuery(target);
|
||||||
|
rawSql = query.buildQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
rawSql = rawSql.replace('$__', '');
|
||||||
|
|
||||||
|
return this.templateSrv.variableExists(rawSql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,13 @@ import { CustomVariable } from 'app/features/templating/custom_variable';
|
|||||||
import { toUtc, dateTime } from '@grafana/data';
|
import { toUtc, dateTime } from '@grafana/data';
|
||||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
import { IQService } from 'angular';
|
import { IQService } from 'angular';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
describe('PostgreSQLDatasource', () => {
|
describe('PostgreSQLDatasource', () => {
|
||||||
const instanceSettings = { name: 'postgresql' };
|
const instanceSettings = { name: 'postgresql' };
|
||||||
|
|
||||||
const backendSrv = {};
|
const backendSrv = {};
|
||||||
const templateSrv: any = {
|
const templateSrv: TemplateSrv = new TemplateSrv();
|
||||||
replace: jest.fn(text => text),
|
|
||||||
};
|
|
||||||
const raw = {
|
const raw = {
|
||||||
from: toUtc('2018-04-25 10:00'),
|
from: toUtc('2018-04-25 10:00'),
|
||||||
to: toUtc('2018-04-25 11:00'),
|
to: toUtc('2018-04-25 11:00'),
|
||||||
@ -249,4 +248,53 @@ describe('PostgreSQLDatasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('targetContainsTemplate', () => {
|
||||||
|
it('given query that contains template variable it should return true', () => {
|
||||||
|
const rawSql = `SELECT
|
||||||
|
$__timeGroup("createdAt",'$summarize'),
|
||||||
|
avg(value) as "value",
|
||||||
|
hostname as "metric"
|
||||||
|
FROM
|
||||||
|
grafana_metric
|
||||||
|
WHERE
|
||||||
|
$__timeFilter("createdAt") AND
|
||||||
|
measurement = 'logins.count' AND
|
||||||
|
hostname IN($host)
|
||||||
|
GROUP BY time, metric
|
||||||
|
ORDER BY time`;
|
||||||
|
const query = {
|
||||||
|
rawSql,
|
||||||
|
rawQuery: true,
|
||||||
|
};
|
||||||
|
templateSrv.init([
|
||||||
|
{ type: 'query', name: 'summarize', current: { value: '1m' } },
|
||||||
|
{ type: 'query', name: 'host', current: { value: 'a' } },
|
||||||
|
]);
|
||||||
|
expect(ctx.ds.targetContainsTemplate(query)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('given query that only contains global template variable it should return false', () => {
|
||||||
|
const rawSql = `SELECT
|
||||||
|
$__timeGroup("createdAt",'$__interval'),
|
||||||
|
avg(value) as "value",
|
||||||
|
hostname as "metric"
|
||||||
|
FROM
|
||||||
|
grafana_metric
|
||||||
|
WHERE
|
||||||
|
$__timeFilter("createdAt") AND
|
||||||
|
measurement = 'logins.count'
|
||||||
|
GROUP BY time, metric
|
||||||
|
ORDER BY time`;
|
||||||
|
const query = {
|
||||||
|
rawSql,
|
||||||
|
rawQuery: true,
|
||||||
|
};
|
||||||
|
templateSrv.init([
|
||||||
|
{ type: 'query', name: 'summarize', current: { value: '1m' } },
|
||||||
|
{ type: 'query', name: 'host', current: { value: 'a' } },
|
||||||
|
]);
|
||||||
|
expect(ctx.ds.targetContainsTemplate(query)).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user