mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Arc bug fix: ADS Create DC wizard should prompt for Log Analytics workspace ID and access token similar to portal (#18742)
* Added monitor log-analytics workspace list to az api * Made resource group and subscription optional for logs analytics workspace list * Added dynamic fields for workspace names, id, primary key, based on value of auto-logs checkbox * Hooked up the newly created source provider for log analytics workspaces. Dropdown now populates all workspace names. * Added workspaceUtils.ts for a valueprovider. Now workspace name maps to id automatically. * Replaced promise.all with promise.resolve * Added workspace id and primary key as env variables in the notebook * Removed extra space in package.json * Made getOptions more concise and put azApi definition in function. * Changed notebook to handle new Azure CLI command with param --clustername
This commit is contained in:
@@ -185,21 +185,24 @@
|
||||
"print (f'Creating Azure Arc Data Controller: {arc_data_controller_name} using configuration {arc_cluster_context}')\n",
|
||||
"os.environ[\"AZDATA_USERNAME\"] = arc_admin_username\n",
|
||||
"os.environ[\"AZDATA_PASSWORD\"] = arc_admin_password\n",
|
||||
"os.environ[\"LOG_WORKSPACE_ID\"] = log_analytics_workspace_id\n",
|
||||
"os.environ[\"LOG_SHARED_KEY\"] = log_analytics_primary_key\n",
|
||||
"\n",
|
||||
"# If connection mode is indirect\n",
|
||||
"namespace = f' --k8s-namespace {arc_data_controller_namespace}' if is_indirect else ''\n",
|
||||
"use_k8s = ' --use-k8s' if is_indirect else ''\n",
|
||||
"\n",
|
||||
"# If connection mode is direct\n",
|
||||
"custom_location = f' --custom-location {arc_data_controller_custom_location}' if not is_indirect else ''\n",
|
||||
"\n",
|
||||
"cluster_name = f' --cluster-name {arc_cluster_context}' if not is_indirect else ''\n",
|
||||
"auto_upload_metrics_value = 'true' if arc_data_controller_auto_upload_metrics == 'true' else 'false'\n",
|
||||
"auto_upload_logs_value = 'true' if arc_data_controller_auto_upload_logs == 'true' else 'false'\n",
|
||||
"\n",
|
||||
"auto_upload_metrics = f' --auto-upload-metrics {auto_upload_metrics_value}' if not is_indirect else ''\n",
|
||||
"auto_upload_logs = f' --auto-upload-logs {auto_upload_logs_value}' if not is_indirect else ''\n",
|
||||
"\n",
|
||||
"if os.name == 'nt':\n",
|
||||
" print(f'If you don\\'t see output produced by az, you can run the following command in a terminal window to check the deployment status:\\n\\t {os.environ[\"AZDATA_NB_VAR_KUBECTL\"]} get pods -n {arc_data_controller_namespace}')\n",
|
||||
"run_command(f'az arcdata dc create --connectivity-mode {arc_data_controller_connectivity_mode} --name {arc_data_controller_name}{namespace} --subscription {arc_subscription} --resource-group {arc_resource_group} --location {arc_data_controller_location} --storage-class {arc_data_controller_storage_class} --profile-name {arc_profile} --infrastructure {arc_infrastructure}{custom_location}{auto_upload_metrics}{auto_upload_logs}{use_k8s}')\n",
|
||||
"run_command(f'az arcdata dc create --connectivity-mode {arc_data_controller_connectivity_mode} --name {arc_data_controller_name}{namespace} --subscription {arc_subscription} --resource-group {arc_resource_group} --location {arc_data_controller_location} --storage-class {arc_data_controller_storage_class} --profile-name {arc_profile} --infrastructure {arc_infrastructure}{custom_location}{cluster_name}{auto_upload_metrics}{auto_upload_logs}{use_k8s}')\n",
|
||||
"print(f'Azure Arc Data Controller: {arc_data_controller_name} created.') "
|
||||
]
|
||||
},
|
||||
|
||||
@@ -360,6 +360,49 @@
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
|
||||
"value": "Direct"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "options",
|
||||
"label": "%arc.data.controller.log.analytics.workspace.names%",
|
||||
"variableName": "AZDATA_NB_VAR_LOG_ANALYTICS_WORKSPACE_NAMES",
|
||||
"required": true,
|
||||
"options": {
|
||||
"source": {
|
||||
"providerId": "arc.logAnalyticsWorkspaceNames"
|
||||
},
|
||||
"optionsType": "dropdown"
|
||||
},
|
||||
"enabled": {
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_LOGS",
|
||||
"value": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "%arc.data.controller.log.analytics.workspace.id%",
|
||||
"required": true,
|
||||
"isEvaluated": true,
|
||||
"variableName": "AZDATA_NB_VAR_LOG_ANALYTICS_WORKSPACE_ID",
|
||||
"valueProvider": {
|
||||
"providerId": "workspace-name-to-id",
|
||||
"triggerFields": [
|
||||
"AZDATA_NB_VAR_LOG_ANALYTICS_WORKSPACE_NAMES"
|
||||
]
|
||||
},
|
||||
"enabled": {
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_LOGS",
|
||||
"value": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "%arc.data.controller.log.analytics.primary.key%",
|
||||
"required": true,
|
||||
"variableName": "AZDATA_NB_VAR_LOG_ANALYTICS_PRIMARY_KEY",
|
||||
"enabled": {
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_LOGS",
|
||||
"value": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1390,6 +1433,9 @@
|
||||
"resourceDeploymentOptionsSources": [
|
||||
{
|
||||
"id": "arc.controllers"
|
||||
},
|
||||
{
|
||||
"id": "arc.logAnalyticsWorkspaceNames"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
"arc.data.controller.auto.upload.metrics.description": "Enable the automatic upload of metrics. Direct mode only.",
|
||||
"arc.data.controller.auto.upload.logs": "Auto-upload Logs",
|
||||
"arc.data.controller.auto.upload.logs.description": "Enable the automatic upload of logs. Direct mode only.",
|
||||
"arc.data.controller.log.analytics.workspace.names": "Log Analytics workspace",
|
||||
"arc.data.controller.log.analytics.workspace.id": "Log Analytics workspace ID",
|
||||
"arc.data.controller.log.analytics.primary.key": "Log Analytics primary key",
|
||||
|
||||
"arc.data.controller.metrics.and.logs.dashboard.credentials.title": "Metrics and Logs Dashboard Credentials",
|
||||
"arc.data.controller.metrics.and.logs.dashboard.credentials.username": "Username",
|
||||
|
||||
28
extensions/arc/src/common/workspaceUtils.ts
Normal file
28
extensions/arc/src/common/workspaceUtils.ts
Normal file
@@ -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 { InputValueType } from 'resource-deployment';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as vscode from 'vscode';
|
||||
import { errorListingLogAnalyticsWorkspaces } from '../localizedConstants';
|
||||
|
||||
export const licenseTypeVarName = 'AZDATA_NB_VAR_LOG_ANALYTICS_WORKSPACE_NAMES';
|
||||
|
||||
// Gets the Log Analytics workspace id from the workspace name.
|
||||
export async function getWorkspaceIdFromName(triggerFields: { [key: string]: InputValueType }): Promise<string | undefined> {
|
||||
try {
|
||||
const _azApi = <azExt.IExtension>vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
const workspaces = await _azApi.az.monitor.logAnalytics.workspace.list();
|
||||
const targetWorkspace = workspaces.stdout.find(workspace => workspace.name === triggerFields[licenseTypeVarName]);
|
||||
if (targetWorkspace) {
|
||||
return targetWorkspace.customerId;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(errorListingLogAnalyticsWorkspaces(e));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ import { AzureArcTreeDataProvider } from './ui/tree/azureArcTreeDataProvider';
|
||||
import { ControllerTreeNode } from './ui/tree/controllerTreeNode';
|
||||
import { TreeNode } from './ui/tree/treeNode';
|
||||
import * as pricing from './common/pricingUtils';
|
||||
import * as workspace from './common/workspaceUtils';
|
||||
import { LogAnalyticsWorkspaceOptionsSourceProvider } from './providers/logAnalyticsWorkspaceOptionsSourceProvider';
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext): Promise<arc.IExtension> {
|
||||
IconPathHelper.setExtensionContext(context);
|
||||
@@ -61,6 +63,15 @@ export async function activate(context: vscode.ExtensionContext): Promise<arc.IE
|
||||
// register option sources
|
||||
const rdApi = <rd.IExtension>vscode.extensions.getExtension(rd.extension.name)?.exports;
|
||||
context.subscriptions.push(rdApi.registerOptionsSourceProvider(new ArcControllersOptionsSourceProvider(treeDataProvider)));
|
||||
context.subscriptions.push(rdApi.registerOptionsSourceProvider(new LogAnalyticsWorkspaceOptionsSourceProvider()));
|
||||
|
||||
// Register valueprovider for getting the Log Analytics workspace id from the workspace name.
|
||||
context.subscriptions.push(rdApi.registerValueProvider({
|
||||
id: 'workspace-name-to-id',
|
||||
getValue: async (triggerFields: { [key: string]: rd.InputValueType }) => {
|
||||
return workspace.getWorkspaceIdFromName(triggerFields);
|
||||
}
|
||||
}));
|
||||
|
||||
// Register valueprovider for getting the calculated cost per VCore.
|
||||
context.subscriptions.push(rdApi.registerValueProvider({
|
||||
|
||||
@@ -334,3 +334,4 @@ export const userCancelledError = localize('arc.userCancelledError', "User cance
|
||||
export const clusterContextConfigNoLongerValid = (configFile: string, clusterContext: string, error: any) => localize('clusterContextConfigNoLongerValid', "The cluster context information specified by config file: {0} and cluster context: {1} is no longer valid. Error is:\n\t{2}\n Do you want to update this information?", configFile, clusterContext, getErrorMessage(error));
|
||||
export const invalidConfigPath = localize('arc.invalidConfigPath', "Invalid config path");
|
||||
export const loadingClusterContextsError = (error: any): string => localize('arc.loadingClusterContextsError', "Error loading cluster contexts. {0}", getErrorMessage(error));
|
||||
export function errorListingLogAnalyticsWorkspaces(error: any): string { return localize('arc.errorListingLogAnalyticsWorkspaces', "Error listing Log Analytics workspaces {0}", getErrorMessage(error, true)); }
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azExt from 'az-ext';
|
||||
import * as rd from 'resource-deployment';
|
||||
import * as vscode from 'vscode';
|
||||
import { errorListingLogAnalyticsWorkspaces } from '../localizedConstants';
|
||||
|
||||
/**
|
||||
* Class that provides options sources for Log Analytics workspace names
|
||||
*/
|
||||
export class LogAnalyticsWorkspaceOptionsSourceProvider implements rd.IOptionsSourceProvider {
|
||||
readonly id = 'arc.logAnalyticsWorkspaceNames';
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
constructor() {
|
||||
this._azApi = <azExt.IExtension>vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
}
|
||||
|
||||
public async getOptions(): Promise<string[]> {
|
||||
try {
|
||||
const workspacesListResult = await this._azApi.az.monitor.logAnalytics.workspace.list();
|
||||
return workspacesListResult.stdout.map(workspace => workspace.name);
|
||||
} catch (err) {
|
||||
vscode.window.showErrorMessage(errorListingLogAnalyticsWorkspaces(err));
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,6 +154,17 @@ export function getAzApi(localAzDiscovered: Promise<IAzTool | undefined>, azTool
|
||||
}
|
||||
}
|
||||
},
|
||||
monitor: {
|
||||
logAnalytics: {
|
||||
workspace: {
|
||||
list: async (resourceGroup?: string, subscription?: string, additionalEnvVars?: azExt.AdditionalEnvVars) => {
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.monitor.logAnalytics.workspace.list(resourceGroup, subscription, additionalEnvVars);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getPath: async () => {
|
||||
await localAzDiscovered;
|
||||
throwIfNoAz(azToolService.localAz);
|
||||
|
||||
@@ -209,6 +209,19 @@ export class AzTool implements azExt.IAzApi {
|
||||
}
|
||||
};
|
||||
|
||||
public monitor = {
|
||||
logAnalytics: {
|
||||
workspace: {
|
||||
list: (resourceGroup?: string, subscription?: string, additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<azExt.LogAnalyticsWorkspaceListResult[]>> => {
|
||||
const argsArray = ['monitor', 'log-analytics', 'workspace', 'list'];
|
||||
if (resourceGroup) { argsArray.push('--resource-group', resourceGroup); }
|
||||
if (subscription) { argsArray.push('--subscription', subscription); }
|
||||
return this.executeCommand<azExt.LogAnalyticsWorkspaceListResult[]>(argsArray, additionalEnvVars);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the output of running '--version' command on the az tool.
|
||||
|
||||
50
extensions/azcli/src/typings/az-ext.d.ts
vendored
50
extensions/azcli/src/typings/az-ext.d.ts
vendored
@@ -187,6 +187,45 @@ declare module 'az-ext' {
|
||||
state: string //Completed
|
||||
}
|
||||
|
||||
export interface LogAnalyticsWorkspaceListResult {
|
||||
createdDate: string, // "2020-02-25T16:59:38Z"
|
||||
customerId: string, // "7e136a79-c0b6-4878-86bf-7bf7a6a7e6f6",
|
||||
eTag: string, // null,
|
||||
etag: string, // "\"00006df1-0000-0700-0000-61ee552f0000\"",
|
||||
features: {
|
||||
clusterResourceId: string, // null,
|
||||
disableLocalAuth: boolean, // null,
|
||||
enableDataExport: boolean, // null,
|
||||
enableLogAccessUsingOnlyResourcePermissions: boolean, //true,
|
||||
immediatePurgeDataOn30Days: boolean, // null,
|
||||
legacy: number, // 0,
|
||||
searchVersion: number // 1
|
||||
},
|
||||
forceCmkForQuery: boolean, // null,
|
||||
id: string, // "/subscriptions/a5082b19-8a6e-4bc5-8fdd-8ef39dfebc39/resourcegroups/bugbash/providers/microsoft.operationalinsights/workspaces/bugbash-logs",
|
||||
location: string, // "westus",
|
||||
modifiedDate: string, // "2022-02-21T09:18:22.3906451Z",
|
||||
name: string, // "bugbash-logs",
|
||||
privateLinkScopedResources: string, // null,
|
||||
provisioningState: string, // "Succeeded",
|
||||
publicNetworkAccessForIngestion: string, // "Enabled",
|
||||
publicNetworkAccessForQuery: string, // "Enabled",
|
||||
resourceGroup: string, // "bugbash",
|
||||
retentionInDays: number, // 30,
|
||||
sku: {
|
||||
capacityReservationLevel: number, // null,
|
||||
lastSkuUpdate: string, // "2020-02-25T16:59:38Z",
|
||||
name: string, // "pergb2018"
|
||||
},
|
||||
tags: string[], //null,
|
||||
type: string, //"Microsoft.OperationalInsights/workspaces",
|
||||
workspaceCapping: {
|
||||
dailyQuotaGb: number, //-1.0,
|
||||
dataIngestionStatus: string, // "RespectQuota",
|
||||
quotaNextResetTime: string, // "2022-02-21T19:00:00Z"
|
||||
}
|
||||
}
|
||||
|
||||
export interface PostgresServerShowResult {
|
||||
apiVersion: string, // "arcdata.microsoft.com/v1alpha1"
|
||||
kind: string, // "postgresql"
|
||||
@@ -362,6 +401,17 @@ declare module 'az-ext' {
|
||||
): Promise<AzOutput<SqlMiDbRestoreResult>>
|
||||
}
|
||||
},
|
||||
monitor: {
|
||||
logAnalytics: {
|
||||
workspace: {
|
||||
list(
|
||||
resourceGroup?: string, // test-rg
|
||||
subscription?: string, // 122c121a-095a-4f5d-22e4-cc6b238490a3
|
||||
additionalEnvVars?: AdditionalEnvVars
|
||||
): Promise<AzOutput<LogAnalyticsWorkspaceListResult[]>>
|
||||
}
|
||||
}
|
||||
},
|
||||
getPath(): Promise<string>,
|
||||
/**
|
||||
* The semVersion corresponding to this installation of the Azure CLI. version() method should have been run
|
||||
|
||||
Reference in New Issue
Block a user