AzureMonitor: Fix ResourcePicker hanging (#71886)

* AzureMonitor: Fix ResourcePicker hanging

Removed location fetching for every subscription.

Fixes #70523

* fix region for multi metricnames

* fix tests

* fix e2e

* remove regions/locations from variable editor

* remove region pieces from e2e
This commit is contained in:
Adam Simpson 2023-07-25 10:18:03 -04:00 committed by GitHub
parent d31d175109
commit 722f787eaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 16 additions and 156 deletions

View File

@ -126,10 +126,6 @@ const addAzureMonitorVariable = (
.input() .input()
.find('input') .find('input')
.type(`${options?.namespace}{enter}`); .type(`${options?.namespace}{enter}`);
e2eSelectors.variableEditor.region
.input()
.find('input')
.type(`${options?.region}{enter}`);
break; break;
case AzureQueryType.MetricNamesQuery: case AzureQueryType.MetricNamesQuery:
e2eSelectors.variableEditor.subscription e2eSelectors.variableEditor.subscription
@ -207,14 +203,11 @@ e2e.scenario({
zone: 'Coordinated Universal Time', zone: 'Coordinated Universal Time',
}, },
}); });
e2e()
.intercept(/locations/)
.as('locations');
e2e.flows.addPanel({ e2e.flows.addPanel({
dataSourceName, dataSourceName,
visitDashboardAtStart: false, visitDashboardAtStart: false,
queriesForm: () => { queriesForm: () => {
e2eSelectors.queryEditor.resourcePicker.select.button().click().wait('@locations'); e2eSelectors.queryEditor.resourcePicker.select.button().click();
e2eSelectors.queryEditor.resourcePicker.search e2eSelectors.queryEditor.resourcePicker.search
.input() .input()
.wait(100) .wait(100)
@ -309,14 +302,10 @@ e2e.scenario({
subscription: '$subscription', subscription: '$subscription',
resourceGroup: '$resourceGroups', resourceGroup: '$resourceGroups',
}); });
addAzureMonitorVariable('region', AzureQueryType.LocationsQuery, false, {
subscription: '$subscription',
});
addAzureMonitorVariable('resource', AzureQueryType.ResourceNamesQuery, false, { addAzureMonitorVariable('resource', AzureQueryType.ResourceNamesQuery, false, {
subscription: '$subscription', subscription: '$subscription',
resourceGroup: '$resourceGroups', resourceGroup: '$resourceGroups',
namespace: '$namespace', namespace: '$namespace',
region: '$region',
}); });
e2e.pages.Dashboard.SubMenu.submenuItemLabels('subscription').click(); e2e.pages.Dashboard.SubMenu.submenuItemLabels('subscription').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('grafanalabs-datasources-dev').click(); e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('grafanalabs-datasources-dev').click();
@ -330,8 +319,6 @@ e2e.scenario({
.parent() .parent()
.find('input') .find('input')
.type('microsoft.storage/storageaccounts{downArrow}{enter}'); .type('microsoft.storage/storageaccounts{downArrow}{enter}');
e2e.pages.Dashboard.SubMenu.submenuItemLabels('region').parent().find('button').click();
e2e.pages.Dashboard.SubMenu.submenuItemLabels('region').parent().find('input').type('uk south{downArrow}{enter}');
e2e.pages.Dashboard.SubMenu.submenuItemLabels('resource').parent().find('button').click(); e2e.pages.Dashboard.SubMenu.submenuItemLabels('resource').parent().find('button').click();
e2e.pages.Dashboard.SubMenu.submenuItemLabels('resource') e2e.pages.Dashboard.SubMenu.submenuItemLabels('resource')
.parent() .parent()
@ -346,7 +333,6 @@ e2e.scenario({
e2eSelectors.queryEditor.resourcePicker.advanced.subscription.input().find('input').type('$subscription'); e2eSelectors.queryEditor.resourcePicker.advanced.subscription.input().find('input').type('$subscription');
e2eSelectors.queryEditor.resourcePicker.advanced.resourceGroup.input().find('input').type('$resourceGroups'); e2eSelectors.queryEditor.resourcePicker.advanced.resourceGroup.input().find('input').type('$resourceGroups');
e2eSelectors.queryEditor.resourcePicker.advanced.namespace.input().find('input').type('$namespaces'); e2eSelectors.queryEditor.resourcePicker.advanced.namespace.input().find('input').type('$namespaces');
e2eSelectors.queryEditor.resourcePicker.advanced.region.input().find('input').type('$region');
e2eSelectors.queryEditor.resourcePicker.advanced.resource.input().find('input').type('$resource'); e2eSelectors.queryEditor.resourcePicker.advanced.resource.input().find('input').type('$resource');
e2eSelectors.queryEditor.resourcePicker.apply.button().click(); e2eSelectors.queryEditor.resourcePicker.apply.button().click();
e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Transactions{enter}'); e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Transactions{enter}');

View File

@ -1,5 +1,4 @@
import { ResourceRowGroup, ResourceRowType } from '../components/ResourcePicker/types'; import { ResourceRowGroup, ResourceRowType } from '../components/ResourcePicker/types';
import { AzureMonitorLocations } from '../types';
export const createMockSubscriptions = (): ResourceRowGroup => [ export const createMockSubscriptions = (): ResourceRowGroup => [
{ {
@ -133,6 +132,3 @@ export const mockSearchResults = (): ResourceRowGroup => [
location: 'northeurope', location: 'northeurope',
}, },
]; ];
export const mockGetValidLocations = (): Map<string, AzureMonitorLocations> =>
new Map([['northeurope', { displayName: 'North Europe', name: 'northeurope', supportsLogs: true }]]);

View File

@ -10,7 +10,6 @@ import createMockQuery from '../../__mocks__/query';
import { import {
createMockResourceGroupsBySubscription, createMockResourceGroupsBySubscription,
createMockSubscriptions, createMockSubscriptions,
mockGetValidLocations,
mockResourcesByResourceGroup, mockResourcesByResourceGroup,
} from '../../__mocks__/resourcePickerRows'; } from '../../__mocks__/resourcePickerRows';
import { selectors } from '../../e2e/selectors'; import { selectors } from '../../e2e/selectors';
@ -46,7 +45,6 @@ export function createMockResourcePickerData() {
mockResourcePicker.getResourcesForResourceGroup = jest.fn().mockResolvedValue(mockResourcesByResourceGroup()); mockResourcePicker.getResourcesForResourceGroup = jest.fn().mockResolvedValue(mockResourcesByResourceGroup());
mockResourcePicker.getResourceURIFromWorkspace = jest.fn().mockReturnValue(''); mockResourcePicker.getResourceURIFromWorkspace = jest.fn().mockReturnValue('');
mockResourcePicker.getResourceURIDisplayProperties = jest.fn().mockResolvedValue({}); mockResourcePicker.getResourceURIDisplayProperties = jest.fn().mockResolvedValue({});
mockResourcePicker.getLocations = jest.fn().mockResolvedValue(mockGetValidLocations());
return mockResourcePicker; return mockResourcePicker;
} }

View File

@ -128,7 +128,8 @@ const defaultMetricMetadata: MetricMetadata = {
export const useMetricMetadata = (query: AzureMonitorQuery, datasource: Datasource, onChange: OnChangeFn) => { export const useMetricMetadata = (query: AzureMonitorQuery, datasource: Datasource, onChange: OnChangeFn) => {
const [metricMetadata, setMetricMetadata] = useState<MetricMetadata>(defaultMetricMetadata); const [metricMetadata, setMetricMetadata] = useState<MetricMetadata>(defaultMetricMetadata);
const { subscription } = query; const { subscription } = query;
const { resources, metricNamespace, metricName, aggregation, timeGrain, customNamespace } = query.azureMonitor ?? {}; const { resources, metricNamespace, metricName, aggregation, timeGrain, customNamespace, region } =
query.azureMonitor ?? {};
const { resourceGroup, resourceName } = getResourceGroupAndName(resources); const { resourceGroup, resourceName } = getResourceGroupAndName(resources);
const multipleResources = (resources && resources.length > 1) ?? false; const multipleResources = (resources && resources.length > 1) ?? false;
@ -138,11 +139,11 @@ export const useMetricMetadata = (query: AzureMonitorQuery, datasource: Datasour
setMetricMetadata(defaultMetricMetadata); setMetricMetadata(defaultMetricMetadata);
return; return;
} }
datasource.azureMonitorDatasource datasource.azureMonitorDatasource
.getMetricMetadata( .getMetricMetadata(
{ subscription, resourceGroup, resourceName, metricNamespace, metricName, customNamespace }, { subscription, resourceGroup, resourceName, metricNamespace, metricName, customNamespace },
multipleResources multipleResources,
region
) )
.then((metadata) => { .then((metadata) => {
// TODO: Move the aggregationTypes and timeGrain defaults into `getMetricMetadata` // TODO: Move the aggregationTypes and timeGrain defaults into `getMetricMetadata`
@ -161,6 +162,7 @@ export const useMetricMetadata = (query: AzureMonitorQuery, datasource: Datasour
}); });
}); });
}, [ }, [
region,
datasource, datasource,
subscription, subscription,
resourceGroup, resourceGroup,

View File

@ -78,7 +78,7 @@ const NestedRow = ({
<td className={styles.cell}>{row.typeLabel}</td> <td className={styles.cell}>{row.typeLabel}</td>
<td className={styles.cell}>{row.locationDisplayName ?? '-'}</td> <td className={styles.cell}>{row.location ?? '-'}</td>
</tr> </tr>
{isOpen && {isOpen &&

View File

@ -12,7 +12,6 @@ export interface ResourceRow {
name: string; name: string;
type: ResourceRowType; type: ResourceRowType;
typeLabel: string; typeLabel: string;
locationDisplayName?: string;
location?: string; location?: string;
children?: ResourceRowGroup; children?: ResourceRowGroup;
} }

View File

@ -258,12 +258,10 @@ describe('VariableEditor:', () => {
await waitFor(() => expect(screen.getByText('Logs')).toBeInTheDocument()); await waitFor(() => expect(screen.getByText('Logs')).toBeInTheDocument());
await selectAndRerender('select query type', 'Resource Names', onChange, rerender); await selectAndRerender('select query type', 'Resource Names', onChange, rerender);
await selectAndRerender('select subscription', 'Primary Subscription', onChange, rerender); await selectAndRerender('select subscription', 'Primary Subscription', onChange, rerender);
await selectAndRerender('select region', 'North Europe', onChange, rerender);
expect(onChange).toHaveBeenCalledWith( expect(onChange).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
queryType: AzureQueryType.ResourceNamesQuery, queryType: AzureQueryType.ResourceNamesQuery,
subscription: 'sub', subscription: 'sub',
region: 'northeurope',
refId: 'A', refId: 'A',
}) })
); );
@ -325,21 +323,5 @@ describe('VariableEditor:', () => {
}) })
); );
}); });
it('should run the query if requesting regions', async () => {
const onChange = jest.fn();
const { rerender } = render(<VariableEditor {...defaultProps} onChange={onChange} />);
// wait for initial load
await waitFor(() => expect(screen.getByText('Logs')).toBeInTheDocument());
await selectAndRerender('select query type', 'Regions', onChange, rerender);
await selectAndRerender('select subscription', 'Primary Subscription', onChange, rerender);
expect(onChange).toHaveBeenCalledWith(
expect.objectContaining({
queryType: AzureQueryType.LocationsQuery,
subscription: 'sub',
refId: 'A',
})
);
});
}); });
}); });

View File

@ -30,7 +30,6 @@ const VariableEditor = (props: Props) => {
{ label: 'Subscriptions', value: AzureQueryType.SubscriptionsQuery }, { label: 'Subscriptions', value: AzureQueryType.SubscriptionsQuery },
{ label: 'Resource Groups', value: AzureQueryType.ResourceGroupsQuery }, { label: 'Resource Groups', value: AzureQueryType.ResourceGroupsQuery },
{ label: 'Namespaces', value: AzureQueryType.NamespacesQuery }, { label: 'Namespaces', value: AzureQueryType.NamespacesQuery },
{ label: 'Regions', value: AzureQueryType.LocationsQuery },
{ label: 'Resource Names', value: AzureQueryType.ResourceNamesQuery }, { label: 'Resource Names', value: AzureQueryType.ResourceNamesQuery },
{ label: 'Metric Names', value: AzureQueryType.MetricNamesQuery }, { label: 'Metric Names', value: AzureQueryType.MetricNamesQuery },
{ label: 'Workspaces', value: AzureQueryType.WorkspacesQuery }, { label: 'Workspaces', value: AzureQueryType.WorkspacesQuery },
@ -51,7 +50,6 @@ const VariableEditor = (props: Props) => {
const [requireSubscription, setRequireSubscription] = useState(false); const [requireSubscription, setRequireSubscription] = useState(false);
const [hasResourceGroup, setHasResourceGroup] = useState(false); const [hasResourceGroup, setHasResourceGroup] = useState(false);
const [hasNamespace, setHasNamespace] = useState(false); const [hasNamespace, setHasNamespace] = useState(false);
const [hasRegion, setHasRegion] = useState(false);
const [requireResourceGroup, setRequireResourceGroup] = useState(false); const [requireResourceGroup, setRequireResourceGroup] = useState(false);
const [requireNamespace, setRequireNamespace] = useState(false); const [requireNamespace, setRequireNamespace] = useState(false);
const [requireResource, setRequireResource] = useState(false); const [requireResource, setRequireResource] = useState(false);
@ -59,7 +57,6 @@ const VariableEditor = (props: Props) => {
const [resourceGroups, setResourceGroups] = useState<SelectableValue[]>([]); const [resourceGroups, setResourceGroups] = useState<SelectableValue[]>([]);
const [namespaces, setNamespaces] = useState<SelectableValue[]>([]); const [namespaces, setNamespaces] = useState<SelectableValue[]>([]);
const [resources, setResources] = useState<SelectableValue[]>([]); const [resources, setResources] = useState<SelectableValue[]>([]);
const [regions, setRegions] = useState<SelectableValue[]>([]);
const [errorMessage, setError] = useLastError(); const [errorMessage, setError] = useLastError();
const queryType = typeof query === 'string' ? '' : query.queryType; const queryType = typeof query === 'string' ? '' : query.queryType;
@ -91,7 +88,6 @@ const VariableEditor = (props: Props) => {
setRequireSubscription(true); setRequireSubscription(true);
setHasResourceGroup(true); setHasResourceGroup(true);
setHasNamespace(true); setHasNamespace(true);
setHasRegion(true);
break; break;
case AzureQueryType.MetricNamesQuery: case AzureQueryType.MetricNamesQuery:
setRequireSubscription(true); setRequireSubscription(true);
@ -99,9 +95,6 @@ const VariableEditor = (props: Props) => {
setRequireNamespace(true); setRequireNamespace(true);
setRequireResource(true); setRequireResource(true);
break; break;
case AzureQueryType.LocationsQuery:
setRequireSubscription(true);
break;
} }
}, [queryType]); }, [queryType]);
@ -142,16 +135,6 @@ const VariableEditor = (props: Props) => {
} }
}, [datasource, subscription, resourceGroup]); }, [datasource, subscription, resourceGroup]);
useEffect(() => {
if (subscription) {
datasource.azureMonitorDatasource.getLocations([subscription]).then((rgs) => {
const regions: SelectableValue[] = [];
rgs.forEach((r) => regions.push({ label: r.displayName, value: r.name }));
setRegions(regions);
});
}
}, [datasource, subscription, resourceGroup]);
const namespace = (typeof query === 'object' && query.namespace) || ''; const namespace = (typeof query === 'object' && query.namespace) || '';
useEffect(() => { useEffect(() => {
if (subscription) { if (subscription) {
@ -208,13 +191,6 @@ const VariableEditor = (props: Props) => {
}); });
}; };
const onChangeRegion = (selectableValue: SelectableValue) => {
onChange({
...query,
region: selectableValue.value,
});
};
const onChangeResource = (selectableValue: SelectableValue) => { const onChangeResource = (selectableValue: SelectableValue) => {
onChange({ onChange({
...query, ...query,
@ -320,22 +296,6 @@ const VariableEditor = (props: Props) => {
/> />
</InlineField> </InlineField>
)} )}
{hasRegion && (
<InlineField
label="Select region"
labelWidth={20}
data-testid={selectors.components.variableEditor.region.input}
>
<Select
aria-label="select region"
onChange={onChangeRegion}
options={regions.concat(variableOptionGroup)}
width={25}
value={query.region || null}
placeholder="Optional"
/>
</InlineField>
)}
{requireResource && ( {requireResource && (
<InlineField <InlineField
label="Select resource" label="Select resource"

View File

@ -5,7 +5,6 @@ import {
} from '../__mocks__/argResourcePickerResponse'; } from '../__mocks__/argResourcePickerResponse';
import createMockDatasource from '../__mocks__/datasource'; import createMockDatasource from '../__mocks__/datasource';
import { createMockInstanceSetttings } from '../__mocks__/instanceSettings'; import { createMockInstanceSetttings } from '../__mocks__/instanceSettings';
import { mockGetValidLocations } from '../__mocks__/resourcePickerRows';
import { ResourceRowType } from '../components/ResourcePicker/types'; import { ResourceRowType } from '../components/ResourcePicker/types';
import { AzureGraphResponse } from '../types'; import { AzureGraphResponse } from '../types';
@ -32,11 +31,7 @@ const createResourcePickerData = (responses: AzureGraphResponse[]) => {
postResource.mockResolvedValueOnce(res); postResource.mockResolvedValueOnce(res);
}); });
resourcePickerData.postResource = postResource; resourcePickerData.postResource = postResource;
const locationsMap = mockGetValidLocations(); return { resourcePickerData, postResource, mockDatasource };
const getLocations = jest.spyOn(resourcePickerData, 'getLocations').mockResolvedValue(locationsMap);
resourcePickerData.locationsMap = locationsMap;
resourcePickerData.locations = Array.from(locationsMap.values()).map((location) => `"${location.name}"`);
return { resourcePickerData, postResource, mockDatasource, getValidLocations: getLocations };
}; };
describe('AzureMonitor resourcePickerData', () => { describe('AzureMonitor resourcePickerData', () => {
@ -252,7 +247,7 @@ describe('AzureMonitor resourcePickerData', () => {
name: 'web-server', name: 'web-server',
type: 'Resource', type: 'Resource',
location: 'northeurope', location: 'northeurope',
locationDisplayName: 'North Europe', locationDisplayName: 'northeurope',
resourceGroupName: 'dev', resourceGroupName: 'dev',
typeLabel: 'Microsoft.Compute/virtualMachines', typeLabel: 'Microsoft.Compute/virtualMachines',
uri: '/subscriptions/def-456/resourceGroups/dev/providers/Microsoft.Compute/virtualMachines/web-server', uri: '/subscriptions/def-456/resourceGroups/dev/providers/Microsoft.Compute/virtualMachines/web-server',
@ -329,7 +324,7 @@ describe('AzureMonitor resourcePickerData', () => {
id: 'vmname', id: 'vmname',
name: 'vmName', name: 'vmName',
type: 'Resource', type: 'Resource',
location: 'North Europe', location: 'northeurope',
resourceGroupName: 'rgName', resourceGroupName: 'rgName',
typeLabel: 'Virtual machines', typeLabel: 'Virtual machines',
uri: '/subscriptions/subId/resourceGroups/rgName/providers/Microsoft.Compute/virtualMachines/vmname', uri: '/subscriptions/subId/resourceGroups/rgName/providers/Microsoft.Compute/virtualMachines/vmname',
@ -359,7 +354,7 @@ describe('AzureMonitor resourcePickerData', () => {
id: 'rgName', id: 'rgName',
name: 'rgName', name: 'rgName',
type: 'ResourceGroup', type: 'ResourceGroup',
location: 'North Europe', location: 'northeurope',
resourceGroupName: 'rgName', resourceGroupName: 'rgName',
typeLabel: 'Resource groups', typeLabel: 'Resource groups',
uri: '/subscriptions/subId/resourceGroups/rgName', uri: '/subscriptions/subId/resourceGroups/rgName',
@ -392,35 +387,6 @@ describe('AzureMonitor resourcePickerData', () => {
}); });
}); });
describe('getValidLocations', () => {
it('returns a locations map', async () => {
const { resourcePickerData, getValidLocations } = createResourcePickerData([createMockARGSubscriptionResponse()]);
getValidLocations.mockRestore();
const subscriptions = await resourcePickerData.getSubscriptions();
const locations = await resourcePickerData.getLocations(subscriptions);
expect(locations.size).toBe(1);
expect(locations.has('northeurope')).toBe(true);
expect(locations.get('northeurope')?.name).toBe('northeurope');
expect(locations.get('northeurope')?.displayName).toBe('North Europe');
});
it('returns the raw locations map if provider is undefined', async () => {
const { resourcePickerData, mockDatasource, getValidLocations } = createResourcePickerData([
createMockARGSubscriptionResponse(),
]);
getValidLocations.mockRestore();
mockDatasource.azureMonitorDatasource.getProvider = jest.fn().mockResolvedValue(undefined);
const subscriptions = await resourcePickerData.getSubscriptions();
const locations = await resourcePickerData.getLocations(subscriptions);
expect(locations.size).toBe(1);
expect(locations.has('northeurope')).toBe(true);
expect(locations.get('northeurope')?.name).toBe('northeurope');
expect(locations.get('northeurope')?.displayName).toBe('North Europe');
});
});
describe('fetchInitialRows', () => { describe('fetchInitialRows', () => {
it('returns a list of subscriptions', async () => { it('returns a list of subscriptions', async () => {
const { resourcePickerData } = createResourcePickerData([createMockARGSubscriptionResponse()]); const { resourcePickerData } = createResourcePickerData([createMockARGSubscriptionResponse()]);

View File

@ -1,7 +1,7 @@
import { uniq } from 'lodash'; import { uniq } from 'lodash';
import { DataSourceInstanceSettings } from '@grafana/data'; import { DataSourceInstanceSettings } from '@grafana/data';
import { DataSourceWithBackend } from '@grafana/runtime'; import { DataSourceWithBackend, reportInteraction } from '@grafana/runtime';
import { logsResourceTypes, resourceTypeDisplayNames } from '../azureMetadata'; import { logsResourceTypes, resourceTypeDisplayNames } from '../azureMetadata';
import AzureMonitorDatasource from '../azure_monitor/azure_monitor_datasource'; import AzureMonitorDatasource from '../azure_monitor/azure_monitor_datasource';
@ -18,7 +18,6 @@ import {
AzureDataSourceJsonData, AzureDataSourceJsonData,
AzureGraphResponse, AzureGraphResponse,
AzureMonitorResource, AzureMonitorResource,
AzureMonitorLocations,
AzureMonitorQuery, AzureMonitorQuery,
AzureResourceGraphOptions, AzureResourceGraphOptions,
AzureResourceSummaryItem, AzureResourceSummaryItem,
@ -39,8 +38,6 @@ export default class ResourcePickerData extends DataSourceWithBackend<AzureMonit
resultLimit = 200; resultLimit = 200;
azureMonitorDatasource; azureMonitorDatasource;
supportedMetricNamespaces = ''; supportedMetricNamespaces = '';
locationsMap: Map<string, AzureMonitorLocations> = new Map();
locations: string[] = [];
constructor( constructor(
instanceSettings: DataSourceInstanceSettings<AzureDataSourceJsonData>, instanceSettings: DataSourceInstanceSettings<AzureDataSourceJsonData>,
@ -57,11 +54,6 @@ export default class ResourcePickerData extends DataSourceWithBackend<AzureMonit
): Promise<ResourceRowGroup> { ): Promise<ResourceRowGroup> {
const subscriptions = await this.getSubscriptions(); const subscriptions = await this.getSubscriptions();
if (this.locationsMap.size === 0) {
this.locationsMap = await this.getLocations(subscriptions);
this.locations = Array.from(this.locationsMap.values()).map((location) => `"${location.name}"`);
}
if (!currentSelection) { if (!currentSelection) {
return subscriptions; return subscriptions;
} }
@ -140,7 +132,7 @@ export default class ResourcePickerData extends DataSourceWithBackend<AzureMonit
resourceGroupName: item.resourceGroup, resourceGroupName: item.resourceGroup,
type, type,
typeLabel: resourceTypeDisplayNames[item.type] || item.type, typeLabel: resourceTypeDisplayNames[item.type] || item.type,
location: this.locationsMap.get(item.location)?.displayName || item.location, location: item.location,
}; };
}); });
}; };
@ -243,14 +235,10 @@ export default class ResourcePickerData extends DataSourceWithBackend<AzureMonit
resourceGroupId: string, resourceGroupId: string,
type: ResourcePickerQueryType type: ResourcePickerQueryType
): Promise<ResourceRowGroup> { ): Promise<ResourceRowGroup> {
if (!this.locations) {
return [];
}
const { data: response } = await this.makeResourceGraphRequest<RawAzureResourceItem[]>(` const { data: response } = await this.makeResourceGraphRequest<RawAzureResourceItem[]>(`
resources resources
| where id hasprefix "${resourceGroupId}" | where id hasprefix "${resourceGroupId}"
${await this.filterByType(type)} and location in (${this.locations}) ${await this.filterByType(type)}
`); `);
return response.map((item) => { return response.map((item) => {
@ -265,7 +253,7 @@ export default class ResourcePickerData extends DataSourceWithBackend<AzureMonit
resourceGroupName: item.resourceGroup, resourceGroupName: item.resourceGroup,
type: ResourceRowType.Resource, type: ResourceRowType.Resource,
typeLabel: resourceTypeDisplayNames[item.type] || item.type, typeLabel: resourceTypeDisplayNames[item.type] || item.type,
locationDisplayName: this.locationsMap.get(item.location)?.displayName || item.location, locationDisplayName: item.location,
location: item.location, location: item.location,
}; };
}); });
@ -370,6 +358,7 @@ export default class ResourcePickerData extends DataSourceWithBackend<AzureMonit
private async fetchAllNamespaces() { private async fetchAllNamespaces() {
const subscriptions = await this.getSubscriptions(); const subscriptions = await this.getSubscriptions();
reportInteraction('grafana_ds_azuremonitor_subscriptions_loaded', { subscriptions: subscriptions.length });
let supportedMetricNamespaces: string[] = []; let supportedMetricNamespaces: string[] = [];
for await (const subscription of subscriptions) { for await (const subscription of subscriptions) {
const namespaces = await this.azureMonitorDatasource.getMetricNamespaces( const namespaces = await this.azureMonitorDatasource.getMetricNamespaces(
@ -392,12 +381,6 @@ export default class ResourcePickerData extends DataSourceWithBackend<AzureMonit
this.supportedMetricNamespaces = uniq(supportedMetricNamespaces).join(','); this.supportedMetricNamespaces = uniq(supportedMetricNamespaces).join(',');
} }
async getLocations(subscriptions: ResourceRowGroup): Promise<Map<string, AzureMonitorLocations>> {
const subscriptionIds = subscriptions.map((sub) => sub.id);
const locations = await this.azureMonitorDatasource.getLocations(subscriptionIds);
return locations;
}
parseRows(resources: Array<string | AzureMonitorResource>): ResourceRow[] { parseRows(resources: Array<string | AzureMonitorResource>): ResourceRow[] {
const resourceObjs = parseMultipleResourceDetails(resources); const resourceObjs = parseMultipleResourceDetails(resources);
const newSelectedRows: ResourceRow[] = []; const newSelectedRows: ResourceRow[] = [];
@ -422,7 +405,6 @@ export default class ResourcePickerData extends DataSourceWithBackend<AzureMonit
uri: resourceToString(resource), uri: resourceToString(resource),
typeLabel: typeLabel:
resourceTypeDisplayNames[resource.metricNamespace?.toLowerCase() ?? ''] ?? resource.metricNamespace ?? '', resourceTypeDisplayNames[resource.metricNamespace?.toLowerCase() ?? ''] ?? resource.metricNamespace ?? '',
locationDisplayName: this.locationsMap.get(resource.region ?? '')?.displayName || resource.region,
location: resource.region, location: resource.region,
}); });
}); });

View File

@ -109,17 +109,6 @@ export class VariableSupport extends CustomVariableSupport<DataSource, AzureMoni
}; };
} }
return { data: [] }; return { data: [] };
case AzureQueryType.LocationsQuery:
if (queryObj.subscription && this.hasValue(queryObj.subscription)) {
const locationMap = await this.datasource.azureMonitorDatasource.getLocations([queryObj.subscription]);
const res: Array<{ text: string; value: string }> = [];
locationMap.forEach((loc) => {
res.push({ text: loc.displayName, value: loc.name });
});
return {
data: res?.length ? [toDataFrame(res)] : [],
};
}
default: default:
request.targets[0] = queryObj; request.targets[0] = queryObj;
const queryResp = await lastValueFrom(this.datasource.query(request)); const queryResp = await lastValueFrom(this.datasource.query(request));