From c907b5315abb5e826e7da020f39c3a4c5d169f8c Mon Sep 17 00:00:00 2001 From: Sarah Zinger Date: Tue, 16 Nov 2021 08:43:57 -0500 Subject: [PATCH] Azure Monitor: Fix bug with template variables. (#41669) --- .../grafanaTemplateVariableFns.ts | 66 ++--- .../grafanaTemplateVariables.test.ts | 241 ++++++++++++++++++ .../variables.test.ts | 24 ++ 3 files changed, 298 insertions(+), 33 deletions(-) create mode 100644 public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariables.test.ts diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariableFns.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariableFns.ts index ef88893257b..a9574e60b9a 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariableFns.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariableFns.ts @@ -75,15 +75,6 @@ const createGrafanaTemplateVariableQuery = (rawQuery: string, datasource: DataSo return queryDetails; } - if (matchesForQuery.resourceGroups && defaultSubscriptionId) { - const queryDetails: ResourceGroupsQuery = { - kind: 'ResourceGroupsQuery', - rawQuery, - subscription: defaultSubscriptionId, - }; - return queryDetails; - } - if (matchesForQuery.resourceGroupsWithSub) { const queryDetails: ResourceGroupsQuery = { kind: 'ResourceGroupsQuery', @@ -93,12 +84,11 @@ const createGrafanaTemplateVariableQuery = (rawQuery: string, datasource: DataSo return queryDetails; } - if (matchesForQuery.metricDefinitions && defaultSubscriptionId) { - const queryDetails: MetricDefinitionsQuery = { - kind: 'MetricDefinitionsQuery', + if (matchesForQuery.resourceGroups && defaultSubscriptionId) { + const queryDetails: ResourceGroupsQuery = { + kind: 'ResourceGroupsQuery', rawQuery, subscription: defaultSubscriptionId, - resourceGroup: matchesForQuery.metricDefinitions[1], }; return queryDetails; } @@ -113,13 +103,12 @@ const createGrafanaTemplateVariableQuery = (rawQuery: string, datasource: DataSo return queryDetails; } - if (matchesForQuery.resourceNames && defaultSubscriptionId) { - const queryDetails: ResourceNamesQuery = { - kind: 'ResourceNamesQuery', + if (matchesForQuery.metricDefinitions && defaultSubscriptionId) { + const queryDetails: MetricDefinitionsQuery = { + kind: 'MetricDefinitionsQuery', rawQuery, subscription: defaultSubscriptionId, - resourceGroup: matchesForQuery.resourceNames[1], - metricDefinition: matchesForQuery.resourceNames[2], + resourceGroup: matchesForQuery.metricDefinitions[1], }; return queryDetails; } @@ -135,14 +124,13 @@ const createGrafanaTemplateVariableQuery = (rawQuery: string, datasource: DataSo return queryDetails; } - if (matchesForQuery.metricNamespace && defaultSubscriptionId) { - const queryDetails: MetricNamespaceQuery = { - kind: 'MetricNamespaceQuery', + if (matchesForQuery.resourceNames && defaultSubscriptionId) { + const queryDetails: ResourceNamesQuery = { + kind: 'ResourceNamesQuery', rawQuery, subscription: defaultSubscriptionId, - resourceGroup: matchesForQuery.metricNamespace[1], - metricDefinition: matchesForQuery.metricNamespace[2], - resourceName: matchesForQuery.metricNamespace[3], + resourceGroup: matchesForQuery.resourceNames[1], + metricDefinition: matchesForQuery.resourceNames[2], }; return queryDetails; } @@ -159,6 +147,18 @@ const createGrafanaTemplateVariableQuery = (rawQuery: string, datasource: DataSo return queryDetails; } + if (matchesForQuery.metricNamespace && defaultSubscriptionId) { + const queryDetails: MetricNamespaceQuery = { + kind: 'MetricNamespaceQuery', + rawQuery, + subscription: defaultSubscriptionId, + resourceGroup: matchesForQuery.metricNamespace[1], + metricDefinition: matchesForQuery.metricNamespace[2], + resourceName: matchesForQuery.metricNamespace[3], + }; + return queryDetails; + } + if (matchesForQuery.metricNames && defaultSubscriptionId) { if (matchesForQuery.metricNames[3].indexOf(',') === -1) { const queryDetails: MetricNamesQuery = { @@ -187,15 +187,6 @@ const createGrafanaTemplateVariableQuery = (rawQuery: string, datasource: DataSo return queryDetails; } - if (matchesForQuery.workspacesQuery && defaultSubscriptionId) { - const queryDetails: WorkspacesQuery = { - kind: 'WorkspacesQuery', - rawQuery, - subscription: defaultSubscriptionId, - }; - return queryDetails; - } - if (matchesForQuery.workspacesQueryWithSub) { const queryDetails: WorkspacesQuery = { kind: 'WorkspacesQuery', @@ -205,6 +196,15 @@ const createGrafanaTemplateVariableQuery = (rawQuery: string, datasource: DataSo return queryDetails; } + if (matchesForQuery.workspacesQuery && defaultSubscriptionId) { + const queryDetails: WorkspacesQuery = { + kind: 'WorkspacesQuery', + rawQuery, + subscription: defaultSubscriptionId, + }; + return queryDetails; + } + // fallback const queryDetails: SubscriptionsQuery = { kind: 'SubscriptionsQuery', rawQuery }; return queryDetails; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariables.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariables.test.ts new file mode 100644 index 00000000000..0a98869d0a9 --- /dev/null +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariables.test.ts @@ -0,0 +1,241 @@ +import { migrateStringQueriesToObjectQueries } from './grafanaTemplateVariableFns'; +import { AzureMonitorQuery, AzureQueryType } from './types'; +import createMockDatasource from './__mocks__/datasource'; + +describe('migrateStringQueriesToObjectQueries', () => { + const expectedMigrations: Array<{ input: string; output: AzureMonitorQuery }> = [ + { + input: 'Subscriptions()', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { kind: 'SubscriptionsQuery', rawQuery: 'Subscriptions()' }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'ResourceGroups()', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'ResourceGroupsQuery', + rawQuery: 'ResourceGroups()', + subscription: 'defaultSubscriptionId', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'ResourceGroups(subId)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'ResourceGroupsQuery', + rawQuery: 'ResourceGroups(subId)', + subscription: 'subId', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'Namespaces(rg)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'MetricDefinitionsQuery', + rawQuery: 'Namespaces(rg)', + subscription: 'defaultSubscriptionId', + resourceGroup: 'rg', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'Namespaces(subId, rg)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'MetricDefinitionsQuery', + rawQuery: 'Namespaces(subId, rg)', + subscription: 'subId', + resourceGroup: 'rg', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'ResourceNames(rg, md)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'ResourceNamesQuery', + rawQuery: 'ResourceNames(rg, md)', + subscription: 'defaultSubscriptionId', + resourceGroup: 'rg', + metricDefinition: 'md', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'ResourceNames(subId, rg, md)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'ResourceNamesQuery', + rawQuery: 'ResourceNames(subId, rg, md)', + subscription: 'subId', + resourceGroup: 'rg', + metricDefinition: 'md', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'MetricNamespace(rg, md, rn)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'MetricNamespaceQuery', + rawQuery: 'MetricNamespace(rg, md, rn)', + subscription: 'defaultSubscriptionId', + resourceGroup: 'rg', + metricDefinition: 'md', + resourceName: 'rn', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'MetricNamespace(subId, rg, md, rn)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'MetricNamespaceQuery', + rawQuery: 'MetricNamespace(subId, rg, md, rn)', + subscription: 'subId', + resourceGroup: 'rg', + metricDefinition: 'md', + resourceName: 'rn', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'MetricNames(rg, md, rn, mn)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'MetricNamesQuery', + rawQuery: 'MetricNames(rg, md, rn, mn)', + subscription: 'defaultSubscriptionId', + resourceGroup: 'rg', + metricDefinition: 'md', + resourceName: 'rn', + metricNamespace: 'mn', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'MetricNames(subId, rg, md, rn, mn)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'MetricNamesQuery', + rawQuery: 'MetricNames(subId, rg, md, rn, mn)', + subscription: 'subId', + resourceGroup: 'rg', + metricDefinition: 'md', + resourceName: 'rn', + metricNamespace: 'mn', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'AppInsightsMetricNames()', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'AppInsightsMetricNameQuery', + rawQuery: 'AppInsightsMetricNames()', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'AppInsightsGroupBys(mn)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'AppInsightsGroupByQuery', + rawQuery: 'AppInsightsGroupBys(mn)', + metricName: 'mn', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'workspaces()', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'WorkspacesQuery', + rawQuery: 'workspaces()', + subscription: 'defaultSubscriptionId', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'workspaces(subId)', + output: { + refId: 'A', + queryType: AzureQueryType.GrafanaTemplateVariableFn, + grafanaTemplateVariableFn: { + kind: 'WorkspacesQuery', + rawQuery: 'workspaces(subId)', + subscription: 'subId', + }, + subscription: 'defaultSubscriptionId', + }, + }, + { + input: 'some kind of kql query', + output: { + refId: 'A', + queryType: AzureQueryType.LogAnalytics, + azureLogAnalytics: { + query: 'some kind of kql query', + resource: '', + }, + subscription: 'defaultSubscriptionId', + }, + }, + ]; + it('successfully converts all old string queries into formatted query objects', async () => { + return expectedMigrations.map(async ({ input, output }) => { + const datasource = createMockDatasource({ + azureMonitorDatasource: { + defaultSubscriptionId: 'defaultSubscriptionId', + }, + }); + const actual = await migrateStringQueriesToObjectQueries(input, { datasource }); + expect(actual).toEqual(output); + }); + }); +}); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts index dd557de92cd..bda352bf58e 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts @@ -427,6 +427,30 @@ describe('VariableSupport', () => { }); }); + it('can handle legacy string queries', (done) => { + const expectedResults = ['test']; + const variableSupport = new VariableSupport( + createMockDatasource({ + azureMonitorDatasource: { + defaultSubscriptionId: 'defaultSubscriptionId', + }, + getMetricDefinitions: jest.fn((sub: string, rg: string) => { + if (sub === 'subscriptionId' && rg === 'resourceGroup') { + return Promise.resolve(expectedResults); + } + return Promise.resolve([`getMetricDefinitions unexpected input: ${sub}, ${rg}`]); + }), + }) + ); + const mockRequest = { + targets: [('Namespaces(subscriptionId, resourceGroup)' as unknown) as AzureMonitorQuery], + } as DataQueryRequest; + const observables = variableSupport.query(mockRequest); + observables.subscribe((result: DataQueryResponseData) => { + expect(result.data[0].source).toEqual(expectedResults); + done(); + }); + }); it('returns an empty array for unknown queries', (done) => { const variableSupport = new VariableSupport(createMockDatasource()); const mockRequest = {