diff --git a/public/app/plugins/datasource/cloud-monitoring/datasource.test.ts b/public/app/plugins/datasource/cloud-monitoring/datasource.test.ts index aff5ccd9100..c3ab51e16e8 100644 --- a/public/app/plugins/datasource/cloud-monitoring/datasource.test.ts +++ b/public/app/plugins/datasource/cloud-monitoring/datasource.test.ts @@ -1,7 +1,7 @@ import { get } from 'lodash'; import { lastValueFrom, of } from 'rxjs'; -import { CustomVariableModel } from '@grafana/data'; +import { CustomVariableModel, ScopedVars } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; import { createMockInstanceSetttings } from './__mocks__/cloudMonitoringInstanceSettings'; @@ -72,6 +72,33 @@ describe('Cloud Monitoring Datasource', () => { expect(templatedQuery[0]).toHaveProperty('datasource'); expect(templatedQuery[0].timeSeriesList?.projectName).toEqual('project-variable'); }); + it('should correctly apply template variables for PromQLQuery (single-value)', () => { + const templateSrv = getTemplateSrv(); + templateSrv.replace = jest.fn().mockReturnValue('filter-variable'); + const mockInstanceSettings = createMockInstanceSetttings(); + const ds = new Datasource(mockInstanceSettings, templateSrv); + const query = createMockQuery({ promQLQuery: { expr: '$testVar', projectName: 'test-project', step: '1' } }); + const templatedQuery = ds.interpolateVariablesInQueries([query], {}); + expect(templatedQuery[0]).toHaveProperty('datasource'); + expect(templatedQuery[0].promQLQuery?.expr).toContain('filter-variable'); + }); + it('should correctly apply template variables for PromQLQuery (multi-value)', () => { + const templateSrv = getTemplateSrv(); + templateSrv.replace = jest + .fn() + .mockImplementation((_target: string, _v2: ScopedVars, formatFunction: Function) => { + if (formatFunction) { + return formatFunction(['filter-variable', 'filter-variable2']); + } + return undefined; + }); + const mockInstanceSettings = createMockInstanceSetttings(); + const ds = new Datasource(mockInstanceSettings, templateSrv); + const query = createMockQuery({ promQLQuery: { expr: '$testVar', projectName: 'test-project', step: '1' } }); + const templatedQuery = ds.interpolateVariablesInQueries([query], {}); + expect(templatedQuery[0]).toHaveProperty('datasource'); + expect(templatedQuery[0].promQLQuery?.expr).toContain('filter-variable|filter-variable2'); + }); }); describe('migrateQuery', () => { diff --git a/public/app/plugins/datasource/cloud-monitoring/datasource.ts b/public/app/plugins/datasource/cloud-monitoring/datasource.ts index 11a062d40b2..09fc1b954b3 100644 --- a/public/app/plugins/datasource/cloud-monitoring/datasource.ts +++ b/public/app/plugins/datasource/cloud-monitoring/datasource.ts @@ -6,6 +6,7 @@ import { DataQueryRequest, DataQueryResponse, DataSourceInstanceSettings, + QueryVariableModel, ScopedVars, SelectableValue, TimeRange, @@ -84,7 +85,7 @@ export default class CloudMonitoringDatasource extends DataSourceWithBackend< ), }, sloQuery: sloQuery && this.interpolateProps(sloQuery, scopedVars), - promQLQuery: promQLQuery && this.interpolateProps(promQLQuery, scopedVars), + promQLQuery: promQLQuery && this.interpolateProps(promQLQuery, scopedVars, { expr: this.interpolatePromQLQuery }), }; } @@ -294,11 +295,31 @@ export default class CloudMonitoringDatasource extends DataSourceWithBackend< return query; } - interpolateProps>(object: T, scopedVars: ScopedVars = {}): T { + interpolatePromQLQuery(value: string | string[], _variable: QueryVariableModel) { + if (isArray(value)) { + return value.join('|'); + } + return value; + } + + interpolateProps>( + object: T, + scopedVars: ScopedVars = {}, + formattingFunctions?: { [key: string]: Function | undefined } + ): T { return Object.entries(object).reduce((acc, [key, value]) => { + let interpolatedValue = value; + if (value && isString(value)) { + // Pass a function to the template service for formatting + interpolatedValue = this.templateSrv.replace( + value, + scopedVars, + formattingFunctions && formattingFunctions[key] + ); + } return { ...acc, - [key]: value && isString(value) ? this.templateSrv.replace(value, scopedVars) : value, + [key]: interpolatedValue, }; }, {} as T); }