diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts index 0f8a0db60c7..2bb45b3d321 100644 --- a/public/app/core/utils/explore.ts +++ b/public/app/core/utils/explore.ts @@ -77,12 +77,18 @@ export async function getExploreUrl( if (exploreDatasource) { const range = timeSrv.timeRangeForUrl(); let state: Partial = { range }; - if (exploreDatasource.getExploreState) { - state = { ...state, ...exploreDatasource.getExploreState(exploreTargets) }; + if (exploreDatasource.interpolateVariablesInQueries) { + state = { + ...state, + datasource: exploreDatasource.name, + context: 'explore', + queries: exploreDatasource.interpolateVariablesInQueries(exploreTargets), + }; } else { state = { ...state, datasource: exploreDatasource.name, + context: 'explore', queries: exploreTargets.map(t => ({ ...t, datasource: exploreDatasource.name })), }; } diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index dfebbabe3f1..4ae3dbdbd13 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -226,6 +226,21 @@ export class ElasticDatasource extends DataSourceApi 0) { + expandedQueries = queries.map(query => { + const expandedQuery = { + ...query, + datasource: this.name, + query: this.templateSrv.replace(query.query), + }; + return expandedQuery; + }); + } + return expandedQueries; + } + testDatasource() { // validate that the index exist and has date field return this.getFields({ type: 'date' }).then( diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts index a3721c77d95..a78a892efcb 100644 --- a/public/app/plugins/datasource/graphite/datasource.ts +++ b/public/app/plugins/datasource/graphite/datasource.ts @@ -6,6 +6,9 @@ import { IQService } from 'angular'; import { BackendSrv } from 'app/core/services/backend_srv'; import { TemplateSrv } from 'app/features/templating/template_srv'; +//Types +import { GraphiteQuery } from './types'; + export class GraphiteDatasource { basicAuth: string; url: string; @@ -117,6 +120,21 @@ export class GraphiteDatasource { return tags; } + interpolateVariablesInQueries(queries: GraphiteQuery[]): GraphiteQuery[] { + let expandedQueries = queries; + if (queries && queries.length > 0) { + expandedQueries = queries.map(query => { + const expandedQuery = { + ...query, + datasource: this.name, + target: this.templateSrv.replace(query.target), + }; + return expandedQuery; + }); + } + return expandedQueries; + } + annotationQuery(options: { annotation: { target: string; tags: string }; rangeRaw: any }) { // Graphite metric as annotation if (options.annotation.target) { diff --git a/public/app/plugins/datasource/graphite/types.ts b/public/app/plugins/datasource/graphite/types.ts new file mode 100644 index 00000000000..5620c1f8e5a --- /dev/null +++ b/public/app/plugins/datasource/graphite/types.ts @@ -0,0 +1,5 @@ +import { DataQuery } from '@grafana/ui'; + +export interface GraphiteQuery extends DataQuery { + target?: string; +} diff --git a/public/app/plugins/datasource/influxdb/datasource.ts b/public/app/plugins/datasource/influxdb/datasource.ts index a08ed91fda9..0adfc1538d4 100644 --- a/public/app/plugins/datasource/influxdb/datasource.ts +++ b/public/app/plugins/datasource/influxdb/datasource.ts @@ -176,6 +176,40 @@ export default class InfluxDatasource extends DataSourceApi 0) { + expandedQueries = queries.map(query => { + const expandedQuery = { + ...query, + datasource: this.name, + measurement: this.templateSrv.replace(query.measurement, null, 'regex'), + }; + + if (query.rawQuery) { + expandedQuery.query = this.templateSrv.replace(query.query, null, 'regex'); + } + + if (query.tags) { + const expandedTags = query.tags.map(tag => { + const expandedTag = { + ...tag, + value: this.templateSrv.replace(tag.value, null, 'regex'), + }; + return expandedTag; + }); + expandedQuery.tags = expandedTags; + } + return expandedQuery; + }); + } + return expandedQueries; + } + metricFindQuery(query: string, options?: any) { const interpolated = this.templateSrv.replace(query, null, 'regex'); diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 65cdcb57f90..69c4701b39e 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -225,6 +225,21 @@ export class LokiDatasource extends DataSourceApi { return merge(...subQueries); } + interpolateVariablesInQueries(queries: LokiQuery[]): LokiQuery[] { + let expandedQueries = queries; + if (queries && queries.length > 0) { + expandedQueries = queries.map(query => { + const expandedQuery = { + ...query, + datasource: this.name, + expr: this.templateSrv.replace(query.expr), + }; + return expandedQuery; + }); + } + return expandedQueries; + } + async importQueries(queries: LokiQuery[], originMeta: PluginMeta): Promise { return this.languageProvider.importQueries(queries, originMeta.id); } diff --git a/public/app/plugins/datasource/mssql/datasource.ts b/public/app/plugins/datasource/mssql/datasource.ts index 71779df0342..2b6bb79a40d 100644 --- a/public/app/plugins/datasource/mssql/datasource.ts +++ b/public/app/plugins/datasource/mssql/datasource.ts @@ -4,6 +4,8 @@ import { BackendSrv } from 'app/core/services/backend_srv'; import { IQService } from 'angular'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +//Types +import { MssqlQueryForInterpolation } from './types'; export class MssqlDatasource { id: any; @@ -48,6 +50,21 @@ export class MssqlDatasource { return quotedValues.join(','); } + interpolateVariablesInQueries(queries: MssqlQueryForInterpolation[]): MssqlQueryForInterpolation[] { + let expandedQueries = queries; + if (queries && queries.length > 0) { + expandedQueries = queries.map(query => { + const expandedQuery = { + ...query, + datasource: this.name, + rawSql: this.templateSrv.replace(query.rawSql, {}, this.interpolateVariable), + }; + return expandedQuery; + }); + } + return expandedQueries; + } + query(options: any) { const queries = _.filter(options.targets, item => { return item.hide !== true; diff --git a/public/app/plugins/datasource/mssql/types.ts b/public/app/plugins/datasource/mssql/types.ts new file mode 100644 index 00000000000..a166a5c9aa1 --- /dev/null +++ b/public/app/plugins/datasource/mssql/types.ts @@ -0,0 +1,7 @@ +export interface MssqlQueryForInterpolation { + alias?: any; + format?: any; + rawSql?: any; + refId?: any; + hide?: any; +} diff --git a/public/app/plugins/datasource/mysql/datasource.ts b/public/app/plugins/datasource/mysql/datasource.ts index f9d6cd79d39..d035a3633f2 100644 --- a/public/app/plugins/datasource/mysql/datasource.ts +++ b/public/app/plugins/datasource/mysql/datasource.ts @@ -5,6 +5,8 @@ import { BackendSrv } from 'app/core/services/backend_srv'; import { IQService } from 'angular'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +//Types +import { MysqlQueryForInterpolation } from './types'; export class MysqlDatasource { id: any; @@ -47,6 +49,21 @@ export class MysqlDatasource { return quotedValues.join(','); }; + interpolateVariablesInQueries(queries: MysqlQueryForInterpolation[]): MysqlQueryForInterpolation[] { + let expandedQueries = queries; + if (queries && queries.length > 0) { + expandedQueries = queries.map(query => { + const expandedQuery = { + ...query, + datasource: this.name, + rawSql: this.templateSrv.replace(query.rawSql, {}, this.interpolateVariable), + }; + return expandedQuery; + }); + } + return expandedQueries; + } + query(options: any) { const queries = _.filter(options.targets, target => { return target.hide !== true; diff --git a/public/app/plugins/datasource/mysql/types.ts b/public/app/plugins/datasource/mysql/types.ts new file mode 100644 index 00000000000..6be0d2549d1 --- /dev/null +++ b/public/app/plugins/datasource/mysql/types.ts @@ -0,0 +1,7 @@ +export interface MysqlQueryForInterpolation { + alias?: any; + format?: any; + rawSql?: any; + refId?: any; + hide?: any; +} diff --git a/public/app/plugins/datasource/postgres/datasource.ts b/public/app/plugins/datasource/postgres/datasource.ts index 360fc9f923f..cc0df228b1e 100644 --- a/public/app/plugins/datasource/postgres/datasource.ts +++ b/public/app/plugins/datasource/postgres/datasource.ts @@ -5,6 +5,8 @@ import { IQService } from 'angular'; import { BackendSrv } from 'app/core/services/backend_srv'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +//Types +import { PostgresQueryForInterpolation } from './types'; export class PostgresDatasource { id: any; @@ -49,6 +51,21 @@ export class PostgresDatasource { return quotedValues.join(','); }; + interpolateVariablesInQueries(queries: PostgresQueryForInterpolation[]): PostgresQueryForInterpolation[] { + let expandedQueries = queries; + if (queries && queries.length > 0) { + expandedQueries = queries.map(query => { + const expandedQuery = { + ...query, + datasource: this.name, + rawSql: this.templateSrv.replace(query.rawSql, {}, this.interpolateVariable), + }; + return expandedQuery; + }); + } + return expandedQueries; + } + query(options: any) { const queries = _.filter(options.targets, target => { return target.hide !== true; diff --git a/public/app/plugins/datasource/postgres/types.ts b/public/app/plugins/datasource/postgres/types.ts new file mode 100644 index 00000000000..d75701e6466 --- /dev/null +++ b/public/app/plugins/datasource/postgres/types.ts @@ -0,0 +1,7 @@ +export interface PostgresQueryForInterpolation { + alias?: any; + format?: any; + rawSql?: any; + refId?: any; + hide?: any; +} diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 86dbe75abc8..27f214bd496 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -27,7 +27,6 @@ import { import { safeStringifyValue } from 'app/core/utils/explore'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { ExploreUrlState } from 'app/types'; import TableModel from 'app/core/table_model'; export interface PromDataQueryResponse { @@ -625,25 +624,19 @@ export class PrometheusDatasource extends DataSourceApi }); } - getExploreState(queries: PromQuery[]): Partial { - let state: Partial = { datasource: this.name }; + interpolateVariablesInQueries(queries: PromQuery[]): PromQuery[] { + let expandedQueries = queries; if (queries && queries.length > 0) { - const expandedQueries = queries.map(query => { + expandedQueries = queries.map(query => { const expandedQuery = { ...query, + datasource: this.name, expr: this.templateSrv.replace(query.expr, {}, this.interpolateQueryExpr), - context: 'explore', }; - return expandedQuery; }); - - state = { - ...state, - queries: expandedQueries, - }; } - return state; + return expandedQueries; } getQueryHints(query: PromQuery, result: any[]) { diff --git a/public/app/types/explore.ts b/public/app/types/explore.ts index cd97de0d664..90c691839ff 100644 --- a/public/app/types/explore.ts +++ b/public/app/types/explore.ts @@ -305,6 +305,7 @@ export interface ExploreUrlState { range: RawTimeRange; ui: ExploreUIState; originPanelId?: number; + context?: string; } export interface HistoryItem {