diff --git a/extensions/azurecore/src/azureDataGridProvider.ts b/extensions/azurecore/src/azureDataGridProvider.ts new file mode 100644 index 0000000000..3b19634e27 --- /dev/null +++ b/extensions/azurecore/src/azureDataGridProvider.ts @@ -0,0 +1,78 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as azdata from 'azdata'; +import { AppContext } from './appContext'; +import { AzureResourceServiceNames } from './azureResource/constants'; +import { IAzureResourceSubscriptionService } from './azureResource/interfaces'; +import { TokenCredentials } from '@azure/ms-rest-js'; +import { azureResource } from 'azureResource'; +import * as azureResourceUtils from './azureResource/utils'; +import * as constants from './constants'; +import * as loc from './localizedConstants'; +import * as utils from './utils'; + +const typesClause = [ + azureResource.AzureResourceType.sqlDatabase, + azureResource.AzureResourceType.sqlServer, + azureResource.AzureResourceType.sqlManagedInstance, + azureResource.AzureResourceType.postgresServer, + azureResource.AzureResourceType.azureArcService, + azureResource.AzureResourceType.azureArcSqlManagedInstance, + azureResource.AzureResourceType.azureArcPostgresServer +].map(type => `type == "${type}"`).join(' or '); + +export class AzureDataGridProvider implements azdata.DataGridProvider { + constructor(private _appContext: AppContext) { } + + public providerId = constants.dataGridProviderId; + public async getDataGridItems() { + const accounts = await azdata.accounts.getAllAccounts(); + const items: any[] = []; + await Promise.all(accounts.map(async (account) => { + await Promise.all(account.properties.tenants.map(async (tenant: { id: string; }) => { + try { + const tokenResponse = await azdata.accounts.getAccountSecurityToken(account, tenant.id, azdata.AzureResource.ResourceManagement); + const token = tokenResponse.token; + const tokenType = tokenResponse.tokenType; + const credential = new TokenCredentials(token, tokenType); + const subscriptionService = this._appContext.getService(AzureResourceServiceNames.subscriptionService); + const subscriptions = await subscriptionService.getSubscriptions(account, credential, tenant.id); + try { + const newItems = (await azureResourceUtils.runResourceQuery(account, subscriptions, true, `where ${typesClause}`)).resources + .map(item => { + return { + id: item.id, + // nameLink: { displayText: item.name, linkOrCommand: ''}, + resourceGroup: item.resourceGroup, + subscriptionName: subscriptions.find(subscription => subscription.id === item.subscriptionId)?.name ?? item.subscriptionId, + locationDisplayName: utils.getRegionDisplayName(item.location), + typeDisplayName: utils.getResourceTypeDisplayName(item.type), + iconPath: utils.getResourceTypeIcon(this._appContext, item.type) + }; + }); + items.push(...newItems); + } catch (err) { + console.log(err); + } + } catch (err) { + console.log(err); + } + })); + })); + return items; + } + + public async getDataGridColumns(): Promise { + return [ + { id: 'icon', type: 'image', field: 'iconPath', name: '', width: 25, sortable: false, filterable: false, resizable: false, tooltip: loc.typeIcon }, + { id: 'name', type: 'hyperlink', field: 'nameLink', name: loc.name, width: 150 }, + { id: 'type', type: 'text', field: 'typeDisplayName', name: loc.resourceType, width: 150 }, + { id: 'type', type: 'text', field: 'resourceGroup', name: loc.resourceGroup, width: 150 }, + { id: 'location', type: 'text', field: 'locationDisplayName', name: loc.location, width: 150 }, + { id: 'subscriptionId', type: 'text', field: 'subscriptionName', name: loc.subscription, width: 150 } + ]; + } +} diff --git a/extensions/azurecore/src/azureResource/azure-resource.d.ts b/extensions/azurecore/src/azureResource/azure-resource.d.ts index 5c4bb9cb11..8551a27044 100644 --- a/extensions/azurecore/src/azureResource/azure-resource.d.ts +++ b/extensions/azurecore/src/azureResource/azure-resource.d.ts @@ -39,6 +39,7 @@ declare module 'azureResource' { name: string; id: string; subscriptionId: string; + resourceGroup?: string; tenant?: string; } diff --git a/extensions/azurecore/src/azureResource/providers/database/databaseService.ts b/extensions/azurecore/src/azureResource/providers/database/databaseService.ts index 516fdff6a2..ff6fbf5f72 100644 --- a/extensions/azurecore/src/azureResource/providers/database/databaseService.ts +++ b/extensions/azurecore/src/azureResource/providers/database/databaseService.ts @@ -52,7 +52,8 @@ export class AzureResourceDatabaseService implements IAzureResourceService onDidChangeConfiguration(e), this)); registerAzureResourceCommands(appContext, azureResourceTree); - - const typesClause = [ - azureResource.AzureResourceType.sqlDatabase, - azureResource.AzureResourceType.sqlServer, - azureResource.AzureResourceType.sqlManagedInstance, - azureResource.AzureResourceType.postgresServer, - azureResource.AzureResourceType.azureArcService, - azureResource.AzureResourceType.azureArcSqlManagedInstance, - azureResource.AzureResourceType.azureArcPostgresServer - ].map(type => `type == "${type}"`).join(' or '); - azdata.dataprotocol.registerDataGridProvider({ - providerId: constants.dataGridProviderId, - getDataGridItems: async () => { - const accounts = await azdata.accounts.getAllAccounts(); - const items: any[] = []; - await Promise.all(accounts.map(async (account) => { - await Promise.all(account.properties.tenants.map(async (tenant: { id: string; }) => { - try { - const tokenResponse = await azdata.accounts.getAccountSecurityToken(account, tenant.id, azdata.AzureResource.ResourceManagement); - const token = tokenResponse.token; - const tokenType = tokenResponse.tokenType; - const credential = new TokenCredentials(token, tokenType); - const subscriptionService = appContext.getService(AzureResourceServiceNames.subscriptionService); - const subscriptions = await subscriptionService.getSubscriptions(account, credential, tenant.id); - try { - const newItems = (await azureResourceUtils.runResourceQuery(account, subscriptions, true, `where ${typesClause}`)).resources - .map(item => { - return { - ...item, - subscriptionName: subscriptions.find(subscription => subscription.id === item.subscriptionId)?.name ?? item.subscriptionId, - locationDisplayName: utils.getRegionDisplayName(item.location), - typeDisplayName: utils.getResourceTypeDisplayName(item.type), - iconPath: utils.getResourceTypeIcon(appContext, item.type) - }; - }); - items.push(...newItems); - } catch (err) { - console.log(err); - } - } catch (err) { - console.log(err); - } - })); - })); - return items; - }, - getDataGridColumns: async () => { - return [ - { id: 'icon', type: 'image', field: 'iconPath', name: '', width: 25, sortable: false, filterable: false, resizable: false, tooltip: loc.typeIcon }, - { id: 'name', type: 'text', field: 'name', name: loc.name, width: 150 }, - { id: 'type', type: 'text', field: 'typeDisplayName', name: loc.resourceType, width: 150 }, - { id: 'type', type: 'text', field: 'resourceGroup', name: loc.resourceGroup, width: 150 }, - { id: 'location', type: 'text', field: 'locationDisplayName', name: loc.location, width: 150 }, - { id: 'subscriptionId', type: 'text', field: 'subscriptionName', name: loc.subscription, width: 150 } - ]; - } - }); + azdata.dataprotocol.registerDataGridProvider(new AzureDataGridProvider(appContext)); return { getSubscriptions(account?: azdata.Account, ignoreErrors?: boolean, selectedOnly: boolean = false): Thenable { diff --git a/extensions/azurecore/src/test/azureResource/providers/database/databaseTreeDataProvider.test.ts b/extensions/azurecore/src/test/azureResource/providers/database/databaseTreeDataProvider.test.ts index e6c4d2d107..40a598bb09 100644 --- a/extensions/azurecore/src/test/azureResource/providers/database/databaseTreeDataProvider.test.ts +++ b/extensions/azurecore/src/test/azureResource/providers/database/databaseTreeDataProvider.test.ts @@ -76,7 +76,8 @@ const mockDatabases: azureResource.AzureResourceDatabase[] = [ serverName: 'mock database server 1', serverFullName: 'mock database server full name 1', loginName: 'mock login', - subscriptionId: 'mock_subscription' + subscriptionId: 'mock_subscription', + resourceGroup: 'rg1' }, { name: 'mock database 2', @@ -84,7 +85,8 @@ const mockDatabases: azureResource.AzureResourceDatabase[] = [ serverName: 'mock database server 2', serverFullName: 'mock database server full name 2', loginName: 'mock login', - subscriptionId: 'mock_subscription' + subscriptionId: 'mock_subscription', + resourceGroup: 'rg2' } ]; diff --git a/extensions/azurecore/src/test/azureResource/providers/databaseServer/databaseServerTreeDataProvider.test.ts b/extensions/azurecore/src/test/azureResource/providers/databaseServer/databaseServerTreeDataProvider.test.ts index 6d570f0fc7..5e52dff0c6 100644 --- a/extensions/azurecore/src/test/azureResource/providers/databaseServer/databaseServerTreeDataProvider.test.ts +++ b/extensions/azurecore/src/test/azureResource/providers/databaseServer/databaseServerTreeDataProvider.test.ts @@ -75,7 +75,8 @@ const mockDatabaseServers: azureResource.AzureResourceDatabaseServer[] = [ fullName: 'mock database server full name 1', loginName: 'mock login', defaultDatabaseName: 'master', - subscriptionId: 'mock_subscription' + subscriptionId: 'mock_subscription', + resourceGroup: 'rg1' }, { name: 'mock database server 2', @@ -83,7 +84,8 @@ const mockDatabaseServers: azureResource.AzureResourceDatabaseServer[] = [ fullName: 'mock database server full name 2', loginName: 'mock login', defaultDatabaseName: 'master', - subscriptionId: 'mock_subscription' + subscriptionId: 'mock_subscription', + resourceGroup: 'rg2' } ];