Azure: Variable editor and resource picker improvements (#101695)

* Update namespace endpoint to filter out only relevant namespaces

* Update tests

* Fix url builder tests

* Add todo comments

* Update func to use ARG to retrieve namespaces with metrics

* Refactor getMetricNamespaces for readability

* Lint

* Remove comments

* Remove type assertion

* Refactor ARG query

* Update tests and refactor class to use ARG

* Update resource group query

- Updates the resource groups query to support users/apps with restricted permissions

* Update resources request to be paginated

- Also order by name
- Add tests

* Start refactoring azure monitor util functions to resource graph

* Minor lint

* Add getMetricNamespaces resource graph function

* Modify getMetricNamespaces call

- Use resource graph function for variable queries

* Return names for getResourceNames values

* Use getMetricNamespaces variable specific req in editor

* Substantial refactor

- Update Azure Resource Graph data source with a method for making paged requests and a method for retrieving metric namespaces (and add tests)
- Extract helpers from azure_monitor_datasource to utils and generalise them (also revert previous changes to datasource and test file)
- Update mock with Azure Resource Graph data source
- Revert response parser changes
- Revert url builder changes
- Update get metric namespaces query to use the resource graph method for variable queries
- Update docs

* Lint

* Oops

* Fix type

* Lint and betterer

* Simplify imports

* Improve type

* Simplify resource picker class

* Start updating tests

* Fix naming and include missing error

* Update resource graph data source mock

* Update tests

* Remove unneeded parser

* Add get subscriptions to resource graph

* Generalise resource groups request

* Fix resource names request to ensure no clashing

* Update types

* Use resource graph queries for resource picker

* Correctly map resource group names

* Update mocks

* Update tests

* Fix mapping

* Refactor getResourceNames

- Remove most of the logic from resourcePickerData
- Add helper for parsing resource names as template vars
- Some renames for clarity
- Update types
- Update tests

* Ensure namespaces are lowercase

* Update docs/sources/datasources/azure-monitor/template-variables/index.md

Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com>

* Prettier write

* Ensure we return all namespaces if resourceGroup isn't specified

---------

Co-authored-by: alyssabull <alyssabull@gmail.com>
Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com>
This commit is contained in:
Andreas Christou
2025-03-06 19:08:35 +00:00
committed by GitHub
parent 32624b3251
commit c7b0bbd262
16 changed files with 313 additions and 424 deletions

View File

@ -1,3 +1,4 @@
import { startsWith } from 'lodash';
import { from, lastValueFrom, Observable } from 'rxjs';
import {
@ -13,10 +14,26 @@ import UrlBuilder from './azure_monitor/url_builder';
import VariableEditor from './components/VariableEditor/VariableEditor';
import DataSource from './datasource';
import { migrateQuery } from './grafanaTemplateVariableFns';
import { AzureMonitorQuery, AzureQueryType } from './types';
import { AzureMonitorQuery, AzureQueryType, RawAzureResourceItem } from './types';
import { GrafanaTemplateVariableQuery } from './types/templateVariables';
import messageFromError from './utils/messageFromError';
export function parseResourceNamesAsTemplateVariable(resources: RawAzureResourceItem[], metricNamespace?: string) {
return resources.map((r) => {
if (startsWith(metricNamespace?.toLowerCase(), 'microsoft.storage/storageaccounts/')) {
return {
text: r.name + '/default',
value: r.name + '/default',
};
}
return {
text: r.name,
value: r.name,
};
});
}
export class VariableSupport extends CustomVariableSupport<DataSource, AzureMonitorQuery> {
constructor(
private readonly datasource: DataSource,
@ -67,14 +84,14 @@ export class VariableSupport extends CustomVariableSupport<DataSource, AzureMoni
return { data: [] };
case AzureQueryType.ResourceNamesQuery:
if (queryObj.subscription && this.hasValue(queryObj.subscription)) {
const rgs = await this.datasource.getResourceNames(
const resources = await this.datasource.getResourceNames(
queryObj.subscription,
queryObj.resourceGroup,
queryObj.namespace,
queryObj.region
);
return {
data: rgs?.length ? [toDataFrame(rgs)] : [],
data: resources?.length ? [toDataFrame(parseResourceNamesAsTemplateVariable(resources))] : [],
};
}
return { data: [] };
@ -201,15 +218,28 @@ export class VariableSupport extends CustomVariableSupport<DataSource, AzureMoni
}
if (query.kind === 'ResourceGroupsQuery') {
return this.datasource.getResourceGroups(this.replaceVariable(query.subscription));
return this.datasource.getResourceGroups(this.replaceVariable(query.subscription)).then((rgs) => {
if (rgs.length > 0) {
return rgs.map((rg) => ({ text: rg.resourceGroupName, value: rg.resourceGroupName }));
}
return [];
});
}
if (query.kind === 'ResourceNamesQuery') {
return this.datasource.getResourceNames(
this.replaceVariable(query.subscription),
this.replaceVariable(query.resourceGroup),
this.replaceVariable(query.metricNamespace)
);
return this.datasource
.getResourceNames(
this.replaceVariable(query.subscription),
this.replaceVariable(query.resourceGroup),
this.replaceVariable(query.metricNamespace)
)
.then((resources) => {
if (resources.length > 0) {
return parseResourceNamesAsTemplateVariable(resources, query.metricNamespace);
}
return [];
});
}
if (query.kind === 'MetricNamespaceQuery') {