diff --git a/extensions/azurecore/src/azureDataGridProvider.ts b/extensions/azurecore/src/azureDataGridProvider.ts index 0cd048d99f..e2a33a57b8 100644 --- a/extensions/azurecore/src/azureDataGridProvider.ts +++ b/extensions/azurecore/src/azureDataGridProvider.ts @@ -21,6 +21,7 @@ const typesClause = [ azureResource.AzureResourceType.sqlSynapseSqlPool, azureResource.AzureResourceType.sqlManagedInstance, azureResource.AzureResourceType.postgresServer, + azureResource.AzureResourceType.postgresFlexibleServer, azureResource.AzureResourceType.azureArcService, azureResource.AzureResourceType.azureArcSqlManagedInstance, azureResource.AzureResourceType.azureArcPostgresServer diff --git a/extensions/azurecore/src/azureResource/constants.ts b/extensions/azurecore/src/azureResource/constants.ts index 37837514b9..66ad7aa81f 100644 --- a/extensions/azurecore/src/azureResource/constants.ts +++ b/extensions/azurecore/src/azureResource/constants.ts @@ -42,6 +42,7 @@ export enum AzureResourcePrefixes { kusto = 'Kusto_', mySqlFlexibleServer = 'mySqlFlexibleServer_', postgresServerArc = 'postgresServerArc_', + postgresFlexibleServer = 'postgresFlexibleServer_', postgresServer = 'postgresServer_', sqlInstance = 'sqlInstance_', sqlInstanceArc = 'sqlInstanceArc_', diff --git a/extensions/azurecore/src/azureResource/providers/mysqlFlexibleServer/mysqlFlexibleServerTreeDataProvider.ts b/extensions/azurecore/src/azureResource/providers/mysqlFlexibleServer/mysqlFlexibleServerTreeDataProvider.ts index f37d6793fa..e41e1a7534 100644 --- a/extensions/azurecore/src/azureResource/providers/mysqlFlexibleServer/mysqlFlexibleServerTreeDataProvider.ts +++ b/extensions/azurecore/src/azureResource/providers/mysqlFlexibleServer/mysqlFlexibleServerTreeDataProvider.ts @@ -16,7 +16,7 @@ import { Account, ExtensionNodeType, TreeItem, connection } from 'azdata'; export class MysqlFlexibleServerTreeDataProvider extends ResourceTreeDataProviderBase { private static readonly CONTAINER_ID = 'azure.resource.providers.databaseServer.treeDataProvider.mysqlFlexibleServerContainer'; - private static readonly CONTAINER_LABEL = localize('azure.resource.providers.databaseServer.treeDataProvider.mysqlFlexibleServerContainerLabel', "Azure Database for MySQL Flexible server"); + private static readonly CONTAINER_LABEL = localize('azure.resource.providers.databaseServer.treeDataProvider.mysqlFlexibleServerContainerLabel', "Azure Database for MySQL flexible servers"); public constructor( databaseServerService: azureResource.IAzureResourceService, diff --git a/extensions/azurecore/src/azureResource/providers/postgresFlexibleServer/postgresFlexibleServerService.ts b/extensions/azurecore/src/azureResource/providers/postgresFlexibleServer/postgresFlexibleServerService.ts new file mode 100644 index 0000000000..2f93f5c73d --- /dev/null +++ b/extensions/azurecore/src/azureResource/providers/postgresFlexibleServer/postgresFlexibleServerService.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + +import { ResourceServiceBase } from '../resourceTreeDataProviderBase'; +import { azureResource } from 'azurecore'; +import { postgresFlexibleServerQuery } from '../queryStringConstants'; +import { DbServerGraphData } from '../../interfaces'; +import { POSTGRES_FLEXIBLE_SERVER_PROVIDER_ID } from '../../../constants'; + +export class PostgresFlexibleServerService extends ResourceServiceBase { + + public override queryFilter: string = postgresFlexibleServerQuery; + + public override convertServerResource(resource: DbServerGraphData): azureResource.AzureResourceDatabaseServer | undefined { + return { + id: resource.id, + name: resource.name, + provider: POSTGRES_FLEXIBLE_SERVER_PROVIDER_ID, + fullName: resource.properties.fullyQualifiedDomainName, + loginName: resource.properties.administratorLogin, + defaultDatabaseName: 'postgres', + subscription: { + id: resource.subscriptionId, + name: resource.subscriptionName || '' + }, + tenant: resource.tenantId, + resourceGroup: resource.resourceGroup + }; + } +} diff --git a/extensions/azurecore/src/azureResource/providers/postgresFlexibleServer/postgresFlexibleServerTreeDataProvider.ts b/extensions/azurecore/src/azureResource/providers/postgresFlexibleServer/postgresFlexibleServerTreeDataProvider.ts new file mode 100644 index 0000000000..e3cfb26f31 --- /dev/null +++ b/extensions/azurecore/src/azureResource/providers/postgresFlexibleServer/postgresFlexibleServerTreeDataProvider.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * 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, connection } from 'azdata'; +import { TreeItemCollapsibleState, ExtensionContext } from 'vscode'; +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + +import { AzureResourceItemType, AzureResourcePrefixes, pgsqlProvider } from '../../constants'; +import { generateGuid } from '../../utils'; +import { GraphData, DbServerGraphData } from '../../interfaces'; +import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase'; +import { AzureAccount, azureResource } from 'azurecore'; + +export class PostgresFlexibleServerTreeDataProvider extends ResourceTreeDataProviderBase { + private static readonly containerId = 'azure.resource.providers.databaseServer.treeDataProvider.postgresFlexibleServerContainer'; + private static readonly containerLabel = localize('azure.resource.providers.databaseServer.treeDataProvider.postgresFlexibleServerContainerLabel', "Azure Database for PostgreSQL flexible servers"); + + public constructor( + databaseServerService: azureResource.IAzureResourceService, + private _extensionContext: ExtensionContext + ) { + super(databaseServerService); + } + + public getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer, account: AzureAccount): TreeItem { + return { + id: `${AzureResourcePrefixes.postgresFlexibleServer}${account.key.accountId}${databaseServer.id ?? databaseServer.name}`, + label: this.browseConnectionMode ? `${databaseServer.name} (${PostgresFlexibleServerTreeDataProvider.containerLabel}, ${databaseServer.subscription.name})` : databaseServer.name, + iconPath: { + dark: this._extensionContext.asAbsolutePath('resources/dark/sql_server_inverse.svg'), + light: this._extensionContext.asAbsolutePath('resources/light/sql_server.svg') + }, + collapsibleState: this.browseConnectionMode ? TreeItemCollapsibleState.None : TreeItemCollapsibleState.Collapsed, + contextValue: AzureResourceItemType.databaseServer, + payload: { + id: generateGuid(), + connectionName: undefined, + serverName: databaseServer.fullName, + databaseName: databaseServer.defaultDatabaseName, + userName: `${databaseServer.loginName}@${databaseServer.fullName}`, + password: '', + authenticationType: connection.AuthenticationType.SqlLogin, + savePassword: true, + groupFullName: '', + groupId: '', + providerName: pgsqlProvider, + saveProfile: false, + options: { + // Set default for SSL or will get error complaining about it not being set correctly + 'sslmode': 'require' + }, + azureAccount: account.key.accountId, + azureTenantId: databaseServer.tenant, + azureResourceId: databaseServer.id, + azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint + }, + childProvider: pgsqlProvider, + type: ExtensionNodeType.Server + }; + } + + public async getRootChildren(): Promise { + return [{ + id: PostgresFlexibleServerTreeDataProvider.containerId, + label: PostgresFlexibleServerTreeDataProvider.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 5ec37b1653..ad0839eb55 100644 --- a/extensions/azurecore/src/azureResource/providers/postgresServer/postgresServerTreeDataProvider.ts +++ b/extensions/azurecore/src/azureResource/providers/postgresServer/postgresServerTreeDataProvider.ts @@ -16,7 +16,7 @@ import { AzureAccount, azureResource } from 'azurecore'; 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 server"); + private static readonly containerLabel = localize('azure.resource.providers.databaseServer.treeDataProvider.postgresServerContainerLabel', "Azure Database for PostgreSQL servers"); public constructor( databaseServerService: azureResource.IAzureResourceService, diff --git a/extensions/azurecore/src/azureResource/providers/queryStringConstants.ts b/extensions/azurecore/src/azureResource/providers/queryStringConstants.ts index 7f4790e014..ad77e43780 100644 --- a/extensions/azurecore/src/azureResource/providers/queryStringConstants.ts +++ b/extensions/azurecore/src/azureResource/providers/queryStringConstants.ts @@ -48,6 +48,11 @@ export const resourceGroupQuery = `ResourceContainers | where type=="${azureReso */ export const postgresServerQuery = `type == "${azureResource.AzureResourceType.postgresServer}"`; +/** + * Lists all postgreSQL flexible servers + */ +export const postgresFlexibleServerQuery = `type == "${azureResource.AzureResourceType.postgresFlexibleServer}"`; + /** * Lists all Azure Arc PostgreSQL servers */ diff --git a/extensions/azurecore/src/azureResource/providers/universal/universalService.ts b/extensions/azurecore/src/azureResource/providers/universal/universalService.ts index 974fb582df..eb96bf875a 100644 --- a/extensions/azurecore/src/azureResource/providers/universal/universalService.ts +++ b/extensions/azurecore/src/azureResource/providers/universal/universalService.ts @@ -13,8 +13,8 @@ import * as nls from 'vscode-nls'; import { AzureResourcePrefixes, ResourceCategory, analyticsKind, mongoDbKind } from '../../constants'; import { COSMOSDB_MONGO_PROVIDER_ID, DATABASE_PROVIDER_ID, DATABASE_SERVER_PROVIDER_ID, KUSTO_PROVIDER_ID, AZURE_MONITOR_PROVIDER_ID, - MYSQL_FLEXIBLE_SERVER_PROVIDER_ID, POSTGRES_SERVER_PROVIDER_ID, POSTGRES_ARC_SERVER_PROVIDER_ID, SQLINSTANCE_PROVIDER_ID, - SQLINSTANCE_ARC_PROVIDER_ID, SYNAPSE_SQL_POOL_PROVIDER_ID, SYNAPSE_WORKSPACE_PROVIDER_ID + MYSQL_FLEXIBLE_SERVER_PROVIDER_ID, POSTGRES_FLEXIBLE_SERVER_PROVIDER_ID, POSTGRES_SERVER_PROVIDER_ID, POSTGRES_ARC_SERVER_PROVIDER_ID, + SQLINSTANCE_PROVIDER_ID, SQLINSTANCE_ARC_PROVIDER_ID, SYNAPSE_SQL_POOL_PROVIDER_ID, SYNAPSE_WORKSPACE_PROVIDER_ID } from '../../../constants'; import { Logger } from '../../../utils/Logger'; @@ -91,6 +91,8 @@ export class AzureResourceUniversalService implements azureResource.IAzureResour return [this.getRegisteredTreeDataProviderInstance(AZURE_MONITOR_PROVIDER_ID), ResourceCategory.Server]; } else if (type === azureResource.AzureResourceType.mysqlFlexibleServer) { return [this.getRegisteredTreeDataProviderInstance(MYSQL_FLEXIBLE_SERVER_PROVIDER_ID), ResourceCategory.Server]; + } else if (type === azureResource.AzureResourceType.postgresFlexibleServer) { + return [this.getRegisteredTreeDataProviderInstance(POSTGRES_FLEXIBLE_SERVER_PROVIDER_ID), ResourceCategory.Server]; } else if (type === azureResource.AzureResourceType.postgresServer) { return [this.getRegisteredTreeDataProviderInstance(POSTGRES_SERVER_PROVIDER_ID), ResourceCategory.Server]; } else if (type === azureResource.AzureResourceType.azureArcPostgresServer) { @@ -121,6 +123,8 @@ export class AzureResourceUniversalService implements azureResource.IAzureResour return this.getRegisteredTreeDataProviderInstance(AZURE_MONITOR_PROVIDER_ID); } else if (id.startsWith(AzureResourcePrefixes.mySqlFlexibleServer)) { return this.getRegisteredTreeDataProviderInstance(MYSQL_FLEXIBLE_SERVER_PROVIDER_ID); + } else if (id.startsWith(AzureResourcePrefixes.postgresFlexibleServer)) { + return this.getRegisteredTreeDataProviderInstance(POSTGRES_FLEXIBLE_SERVER_PROVIDER_ID); } else if (id.startsWith(AzureResourcePrefixes.postgresServer)) { return this.getRegisteredTreeDataProviderInstance(POSTGRES_SERVER_PROVIDER_ID); } else if (id.startsWith(AzureResourcePrefixes.postgresServerArc)) { diff --git a/extensions/azurecore/src/azureResource/utils.ts b/extensions/azurecore/src/azureResource/utils.ts index 0c6ca2d3f9..6f0663b016 100644 --- a/extensions/azurecore/src/azureResource/utils.ts +++ b/extensions/azurecore/src/azureResource/utils.ts @@ -48,6 +48,8 @@ import { AzureResourceSynapseService } from './providers/synapseSqlPool/synapseS import { AzureResourceSynapseSqlPoolTreeDataProvider } from './providers/synapseSqlPool/synapseSqlPoolTreeDataProvider'; import { AzureResourceSynapseWorkspaceService } from './providers/synapseWorkspace/synapseWorkspaceService'; import { AzureResourceSynapseWorkspaceTreeDataProvider } from './providers/synapseWorkspace/synapseWorkspaceTreeDataProvider'; +import { PostgresFlexibleServerTreeDataProvider } from './providers/postgresFlexibleServer/postgresFlexibleServerTreeDataProvider'; +import { PostgresFlexibleServerService } from './providers/postgresFlexibleServer/postgresFlexibleServerService'; const localize = nls.loadMessageBundle(); @@ -268,6 +270,7 @@ export function getAllResourceProviders(extensionContext: vscode.ExtensionContex new ResourceProvider(Constants.DATABASE_SERVER_PROVIDER_ID, new AzureResourceDatabaseServerTreeDataProvider(new AzureResourceDatabaseServerService(), extensionContext)), new ResourceProvider(Constants.KUSTO_PROVIDER_ID, new KustoTreeDataProvider(new KustoResourceService(), extensionContext)), new ResourceProvider(Constants.MYSQL_FLEXIBLE_SERVER_PROVIDER_ID, new MysqlFlexibleServerTreeDataProvider(new MysqlFlexibleServerService(), extensionContext)), + new ResourceProvider(Constants.POSTGRES_FLEXIBLE_SERVER_PROVIDER_ID, new PostgresFlexibleServerTreeDataProvider(new PostgresFlexibleServerService(), extensionContext)), new ResourceProvider(Constants.POSTGRES_SERVER_PROVIDER_ID, new PostgresServerTreeDataProvider(new PostgresServerService(), extensionContext)), new ResourceProvider(Constants.SQLINSTANCE_PROVIDER_ID, new SqlInstanceTreeDataProvider(new SqlInstanceResourceService(), extensionContext)), new ResourceProvider(Constants.SYNAPSE_SQL_POOL_PROVIDER_ID, new AzureResourceSynapseSqlPoolTreeDataProvider(new AzureResourceSynapseService(), extensionContext)), diff --git a/extensions/azurecore/src/azurecore.d.ts b/extensions/azurecore/src/azurecore.d.ts index 0c6ecdcbda..038ad11ef1 100644 --- a/extensions/azurecore/src/azurecore.d.ts +++ b/extensions/azurecore/src/azurecore.d.ts @@ -378,6 +378,7 @@ declare module 'azurecore' { kustoClusters = 'microsoft.kusto/clusters', azureArcPostgresServer = 'microsoft.azuredata/postgresinstances', postgresServer = 'microsoft.dbforpostgresql/servers', + postgresFlexibleServer = 'microsoft.dbforpostgresql/flexibleservers', azureArcService = 'microsoft.azuredata/datacontrollers', storageAccount = 'microsoft.storage/storageaccounts', logAnalytics = 'microsoft.operationalinsights/workspaces', diff --git a/extensions/azurecore/src/constants.ts b/extensions/azurecore/src/constants.ts index 81bde08895..edb387028b 100644 --- a/extensions/azurecore/src/constants.ts +++ b/extensions/azurecore/src/constants.ts @@ -143,6 +143,7 @@ export const DATABASE_SERVER_PROVIDER_ID = 'azure.resource.providers.databaseSer export const KUSTO_PROVIDER_ID = 'azure.resource.providers.azureDataExplorer'; export const MYSQL_FLEXIBLE_SERVER_PROVIDER_ID = 'azure.resource.providers.mysqlFlexibleServer'; export const POSTGRES_ARC_SERVER_PROVIDER_ID = 'azure.resource.providers.postgresArcServer'; +export const POSTGRES_FLEXIBLE_SERVER_PROVIDER_ID = 'azure.resource.providers.postgresFlexibleServer'; export const POSTGRES_SERVER_PROVIDER_ID = 'azure.resource.providers.postgresServer'; export const SQLINSTANCE_PROVIDER_ID = 'azure.resource.providers.sqlInstance'; export const SQLINSTANCE_ARC_PROVIDER_ID = 'azure.resource.providers.sqlInstanceArc'; diff --git a/extensions/azurecore/src/localizedConstants.ts b/extensions/azurecore/src/localizedConstants.ts index b10f74431f..f660d62fec 100644 --- a/extensions/azurecore/src/localizedConstants.ts +++ b/extensions/azurecore/src/localizedConstants.ts @@ -74,7 +74,8 @@ export const dismiss = localize('azurecore.dismiss', 'Dismiss'); // Azure Resource Types export const sqlServer = localize('azurecore.sqlServer', "SQL server"); export const sqlDatabase = localize('azurecore.sqlDatabase', "SQL database"); -export const postgresServer = localize('azurecore.postgresServer', "Azure Database for PostgreSQL server"); +export const postgresServer = localize('azurecore.postgresServer', "Azure Database for PostgreSQL servers"); +export const postgresFlexibleServer = localize('azurecore.postgresFlexibleServer', "Azure Database for PostgreSQL flexible servers"); export const sqlManagedInstance = localize('azurecore.sqlManagedInstance', "SQL managed instance"); export const azureArcsqlManagedInstance = localize('azurecore.azureArcsqlManagedInstance', "SQL managed instance - Azure Arc"); export const azureArcService = localize('azurecore.azureArcService', "Data Service - Azure Arc"); diff --git a/extensions/azurecore/src/utils.ts b/extensions/azurecore/src/utils.ts index 3e111b56f0..5a74b77054 100644 --- a/extensions/azurecore/src/utils.ts +++ b/extensions/azurecore/src/utils.ts @@ -127,6 +127,8 @@ export function getResourceTypeDisplayName(type: string): string { return loc.sqlManagedInstance; case azureResource.AzureResourceType.postgresServer: return loc.postgresServer; + case azureResource.AzureResourceType.postgresFlexibleServer: + return loc.postgresFlexibleServer; case azureResource.AzureResourceType.azureArcSqlManagedInstance: return loc.azureArcsqlManagedInstance; case azureResource.AzureResourceType.azureArcService: