From cac14ff181e6537ddd62d551ee3c24bf5b9abfdc Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Fri, 18 Sep 2020 07:33:58 -0700 Subject: [PATCH] Add Arc MIAA username configuration (#12429) * Add Arc MIAA username configuration * username -> userName --- .../deploy.sql.existing.arc.ipynb | 7 +++++ extensions/arc/package.json | 6 +++-- extensions/arc/package.nls.json | 1 + extensions/arc/src/models/miaaModel.ts | 26 +++++++++++-------- extensions/arc/src/typings/arc.d.ts | 5 +++- .../arc/src/ui/dialogs/connectSqlDialog.ts | 3 +-- .../arc/src/ui/tree/controllerTreeNode.ts | 6 ++++- 7 files changed, 37 insertions(+), 17 deletions(-) diff --git a/extensions/arc/notebooks/arcDeployment/deploy.sql.existing.arc.ipynb b/extensions/arc/notebooks/arcDeployment/deploy.sql.existing.arc.ipynb index 4ab742724f..4c89d7d11e 100644 --- a/extensions/arc/notebooks/arcDeployment/deploy.sql.existing.arc.ipynb +++ b/extensions/arc/notebooks/arcDeployment/deploy.sql.existing.arc.ipynb @@ -109,6 +109,12 @@ "else:\n", " sys.exit(f'environment variable: AZDATA_NB_VAR_SQL_INSTANCE_NAME was not defined. Exiting\\n')\n", "\n", + "env_var = \"AZDATA_NB_VAR_SQL_USERNAME\" in os.environ\n", + "if env_var:\n", + " mssql_username = os.environ[\"AZDATA_NB_VAR_SQL_USERNAME\"]\n", + "else:\n", + " sys.exit(f'environment variable: AZDATA_NB_VAR_SQL_USERNAME was not defined. Exiting\\n')\n", + "\n", "env_var = \"AZDATA_NB_VAR_SQL_PASSWORD\" in os.environ\n", "if env_var:\n", " mssql_password = os.environ[\"AZDATA_NB_VAR_SQL_PASSWORD\"]\n", @@ -192,6 +198,7 @@ "memory_request_option = f' -mr \"{sql_instance_memory_request}Mi\"' if sql_instance_memory_request else \"\"\n", "memory_limit_option = f' -ml \"{sql_instance_memory_limit}Mi\"' if sql_instance_memory_limit else \"\"\n", "\n", + "os.environ[\"AZDATA_USERNAME\"] = mssql_username\n", "os.environ[\"AZDATA_PASSWORD\"] = mssql_password\n", "cmd = f'azdata arc sql mi create -n {mssql_instance_name} -scd {mssql_storage_class_data} -scl {mssql_storage_class_logs}{cores_request_option}{cores_limit_option}{memory_request_option}{memory_limit_option}'\n", "out=run_command()" diff --git a/extensions/arc/package.json b/extensions/arc/package.json index 9e9effc994..f915c0be9c 100644 --- a/extensions/arc/package.json +++ b/extensions/arc/package.json @@ -583,8 +583,10 @@ "label": "%arc.sql.username%", "variableName": "AZDATA_NB_VAR_SQL_USERNAME", "type": "text", - "defaultValue": "sa", - "enabled": false + "required": true, + "textValidationRequired": true, + "textValidationRegex": "^(?!sa$)", + "textValidationDescription": "%arc.sql.invalidusername%" }, { "label": "%arc.password%", diff --git a/extensions/arc/package.nls.json b/extensions/arc/package.nls.json index 75e988f540..b4dadc2cb8 100644 --- a/extensions/arc/package.nls.json +++ b/extensions/arc/package.nls.json @@ -76,6 +76,7 @@ "arc.azure.section.title": "Azure information", "arc.sql.instance.name": "Instance name (lower case letters and digits only)", "arc.sql.username": "Username", + "arc.sql.invalidusername": "sa username is disabled, please choose another username", "arc.storage-class.dc.label": "Storage Class", "arc.sql.storage-class.dc.description": "The storage class to be used for all data and logs persistent volumes for all data controller pods that require them.", "arc.storage-class.data.label": "Storage Class (Data)", diff --git a/extensions/arc/src/models/miaaModel.ts b/extensions/arc/src/models/miaaModel.ts index 616877e4cc..46c5c8c852 100644 --- a/extensions/arc/src/models/miaaModel.ts +++ b/extensions/arc/src/models/miaaModel.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ResourceInfo } from 'arc'; +import { MiaaResourceInfo } from 'arc'; import * as azdata from 'azdata'; import * as azdataExt from 'azdata-ext'; import * as vscode from 'vscode'; @@ -37,8 +37,8 @@ export class MiaaModel extends ResourceModel { private _refreshPromise: Deferred | undefined = undefined; - constructor(private _controllerModel: ControllerModel, info: ResourceInfo, registration: Registration, private _treeDataProvider: AzureArcTreeDataProvider) { - super(info, registration); + constructor(private _controllerModel: ControllerModel, private _miaaInfo: MiaaResourceInfo, registration: Registration, private _treeDataProvider: AzureArcTreeDataProvider) { + super(_miaaInfo, registration); this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports; } @@ -165,7 +165,7 @@ export class MiaaModel extends ResourceModel { authenticationType: 'SqlLogin', providerName: 'MSSQL', connectionName: '', - userName: 'sa', + userName: this._miaaInfo.userName || '', password: '', savePassword: true, groupFullName: undefined, @@ -183,12 +183,15 @@ export class MiaaModel extends ResourceModel { if (credentials.password) { // Try to connect to verify credentials are still valid connectionProfile.password = credentials.password; - const result = await azdata.connection.connect(connectionProfile, false, false); - if (!result.connected) { - vscode.window.showErrorMessage(loc.connectToSqlFailed(connectionProfile.serverName, result.errorMessage)); - const connectToSqlDialog = new ConnectToSqlDialog(this._controllerModel, this); - connectToSqlDialog.showDialog(connectionProfile); - connectionProfile = await connectToSqlDialog.waitForClose(); + // If we don't have a username for some reason then just continue on and we'll prompt for the username below + if (connectionProfile.userName) { + const result = await azdata.connection.connect(connectionProfile, false, false); + if (!result.connected) { + vscode.window.showErrorMessage(loc.connectToSqlFailed(connectionProfile.serverName, result.errorMessage)); + const connectToSqlDialog = new ConnectToSqlDialog(this._controllerModel, this); + connectToSqlDialog.showDialog(connectionProfile); + connectionProfile = await connectToSqlDialog.waitForClose(); + } } } } catch (err) { @@ -197,7 +200,7 @@ export class MiaaModel extends ResourceModel { } } - if (!connectionProfile?.password) { + if (!connectionProfile?.userName || !connectionProfile?.password) { // Need to prompt user for password since we don't have one stored const connectToSqlDialog = new ConnectToSqlDialog(this._controllerModel, this); connectToSqlDialog.showDialog(connectionProfile); @@ -214,6 +217,7 @@ export class MiaaModel extends ResourceModel { private async updateConnectionProfile(connectionProfile: azdata.IConnectionProfile): Promise { this._connectionProfile = connectionProfile; this.info.connectionId = connectionProfile.id; + this._miaaInfo.userName = connectionProfile.userName; await this._treeDataProvider.saveControllers(); } } diff --git a/extensions/arc/src/typings/arc.d.ts b/extensions/arc/src/typings/arc.d.ts index 8784c2ac54..0fcc14c352 100644 --- a/extensions/arc/src/typings/arc.d.ts +++ b/extensions/arc/src/typings/arc.d.ts @@ -3,7 +3,6 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ declare module 'arc' { - import * as vscode from 'vscode'; /** * Covers defining what the arc extension exports to other extensions @@ -20,6 +19,10 @@ declare module 'arc' { sqlManagedInstances = 'sqlManagedInstances' } + export type MiaaResourceInfo = ResourceInfo & { + userName?: string + }; + export type ResourceInfo = { name: string, resourceType: ResourceType | string, diff --git a/extensions/arc/src/ui/dialogs/connectSqlDialog.ts b/extensions/arc/src/ui/dialogs/connectSqlDialog.ts index e2ab5c1579..de9fdd1683 100644 --- a/extensions/arc/src/ui/dialogs/connectSqlDialog.ts +++ b/extensions/arc/src/ui/dialogs/connectSqlDialog.ts @@ -40,8 +40,7 @@ export class ConnectToSqlDialog extends InitializingComponent { }).component(); this.usernameInputBox = this.modelBuilder.inputBox() .withProperties({ - value: connectionProfile?.userName, - enabled: false + value: connectionProfile?.userName }).component(); this.passwordInputBox = this.modelBuilder.inputBox() .withProperties({ diff --git a/extensions/arc/src/ui/tree/controllerTreeNode.ts b/extensions/arc/src/ui/tree/controllerTreeNode.ts index b4cbbdb9ef..7afbc85687 100644 --- a/extensions/arc/src/ui/tree/controllerTreeNode.ts +++ b/extensions/arc/src/ui/tree/controllerTreeNode.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ResourceInfo, ResourceType } from 'arc'; +import { MiaaResourceInfo, ResourceInfo, ResourceType } from 'arc'; import * as vscode from 'vscode'; import { UserCancelledError } from '../../common/utils'; import * as loc from '../../localizedConstants'; @@ -105,6 +105,10 @@ export class ControllerTreeNode extends TreeNode { node = new PostgresTreeNode(postgresModel, this.model, this._context); break; case ResourceType.sqlManagedInstances: + // Fill in the username too if we already have it + (resourceInfo as MiaaResourceInfo).userName = (this.model.info.resources.find(info => + info.name === resourceInfo.name && + info.resourceType === resourceInfo.resourceType) as MiaaResourceInfo)?.userName; const miaaModel = new MiaaModel(this.model, resourceInfo, registration, this._treeDataProvider); node = new MiaaTreeNode(miaaModel, this.model); break;