mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AzureMonitor: Ensure legacy properties containing template variables are correctly migrated (#68697)
* Update migration ordering - Update migration in applyTemplateVariables to account for interpolation from expression datasource - Update mock to ensure overrides are passed through correctly - Update tests - Update migrateQuery function name for clarity * Fix tests * Remove comment
This commit is contained in:
parent
bca8428f63
commit
0be29b4c78
@ -183,6 +183,47 @@ describe('AzureMonitorDatasource', () => {
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should migrate legacy properties before interpolation', () => {
|
||||
templateSrv.init([
|
||||
{
|
||||
id: 'resourcegroup',
|
||||
name: 'resourcegroup',
|
||||
current: {
|
||||
value: `test-rg`,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'resourcename',
|
||||
name: 'resourcename',
|
||||
current: {
|
||||
value: `test-resource`,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'metric',
|
||||
name: 'metric',
|
||||
current: {
|
||||
value: `test-ns`,
|
||||
},
|
||||
},
|
||||
]);
|
||||
const query = createMockQuery({
|
||||
azureMonitor: {
|
||||
metricDefinition: '$metric',
|
||||
resourceGroup: '$resourcegroup',
|
||||
resourceName: '$resourcename',
|
||||
metricNamespace: undefined,
|
||||
},
|
||||
});
|
||||
const templatedQuery = ctx.ds.azureMonitorDatasource.applyTemplateVariables(query, {});
|
||||
expect(templatedQuery).toMatchObject({
|
||||
azureMonitor: {
|
||||
metricNamespace: 'test-ns',
|
||||
resources: [{ resourceGroup: 'test-rg', resourceName: 'test-resource' }],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When performing getMetricNamespaces', () => {
|
||||
|
@ -84,29 +84,46 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend<AzureM
|
||||
}
|
||||
|
||||
applyTemplateVariables(target: AzureMonitorQuery, scopedVars: ScopedVars): AzureMonitorQuery {
|
||||
const item = target.azureMonitor;
|
||||
const preMigrationQuery = target.azureMonitor;
|
||||
|
||||
if (!item) {
|
||||
// return target;
|
||||
if (!preMigrationQuery) {
|
||||
throw new Error('Query is not a valid Azure Monitor Metrics query');
|
||||
}
|
||||
|
||||
// fix for timeGrainUnit which is a deprecated/removed field name
|
||||
if (item.timeGrain && item.timeGrainUnit && item.timeGrain !== 'auto') {
|
||||
item.timeGrain = TimegrainConverter.createISO8601Duration(item.timeGrain, item.timeGrainUnit);
|
||||
}
|
||||
|
||||
const templateSrv = getTemplateSrv();
|
||||
|
||||
const subscriptionId = templateSrv.replace(target.subscription || this.defaultSubscriptionId, scopedVars);
|
||||
const resources = item.resources?.map((r) => this.replaceTemplateVariables(r, scopedVars)).flat();
|
||||
const metricNamespace = templateSrv.replace(item.metricNamespace, scopedVars);
|
||||
const customNamespace = templateSrv.replace(item.customNamespace, scopedVars);
|
||||
const timeGrain = templateSrv.replace((item.timeGrain || '').toString(), scopedVars);
|
||||
const aggregation = templateSrv.replace(item.aggregation, scopedVars);
|
||||
const top = templateSrv.replace(item.top || '', scopedVars);
|
||||
// These properties need to be replaced pre-migration to ensure values are correctly interpolated
|
||||
if (preMigrationQuery.resourceUri) {
|
||||
preMigrationQuery.resourceUri = templateSrv.replace(preMigrationQuery.resourceUri, scopedVars);
|
||||
}
|
||||
if (preMigrationQuery.metricDefinition) {
|
||||
preMigrationQuery.metricDefinition = templateSrv.replace(preMigrationQuery.metricDefinition, scopedVars);
|
||||
}
|
||||
|
||||
const dimensionFilters = (item.dimensionFilters ?? [])
|
||||
// fix for timeGrainUnit which is a deprecated/removed field name
|
||||
if (preMigrationQuery.timeGrain && preMigrationQuery.timeGrainUnit && preMigrationQuery.timeGrain !== 'auto') {
|
||||
preMigrationQuery.timeGrain = TimegrainConverter.createISO8601Duration(
|
||||
preMigrationQuery.timeGrain,
|
||||
preMigrationQuery.timeGrainUnit
|
||||
);
|
||||
}
|
||||
|
||||
const migratedTarget = migrateQuery(target);
|
||||
const migratedQuery = migratedTarget.azureMonitor;
|
||||
// This should never be triggered because the above error would've been thrown
|
||||
if (!migratedQuery) {
|
||||
throw new Error('Query is not a valid Azure Monitor Metrics query');
|
||||
}
|
||||
|
||||
const subscriptionId = templateSrv.replace(migratedTarget.subscription || this.defaultSubscriptionId, scopedVars);
|
||||
const resources = migratedQuery.resources?.map((r) => this.replaceTemplateVariables(r, scopedVars)).flat();
|
||||
const metricNamespace = templateSrv.replace(migratedQuery.metricNamespace, scopedVars);
|
||||
const customNamespace = templateSrv.replace(migratedQuery.customNamespace, scopedVars);
|
||||
const timeGrain = templateSrv.replace((migratedQuery.timeGrain || '').toString(), scopedVars);
|
||||
const aggregation = templateSrv.replace(migratedQuery.aggregation, scopedVars);
|
||||
const top = templateSrv.replace(migratedQuery.top || '', scopedVars);
|
||||
|
||||
const dimensionFilters = (migratedQuery.dimensionFilters ?? [])
|
||||
.filter((f) => f.dimension && f.dimension !== 'None')
|
||||
.map((f) => {
|
||||
const filters = f.filters?.map((filter) => templateSrv.replace(filter ?? '', scopedVars));
|
||||
@ -118,32 +135,26 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend<AzureM
|
||||
});
|
||||
|
||||
const azMonitorQuery: AzureMetricQuery = {
|
||||
...item,
|
||||
...migratedQuery,
|
||||
resources,
|
||||
metricNamespace,
|
||||
customNamespace,
|
||||
timeGrain,
|
||||
allowedTimeGrainsMs: item.allowedTimeGrainsMs,
|
||||
metricName: templateSrv.replace(item.metricName, scopedVars),
|
||||
region: templateSrv.replace(item.region, scopedVars),
|
||||
allowedTimeGrainsMs: migratedQuery.allowedTimeGrainsMs,
|
||||
metricName: templateSrv.replace(migratedQuery.metricName, scopedVars),
|
||||
region: templateSrv.replace(migratedQuery.region, scopedVars),
|
||||
aggregation: aggregation,
|
||||
dimensionFilters,
|
||||
top: top || '10',
|
||||
alias: item.alias,
|
||||
alias: migratedQuery.alias,
|
||||
};
|
||||
if (item.metricDefinition) {
|
||||
azMonitorQuery.metricDefinition = templateSrv.replace(item.metricDefinition, scopedVars);
|
||||
}
|
||||
if (item.resourceUri) {
|
||||
azMonitorQuery.resourceUri = templateSrv.replace(item.resourceUri, scopedVars);
|
||||
}
|
||||
|
||||
return migrateQuery({
|
||||
return {
|
||||
...target,
|
||||
subscription: subscriptionId,
|
||||
queryType: AzureQueryType.AzureMonitor,
|
||||
azureMonitor: azMonitorQuery,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
async getSubscriptions(): Promise<Array<{ text: string; value: string }>> {
|
||||
|
@ -25,7 +25,7 @@ export default function migrateQuery(query: AzureMonitorQuery): AzureMonitorQuer
|
||||
workingQuery = migrateToDefaultNamespace(workingQuery);
|
||||
workingQuery = migrateDimensionToDimensionFilter(workingQuery);
|
||||
workingQuery = migrateDimensionFilterToArray(workingQuery);
|
||||
workingQuery = migrateDimensionToResourceObj(workingQuery);
|
||||
workingQuery = migrateResourceUriToResourceObj(workingQuery);
|
||||
}
|
||||
|
||||
if (workingQuery.azureMonitor?.resourceGroup || workingQuery.azureMonitor?.resourceName) {
|
||||
@ -154,7 +154,7 @@ function migrateDimensionFilterToArray(query: AzureMonitorQuery): AzureMonitorQu
|
||||
return query;
|
||||
}
|
||||
|
||||
function migrateDimensionToResourceObj(query: AzureMonitorQuery): AzureMonitorQuery {
|
||||
function migrateResourceUriToResourceObj(query: AzureMonitorQuery): AzureMonitorQuery {
|
||||
if (query.azureMonitor?.resourceUri && !query.azureMonitor.resourceUri.startsWith('$')) {
|
||||
const details = parseResourceDetails(query.azureMonitor.resourceUri);
|
||||
const isWellFormedUri = details?.subscription && details?.resourceGroup && details?.resourceName;
|
||||
|
Loading…
Reference in New Issue
Block a user