AzureMonitor: move metric deep link code to backend (#39524)

This commit is contained in:
Isabella Siu
2021-09-28 09:24:18 -04:00
committed by GitHub
parent 73936fc63c
commit bf9be975ac
6 changed files with 190 additions and 162 deletions

View File

@@ -9,20 +9,10 @@ import {
AzureMonitorMetricDefinitionsResponse,
AzureMonitorResourceGroupsResponse,
AzureQueryType,
AzureMetricQuery,
DatasourceValidationResult,
} from '../types';
import {
DataSourceInstanceSettings,
ScopedVars,
MetricFindValue,
DataQueryResponse,
DataQueryRequest,
TimeRange,
} from '@grafana/data';
import { DataSourceInstanceSettings, ScopedVars, MetricFindValue } from '@grafana/data';
import { DataSourceWithBackend, getTemplateSrv } from '@grafana/runtime';
import { from, Observable } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { getAuthType, getAzureCloud, getAzurePortalUrl } from '../credentials';
@@ -31,16 +21,6 @@ import { routeNames } from '../utils/common';
const defaultDropdownValue = 'select';
// Used to convert our aggregation value to the Azure enum for deep linking
const aggregationTypeMap: Record<string, number> = {
None: 0,
Total: 1,
Minimum: 2,
Maximum: 3,
Average: 4,
Count: 7,
};
export default class AzureMonitorDatasource extends DataSourceWithBackend<AzureMonitorQuery, AzureDataSourceJsonData> {
apiVersion = '2018-01-01';
apiPreviewVersion = '2017-12-01-preview';
@@ -86,90 +66,6 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend<AzureM
);
}
query(request: DataQueryRequest<AzureMonitorQuery>): Observable<DataQueryResponse> {
const metricQueries = request.targets.reduce((prev: Record<string, AzureMonitorQuery>, cur) => {
prev[cur.refId] = cur;
return prev;
}, {});
return super.query(request).pipe(
mergeMap((res: DataQueryResponse) => {
return from(this.processResponse(res, metricQueries));
})
);
}
async processResponse(
res: DataQueryResponse,
metricQueries: Record<string, AzureMonitorQuery>
): Promise<DataQueryResponse> {
if (res.data) {
for (const df of res.data) {
const metricQuery = metricQueries[df.refId];
if (!metricQuery.azureMonitor || !metricQuery.subscription) {
continue;
}
const url = this.buildAzurePortalUrl(
metricQuery.azureMonitor,
metricQuery.subscription,
this.timeSrv.timeRange()
);
for (const field of df.fields) {
field.config.links = [
{
url: url,
title: 'View in Azure Portal',
targetBlank: true,
},
];
}
}
}
return res;
}
stringifyAzurePortalUrlParam(value: string | object): string {
const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
return encodeURIComponent(stringValue);
}
buildAzurePortalUrl(metricQuery: AzureMetricQuery, subscriptionId: string, timeRange: TimeRange) {
const aggregationType =
(metricQuery.aggregation && aggregationTypeMap[metricQuery.aggregation]) ?? aggregationTypeMap.Average;
const chartDef = this.stringifyAzurePortalUrlParam({
v2charts: [
{
metrics: [
{
resourceMetadata: {
id: `/subscriptions/${subscriptionId}/resourceGroups/${metricQuery.resourceGroup}/providers/${metricQuery.metricDefinition}/${metricQuery.resourceName}`,
},
name: metricQuery.metricName,
aggregationType: aggregationType,
namespace: metricQuery.metricNamespace,
metricVisualization: {
displayName: metricQuery.metricName,
resourceDisplayName: metricQuery.resourceName,
},
},
],
},
],
});
const timeContext = this.stringifyAzurePortalUrlParam({
absolute: {
startTime: timeRange.from,
endTime: timeRange.to,
},
});
return `${this.azurePortalUrl}/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/${timeContext}/ChartDefinition/${chartDef}`;
}
applyTemplateVariables(target: AzureMonitorQuery, scopedVars: ScopedVars): AzureMonitorQuery {
const item = target.azureMonitor;