1import { from, lastValueFrom, Observable } from 'rxjs'; 2import { 3 CustomVariableSupport, 4 DataQueryRequest, 5 DataQueryResponse, 6 MetricFindValue, 7 toDataFrame, 8} from '@grafana/data'; 9import VariableEditor from './components/VariableEditor/VariableEditor'; 10import DataSource from './datasource'; 11import { AzureQueryType, AzureMonitorQuery } from './types'; 12import { getTemplateSrv } from '@grafana/runtime'; 13import { migrateStringQueriesToObjectQueries } from './grafanaTemplateVariableFns'; 14import { GrafanaTemplateVariableQuery } from './types/templateVariables'; 15import messageFromError from './utils/messageFromError'; 16export class VariableSupport extends CustomVariableSupport<DataSource, AzureMonitorQuery> { 17 constructor(private readonly datasource: DataSource) { 18 super(); 19 this.datasource = datasource; 20 this.query = this.query.bind(this); 21 } 22 23 editor = VariableEditor; 24 25 query(request: DataQueryRequest<AzureMonitorQuery>): Observable<DataQueryResponse> { 26 const promisedResults = async () => { 27 const queryObj = await migrateStringQueriesToObjectQueries(request.targets[0], { datasource: this.datasource }); 28 29 if (queryObj.queryType === AzureQueryType.GrafanaTemplateVariableFn && queryObj.grafanaTemplateVariableFn) { 30 try { 31 const templateVariablesResults = await this.callGrafanaTemplateVariableFn(queryObj.grafanaTemplateVariableFn); 32 return { 33 data: templateVariablesResults ? [toDataFrame(templateVariablesResults)] : [], 34 }; 35 } catch (err) { 36 return { data: [], error: { message: messageFromError(err) } }; 37 } 38 } 39 request.targets[0] = queryObj; 40 return lastValueFrom(this.datasource.query(request)); 41 }; 42 43 return from(promisedResults()); 44 } 45 46 callGrafanaTemplateVariableFn(query: GrafanaTemplateVariableQuery): Promise<MetricFindValue[]> | null { 47 // deprecated app insights template variables (will most likely remove in grafana 9) 48 if (this.datasource.insightsAnalyticsDatasource) { 49 if (query.kind === 'AppInsightsMetricNameQuery') { 50 return this.datasource.insightsAnalyticsDatasource.getMetricNames(); 51 } 52 53 if (query.kind === 'AppInsightsGroupByQuery') { 54 return this.datasource.insightsAnalyticsDatasource.getGroupBys(getTemplateSrv().replace(query.metricName)); 55 } 56 } 57 58 if (query.kind === 'SubscriptionsQuery') { 59 return this.datasource.getSubscriptions(); 60 } 61 62 if (query.kind === 'ResourceGroupsQuery') { 63 return this.datasource.getResourceGroups(this.replaceVariable(query.subscription)); 64 } 65 66 if (query.kind === 'MetricDefinitionsQuery') { 67 return this.datasource.getMetricDefinitions( 68 this.replaceVariable(query.subscription), 69 this.replaceVariable(query.resourceGroup) 70 ); 71 } 72 73 if (query.kind === 'ResourceNamesQuery') { 74 return this.datasource.getResourceNames( 75 this.replaceVariable(query.subscription), 76 this.replaceVariable(query.resourceGroup), 77 this.replaceVariable(query.metricDefinition) 78 ); 79 } 80 81 if (query.kind === 'MetricNamespaceQuery') { 82 return this.datasource.getMetricNamespaces( 83 this.replaceVariable(query.subscription), 84 this.replaceVariable(query.resourceGroup), 85 this.replaceVariable(query.metricDefinition), 86 this.replaceVariable(query.resourceName) 87 ); 88 } 89 90 if (query.kind === 'MetricNamesQuery') { 91 return this.datasource.getMetricNames( 92 this.replaceVariable(query.subscription), 93 this.replaceVariable(query.resourceGroup), 94 this.replaceVariable(query.metricDefinition), 95 this.replaceVariable(query.resourceName), 96 this.replaceVariable(query.metricNamespace) 97 ); 98 } 99 100 if (query.kind === 'WorkspacesQuery') { 101 return this.datasource.azureLogAnalyticsDatasource.getWorkspaces(this.replaceVariable(query.subscription)); 102 } 103 104 return null; 105 } 106 107 replaceVariable(metric: string) { 108 return getTemplateSrv().replace((metric || '').trim()); 109 } 110} 111