mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -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 { ServiceClientCredentials } from '@azure/ms-rest-js';
|
||||||
import { IAzureResourceService } from '../../interfaces';
|
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 { ResourceGraphClient } from '@azure/arm-resourcegraph';
|
||||||
import { queryGraphResources, GraphData } from '../resourceTreeDataProviderBase';
|
import { queryGraphResources, GraphData } from '../resourceTreeDataProviderBase';
|
||||||
import { AzureAccount, azureResource } from 'azurecore';
|
import { AzureAccount, azureResource } from 'azurecore';
|
||||||
@@ -18,19 +19,45 @@ export class AzureResourceDatabaseService implements IAzureResourceService<azure
|
|||||||
const databases: azureResource.AzureResourceDatabase[] = [];
|
const databases: azureResource.AzureResourceDatabase[] = [];
|
||||||
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
|
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)
|
// Query servers, synapse workspaces, and databases in parallel (start all promises before waiting on the 1st)
|
||||||
let serverQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, serversQuery);
|
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 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[];
|
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
|
// 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
|
// can get the login name and server fully qualified name to use for connections
|
||||||
let rgMap = new Map<string, DbServerGraphData[]>();
|
let rgMap = new Map<string, (DbServerGraphData | SynapseWorkspaceGraphData)[]>();
|
||||||
servers.forEach(s => {
|
combined.forEach(s => {
|
||||||
let serversForRg = rgMap.get(s.resourceGroup) || [];
|
if ((s as SynapseWorkspaceGraphData).properties.connectivityEndpoints) {
|
||||||
serversForRg.push(s);
|
// If the resource is a Synapse Workspace, we need to use the managedResourceGroupName
|
||||||
rgMap.set(s.resourceGroup, serversForRg);
|
// (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
|
// 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)) {
|
if (serversForRg && !db.kind.endsWith('system') && svrIdRegExp.test(db.id)) {
|
||||||
const founds = svrIdRegExp.exec(db.id);
|
const founds = svrIdRegExp.exec(db.id);
|
||||||
const serverName = founds[2];
|
const serverName = founds[2];
|
||||||
let server = servers.find(s => s.name === serverName);
|
let server = combined.find(s => s.name === serverName);
|
||||||
if (server) {
|
if (server) {
|
||||||
databases.push({
|
databases.push({
|
||||||
name: db.name,
|
name: db.name,
|
||||||
id: db.id,
|
id: db.id,
|
||||||
serverName: server.name,
|
serverName: server.name,
|
||||||
serverFullName: server.properties.fullyQualifiedDomainName,
|
// Determine if server object is for Synapse Workspace or not and get the needed property from the correct place.
|
||||||
loginName: server.properties.administratorLogin,
|
serverFullName: (server as SynapseWorkspaceGraphData).properties.connectivityEndpoints?.sql ?? (server as DbServerGraphData).properties.fullyQualifiedDomainName,
|
||||||
|
loginName: (server as SynapseWorkspaceGraphData).properties.sqlAdministratorLogin ?? (server as DbServerGraphData).properties.administratorLogin,
|
||||||
subscription: {
|
subscription: {
|
||||||
id: db.subscriptionId,
|
id: db.subscriptionId,
|
||||||
name: (subscriptions.find(sub => sub.id === db.subscriptionId))?.name
|
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.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { ServiceClientCredentials } from '@azure/ms-rest-js';
|
||||||
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
|
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
|
||||||
import { azureResource } from 'azurecore';
|
import { GraphData, queryGraphResources } from '../resourceTreeDataProviderBase';
|
||||||
|
import { azureResource, AzureAccount } from 'azurecore';
|
||||||
|
import { sqlServersQuery, synapseWorkspacesQuery } from './serverQueryStrings';
|
||||||
|
import { IAzureResourceService } from '../../interfaces';
|
||||||
|
|
||||||
export interface DbServerGraphData extends GraphData {
|
export interface DbServerGraphData extends GraphData {
|
||||||
properties: {
|
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 {
|
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 {
|
return {
|
||||||
id: resource.id,
|
id: resource.id,
|
||||||
name: resource.name,
|
name: resource.name,
|
||||||
fullName: resource.properties.fullyQualifiedDomainName,
|
// Determine if resource object is for Synapse Workspace or not and get the needed property from the correct place.
|
||||||
loginName: resource.properties.administratorLogin,
|
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',
|
defaultDatabaseName: 'master',
|
||||||
subscription: {
|
subscription: {
|
||||||
id: resource.subscriptionId,
|
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