mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 02:32:35 -05:00
Replace FQDN for Sql Synapse Servers (#20581)
* WIP work on rest call * moved check to resourceTreeDataProviderBase * some cleanup * added working check * placeholder, using filter function in resourceTreeDataProviderBase * added connectivityEndpoints * added kind filter * fixed minor bits * added wip changes * added working queries * added synapse to getSqlServers * added override * massive overhaul * added property check * made changes * added clarifying comments * added comment fixes * remove async
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
|
||||
import { ServiceClientCredentials } from '@azure/ms-rest-js';
|
||||
import { IAzureResourceService } from '../../interfaces';
|
||||
import { serversQuery, DbServerGraphData } from '../databaseServer/databaseServerService';
|
||||
import { DbServerGraphData, SynapseWorkspaceGraphData } from '../databaseServer/databaseServerService';
|
||||
import { synapseWorkspacesQuery, sqlServersQuery } from '../databaseServer/serverQueryStrings';
|
||||
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
|
||||
import { queryGraphResources, GraphData } from '../resourceTreeDataProviderBase';
|
||||
import { AzureAccount, azureResource } from 'azurecore';
|
||||
@@ -18,19 +19,45 @@ export class AzureResourceDatabaseService implements IAzureResourceService<azure
|
||||
const databases: azureResource.AzureResourceDatabase[] = [];
|
||||
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
|
||||
|
||||
// Query servers and databases in parallel (start both promises before waiting on the 1st)
|
||||
let serverQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, serversQuery);
|
||||
// Query servers, synapse workspaces, and databases in parallel (start all promises before waiting on the 1st)
|
||||
let servers: DbServerGraphData[];
|
||||
let synapseWorkspaces: SynapseWorkspaceGraphData[];
|
||||
let combined: (DbServerGraphData | SynapseWorkspaceGraphData)[] = [];
|
||||
/**
|
||||
* We need to get the list of servers minus the Synapse Workspaces,
|
||||
* then we need to make another query to get them.
|
||||
*
|
||||
* This is done because the first query provides invalid endpoints for Synapse Workspaces
|
||||
* While the second one provides them as one of its properties.
|
||||
*
|
||||
* They have to be processed in different ways as their structure differs
|
||||
* in terms of properties. (See databaseServer/databaseServerService.ts for more info)
|
||||
*
|
||||
* Queries must be made separately due to union not being recognized by resourceGraph resource calls
|
||||
*/
|
||||
let synapseQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, synapseWorkspacesQuery);
|
||||
let serverQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, sqlServersQuery);
|
||||
let dbQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, `where type == "${azureResource.AzureResourceType.sqlDatabase}"`);
|
||||
let servers: DbServerGraphData[] = await serverQueryPromise as DbServerGraphData[];
|
||||
servers = await serverQueryPromise as DbServerGraphData[];
|
||||
synapseWorkspaces = await synapseQueryPromise as SynapseWorkspaceGraphData[];
|
||||
let dbByGraph: DatabaseGraphData[] = await dbQueryPromise as DatabaseGraphData[];
|
||||
combined = combined.concat(servers).concat(synapseWorkspaces);
|
||||
|
||||
// Group servers by resource group, then merge DB results with servers so we
|
||||
// can get the login name and server fully qualified name to use for connections
|
||||
let rgMap = new Map<string, DbServerGraphData[]>();
|
||||
servers.forEach(s => {
|
||||
let serversForRg = rgMap.get(s.resourceGroup) || [];
|
||||
serversForRg.push(s);
|
||||
rgMap.set(s.resourceGroup, serversForRg);
|
||||
let rgMap = new Map<string, (DbServerGraphData | SynapseWorkspaceGraphData)[]>();
|
||||
combined.forEach(s => {
|
||||
if ((s as SynapseWorkspaceGraphData).properties.connectivityEndpoints) {
|
||||
// If the resource is a Synapse Workspace, we need to use the managedResourceGroupName
|
||||
// (any SQL pools inside will use this instead of the regular resource group associated with the workspace itself).
|
||||
let serversForRg = rgMap.get((s as SynapseWorkspaceGraphData).properties.managedResourceGroupName) || [];
|
||||
serversForRg.push(s as SynapseWorkspaceGraphData);
|
||||
rgMap.set((s as SynapseWorkspaceGraphData).properties.managedResourceGroupName, serversForRg);
|
||||
} else {
|
||||
let serversForRg = rgMap.get(s.resourceGroup) || [];
|
||||
serversForRg.push(s);
|
||||
rgMap.set(s.resourceGroup, serversForRg);
|
||||
}
|
||||
});
|
||||
|
||||
// Match database ID. When calling exec [0] is full match, [1] is resource group name, [2] is server name
|
||||
@@ -42,14 +69,15 @@ export class AzureResourceDatabaseService implements IAzureResourceService<azure
|
||||
if (serversForRg && !db.kind.endsWith('system') && svrIdRegExp.test(db.id)) {
|
||||
const founds = svrIdRegExp.exec(db.id);
|
||||
const serverName = founds[2];
|
||||
let server = servers.find(s => s.name === serverName);
|
||||
let server = combined.find(s => s.name === serverName);
|
||||
if (server) {
|
||||
databases.push({
|
||||
name: db.name,
|
||||
id: db.id,
|
||||
serverName: server.name,
|
||||
serverFullName: server.properties.fullyQualifiedDomainName,
|
||||
loginName: server.properties.administratorLogin,
|
||||
// Determine if server object is for Synapse Workspace or not and get the needed property from the correct place.
|
||||
serverFullName: (server as SynapseWorkspaceGraphData).properties.connectivityEndpoints?.sql ?? (server as DbServerGraphData).properties.fullyQualifiedDomainName,
|
||||
loginName: (server as SynapseWorkspaceGraphData).properties.sqlAdministratorLogin ?? (server as DbServerGraphData).properties.administratorLogin,
|
||||
subscription: {
|
||||
id: db.subscriptionId,
|
||||
name: (subscriptions.find(sub => sub.id === db.subscriptionId))?.name
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
|
||||
import { azureResource } from 'azurecore';
|
||||
import { ServiceClientCredentials } from '@azure/ms-rest-js';
|
||||
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
|
||||
import { GraphData, queryGraphResources } from '../resourceTreeDataProviderBase';
|
||||
import { azureResource, AzureAccount } from 'azurecore';
|
||||
import { sqlServersQuery, synapseWorkspacesQuery } from './serverQueryStrings';
|
||||
import { IAzureResourceService } from '../../interfaces';
|
||||
|
||||
export interface DbServerGraphData extends GraphData {
|
||||
properties: {
|
||||
@@ -14,20 +17,73 @@ export interface DbServerGraphData extends GraphData {
|
||||
};
|
||||
}
|
||||
|
||||
export const serversQuery = `where type == "${azureResource.AzureResourceType.sqlServer}"`;
|
||||
/**
|
||||
* Properties returned by the Synapse query are different from the server ones and have to be treated differently.
|
||||
*/
|
||||
export interface SynapseWorkspaceGraphData extends GraphData {
|
||||
properties: {
|
||||
/**
|
||||
* SQL connectivity endpoint and other endpoints are found here, instead of fullyQualifiedDomainName.
|
||||
*/
|
||||
connectivityEndpoints: { sql: string };
|
||||
/**
|
||||
* managedResourceGroupName is the resource group used by any SQL pools inside the workspace
|
||||
* which is different from the resource group of the workspace itself.
|
||||
*/
|
||||
managedResourceGroupName: string;
|
||||
/**
|
||||
* administratorLogin is called sqlAdministratorLogin here.
|
||||
*/
|
||||
sqlAdministratorLogin: string;
|
||||
};
|
||||
}
|
||||
|
||||
export class AzureResourceDatabaseServerService extends ResourceServiceBase<DbServerGraphData, azureResource.AzureResourceDatabaseServer> {
|
||||
export class AzureResourceDatabaseServerService implements IAzureResourceService<azureResource.AzureResourceDatabaseServer> {
|
||||
|
||||
protected get query(): string {
|
||||
return serversQuery;
|
||||
return sqlServersQuery;
|
||||
}
|
||||
|
||||
protected convertResource(resource: DbServerGraphData): azureResource.AzureResourceDatabaseServer {
|
||||
public async getResources(subscriptions: azureResource.AzureResourceSubscription[], credential: ServiceClientCredentials, account: AzureAccount): Promise<azureResource.AzureResourceDatabaseServer[]> {
|
||||
const convertedResources: azureResource.AzureResourceDatabaseServer[] = [];
|
||||
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
|
||||
/**
|
||||
* We need to get the list of servers minus the Synapse Workspaces,
|
||||
* then we need to make another query to get them.
|
||||
*
|
||||
* This is done because the first query provides invalid endpoints for Synapse Workspaces
|
||||
* While the second one provides them as one of its properties.
|
||||
*
|
||||
* They have to be processed in different ways by convertResource as their structure differs
|
||||
* in terms of properties. (See above)
|
||||
*
|
||||
* Queries must be made separately due to union not being recognized by resourceGraph resource calls.
|
||||
*/
|
||||
let combinedGraphResources: (DbServerGraphData | SynapseWorkspaceGraphData)[] = [];
|
||||
let serverGraphResources: DbServerGraphData[] = await queryGraphResources<DbServerGraphData>(resourceClient, subscriptions, this.query);
|
||||
let synapseGraphResources: SynapseWorkspaceGraphData[] = await queryGraphResources<SynapseWorkspaceGraphData>(resourceClient, subscriptions, synapseWorkspacesQuery);
|
||||
combinedGraphResources = combinedGraphResources.concat(serverGraphResources).concat(synapseGraphResources);
|
||||
const ids = new Set<string>();
|
||||
combinedGraphResources.forEach((res) => {
|
||||
if (!ids.has(res.id)) {
|
||||
ids.add(res.id);
|
||||
res.subscriptionName = subscriptions.find(sub => sub.id === res.subscriptionId).name;
|
||||
const converted = this.convertResource(res);
|
||||
convertedResources.push(converted);
|
||||
}
|
||||
});
|
||||
|
||||
return convertedResources;
|
||||
}
|
||||
|
||||
protected convertResource(resource: DbServerGraphData | SynapseWorkspaceGraphData): azureResource.AzureResourceDatabaseServer {
|
||||
|
||||
return {
|
||||
id: resource.id,
|
||||
name: resource.name,
|
||||
fullName: resource.properties.fullyQualifiedDomainName,
|
||||
loginName: resource.properties.administratorLogin,
|
||||
// Determine if resource object is for Synapse Workspace or not and get the needed property from the correct place.
|
||||
fullName: (resource as SynapseWorkspaceGraphData).properties.connectivityEndpoints?.sql ?? (resource as DbServerGraphData).properties.fullyQualifiedDomainName,
|
||||
loginName: (resource as SynapseWorkspaceGraphData).properties.sqlAdministratorLogin ?? (resource as DbServerGraphData).properties.administratorLogin,
|
||||
defaultDatabaseName: 'master',
|
||||
subscription: {
|
||||
id: resource.subscriptionId,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { azureResource } from 'azurecore';
|
||||
/**
|
||||
* Get list of Synapse Workspaces with information such as SQL connection endpoints.
|
||||
*/
|
||||
export const synapseWorkspacesQuery = `where type == "microsoft.synapse/workspaces"`;
|
||||
|
||||
|
||||
/**
|
||||
* Lists all Sql Servers except for Synapse Pool Servers
|
||||
* (they have different properties and need to be handled separately,
|
||||
* see databaseServerService.ts for more details)
|
||||
*/
|
||||
export const sqlServersQuery = `where type == "${azureResource.AzureResourceType.sqlServer}" and kind != "v12.0,analytics"`;
|
||||
Reference in New Issue
Block a user