Explore: Expand template variables when redirecting from dashboard panel (#19582)

* Fix redirect but adding getExploreState method to graphite

* Explore: Create interpolateVariablesInQueries function for datasources

* Explore: Add interpolateVariablesInQueries method to elasticsearch datasource

* Add interpolateVariablesInQueries function to influx and postgres

* Explore: Add interpolateVariablesInQueries to Mssql and Mysql datasources

* Explore: Add datasources to queries

* Explore: Code formatting

* Prettier formating fix

* Explore: Add rawQuery expanding of variables for influxdb

* Remove console.logs

* Explore: Add rawQuery expanding of multiple variables for influxdb

* Explore: If no queries in Influxdb, return early []

* Explore: Refactor influxDb to follow the code structure
This commit is contained in:
Ivana Huckova 2019-10-08 17:01:20 +02:00 committed by GitHub
parent 9904e14f8e
commit 90b0953620
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 173 additions and 14 deletions

View File

@ -77,12 +77,18 @@ export async function getExploreUrl(
if (exploreDatasource) {
const range = timeSrv.timeRangeForUrl();
let state: Partial<ExploreUrlState> = { 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 })),
};
}

View File

@ -226,6 +226,21 @@ export class ElasticDatasource extends DataSourceApi<ElasticsearchQuery, Elastic
});
}
interpolateVariablesInQueries(queries: ElasticsearchQuery[]): ElasticsearchQuery[] {
let expandedQueries = queries;
if (queries && queries.length > 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(

View File

@ -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) {

View File

@ -0,0 +1,5 @@
import { DataQuery } from '@grafana/ui';
export interface GraphiteQuery extends DataQuery {
target?: string;
}

View File

@ -176,6 +176,40 @@ export default class InfluxDatasource extends DataSourceApi<InfluxQuery, InfluxO
return false;
}
interpolateVariablesInQueries(queries: InfluxQuery[]): InfluxQuery[] {
if (!queries || queries.length === 0) {
return [];
}
let expandedQueries = queries;
if (queries && queries.length > 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');

View File

@ -225,6 +225,21 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
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<LokiQuery[]> {
return this.languageProvider.importQueries(queries, originMeta.id);
}

View File

@ -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;

View File

@ -0,0 +1,7 @@
export interface MssqlQueryForInterpolation {
alias?: any;
format?: any;
rawSql?: any;
refId?: any;
hide?: any;
}

View File

@ -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;

View File

@ -0,0 +1,7 @@
export interface MysqlQueryForInterpolation {
alias?: any;
format?: any;
rawSql?: any;
refId?: any;
hide?: any;
}

View File

@ -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;

View File

@ -0,0 +1,7 @@
export interface PostgresQueryForInterpolation {
alias?: any;
format?: any;
rawSql?: any;
refId?: any;
hide?: any;
}

View File

@ -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<PromQuery, PromOptions>
});
}
getExploreState(queries: PromQuery[]): Partial<ExploreUrlState> {
let state: Partial<ExploreUrlState> = { 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[]) {

View File

@ -305,6 +305,7 @@ export interface ExploreUrlState {
range: RawTimeRange;
ui: ExploreUIState;
originPanelId?: number;
context?: string;
}
export interface HistoryItem<TQuery extends DataQuery = DataQuery> {