diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts index 022569cdb0b..80704df6699 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts @@ -284,6 +284,54 @@ describe('AzureMonitorDatasource', () => { }); }); }); + + describe('and there are several pages', () => { + const skipToken = 'token'; + const response1 = { + value: [ + { + name: `${resourceGroup}1`, + type: metricDefinition, + }, + ], + nextLink: `https://management.azure.com/resourceuri?$skiptoken=${skipToken}`, + }; + const response2 = { + value: [ + { + name: `${resourceGroup}2`, + type: metricDefinition, + }, + ], + }; + + beforeEach(() => { + const fn = jest.fn(); + ctx.ds.azureMonitorDatasource.getResource = fn; + const basePath = `azuremonitor/subscriptions/${subscription}/resourceGroups`; + const expectedPath = `${basePath}/${resourceGroup}/resources?$filter=resourceType eq '${metricDefinition}'&api-version=2021-04-01`; + // first page + fn.mockImplementationOnce((path: string) => { + expect(path).toBe(expectedPath); + return Promise.resolve(response1); + }); + // second page + fn.mockImplementationOnce((path: string) => { + expect(path).toBe(`${expectedPath}&$skiptoken=${skipToken}`); + return Promise.resolve(response2); + }); + }); + + it('should return list of Resource Names', () => { + return ctx.ds + .getResourceNames(subscription, resourceGroup, metricDefinition) + .then((results: Array<{ text: string; value: string }>) => { + expect(results.length).toEqual(2); + expect(results[0].value).toEqual(`${resourceGroup}1`); + expect(results[1].value).toEqual(`${resourceGroup}2`); + }); + }); + }); }); describe('When performing getMetricNames', () => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts index 2930269776e..9f876557e0f 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts @@ -194,18 +194,35 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend { - if (!startsWith(metricDefinition, 'Microsoft.Storage/storageAccounts/')) { - return ResponseParser.parseResourceNames(result, metricDefinition); + getResourceNames(subscriptionId: string, resourceGroup: string, metricDefinition: string, skipToken?: string) { + let url = + `${this.resourcePath}/${subscriptionId}/resourceGroups/${resourceGroup}/resources?` + + `$filter=resourceType eq '${metricDefinition}'&` + + `api-version=${this.listByResourceGroupApiVersion}`; + if (skipToken) { + url += `&$skiptoken=${skipToken}`; + } + return this.getResource(url).then(async (result: any) => { + let list: Array<{ text: string; value: string }> = []; + if (startsWith(metricDefinition, 'Microsoft.Storage/storageAccounts/')) { + list = ResponseParser.parseResourceNames(result, 'Microsoft.Storage/storageAccounts'); + for (let i = 0; i < list.length; i++) { + list[i].text += '/default'; + list[i].value += '/default'; + } + } else { + list = ResponseParser.parseResourceNames(result, metricDefinition); } - const list = ResponseParser.parseResourceNames(result, 'Microsoft.Storage/storageAccounts'); - for (let i = 0; i < list.length; i++) { - list[i].text += '/default'; - list[i].value += '/default'; + if (result.nextLink) { + // If there is a nextLink, we should request more pages + const nextURL = new URL(result.nextLink); + const nextToken = nextURL.searchParams.get('$skiptoken'); + if (!nextToken) { + throw Error('unable to request the next page of resources'); + } + const nextPage = await this.getResourceNames(subscriptionId, resourceGroup, metricDefinition, nextToken); + list = list.concat(nextPage); } return list;