diff --git a/extensions/azurecore/package.json b/extensions/azurecore/package.json index 88a9399976..39b8c3d14b 100644 --- a/extensions/azurecore/package.json +++ b/extensions/azurecore/package.json @@ -41,6 +41,17 @@ "description": "%config.enablePublicCloudDescription%" } } + }, + { + "type": "object", + "title": "Azure", + "properties": { + "azure.enableArcFeatures": { + "type": "boolean", + "default": false, + "description": "%config.enableArcFeatures%" + } + } } ], "account-type": [ diff --git a/extensions/azurecore/package.nls.json b/extensions/azurecore/package.nls.json index 1ffff27888..c7083e86fc 100644 --- a/extensions/azurecore/package.nls.json +++ b/extensions/azurecore/package.nls.json @@ -20,5 +20,6 @@ "config.enablePublicCloudDescription": "Should Azure public cloud integration be enabled", "config.enableUsGovCloudDescription": "Should US Government Azure cloud (Fairfax) integration be enabled", "config.enableChinaCloudDescription": "Should Azure China integration be enabled", - "config.enableGermanyCloudDescription": "Should Azure Germany integration be enabled" + "config.enableGermanyCloudDescription": "Should Azure Germany integration be enabled", + "config.enableArcFeatures": "Should features related to Azure Arc be enabled (preview)" } diff --git a/extensions/azurecore/src/account-provider/azureAccountProviderService.ts b/extensions/azurecore/src/account-provider/azureAccountProviderService.ts index 4b124a9e44..d9869fd67f 100644 --- a/extensions/azurecore/src/account-provider/azureAccountProviderService.ts +++ b/extensions/azurecore/src/account-provider/azureAccountProviderService.ts @@ -3,7 +3,6 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as constants from '../constants'; import * as azdata from 'azdata'; import * as events from 'events'; import * as nls from 'vscode-nls'; @@ -13,6 +12,7 @@ import CredentialServiceTokenCache from './tokenCache'; import providerSettings from './providerSettings'; import { AzureAccountProvider as AzureAccountProvider } from './azureAccountProvider2'; import { AzureAccountProviderMetadata, ProviderSettings } from './interfaces'; +import * as loc from '../localizedConstants'; let localize = nls.loadMessageBundle(); @@ -78,11 +78,11 @@ export class AzureAccountProviderService implements vscode.Disposable { .then( () => { let message = localize('clearTokenCacheSuccess', "Token cache successfully cleared"); - vscode.window.showInformationMessage(`${constants.extensionName}: ${message}`); + vscode.window.showInformationMessage(`${loc.extensionName}: ${message}`); }, err => { let message = localize('clearTokenCacheFailure', "Failed to clear token cache"); - vscode.window.showErrorMessage(`${constants.extensionName}: ${message}: ${err}`); + vscode.window.showErrorMessage(`${loc.extensionName}: ${message}: ${err}`); }); } diff --git a/extensions/azurecore/src/apiWrapper.ts b/extensions/azurecore/src/apiWrapper.ts index 303a3e5611..344f905512 100644 --- a/extensions/azurecore/src/apiWrapper.ts +++ b/extensions/azurecore/src/apiWrapper.ts @@ -138,6 +138,10 @@ export class ApiWrapper { return this.getConfiguration(constants.extensionConfigSectionName); } + public get onDidChangeConfiguration(): vscode.Event { + return vscode.workspace.onDidChangeConfiguration; + } + /** * Parse uri */ diff --git a/extensions/azurecore/src/azureResource/providers/database/databaseTreeDataProvider.ts b/extensions/azurecore/src/azureResource/providers/database/databaseTreeDataProvider.ts index c730b925ac..c5a0df9230 100644 --- a/extensions/azurecore/src/azureResource/providers/database/databaseTreeDataProvider.ts +++ b/extensions/azurecore/src/azureResource/providers/database/databaseTreeDataProvider.ts @@ -18,7 +18,7 @@ import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase'; export class AzureResourceDatabaseTreeDataProvider extends ResourceTreeDataProviderBase { private static readonly containerId = 'azure.resource.providers.database.treeDataProvider.databaseContainer'; - private static readonly containerLabel = localize('azure.resource.providers.database.treeDataProvider.databaseContainerLabel', "SQL Databases"); + private static readonly containerLabel = localize('azure.resource.providers.database.treeDataProvider.databaseContainerLabel', "SQL database"); public constructor( databaseService: IAzureResourceService, diff --git a/extensions/azurecore/src/azureResource/providers/databaseServer/databaseServerTreeDataProvider.ts b/extensions/azurecore/src/azureResource/providers/databaseServer/databaseServerTreeDataProvider.ts index 6595c518f6..9686651d83 100644 --- a/extensions/azurecore/src/azureResource/providers/databaseServer/databaseServerTreeDataProvider.ts +++ b/extensions/azurecore/src/azureResource/providers/databaseServer/databaseServerTreeDataProvider.ts @@ -17,7 +17,7 @@ import { azureResource } from '../../azure-resource'; export class AzureResourceDatabaseServerTreeDataProvider extends ResourceTreeDataProviderBase { private static readonly containerId = 'azure.resource.providers.databaseServer.treeDataProvider.databaseServerContainer'; - private static readonly containerLabel = localize('azure.resource.providers.databaseServer.treeDataProvider.databaseServerContainerLabel', "SQL Servers"); + private static readonly containerLabel = localize('azure.resource.providers.databaseServer.treeDataProvider.databaseServerContainerLabel', "SQL server"); public constructor( databaseServerService: IAzureResourceService, diff --git a/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerProvider.ts b/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerProvider.ts new file mode 100644 index 0000000000..4ea82c61c9 --- /dev/null +++ b/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerProvider.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ExtensionContext } from 'vscode'; +import { ApiWrapper } from '../../../apiWrapper'; + +import { azureResource } from '../../azure-resource'; +import { IAzureResourceService } from '../../interfaces'; +import { PostgresServerArcTreeDataProvider as PostgresServerArcTreeDataProvider } from './postgresServerTreeDataProvider'; + +export class PostgresServerArcProvider implements azureResource.IAzureResourceProvider { + public constructor( + private _databaseServerService: IAzureResourceService, + private _apiWrapper: ApiWrapper, + private _extensionContext: ExtensionContext + ) { + } + + public getTreeDataProvider(): azureResource.IAzureResourceTreeDataProvider { + return new PostgresServerArcTreeDataProvider(this._databaseServerService, this._apiWrapper, this._extensionContext); + } + + public get providerId(): string { + return 'azure.resource.providers.postgresArcServer'; + } +} diff --git a/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerService.ts b/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerService.ts new file mode 100644 index 0000000000..196d1e5f61 --- /dev/null +++ b/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerService.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase'; +import { azureResource } from '../../azure-resource'; + +export interface PostgresArcServerGraphData extends GraphData { + properties: { + admin: string; + }; +} + +export const serversQuery = 'where type == "microsoft.azuredata/postgresinstances"'; + +export class PostgresServerArcService extends ResourceServiceBase { + + protected get query(): string { + return serversQuery; + } + + protected convertResource(resource: PostgresArcServerGraphData): azureResource.AzureResourceDatabaseServer { + return { + id: resource.id, + name: resource.name, + fullName: resource.name, + loginName: resource.properties.admin, + defaultDatabaseName: 'postgres' + }; + } +} diff --git a/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerTreeDataProvider.ts b/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerTreeDataProvider.ts new file mode 100644 index 0000000000..89715925de --- /dev/null +++ b/extensions/azurecore/src/azureResource/providers/postgresArcServer/postgresServerTreeDataProvider.ts @@ -0,0 +1,81 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ExtensionNodeType, TreeItem } from 'azdata'; +import { TreeItemCollapsibleState, ExtensionContext } from 'vscode'; +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + +import { AzureResourceItemType } from '../../constants'; +import { ApiWrapper } from '../../../apiWrapper'; +import { generateGuid } from '../../utils'; +import { IAzureResourceService } from '../../interfaces'; +import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase'; +import { azureResource } from '../../azure-resource'; + +export class PostgresServerArcTreeDataProvider extends ResourceTreeDataProviderBase { + private static readonly containerId = 'azure.resource.providers.postgresArcServer.treeDataProvider.postgresServerContainer'; + private static readonly containerLabel = localize('azure.resource.providers.postgresArcServer.treeDataProvider.postgresServerContainerLabel', "PostgreSQL Hyperscale - Azure Arc"); + + public constructor( + databaseServerService: IAzureResourceService, + apiWrapper: ApiWrapper, + private _extensionContext: ExtensionContext + ) { + super(databaseServerService, apiWrapper); + } + + + protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer): TreeItem { + return { + id: `databaseServer_${databaseServer.id ? databaseServer.id : databaseServer.name}`, + label: databaseServer.name, + iconPath: { + dark: this._extensionContext.asAbsolutePath('resources/dark/sql_server_inverse.svg'), + light: this._extensionContext.asAbsolutePath('resources/light/sql_server.svg') + }, + collapsibleState: TreeItemCollapsibleState.Collapsed, + contextValue: AzureResourceItemType.databaseServer, + payload: { + id: generateGuid(), + connectionName: undefined, + serverName: databaseServer.fullName, + databaseName: databaseServer.defaultDatabaseName, + userName: `${databaseServer.loginName}@${databaseServer.fullName}`, + password: '', + authenticationType: 'SqlLogin', + savePassword: true, + groupFullName: '', + groupId: '', + providerName: 'PGSQL', + saveProfile: false, + options: { + // Set default for SSL or will get error complaining about it not being set correctly + 'sslmode': 'require' + } + }, + childProvider: 'PGSQL', + type: ExtensionNodeType.Server + }; + } + + protected createContainerNode(): azureResource.IAzureResourceNode { + return { + account: undefined, + subscription: undefined, + tenantId: undefined, + treeItem: { + id: PostgresServerArcTreeDataProvider.containerId, + label: PostgresServerArcTreeDataProvider.containerLabel, + iconPath: { + dark: this._extensionContext.asAbsolutePath('resources/dark/folder_inverse.svg'), + light: this._extensionContext.asAbsolutePath('resources/light/folder.svg') + }, + collapsibleState: TreeItemCollapsibleState.Collapsed, + contextValue: AzureResourceItemType.databaseServerContainer + } + }; + } +} diff --git a/extensions/azurecore/src/azureResource/providers/postgresServer/postgresServerTreeDataProvider.ts b/extensions/azurecore/src/azureResource/providers/postgresServer/postgresServerTreeDataProvider.ts index 525fecd2dd..84ae264368 100644 --- a/extensions/azurecore/src/azureResource/providers/postgresServer/postgresServerTreeDataProvider.ts +++ b/extensions/azurecore/src/azureResource/providers/postgresServer/postgresServerTreeDataProvider.ts @@ -17,7 +17,7 @@ import { azureResource } from '../../azure-resource'; export class PostgresServerTreeDataProvider extends ResourceTreeDataProviderBase { private static readonly containerId = 'azure.resource.providers.databaseServer.treeDataProvider.postgresServerContainer'; - private static readonly containerLabel = localize('azure.resource.providers.databaseServer.treeDataProvider.postgresServerContainerLabel', "Azure Database for PostgreSQL Servers"); + private static readonly containerLabel = localize('azure.resource.providers.databaseServer.treeDataProvider.postgresServerContainerLabel', "Azure Database for PostgreSQL server"); public constructor( databaseServerService: IAzureResourceService, @@ -32,7 +32,6 @@ export class PostgresServerTreeDataProvider extends ResourceTreeDataProviderBase return { id: `databaseServer_${databaseServer.id ? databaseServer.id : databaseServer.name}`, label: databaseServer.name, - // TODO: should get PGSQL-specific icons (also needed in that extension) iconPath: { dark: this._extensionContext.asAbsolutePath('resources/dark/sql_server_inverse.svg'), light: this._extensionContext.asAbsolutePath('resources/light/sql_server.svg') diff --git a/extensions/azurecore/src/azureResource/providers/sqlinstance/sqlInstanceTreeDataProvider.ts b/extensions/azurecore/src/azureResource/providers/sqlinstance/sqlInstanceTreeDataProvider.ts index 72fc994c21..4fedf297f4 100644 --- a/extensions/azurecore/src/azureResource/providers/sqlinstance/sqlInstanceTreeDataProvider.ts +++ b/extensions/azurecore/src/azureResource/providers/sqlinstance/sqlInstanceTreeDataProvider.ts @@ -17,7 +17,7 @@ import { azureResource } from '../../azure-resource'; export class SqlInstanceTreeDataProvider extends ResourceTreeDataProviderBase { private static readonly containerId = 'azure.resource.providers.sqlInstanceContainer'; - private static readonly containerLabel = localize('azure.resource.providers.sqlInstanceContainerLabel', "SQL Managed Instances"); + private static readonly containerLabel = localize('azure.resource.providers.sqlInstanceContainerLabel', "Azure SQL DB managed instance"); public constructor( databaseServerService: IAzureResourceService, diff --git a/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcProvider.ts b/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcProvider.ts new file mode 100644 index 0000000000..a73d91fad4 --- /dev/null +++ b/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcProvider.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ExtensionContext } from 'vscode'; +import { ApiWrapper } from '../../../apiWrapper'; + +import { azureResource } from '../../azure-resource'; +import { IAzureResourceService } from '../../interfaces'; +import { SqlInstanceArcTreeDataProvider as SqlInstanceArcTreeDataProvider } from './sqlInstanceArcTreeDataProvider'; + +export class SqlInstanceArcProvider implements azureResource.IAzureResourceProvider { + public constructor( + private _service: IAzureResourceService, + private _apiWrapper: ApiWrapper, + private _extensionContext: ExtensionContext + ) { + } + + public getTreeDataProvider(): azureResource.IAzureResourceTreeDataProvider { + return new SqlInstanceArcTreeDataProvider(this._service, this._apiWrapper, this._extensionContext); + } + + public get providerId(): string { + return 'azure.resource.providers.sqlInstanceArc'; + } +} diff --git a/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcService.ts b/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcService.ts new file mode 100644 index 0000000000..bec76bad55 --- /dev/null +++ b/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcService.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase'; +import { azureResource } from '../../azure-resource'; + +export interface SqlInstanceArcGraphData extends GraphData { + properties: { + admin: string; + hybridDataManager: string; + }; +} + +const instanceQuery = 'where type == "microsoft.azuredata/sqlinstances"'; +export class SqlInstanceArcResourceService extends ResourceServiceBase { + + protected get query(): string { + return instanceQuery; + } + + protected convertResource(resource: SqlInstanceArcGraphData): azureResource.AzureResourceDatabaseServer { + return { + id: resource.id, + name: resource.name, + fullName: resource.name, + loginName: resource.properties.admin, + defaultDatabaseName: 'master' + }; + } +} diff --git a/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcTreeDataProvider.ts b/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcTreeDataProvider.ts new file mode 100644 index 0000000000..c2c69dbf61 --- /dev/null +++ b/extensions/azurecore/src/azureResource/providers/sqlinstanceArc/sqlInstanceArcTreeDataProvider.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 { ExtensionNodeType, TreeItem } from 'azdata'; +import { TreeItemCollapsibleState, ExtensionContext } from 'vscode'; +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + +import { AzureResourceItemType } from '../../constants'; +import { ApiWrapper } from '../../../apiWrapper'; +import { generateGuid } from '../../utils'; +import { IAzureResourceService } from '../../interfaces'; +import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase'; +import { azureResource } from '../../azure-resource'; + +export class SqlInstanceArcTreeDataProvider extends ResourceTreeDataProviderBase { + private static readonly containerId = 'azure.resource.providers.sqlInstanceArcContainer'; + private static readonly containerLabel = localize('azure.resource.providers.sqlInstanceArcContainerLabel', "Azure SQL DB managed instance – Azure Arc"); + + public constructor( + databaseServerService: IAzureResourceService, + apiWrapper: ApiWrapper, + private _extensionContext: ExtensionContext + ) { + super(databaseServerService, apiWrapper); + } + + + protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer): TreeItem { + return { + id: `sqlInstance_${databaseServer.id ? databaseServer.id : databaseServer.name}`, + label: databaseServer.name, + iconPath: { + dark: this._extensionContext.asAbsolutePath('resources/dark/sql_instance_inverse.svg'), + light: this._extensionContext.asAbsolutePath('resources/light/sql_instance.svg') + }, + collapsibleState: TreeItemCollapsibleState.Collapsed, + contextValue: AzureResourceItemType.databaseServer, + payload: { + id: generateGuid(), + connectionName: undefined, + serverName: databaseServer.fullName, + databaseName: databaseServer.defaultDatabaseName, + userName: databaseServer.loginName, + password: '', + authenticationType: 'SqlLogin', + savePassword: true, + groupFullName: '', + groupId: '', + providerName: 'MSSQL', + saveProfile: false, + options: {} + }, + childProvider: 'MSSQL', + type: ExtensionNodeType.Server + }; + } + + protected createContainerNode(): azureResource.IAzureResourceNode { + return { + account: undefined, + subscription: undefined, + tenantId: undefined, + treeItem: { + id: SqlInstanceArcTreeDataProvider.containerId, + label: SqlInstanceArcTreeDataProvider.containerLabel, + iconPath: { + dark: this._extensionContext.asAbsolutePath('resources/dark/folder_inverse.svg'), + light: this._extensionContext.asAbsolutePath('resources/light/folder.svg') + }, + collapsibleState: TreeItemCollapsibleState.Collapsed, + contextValue: AzureResourceItemType.databaseServerContainer + } + }; + } +} diff --git a/extensions/azurecore/src/azureResource/resourceService.ts b/extensions/azurecore/src/azureResource/resourceService.ts index b65ed19828..d99456a4b7 100644 --- a/extensions/azurecore/src/azureResource/resourceService.ts +++ b/extensions/azurecore/src/azureResource/resourceService.ts @@ -105,7 +105,9 @@ export class AzureResourceService { if (extension.exports && extension.exports.provideResources) { for (const resourceProvider of extension.exports.provideResources()) { - this.doRegisterResourceProvider(resourceProvider); + if (resourceProvider) { + this.doRegisterResourceProvider(resourceProvider); + } } } } diff --git a/extensions/azurecore/src/constants.ts b/extensions/azurecore/src/constants.ts index 1c2cb37a92..029ae4e2ee 100644 --- a/extensions/azurecore/src/constants.ts +++ b/extensions/azurecore/src/constants.ts @@ -3,15 +3,9 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vscode-nls'; - -const localize = nls.loadMessageBundle(); - export const extensionConfigSectionName = 'azure'; export const ViewType = 'view'; export enum BuiltInCommands { SetContext = 'setContext' } - -export const extensionName = localize('extensionName', "Azure Accounts"); diff --git a/extensions/azurecore/src/extension.ts b/extensions/azurecore/src/extension.ts index 6c96fa7aac..21300c7b7e 100644 --- a/extensions/azurecore/src/extension.ts +++ b/extensions/azurecore/src/extension.ts @@ -7,7 +7,6 @@ import * as vscode from 'vscode'; import { promises as fs } from 'fs'; import * as path from 'path'; import * as os from 'os'; -import * as constants from './constants'; import { AppContext } from './appContext'; import { ApiWrapper } from './apiWrapper'; @@ -31,6 +30,12 @@ import { SqlInstanceResourceService } from './azureResource/providers/sqlinstanc import { SqlInstanceProvider } from './azureResource/providers/sqlinstance/sqlInstanceProvider'; import { PostgresServerProvider } from './azureResource/providers/postgresServer/postgresServerProvider'; import { PostgresServerService } from './azureResource/providers/postgresServer/postgresServerService'; +import { SqlInstanceArcProvider } from './azureResource/providers/sqlinstanceArc/sqlInstanceArcProvider'; +import { SqlInstanceArcResourceService } from './azureResource/providers/sqlinstanceArc/sqlInstanceArcService'; +import { PostgresServerArcProvider } from './azureResource/providers/postgresArcServer/postgresServerProvider'; +import { PostgresServerArcService } from './azureResource/providers/postgresArcServer/postgresServerService'; +import { azureResource } from './azureResource/azure-resource'; +import * as loc from './localizedConstants'; let extensionContext: vscode.ExtensionContext; @@ -72,16 +77,25 @@ export async function activate(context: vscode.ExtensionContext) { registerAzureServices(appContext); const azureResourceTree = new AzureResourceTreeProvider(appContext); pushDisposable(apiWrapper.registerTreeDataProvider('azureResourceExplorer', azureResourceTree)); + pushDisposable(apiWrapper.onDidChangeConfiguration(e => onDidChangeConfiguration(e, apiWrapper), this)); registerAzureResourceCommands(appContext, azureResourceTree); return { provideResources() { - return [ + const arcFeaturedEnabled = apiWrapper.getExtensionConfiguration().get('enableArcFeatures'); + const providers: azureResource.IAzureResourceProvider[] = [ new AzureResourceDatabaseServerProvider(new AzureResourceDatabaseServerService(), apiWrapper, extensionContext), new AzureResourceDatabaseProvider(new AzureResourceDatabaseService(), apiWrapper, extensionContext), new SqlInstanceProvider(new SqlInstanceResourceService(), apiWrapper, extensionContext), - new PostgresServerProvider(new PostgresServerService(), apiWrapper, extensionContext) + new PostgresServerProvider(new PostgresServerService(), apiWrapper, extensionContext), ]; + if (arcFeaturedEnabled) { + providers.push( + new SqlInstanceArcProvider(new SqlInstanceArcResourceService(), apiWrapper, extensionContext), + new PostgresServerArcProvider(new PostgresServerArcService(), apiWrapper, extensionContext) + ); + } + return providers; } }; } @@ -89,7 +103,7 @@ export async function activate(context: vscode.ExtensionContext) { // Create the folder for storing the token caches async function findOrMakeStoragePath() { let defaultLogLocation = getDefaultLogLocation(); - let storagePath = path.join(defaultLogLocation, constants.extensionName); + let storagePath = path.join(defaultLogLocation, loc.extensionName); try { await fs.mkdir(defaultLogLocation, { recursive: true }); @@ -132,3 +146,12 @@ function registerAzureServices(appContext: AppContext): void { appContext.registerService(AzureResourceServiceNames.subscriptionFilterService, new AzureResourceSubscriptionFilterService(new AzureResourceCacheService(extensionContext))); appContext.registerService(AzureResourceServiceNames.tenantService, new AzureResourceTenantService()); } + +async function onDidChangeConfiguration(e: vscode.ConfigurationChangeEvent, apiWrapper: ApiWrapper): Promise { + if (e.affectsConfiguration('azure.enableArcFeatures')) { + const response = await apiWrapper.showInformationMessage(loc.requiresReload, loc.reload); + if (response === loc.reload) { + await apiWrapper.executeCommand('workbench.action.reloadWindow'); + } + } +} diff --git a/extensions/azurecore/src/localizedConstants.ts b/extensions/azurecore/src/localizedConstants.ts new file mode 100644 index 0000000000..696e5c990f --- /dev/null +++ b/extensions/azurecore/src/localizedConstants.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + +export const extensionName = localize('azurecore.extensionName', "Azure Accounts"); + +export const requiresReload = localize('azurecore.requiresReload', "Modifying this setting requires reloading the window for all changes to take effect."); +export const reload = localize('azurecore.reload', "Reload"); 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 10c9ab0a49..ded8f531b1 100644 --- a/extensions/azurecore/src/test/azureResource/providers/database/databaseTreeDataProvider.test.ts +++ b/extensions/azurecore/src/test/azureResource/providers/database/databaseTreeDataProvider.test.ts @@ -121,7 +121,7 @@ describe('AzureResourceDatabaseTreeDataProvider.getChildren', function (): void should(child.subscription).undefined(); should(child.tenantId).undefined(); should(child.treeItem.id).equal('azure.resource.providers.database.treeDataProvider.databaseContainer'); - should(child.treeItem.label).equal('SQL Databases'); + should(child.treeItem.label).equal('SQL database'); should(child.treeItem.collapsibleState).equal(vscode.TreeItemCollapsibleState.Collapsed); should(child.treeItem.contextValue).equal('azure.resource.itemType.databaseContainer'); }); 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 f6215f7024..49fb505906 100644 --- a/extensions/azurecore/src/test/azureResource/providers/databaseServer/databaseServerTreeDataProvider.test.ts +++ b/extensions/azurecore/src/test/azureResource/providers/databaseServer/databaseServerTreeDataProvider.test.ts @@ -121,7 +121,7 @@ describe('AzureResourceDatabaseServerTreeDataProvider.getChildren', function (): should(child.subscription).undefined(); should(child.tenantId).undefined(); should(child.treeItem.id).equal('azure.resource.providers.databaseServer.treeDataProvider.databaseServerContainer'); - should(child.treeItem.label).equal('SQL Servers'); + should(child.treeItem.label).equal('SQL server'); should(child.treeItem.collapsibleState).equal(vscode.TreeItemCollapsibleState.Collapsed); should(child.treeItem.contextValue).equal('azure.resource.itemType.databaseServerContainer'); });