mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Azure Monitor: Migrate metrics queries to use a resource URI (#47696)
* migrate old query to new query * remove new prefixed data fetchers * fix lint * add test cases for v7 and v8 query versions * add mock ids in test * add clarifying comment * add types for azure monitor api data fetchers * add additional comment to explain the types
This commit is contained in:
parent
79c06fdddc
commit
01c22ee366
@ -16,9 +16,9 @@ export default function createMockDatasource(overrides?: DeepPartial<Datasource>
|
||||
},
|
||||
getSubscriptions: jest.fn().mockResolvedValueOnce([]),
|
||||
defaultSubscriptionId: 'subscriptionId',
|
||||
newGetMetricNamespaces: jest.fn().mockResolvedValueOnce([]),
|
||||
newGetMetricNames: jest.fn().mockResolvedValueOnce([]),
|
||||
newGetMetricMetadata: jest.fn().mockResolvedValueOnce({
|
||||
getMetricNamespaces: jest.fn().mockResolvedValueOnce([]),
|
||||
getMetricNames: jest.fn().mockResolvedValueOnce([]),
|
||||
getMetricMetadata: jest.fn().mockResolvedValueOnce({
|
||||
primaryAggType: 'Average',
|
||||
supportedAggTypes: ['Average', 'Maximum', 'Minimum'],
|
||||
supportedTimeGrains: [],
|
||||
@ -31,14 +31,6 @@ export default function createMockDatasource(overrides?: DeepPartial<Datasource>
|
||||
getResourceGroups: jest.fn().mockResolvedValueOnce([]),
|
||||
getMetricDefinitions: jest.fn().mockResolvedValueOnce([]),
|
||||
getResourceNames: jest.fn().mockResolvedValueOnce([]),
|
||||
getMetricNamespaces: jest.fn().mockResolvedValueOnce([]),
|
||||
getMetricNames: jest.fn().mockResolvedValueOnce([]),
|
||||
getMetricMetadata: jest.fn().mockResolvedValueOnce({
|
||||
primaryAggType: 'Average',
|
||||
supportedAggTypes: ['Average', 'Maximum', 'Minimum'],
|
||||
supportedTimeGrains: [],
|
||||
dimensions: [],
|
||||
}),
|
||||
|
||||
azureLogAnalyticsDatasource: {
|
||||
getKustoSchema: () => Promise.resolve(),
|
||||
|
@ -26,7 +26,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
ctx.instanceSettings = {
|
||||
name: 'test',
|
||||
url: 'http://azuremonitor.com',
|
||||
jsonData: { subscriptionId: '9935389e-9122-4ef9-95f9-1513dd24753f', cloudName: 'azuremonitor' },
|
||||
jsonData: { subscriptionId: 'mock-subscription-id', cloudName: 'azuremonitor' },
|
||||
} as unknown as DataSourceInstanceSettings<AzureDataSourceJsonData>;
|
||||
ctx.ds = new AzureMonitorDatasource(ctx.instanceSettings);
|
||||
});
|
||||
@ -76,11 +76,11 @@ describe('AzureMonitorDatasource', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('When performing newGetMetricNamespaces', () => {
|
||||
describe('When performing getMetricNamespaces', () => {
|
||||
const response = {
|
||||
value: [
|
||||
{
|
||||
id: '/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1/providers/microsoft.insights/metricNamespaces/Azure.ApplicationInsights',
|
||||
id: '/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1/providers/microsoft.insights/metricNamespaces/Azure.ApplicationInsights',
|
||||
name: 'Azure.ApplicationInsights',
|
||||
type: 'Microsoft.Insights/metricNamespaces',
|
||||
classification: 'Custom',
|
||||
@ -89,7 +89,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1/providers/microsoft.insights/metricNamespaces/microsoft.insights-components',
|
||||
id: '/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1/providers/microsoft.insights/metricNamespaces/microsoft.insights-components',
|
||||
name: 'microsoft.insights-components',
|
||||
type: 'Microsoft.Insights/metricNamespaces',
|
||||
classification: 'Platform',
|
||||
@ -102,7 +102,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => {
|
||||
const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp';
|
||||
const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp';
|
||||
const expected =
|
||||
basePath +
|
||||
'/providers/microsoft.insights/components/resource1' +
|
||||
@ -114,9 +114,10 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
it('should return list of Metric Namspaces', () => {
|
||||
return ctx.ds.azureMonitorDatasource
|
||||
.newGetMetricNamespaces(
|
||||
'/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1'
|
||||
)
|
||||
.getMetricNamespaces({
|
||||
resourceUri:
|
||||
'/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1',
|
||||
})
|
||||
.then((results: Array<{ text: string; value: string }>) => {
|
||||
expect(results.length).toEqual(2);
|
||||
expect(results[0].text).toEqual('Azure.ApplicationInsights');
|
||||
@ -127,7 +128,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('When performing newGetMetricNames', () => {
|
||||
describe('When performing getMetricNames', () => {
|
||||
const response = {
|
||||
value: [
|
||||
{
|
||||
@ -165,7 +166,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => {
|
||||
const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp';
|
||||
const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp';
|
||||
const expected =
|
||||
basePath +
|
||||
'/providers/microsoft.insights/components/resource1' +
|
||||
@ -177,10 +178,11 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
it('should return list of Metric Definitions', () => {
|
||||
return ctx.ds.azureMonitorDatasource
|
||||
.newGetMetricNames(
|
||||
'/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1',
|
||||
'default'
|
||||
)
|
||||
.getMetricNames({
|
||||
resourceUri:
|
||||
'/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1',
|
||||
metricNamespace: 'default',
|
||||
})
|
||||
.then((results: Array<{ text: string; value: string }>) => {
|
||||
expect(results.length).toEqual(2);
|
||||
expect(results[0].text).toEqual('Used capacity');
|
||||
@ -191,7 +193,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('When performing newGetMetricMetadata', () => {
|
||||
describe('When performing getMetricMetadata', () => {
|
||||
const response = {
|
||||
value: [
|
||||
{
|
||||
@ -229,7 +231,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => {
|
||||
const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp';
|
||||
const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp';
|
||||
const expected =
|
||||
basePath +
|
||||
'/providers/microsoft.insights/components/resource1' +
|
||||
@ -241,11 +243,12 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
it('should return Aggregation metadata for a Metric', () => {
|
||||
return ctx.ds.azureMonitorDatasource
|
||||
.newGetMetricMetadata(
|
||||
'/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1',
|
||||
'default',
|
||||
'UsedCapacity'
|
||||
)
|
||||
.getMetricMetadata({
|
||||
resourceUri:
|
||||
'/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1',
|
||||
metricNamespace: 'default',
|
||||
metricName: 'UsedCapacity',
|
||||
})
|
||||
.then((results) => {
|
||||
expect(results.primaryAggType).toEqual('Total');
|
||||
expect(results.supportedAggTypes.length).toEqual(6);
|
||||
@ -342,7 +345,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => {
|
||||
const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups';
|
||||
const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups';
|
||||
expect(path).toBe(basePath + '/nodesapp/resources?api-version=2021-04-01');
|
||||
return Promise.resolve(response);
|
||||
});
|
||||
@ -350,7 +353,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
it('should return list of Metric Definitions with no duplicates and no unsupported namespaces', () => {
|
||||
return ctx.ds
|
||||
.getMetricDefinitions('9935389e-9122-4ef9-95f9-1513dd24753f', 'nodesapp')
|
||||
.getMetricDefinitions('mock-subscription-id', 'nodesapp')
|
||||
.then((results: Array<{ text: string; value: string }>) => {
|
||||
expect(results.length).toEqual(7);
|
||||
expect(results[0].text).toEqual('Network interface');
|
||||
@ -372,12 +375,12 @@ describe('AzureMonitorDatasource', () => {
|
||||
});
|
||||
|
||||
describe('When performing getResourceNames', () => {
|
||||
let subscription = '9935389e-9122-4ef9-95f9-1513dd24753f';
|
||||
let subscription = 'mock-subscription-id';
|
||||
let resourceGroup = 'nodeapp';
|
||||
let metricDefinition = 'microsoft.insights/components';
|
||||
|
||||
beforeEach(() => {
|
||||
subscription = '9935389e-9122-4ef9-95f9-1513dd24753f';
|
||||
subscription = 'mock-subscription-id';
|
||||
resourceGroup = 'nodeapp';
|
||||
metricDefinition = 'microsoft.insights/components';
|
||||
});
|
||||
@ -552,7 +555,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => {
|
||||
const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp';
|
||||
const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp';
|
||||
const expected =
|
||||
basePath +
|
||||
'/providers/microsoft.insights/components/resource1' +
|
||||
@ -563,14 +566,14 @@ describe('AzureMonitorDatasource', () => {
|
||||
});
|
||||
|
||||
it('should return list of Metric Definitions', () => {
|
||||
return ctx.ds
|
||||
.getMetricNames(
|
||||
'9935389e-9122-4ef9-95f9-1513dd24753f',
|
||||
'nodeapp',
|
||||
'microsoft.insights/components',
|
||||
'resource1',
|
||||
'default'
|
||||
)
|
||||
return ctx.ds.azureMonitorDatasource
|
||||
.getMetricNames({
|
||||
subscription: 'mock-subscription-id',
|
||||
resourceGroup: 'nodeapp',
|
||||
metricDefinition: 'microsoft.insights/components',
|
||||
resourceName: 'resource1',
|
||||
metricNamespace: 'default',
|
||||
})
|
||||
.then((results: Array<{ text: string; value: string }>) => {
|
||||
expect(results.length).toEqual(2);
|
||||
expect(results[0].text).toEqual('Used capacity');
|
||||
@ -619,7 +622,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => {
|
||||
const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp';
|
||||
const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp';
|
||||
const expected =
|
||||
basePath +
|
||||
'/providers/microsoft.insights/components/resource1' +
|
||||
@ -630,15 +633,15 @@ describe('AzureMonitorDatasource', () => {
|
||||
});
|
||||
|
||||
it('should return Aggregation metadata for a Metric', () => {
|
||||
return ctx.ds
|
||||
.getMetricMetadata(
|
||||
'9935389e-9122-4ef9-95f9-1513dd24753f',
|
||||
'nodeapp',
|
||||
'microsoft.insights/components',
|
||||
'resource1',
|
||||
'default',
|
||||
'UsedCapacity'
|
||||
)
|
||||
return ctx.ds.azureMonitorDatasource
|
||||
.getMetricMetadata({
|
||||
subscription: 'mock-subscription-id',
|
||||
resourceGroup: 'nodeapp',
|
||||
metricDefinition: 'microsoft.insights/components',
|
||||
resourceName: 'resource1',
|
||||
metricNamespace: 'default',
|
||||
metricName: 'UsedCapacity',
|
||||
})
|
||||
.then((results) => {
|
||||
expect(results.primaryAggType).toEqual('Total');
|
||||
expect(results.supportedAggTypes.length).toEqual(6);
|
||||
@ -688,7 +691,7 @@ describe('AzureMonitorDatasource', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => {
|
||||
const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp';
|
||||
const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp';
|
||||
const expected =
|
||||
basePath +
|
||||
'/providers/microsoft.insights/components/resource1' +
|
||||
@ -699,15 +702,15 @@ describe('AzureMonitorDatasource', () => {
|
||||
});
|
||||
|
||||
it('should return dimensions for a Metric that has dimensions', () => {
|
||||
return ctx.ds
|
||||
.getMetricMetadata(
|
||||
'9935389e-9122-4ef9-95f9-1513dd24753f',
|
||||
'nodeapp',
|
||||
'microsoft.insights/components',
|
||||
'resource1',
|
||||
'default',
|
||||
'Transactions'
|
||||
)
|
||||
return ctx.ds.azureMonitorDatasource
|
||||
.getMetricMetadata({
|
||||
subscription: 'mock-subscription-id',
|
||||
resourceGroup: 'nodeapp',
|
||||
metricDefinition: 'microsoft.insights/components',
|
||||
resourceName: 'resource1',
|
||||
metricNamespace: 'default',
|
||||
metricName: 'Transactions',
|
||||
})
|
||||
.then((results: any) => {
|
||||
expect(results.dimensions).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
@ -759,15 +762,15 @@ describe('AzureMonitorDatasource', () => {
|
||||
});
|
||||
|
||||
it('should return an empty array for a Metric that does not have dimensions', () => {
|
||||
return ctx.ds
|
||||
.getMetricMetadata(
|
||||
'9935389e-9122-4ef9-95f9-1513dd24753f',
|
||||
'nodeapp',
|
||||
'microsoft.insights/components',
|
||||
'resource1',
|
||||
'default',
|
||||
'FreeCapacity'
|
||||
)
|
||||
return ctx.ds.azureMonitorDatasource
|
||||
.getMetricMetadata({
|
||||
subscription: 'mock-subscription-id',
|
||||
resourceGroup: 'nodeapp',
|
||||
metricDefinition: 'microsoft.insights/components',
|
||||
resourceName: 'resource1',
|
||||
metricNamespace: 'default',
|
||||
metricName: 'FreeCapacity',
|
||||
})
|
||||
.then((results: any) => {
|
||||
expect(results.dimensions.length).toEqual(0);
|
||||
});
|
||||
|
@ -16,6 +16,9 @@ import {
|
||||
AzureMonitorResourceGroupsResponse,
|
||||
AzureQueryType,
|
||||
DatasourceValidationResult,
|
||||
GetMetricNamespacesQuery,
|
||||
GetMetricNamesQuery,
|
||||
GetMetricMetadataQuery,
|
||||
} from '../types';
|
||||
import { routeNames } from '../utils/common';
|
||||
import ResponseParser from './response_parser';
|
||||
@ -236,102 +239,35 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend<AzureM
|
||||
});
|
||||
}
|
||||
|
||||
getMetricNamespaces(subscriptionId: string, resourceGroup: string, metricDefinition: string, resourceName: string) {
|
||||
getMetricNamespaces(query: GetMetricNamespacesQuery) {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl(
|
||||
this.resourcePath,
|
||||
subscriptionId,
|
||||
resourceGroup,
|
||||
metricDefinition,
|
||||
resourceName,
|
||||
this.apiPreviewVersion
|
||||
this.apiPreviewVersion,
|
||||
this.replaceTemplateVariables(query)
|
||||
);
|
||||
|
||||
return this.getResource(url).then((result: any) => {
|
||||
return ResponseParser.parseResponseValues(result, 'name', 'properties.metricNamespaceName');
|
||||
});
|
||||
}
|
||||
|
||||
newGetMetricNamespaces(resourceUri: string) {
|
||||
const templateSrv = getTemplateSrv();
|
||||
const url = UrlBuilder.newBuildAzureMonitorGetMetricNamespacesUrl(
|
||||
this.resourcePath,
|
||||
templateSrv.replace(resourceUri),
|
||||
this.apiPreviewVersion
|
||||
);
|
||||
|
||||
return this.getResource(url).then((result: AzureMonitorMetricNamespacesResponse) => {
|
||||
return ResponseParser.parseResponseValues(result, 'name', 'properties.metricNamespaceName');
|
||||
});
|
||||
}
|
||||
|
||||
getMetricNames(
|
||||
subscriptionId: string,
|
||||
resourceGroup: string,
|
||||
metricDefinition: string,
|
||||
resourceName: string,
|
||||
metricNamespace: string
|
||||
) {
|
||||
getMetricNames(query: GetMetricNamesQuery) {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
this.resourcePath,
|
||||
subscriptionId,
|
||||
resourceGroup,
|
||||
metricDefinition,
|
||||
resourceName,
|
||||
metricNamespace,
|
||||
this.apiVersion
|
||||
this.apiVersion,
|
||||
this.replaceTemplateVariables(query)
|
||||
);
|
||||
|
||||
return this.getResource(url).then((result: any) => {
|
||||
return ResponseParser.parseResponseValues(result, 'name.localizedValue', 'name.value');
|
||||
});
|
||||
}
|
||||
|
||||
newGetMetricNames(resourceUri: string, metricNamespace: string) {
|
||||
const templateSrv = getTemplateSrv();
|
||||
const url = UrlBuilder.newBuildAzureMonitorGetMetricNamesUrl(
|
||||
this.resourcePath,
|
||||
templateSrv.replace(resourceUri),
|
||||
templateSrv.replace(metricNamespace),
|
||||
this.apiVersion
|
||||
);
|
||||
|
||||
return this.getResource(url).then((result: AzureMonitorMetricNamesResponse) => {
|
||||
return ResponseParser.parseResponseValues(result, 'name.localizedValue', 'name.value');
|
||||
});
|
||||
}
|
||||
|
||||
getMetricMetadata(
|
||||
subscriptionId: string,
|
||||
resourceGroup: string,
|
||||
metricDefinition: string,
|
||||
resourceName: string,
|
||||
metricNamespace: string,
|
||||
metricName: string
|
||||
) {
|
||||
getMetricMetadata(query: GetMetricMetadataQuery) {
|
||||
const { metricName } = query;
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
this.resourcePath,
|
||||
subscriptionId,
|
||||
resourceGroup,
|
||||
metricDefinition,
|
||||
resourceName,
|
||||
metricNamespace,
|
||||
this.apiVersion
|
||||
this.apiVersion,
|
||||
this.replaceTemplateVariables(query)
|
||||
);
|
||||
|
||||
return this.getResource(url).then((result: any) => {
|
||||
return ResponseParser.parseMetadata(result, metricName);
|
||||
});
|
||||
}
|
||||
|
||||
newGetMetricMetadata(resourceUri: string, metricNamespace: string, metricName: string) {
|
||||
const templateSrv = getTemplateSrv();
|
||||
const url = UrlBuilder.newBuildAzureMonitorGetMetricNamesUrl(
|
||||
this.resourcePath,
|
||||
templateSrv.replace(resourceUri),
|
||||
templateSrv.replace(metricNamespace),
|
||||
this.apiVersion
|
||||
);
|
||||
|
||||
return this.getResource(url).then((result: AzureMonitorMetricsMetadataResponse) => {
|
||||
return ResponseParser.parseMetadata(result, metricName);
|
||||
});
|
||||
@ -398,4 +334,16 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend<AzureM
|
||||
private isValidConfigField(field?: string): boolean {
|
||||
return typeof field === 'string' && field.length > 0;
|
||||
}
|
||||
|
||||
private replaceTemplateVariables<T extends { [K in keyof T]: string }>(query: T) {
|
||||
const templateSrv = getTemplateSrv();
|
||||
|
||||
const workingQuery: { [K in keyof T]: string } = { ...query };
|
||||
const keys = Object.keys(query) as Array<keyof T>;
|
||||
keys.forEach((key) => {
|
||||
workingQuery[key] = templateSrv.replace(workingQuery[key]);
|
||||
});
|
||||
|
||||
return workingQuery;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,19 @@
|
||||
import UrlBuilder from './url_builder';
|
||||
|
||||
describe('AzureMonitorUrlBuilder', () => {
|
||||
describe('buildResourceUri', () => {
|
||||
it('builds a resource uri when the required properties are provided', () => {
|
||||
expect(UrlBuilder.buildResourceUri('sub', 'group', 'Microsoft.NetApp/netAppAccounts', 'name')).toEqual(
|
||||
'/subscriptions/sub/resourceGroups/group/providers/Microsoft.NetApp/netAppAccounts/name'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a resource uri is provided', () => {
|
||||
it('builds a getMetricNamesnamespace url', () => {
|
||||
const url = UrlBuilder.newBuildAzureMonitorGetMetricNamespacesUrl(
|
||||
'',
|
||||
'/subscriptions/sub/resource-uri/resource',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl('', '2017-05-01-preview', {
|
||||
resourceUri: '/subscriptions/sub/resource-uri/resource',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub/resource-uri/resource/providers/microsoft.insights/metricNamespaces?api-version=2017-05-01-preview'
|
||||
);
|
||||
@ -16,12 +22,10 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when a resource uri and metric namespace is provided', () => {
|
||||
it('builds a getMetricNames url', () => {
|
||||
const url = UrlBuilder.newBuildAzureMonitorGetMetricNamesUrl(
|
||||
'',
|
||||
'/subscriptions/sub/resource-uri/resource',
|
||||
'Microsoft.Sql/servers',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', {
|
||||
resourceUri: '/subscriptions/sub/resource-uri/resource',
|
||||
metricNamespace: 'Microsoft.Sql/servers',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub/resource-uri/resource/providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=Microsoft.Sql%2Fservers'
|
||||
);
|
||||
@ -31,14 +35,12 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
describe('Legacy query object', () => {
|
||||
describe('when metric definition is Microsoft.NetApp/netAppAccounts/capacityPools/volumes', () => {
|
||||
it('should build the getMetricNamespaces url in the even longer format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.NetApp/netAppAccounts/capacityPools/volumes',
|
||||
'rn1/rn2/rn3',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes',
|
||||
resourceName: 'rn1/rn2/rn3',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.NetApp/netAppAccounts/rn1/capacityPools/rn2/volumes/rn3/' +
|
||||
'providers/microsoft.insights/metricNamespaces?api-version=2017-05-01-preview'
|
||||
@ -48,14 +50,12 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.Sql/servers/databases', () => {
|
||||
it('should build the getMetricNamespaces url in the longer format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.Sql/servers/databases',
|
||||
'rn1/rn2',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.Sql/servers/databases',
|
||||
resourceName: 'rn1/rn2',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Sql/servers/rn1/databases/rn2/' +
|
||||
'providers/microsoft.insights/metricNamespaces?api-version=2017-05-01-preview'
|
||||
@ -65,14 +65,12 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.Sql/servers', () => {
|
||||
it('should build the getMetricNamespaces url in the shorter format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.Sql/servers',
|
||||
'rn',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.Sql/servers',
|
||||
resourceName: 'rn',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Sql/servers/rn/' +
|
||||
'providers/microsoft.insights/metricNamespaces?api-version=2017-05-01-preview'
|
||||
@ -82,15 +80,13 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.NetApp/netAppAccounts/capacityPools/volumes and the metricNamespace is default', () => {
|
||||
it('should build the getMetricNames url in the even longer format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.NetApp/netAppAccounts/capacityPools/volumes',
|
||||
'rn1/rn2/rn3',
|
||||
'default',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes',
|
||||
resourceName: 'rn1/rn2/rn3',
|
||||
metricNamespace: 'default',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.NetApp/netAppAccounts/rn1/capacityPools/rn2/volumes/rn3/' +
|
||||
'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default'
|
||||
@ -100,15 +96,13 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.Sql/servers/databases and the metricNamespace is default', () => {
|
||||
it('should build the getMetricNames url in the longer format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.Sql/servers/databases',
|
||||
'rn1/rn2',
|
||||
'default',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.Sql/servers/databases',
|
||||
resourceName: 'rn1/rn2',
|
||||
metricNamespace: 'default',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Sql/servers/rn1/databases/rn2/' +
|
||||
'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default'
|
||||
@ -118,15 +112,13 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.Sql/servers and the metricNamespace is default', () => {
|
||||
it('should build the getMetricNames url in the shorter format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.Sql/servers',
|
||||
'rn',
|
||||
'default',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.Sql/servers',
|
||||
resourceName: 'rn',
|
||||
metricNamespace: 'default',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Sql/servers/rn/' +
|
||||
'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default'
|
||||
@ -136,15 +128,13 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.Storage/storageAccounts/blobServices and the metricNamespace is default', () => {
|
||||
it('should build the getMetricNames url in the longer format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.Storage/storageAccounts/blobServices',
|
||||
'rn1/default',
|
||||
'default',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.Storage/storageAccounts/blobServices',
|
||||
resourceName: 'rn1/default',
|
||||
metricNamespace: 'default',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/blobServices/default/' +
|
||||
'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default'
|
||||
@ -154,15 +144,13 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.Storage/storageAccounts/fileServices and the metricNamespace is default', () => {
|
||||
it('should build the getMetricNames url in the longer format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.Storage/storageAccounts/fileServices',
|
||||
'rn1/default',
|
||||
'default',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.Storage/storageAccounts/fileServices',
|
||||
resourceName: 'rn1/default',
|
||||
metricNamespace: 'default',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/fileServices/default/' +
|
||||
'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default'
|
||||
@ -172,15 +160,13 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.Storage/storageAccounts/tableServices and the metricNamespace is default', () => {
|
||||
it('should build the getMetricNames url in the longer format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.Storage/storageAccounts/tableServices',
|
||||
'rn1/default',
|
||||
'default',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.Storage/storageAccounts/tableServices',
|
||||
resourceName: 'rn1/default',
|
||||
metricNamespace: 'default',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/tableServices/default/' +
|
||||
'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default'
|
||||
@ -190,15 +176,13 @@ describe('AzureMonitorUrlBuilder', () => {
|
||||
|
||||
describe('when metric definition is Microsoft.Storage/storageAccounts/queueServices and the metricNamespace is default', () => {
|
||||
it('should build the getMetricNames url in the longer format', () => {
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl(
|
||||
'',
|
||||
'sub1',
|
||||
'rg',
|
||||
'Microsoft.Storage/storageAccounts/queueServices',
|
||||
'rn1/default',
|
||||
'default',
|
||||
'2017-05-01-preview'
|
||||
);
|
||||
const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', {
|
||||
subscription: 'sub1',
|
||||
resourceGroup: 'rg',
|
||||
metricDefinition: 'Microsoft.Storage/storageAccounts/queueServices',
|
||||
resourceName: 'rn1/default',
|
||||
metricNamespace: 'default',
|
||||
});
|
||||
expect(url).toBe(
|
||||
'/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/queueServices/default/' +
|
||||
'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default'
|
||||
|
@ -1,58 +1,47 @@
|
||||
import { GetMetricNamespacesQuery, GetMetricNamesQuery } from '../types';
|
||||
|
||||
export default class UrlBuilder {
|
||||
static buildAzureMonitorGetMetricNamespacesUrl(
|
||||
baseUrl: string,
|
||||
static buildResourceUri(
|
||||
subscriptionId: string,
|
||||
resourceGroup: string,
|
||||
metricDefinition: string,
|
||||
resourceName: string,
|
||||
apiVersion: string
|
||||
resourceName: string
|
||||
) {
|
||||
const metricDefinitionArray = metricDefinition.split('/');
|
||||
const resourceNameArray = resourceName.split('/');
|
||||
const provider = metricDefinitionArray.shift();
|
||||
const urlArray = [baseUrl, 'subscriptions', subscriptionId, 'resourceGroups', resourceGroup, 'providers', provider];
|
||||
const urlArray = ['/subscriptions', subscriptionId, 'resourceGroups', resourceGroup, 'providers', provider];
|
||||
for (const i in metricDefinitionArray) {
|
||||
urlArray.push(metricDefinitionArray[i]);
|
||||
urlArray.push(resourceNameArray[i]);
|
||||
}
|
||||
const urlPrefix = urlArray.join('/');
|
||||
return `${urlPrefix}/providers/microsoft.insights/metricNamespaces?api-version=${apiVersion}`;
|
||||
return urlArray.join('/');
|
||||
}
|
||||
|
||||
static buildAzureMonitorGetMetricNamesUrl(
|
||||
baseUrl: string,
|
||||
subscriptionId: string,
|
||||
resourceGroup: string,
|
||||
metricDefinition: string,
|
||||
resourceName: string,
|
||||
metricNamespace: string,
|
||||
apiVersion: string
|
||||
) {
|
||||
const metricDefinitionArray = metricDefinition.split('/');
|
||||
const resourceNameArray = resourceName.split('/');
|
||||
const provider = metricDefinitionArray.shift();
|
||||
const urlArray = [baseUrl, 'subscriptions', subscriptionId, 'resourceGroups', resourceGroup, 'providers', provider];
|
||||
for (const i in metricDefinitionArray) {
|
||||
urlArray.push(metricDefinitionArray[i]);
|
||||
urlArray.push(resourceNameArray[i]);
|
||||
static buildAzureMonitorGetMetricNamespacesUrl(baseUrl: string, apiVersion: string, query: GetMetricNamespacesQuery) {
|
||||
let resourceUri: string;
|
||||
|
||||
if ('resourceUri' in query) {
|
||||
resourceUri = query.resourceUri;
|
||||
} else {
|
||||
const { subscription, resourceGroup, metricDefinition, resourceName } = query;
|
||||
resourceUri = UrlBuilder.buildResourceUri(subscription, resourceGroup, metricDefinition, resourceName);
|
||||
}
|
||||
const urlPrefix = urlArray.join('/');
|
||||
return (
|
||||
`${urlPrefix}/providers/microsoft.insights/metricdefinitions?api-version=${apiVersion}` +
|
||||
`&metricnamespace=${encodeURIComponent(metricNamespace)}`
|
||||
);
|
||||
}
|
||||
|
||||
static newBuildAzureMonitorGetMetricNamespacesUrl(baseUrl: string, resourceUri: string, apiVersion: string) {
|
||||
return `${baseUrl}${resourceUri}/providers/microsoft.insights/metricNamespaces?api-version=${apiVersion}`;
|
||||
}
|
||||
|
||||
static newBuildAzureMonitorGetMetricNamesUrl(
|
||||
baseUrl: string,
|
||||
resourceUri: string,
|
||||
metricNamespace: string,
|
||||
apiVersion: string
|
||||
) {
|
||||
static buildAzureMonitorGetMetricNamesUrl(baseUrl: string, apiVersion: string, query: GetMetricNamesQuery) {
|
||||
let resourceUri: string;
|
||||
const { metricNamespace } = query;
|
||||
|
||||
if ('resourceUri' in query) {
|
||||
resourceUri = query.resourceUri;
|
||||
} else {
|
||||
const { subscription, resourceGroup, metricDefinition, resourceName } = query;
|
||||
resourceUri = UrlBuilder.buildResourceUri(subscription, resourceGroup, metricDefinition, resourceName);
|
||||
}
|
||||
|
||||
return (
|
||||
`${baseUrl}${resourceUri}/providers/microsoft.insights/metricdefinitions?api-version=${apiVersion}` +
|
||||
`&metricnamespace=${encodeURIComponent(metricNamespace)}`
|
||||
|
@ -79,7 +79,7 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
const mockDatasource = createMockDatasource();
|
||||
const onChange = jest.fn();
|
||||
const mockQuery = createMockQuery();
|
||||
mockDatasource.getMetricNames = jest.fn().mockResolvedValue([
|
||||
mockDatasource.azureMonitorDatasource.getMetricNames = jest.fn().mockResolvedValue([
|
||||
{
|
||||
value: 'metric-a',
|
||||
text: 'Metric A',
|
||||
|
@ -247,11 +247,11 @@ describe('AzureMonitor: metrics dataHooks', () => {
|
||||
.fn()
|
||||
.mockResolvedValue([opt('Web server', 'web-server'), opt('Job server', 'job-server')]);
|
||||
|
||||
datasource.getMetricNames = jest
|
||||
datasource.azureMonitorDatasource.getMetricNames = jest
|
||||
.fn()
|
||||
.mockResolvedValue([opt('Percentage CPU', 'percentage-cpu'), opt('Free memory', 'free-memory')]);
|
||||
|
||||
datasource.getMetricNamespaces = jest
|
||||
datasource.azureMonitorDatasource.getMetricNamespaces = jest
|
||||
.fn()
|
||||
.mockResolvedValue([opt('Compute Virtual Machine', 'azure/vmc'), opt('Database NS', 'azure/dbns')]);
|
||||
});
|
||||
|
@ -153,7 +153,12 @@ export const useMetricNamespaces: DataHook = (query, datasource, onChange, setEr
|
||||
return;
|
||||
}
|
||||
|
||||
const results = await datasource.getMetricNamespaces(subscription, resourceGroup, metricDefinition, resourceName);
|
||||
const results = await datasource.azureMonitorDatasource.getMetricNamespaces({
|
||||
subscription,
|
||||
resourceGroup,
|
||||
metricDefinition,
|
||||
resourceName,
|
||||
});
|
||||
const options = formatOptions(results, metricNamespace);
|
||||
|
||||
// Do some cleanup of the query state if need be
|
||||
@ -180,13 +185,13 @@ export const useMetricNames: DataHook = (query, datasource, onChange, setError)
|
||||
return;
|
||||
}
|
||||
|
||||
const results = await datasource.getMetricNames(
|
||||
const results = await datasource.azureMonitorDatasource.getMetricNames({
|
||||
subscription,
|
||||
resourceGroup,
|
||||
metricDefinition,
|
||||
resourceName,
|
||||
metricNamespace
|
||||
);
|
||||
metricNamespace,
|
||||
});
|
||||
|
||||
const options = formatOptions(results, metricName);
|
||||
|
||||
@ -217,8 +222,8 @@ export const useMetricMetadata = (query: AzureMonitorQuery, datasource: Datasour
|
||||
return;
|
||||
}
|
||||
|
||||
datasource
|
||||
.getMetricMetadata(subscription, resourceGroup, metricDefinition, resourceName, metricNamespace, metricName)
|
||||
datasource.azureMonitorDatasource
|
||||
.getMetricMetadata({ subscription, resourceGroup, metricDefinition, resourceName, metricNamespace, metricName })
|
||||
.then((metadata) => {
|
||||
// TODO: Move the aggregationTypes and timeGrain defaults into `getMetricMetadata`
|
||||
const aggregations = (metadata.supportedAggTypes || [metadata.primaryAggType]).map((v) => ({
|
||||
|
@ -160,7 +160,7 @@ describe('MetricsQueryEditor', () => {
|
||||
const mockDatasource = createMockDatasource({ resourcePickerData });
|
||||
const onChange = jest.fn();
|
||||
const mockQuery = createMockQuery();
|
||||
mockDatasource.azureMonitorDatasource.newGetMetricNames = jest.fn().mockResolvedValue([
|
||||
mockDatasource.azureMonitorDatasource.getMetricNames = jest.fn().mockResolvedValue([
|
||||
{
|
||||
value: 'metric-a',
|
||||
text: 'Metric A',
|
||||
|
@ -130,11 +130,11 @@ describe('AzureMonitor: metrics dataHooks', () => {
|
||||
.fn()
|
||||
.mockResolvedValue([opt('Web server', 'web-server'), opt('Job server', 'job-server')]);
|
||||
|
||||
datasource.azureMonitorDatasource.newGetMetricNames = jest
|
||||
datasource.azureMonitorDatasource.getMetricNames = jest
|
||||
.fn()
|
||||
.mockResolvedValue([opt('Percentage CPU', 'percentage-cpu'), opt('Free memory', 'free-memory')]);
|
||||
|
||||
datasource.azureMonitorDatasource.newGetMetricNamespaces = jest
|
||||
datasource.azureMonitorDatasource.getMetricNamespaces = jest
|
||||
.fn()
|
||||
.mockResolvedValue([opt('Compute Virtual Machine', 'azure/vmc'), opt('Database NS', 'azure/dbns')]);
|
||||
});
|
||||
|
@ -29,7 +29,7 @@ export const useMetricNamespaces: DataHook = (query, datasource, onChange, setEr
|
||||
return;
|
||||
}
|
||||
|
||||
const results = await datasource.azureMonitorDatasource.newGetMetricNamespaces(resourceUri);
|
||||
const results = await datasource.azureMonitorDatasource.getMetricNamespaces({ resourceUri });
|
||||
const options = formatOptions(results, metricNamespace);
|
||||
|
||||
// Do some cleanup of the query state if need be
|
||||
@ -55,7 +55,7 @@ export const useMetricNames: DataHook = (query, datasource, onChange, setError)
|
||||
return;
|
||||
}
|
||||
|
||||
const results = await datasource.azureMonitorDatasource.newGetMetricNames(resourceUri, metricNamespace);
|
||||
const results = await datasource.azureMonitorDatasource.getMetricNames({ resourceUri, metricNamespace });
|
||||
const options = formatOptions(results, metricName);
|
||||
|
||||
return options;
|
||||
@ -87,7 +87,7 @@ export const useMetricMetadata = (query: AzureMonitorQuery, datasource: Datasour
|
||||
}
|
||||
|
||||
datasource.azureMonitorDatasource
|
||||
.newGetMetricMetadata(resourceUri, metricNamespace, metricName)
|
||||
.getMetricMetadata({ resourceUri, metricNamespace, metricName })
|
||||
.then((metadata) => {
|
||||
// TODO: Move the aggregationTypes and timeGrain defaults into `getMetricMetadata`
|
||||
const aggregations = (metadata.supportedAggTypes || [metadata.primaryAggType]).map((v) => ({
|
||||
|
@ -218,49 +218,6 @@ export default class Datasource extends DataSourceApi<AzureMonitorQuery, AzureDa
|
||||
);
|
||||
}
|
||||
|
||||
getMetricNames(
|
||||
subscriptionId: string,
|
||||
resourceGroup: string,
|
||||
metricDefinition: string,
|
||||
resourceName: string,
|
||||
metricNamespace: string
|
||||
) {
|
||||
return this.azureMonitorDatasource.getMetricNames(
|
||||
this.replaceTemplateVariable(subscriptionId),
|
||||
this.replaceTemplateVariable(resourceGroup),
|
||||
this.replaceTemplateVariable(metricDefinition),
|
||||
this.replaceTemplateVariable(resourceName),
|
||||
this.replaceTemplateVariable(metricNamespace)
|
||||
);
|
||||
}
|
||||
|
||||
getMetricNamespaces(subscriptionId: string, resourceGroup: string, metricDefinition: string, resourceName: string) {
|
||||
return this.azureMonitorDatasource.getMetricNamespaces(
|
||||
this.replaceTemplateVariable(subscriptionId),
|
||||
this.replaceTemplateVariable(resourceGroup),
|
||||
this.replaceTemplateVariable(metricDefinition),
|
||||
this.replaceTemplateVariable(resourceName)
|
||||
);
|
||||
}
|
||||
|
||||
getMetricMetadata(
|
||||
subscriptionId: string,
|
||||
resourceGroup: string,
|
||||
metricDefinition: string,
|
||||
resourceName: string,
|
||||
metricNamespace: string,
|
||||
metricName: string
|
||||
) {
|
||||
return this.azureMonitorDatasource.getMetricMetadata(
|
||||
this.replaceTemplateVariable(subscriptionId),
|
||||
this.replaceTemplateVariable(resourceGroup),
|
||||
this.replaceTemplateVariable(metricDefinition),
|
||||
this.replaceTemplateVariable(resourceName),
|
||||
this.replaceTemplateVariable(metricNamespace),
|
||||
this.replaceTemplateVariable(metricName)
|
||||
);
|
||||
}
|
||||
|
||||
/* Application Insights API method */
|
||||
getAppInsightsMetricNames() {
|
||||
return this.appInsightsDatasource?.getMetricNames();
|
||||
|
@ -209,3 +209,50 @@ export interface AzureResourceGraphOptions {
|
||||
allowPartialScopes: boolean;
|
||||
resultFormat: 'objectArray' | 'table';
|
||||
}
|
||||
|
||||
// Azure Monitor Metrics query API data fetcher argument types.
|
||||
// The types prefixed by Legacy are applicable to pre-version 9 of Grafana
|
||||
// that do not have a resourceUri, instead the resourceUri is built up from
|
||||
// the subscription, resource group, metric definition (a.k.a. resource type)
|
||||
// and the resource name.
|
||||
export type GetMetricNamespacesQuery = AzureGetMetricNamespacesQuery | LegacyAzureGetMetricNamespacesQuery;
|
||||
export type GetMetricNamesQuery = AzureGetMetricNamesQuery | LegacyAzureGetMetricNamesQuery;
|
||||
export type GetMetricMetadataQuery = AzureGetMetricMetadataQuery | LegacyAzureGetMetricMetadataQuery;
|
||||
|
||||
export interface AzureGetMetricNamespacesQuery {
|
||||
resourceUri: string;
|
||||
}
|
||||
export interface LegacyAzureGetMetricNamespacesQuery {
|
||||
subscription: string;
|
||||
resourceGroup: string;
|
||||
metricDefinition: string;
|
||||
resourceName: string;
|
||||
}
|
||||
|
||||
export interface AzureGetMetricNamesQuery {
|
||||
resourceUri: string;
|
||||
metricNamespace: string;
|
||||
}
|
||||
|
||||
export interface LegacyAzureGetMetricNamesQuery {
|
||||
subscription: string;
|
||||
resourceGroup: string;
|
||||
metricDefinition: string;
|
||||
resourceName: string;
|
||||
metricNamespace: string;
|
||||
}
|
||||
|
||||
export interface AzureGetMetricMetadataQuery {
|
||||
resourceUri: string;
|
||||
metricNamespace: string;
|
||||
metricName: string;
|
||||
}
|
||||
|
||||
export interface LegacyAzureGetMetricMetadataQuery {
|
||||
subscription: string;
|
||||
resourceGroup: string;
|
||||
metricDefinition: string;
|
||||
resourceName: string;
|
||||
metricNamespace: string;
|
||||
metricName: string;
|
||||
}
|
||||
|
@ -1,13 +1,62 @@
|
||||
import { AzureMonitorQuery, AzureQueryType } from '../types';
|
||||
import migrateQuery from './migrateQuery';
|
||||
|
||||
const azureMonitorQueryV7 = {
|
||||
appInsights: { dimension: [], metricName: 'select', timeGrain: 'auto' },
|
||||
azureLogAnalytics: {
|
||||
query:
|
||||
'//change this example to create your own time series query\n<table name> //the table to query (e.g. Usage, Heartbeat, Perf)\n| where $__timeFilter(TimeGenerated) //this is a macro used to show the full chart’s time range, choose the datetime column here\n| summarize count() by <group by column>, bin(TimeGenerated, $__interval) //change “group by column” to a column in your table, such as “Computer”. The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.\n| order by TimeGenerated asc',
|
||||
resultFormat: 'time_series',
|
||||
workspace: 'mock-workspace-id',
|
||||
},
|
||||
azureMonitor: {
|
||||
aggregation: 'Average',
|
||||
allowedTimeGrainsMs: [60000, 300000, 900000, 1800000, 3600000, 21600000, 43200000, 86400000],
|
||||
dimensionFilters: [{ dimension: 'dependency/success', filter: '', operator: 'eq' }],
|
||||
metricDefinition: 'microsoft.insights/components',
|
||||
metricName: 'dependencies/duration',
|
||||
metricNamespace: 'microsoft.insights/components',
|
||||
resourceGroup: 'cloud-datasources',
|
||||
resourceName: 'AppInsightsTestData',
|
||||
timeGrain: 'auto',
|
||||
top: '10',
|
||||
},
|
||||
insightsAnalytics: {
|
||||
query: '',
|
||||
resultFormat: 'time_series',
|
||||
},
|
||||
queryType: AzureQueryType.AzureMonitor,
|
||||
refId: 'A',
|
||||
subscription: '44693801-6ee6-49de-9b2d-9106972f9572',
|
||||
};
|
||||
|
||||
const azureMonitorQueryV8 = {
|
||||
azureMonitor: {
|
||||
aggregation: 'Average',
|
||||
dimensionFilters: [],
|
||||
metricDefinition: 'microsoft.insights/components',
|
||||
metricName: 'dependencies/duration',
|
||||
metricNamespace: 'microsoft.insights/components',
|
||||
resourceGroup: 'cloud-datasources',
|
||||
resourceName: 'AppInsightsTestData',
|
||||
timeGrain: 'auto',
|
||||
},
|
||||
datasource: {
|
||||
type: 'grafana-azure-monitor-datasource',
|
||||
uid: 'sD-ZuB87k',
|
||||
},
|
||||
queryType: AzureQueryType.AzureMonitor,
|
||||
refId: 'A',
|
||||
subscription: '44693801-6ee6-49de-9b2d-9106972f9572',
|
||||
};
|
||||
|
||||
const modernMetricsQuery: AzureMonitorQuery = {
|
||||
appInsights: { dimension: [], metricName: 'select', timeGrain: 'auto' },
|
||||
azureLogAnalytics: {
|
||||
query:
|
||||
'//change this example to create your own time series query\n<table name> //the table to query (e.g. Usage, Heartbeat, Perf)\n| where $__timeFilter(TimeGenerated) //this is a macro used to show the full chart’s time range, choose the datetime column here\n| summarize count() by <group by column>, bin(TimeGenerated, $__interval) //change “group by column” to a column in your table, such as “Computer”. The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.\n| order by TimeGenerated asc',
|
||||
resultFormat: 'time_series',
|
||||
workspace: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2',
|
||||
workspace: 'mock-workspace-id',
|
||||
},
|
||||
azureMonitor: {
|
||||
aggregation: 'Average',
|
||||
@ -19,6 +68,8 @@ const modernMetricsQuery: AzureMonitorQuery = {
|
||||
metricNamespace: 'microsoft.insights/components',
|
||||
resourceGroup: 'cloud-datasources',
|
||||
resourceName: 'AppInsightsTestData',
|
||||
resourceUri:
|
||||
'/subscriptions/44693801-6ee6-49de-9b2d-9106972f9572/resourceGroups/cloud-datasources/providers/microsoft.insights/components/AppInsightsTestData',
|
||||
timeGrain: 'PT5M',
|
||||
top: '10',
|
||||
},
|
||||
@ -37,4 +88,32 @@ describe('AzureMonitor: migrateQuery', () => {
|
||||
// MUST use .toBe because we want to assert that the identity of unmigrated queries remains the same
|
||||
expect(modernMetricsQuery).toBe(result);
|
||||
});
|
||||
|
||||
describe('migrating from a v7 query to the latest query version', () => {
|
||||
it('should build a resource uri', () => {
|
||||
const result = migrateQuery(azureMonitorQueryV7);
|
||||
expect(result).toMatchObject(
|
||||
expect.objectContaining({
|
||||
azureMonitor: expect.objectContaining({
|
||||
resourceUri:
|
||||
'/subscriptions/44693801-6ee6-49de-9b2d-9106972f9572/resourceGroups/cloud-datasources/providers/microsoft.insights/components/AppInsightsTestData',
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('migrating from a v8 query to the latest query version', () => {
|
||||
it('should build a resource uri', () => {
|
||||
const result = migrateQuery(azureMonitorQueryV8);
|
||||
expect(result).toMatchObject(
|
||||
expect.objectContaining({
|
||||
azureMonitor: expect.objectContaining({
|
||||
resourceUri:
|
||||
'/subscriptions/44693801-6ee6-49de-9b2d-9106972f9572/resourceGroups/cloud-datasources/providers/microsoft.insights/components/AppInsightsTestData',
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
setTimeGrain as setMetricsTimeGrain,
|
||||
} from '../components/MetricsQueryEditor/setQueryValue';
|
||||
import TimegrainConverter from '../time_grain_converter';
|
||||
import UrlBuilder from '../azure_monitor/url_builder';
|
||||
import { AzureMonitorQuery, AzureQueryType, DeprecatedAzureQueryType } from '../types';
|
||||
|
||||
const OLD_DEFAULT_DROPDOWN_VALUE = 'select';
|
||||
@ -21,6 +22,7 @@ export default function migrateQuery(query: AzureMonitorQuery): AzureMonitorQuer
|
||||
workingQuery = migrateToDefaultNamespace(workingQuery);
|
||||
workingQuery = migrateApplicationInsightsDimensions(workingQuery);
|
||||
workingQuery = migrateMetricsDimensionFilters(workingQuery);
|
||||
workingQuery = migrateResourceUri(workingQuery);
|
||||
|
||||
return workingQuery;
|
||||
}
|
||||
@ -121,7 +123,6 @@ function migrateApplicationInsightsDimensions(query: AzureMonitorQuery): AzureMo
|
||||
return query;
|
||||
}
|
||||
|
||||
// Exported because its also used directly in the datasource.ts for some reason
|
||||
function migrateMetricsDimensionFilters(query: AzureMonitorQuery): AzureMonitorQuery {
|
||||
let workingQuery = query;
|
||||
|
||||
@ -133,6 +134,33 @@ function migrateMetricsDimensionFilters(query: AzureMonitorQuery): AzureMonitorQ
|
||||
return workingQuery;
|
||||
}
|
||||
|
||||
// Azure Monitor metric queries prior to Grafana version 9 did not include a `resourceUri`.
|
||||
// The resourceUri was previously constructed with the subscription id, resource group,
|
||||
// metric definition (a.k.a. resource type), and the resource name.
|
||||
function migrateResourceUri(query: AzureMonitorQuery): AzureMonitorQuery {
|
||||
const azureMonitorQuery = query.azureMonitor;
|
||||
|
||||
if (!azureMonitorQuery || azureMonitorQuery.resourceUri) {
|
||||
return query;
|
||||
}
|
||||
|
||||
const { subscription } = query;
|
||||
const { resourceGroup, metricDefinition, resourceName } = azureMonitorQuery;
|
||||
if (!(subscription && resourceGroup && metricDefinition && resourceName)) {
|
||||
return query;
|
||||
}
|
||||
|
||||
const resourceUri = UrlBuilder.buildResourceUri(subscription, resourceGroup, metricDefinition, resourceName);
|
||||
|
||||
return {
|
||||
...query,
|
||||
azureMonitor: {
|
||||
...azureMonitorQuery,
|
||||
resourceUri,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// datasource.ts also contains some migrations, which have been moved to here. Unsure whether
|
||||
// they should also do all the other migrations...
|
||||
export function datasourceMigrations(query: AzureMonitorQuery): AzureMonitorQuery {
|
||||
@ -159,6 +187,7 @@ export function datasourceMigrations(query: AzureMonitorQuery): AzureMonitorQuer
|
||||
|
||||
if (workingQuery.queryType === AzureQueryType.AzureMonitor && workingQuery.azureMonitor) {
|
||||
workingQuery = migrateMetricsDimensionFilters(workingQuery);
|
||||
workingQuery = migrateResourceUri(workingQuery);
|
||||
}
|
||||
|
||||
return workingQuery;
|
||||
|
@ -270,7 +270,9 @@ describe('VariableSupport', () => {
|
||||
azureLogAnalyticsDatasource: {
|
||||
defaultSubscriptionId: 'defaultSubscriptionId',
|
||||
},
|
||||
getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults),
|
||||
azureMonitorDatasource: {
|
||||
getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults),
|
||||
},
|
||||
})
|
||||
);
|
||||
const mockRequest = {
|
||||
@ -296,7 +298,9 @@ describe('VariableSupport', () => {
|
||||
const expectedResults = ['test'];
|
||||
const variableSupport = new VariableSupport(
|
||||
createMockDatasource({
|
||||
getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults),
|
||||
azureMonitorDatasource: {
|
||||
getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults),
|
||||
},
|
||||
})
|
||||
);
|
||||
const mockRequest = {
|
||||
@ -325,7 +329,9 @@ describe('VariableSupport', () => {
|
||||
azureLogAnalyticsDatasource: {
|
||||
defaultSubscriptionId: 'defaultSubscriptionId',
|
||||
},
|
||||
getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults),
|
||||
azureMonitorDatasource: {
|
||||
getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults),
|
||||
},
|
||||
})
|
||||
);
|
||||
const mockRequest = {
|
||||
@ -351,7 +357,9 @@ describe('VariableSupport', () => {
|
||||
const expectedResults = ['test'];
|
||||
const variableSupport = new VariableSupport(
|
||||
createMockDatasource({
|
||||
getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults),
|
||||
azureMonitorDatasource: {
|
||||
getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults),
|
||||
},
|
||||
})
|
||||
);
|
||||
const mockRequest = {
|
||||
@ -478,7 +486,9 @@ describe('VariableSupport', () => {
|
||||
azureLogAnalyticsDatasource: {
|
||||
defaultSubscriptionId: 'defaultSubscriptionId',
|
||||
},
|
||||
getMetricNames: jest.fn().mockResolvedValueOnce([]),
|
||||
azureMonitorDatasource: {
|
||||
getMetricNames: jest.fn().mockResolvedValueOnce([]),
|
||||
},
|
||||
})
|
||||
);
|
||||
const mockRequest = {
|
||||
|
@ -81,22 +81,11 @@ export class VariableSupport extends CustomVariableSupport<DataSource, AzureMoni
|
||||
}
|
||||
|
||||
if (query.kind === 'MetricNamespaceQuery') {
|
||||
return this.datasource.getMetricNamespaces(
|
||||
this.replaceVariable(query.subscription),
|
||||
this.replaceVariable(query.resourceGroup),
|
||||
this.replaceVariable(query.metricDefinition),
|
||||
this.replaceVariable(query.resourceName)
|
||||
);
|
||||
return this.datasource.azureMonitorDatasource.getMetricNamespaces(query);
|
||||
}
|
||||
|
||||
if (query.kind === 'MetricNamesQuery') {
|
||||
return this.datasource.getMetricNames(
|
||||
this.replaceVariable(query.subscription),
|
||||
this.replaceVariable(query.resourceGroup),
|
||||
this.replaceVariable(query.metricDefinition),
|
||||
this.replaceVariable(query.resourceName),
|
||||
this.replaceVariable(query.metricNamespace)
|
||||
);
|
||||
return this.datasource.azureMonitorDatasource.getMetricNames(query);
|
||||
}
|
||||
|
||||
if (query.kind === 'WorkspacesQuery') {
|
||||
|
Loading…
Reference in New Issue
Block a user