diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts index 122163c2636..7a64ef556ad 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts @@ -59,22 +59,24 @@ export const useSubscriptions: DataHook = (query, datasource, onChange, setError const { subscription } = query; const defaultSubscription = datasource.azureMonitorDatasource.defaultSubscriptionId; - return useAsyncState( + const subscriptionOptions = useAsyncState( async () => { const results = await datasource.azureMonitorDatasource.getSubscriptions(); - const options = results.map((v) => ({ label: v.text, value: v.value, description: v.value })); - - if (!subscription && defaultSubscription && hasOption(options, defaultSubscription)) { - onChange(setSubscriptionID(query, defaultSubscription)); - } else if ((!subscription && options.length) || options.length === 1) { - onChange(setSubscriptionID(query, options[0].value)); - } - - return options; + return results.map((v) => ({ label: v.text, value: v.value, description: v.value })); }, setError, [] ); + + useEffect(() => { + if (!subscription && defaultSubscription && hasOption(subscriptionOptions, defaultSubscription)) { + onChange(setSubscriptionID(query, defaultSubscription)); + } else if ((!subscription && subscriptionOptions.length) || subscriptionOptions.length === 1) { + onChange(setSubscriptionID(query, subscriptionOptions[0].value)); + } + }, [subscriptionOptions, query, subscription, defaultSubscription, onChange]); + + return subscriptionOptions; }; export const useResourceGroups: DataHook = (query, datasource, onChange, setError) => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/useDefaultQuery.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/useDefaultQuery.ts index f1a571c959a..002c52068a9 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/useDefaultQuery.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/useDefaultQuery.ts @@ -24,7 +24,6 @@ const useDefaultQuery = (query: AzureMonitorQuery, onChangeQuery: (newQuery: Azu useEffect(() => { if (queryWithDefaults !== query) { - console.log('changing default query'); onChangeQuery(queryWithDefaults); } }, [queryWithDefaults, query, onChangeQuery]); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts index 220c5d2a1e7..86041ce506c 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts @@ -26,8 +26,13 @@ import { migrateMetricsDimensionFilters } from './query_ctrl'; import { map } from 'rxjs/operators'; import AzureResourceGraphDatasource from './azure_resource_graph/azure_resource_graph_datasource'; import { getAzureCloud } from './credentials'; +import migrateAnnotation from './utils/migrateAnnotation'; export default class Datasource extends DataSourceApi { + annotations = { + prepareAnnotation: migrateAnnotation, + }; + azureMonitorDatasource: AzureMonitorDatasource; azureLogAnalyticsDatasource: AzureLogAnalyticsDatasource; resourcePickerData: ResourcePickerData; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/module.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/module.ts index 09b5065d360..1215c103b32 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/module.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/module.ts @@ -2,10 +2,8 @@ import { DataSourcePlugin } from '@grafana/data'; import Datasource from './datasource'; import { ConfigEditor } from './components/ConfigEditor'; import AzureMonitorQueryEditor from './components/QueryEditor'; -import { AzureMonitorAnnotationsQueryCtrl } from './annotations_query_ctrl'; import { AzureMonitorQuery, AzureDataSourceJsonData } from './types'; export const plugin = new DataSourcePlugin(Datasource) .setConfigEditor(ConfigEditor) - .setQueryEditor(AzureMonitorQueryEditor) - .setAnnotationQueryCtrl(AzureMonitorAnnotationsQueryCtrl); + .setQueryEditor(AzureMonitorQueryEditor); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.test.ts new file mode 100644 index 00000000000..6d3380a76ab --- /dev/null +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.test.ts @@ -0,0 +1,62 @@ +import { AnnotationQuery } from '@grafana/data'; +import { AzureMonitorQuery, AzureQueryType } from '../types'; +import migrateAnnotation from './migrateAnnotation'; + +const OLD_ANNOTATION: AnnotationQuery = { + datasource: null, + enable: true, + iconColor: 'red', + name: 'azure-activity', + + queryType: 'Azure Log Analytics', + subscription: 'abc-123-def-456', + rawQuery: 'AzureActivity\r\n| where $__timeFilter() \r\n| project TimeGenerated, Text=OperationName', + workspace: + '/subscriptions/abc-123-def-456/resourcegroups/our-datasource/providers/microsoft.operationalinsights/workspaces/azureactivitylog', + + target: { + refId: 'Anno', + }, +}; + +const NEW_ANNOTATION: AnnotationQuery = { + datasource: null, + enable: true, + iconColor: 'red', + name: 'azure-activity', + + rawQuery: undefined, + workspace: undefined, + subscription: undefined, + queryType: undefined, + + target: { + refId: 'Anno', + queryType: AzureQueryType.LogAnalytics, + azureLogAnalytics: { + query: 'AzureActivity\r\n| where $__timeFilter() \r\n| project TimeGenerated, Text=OperationName', + resource: + '/subscriptions/abc-123-def-456/resourcegroups/our-datasource/providers/microsoft.operationalinsights/workspaces/azureactivitylog', + }, + }, +}; + +describe('AzureMonitor: migrateAnnotation', () => { + it('migrates old annotations to AzureMonitorQuery', () => { + const migrated = migrateAnnotation(OLD_ANNOTATION); + expect(migrated).toEqual(NEW_ANNOTATION); + }); + + it('passes through already migrated queries untouched', () => { + const newAnnotation = { ...NEW_ANNOTATION }; + delete newAnnotation.rawQuery; + delete newAnnotation.workspace; + delete newAnnotation.subscription; + delete newAnnotation.queryType; + + const migrated = migrateAnnotation(newAnnotation); + + // We use .toBe because we want to assert that the object identity did not change!!! + expect(migrated).toBe(newAnnotation); + }); +}); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.ts new file mode 100644 index 00000000000..3dc8098e1fc --- /dev/null +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.ts @@ -0,0 +1,34 @@ +import { AzureMonitorQuery, AzureQueryType } from '../types'; +import { AnnotationQuery } from '@grafana/data'; + +// The old Angular annotations editor put some properties (rawQuery, workspace, subscription) +// on the root annotation object, rather than down in the 'targets' query value +// This migration moves them to a Log Analytics query compatible with the React query editor +// The old Angular annotations editor did not support any other query types. +export default function migrateAnnotation(annotation: AnnotationQuery) { + const oldQuery = typeof annotation.rawQuery === 'string' ? annotation.rawQuery : null; + const oldWorkspace = typeof annotation.workspace === 'string' ? annotation.workspace : null; + + if (!(oldQuery && oldWorkspace && !annotation.target?.azureLogAnalytics?.query)) { + return annotation; + } + + const newQuery: AzureMonitorQuery = { + ...(annotation.target ?? {}), + refId: annotation.target?.refId ?? 'Anno', + queryType: AzureQueryType.LogAnalytics, + azureLogAnalytics: { + query: oldQuery, + resource: oldWorkspace, + }, + }; + + return { + ...annotation, + rawQuery: undefined, + workspace: undefined, + subscription: undefined, + queryType: undefined, + target: newQuery, + }; +}