Replacing all azdata with az (#16502)

* Changed azdata to az in azcli extension and resource-deployment, and some arc. Removed user, pass, url from controller connect blade. Commented out tests. Ported over work from old branch.

* Changed unit tests, all unit tests passing. Changed parameters to new ones, fixed some Controller Connect issues.

* Connect data controller and create dc working.

* Changed az back to azdata in necessary places in resource-deployment.

* Changed notebook values and added namespace to some params.

* Added some changes from PR to this branch

* Changed azdata.ts to az.ts and changed subscription parameter

* Brought over changes from azcli PR into this branch.

* added endpoint, username, password to getIsPassword

* Changed notebooks to use proper az params, hard coded in some values to verify it is working, removed some variableNames from package.json.

* Changed -sc to --storage-class in notebook

* Added namespace to SQL deploy, deleted dc create in api

* Deleted more dc create code and uncommented findAz() with unfinished work on Do Not Ask Again.

* Removed (preview) from extensions/arc and extensions/azcli excluding preview:true in package.json

* Commented out install/update prompts until DoNotAskAgain is implemented

* Fixed bugs: JSON Output errors are now being caught, --infrastructure now has a required UI component with dropdown options, config page loads properly, SQL create flags use full names instead of shortnames.

* Adds validation to pg extensions and bug fixes (#16486)

* Extensions

* Server parameters

* Change locaiton of postgres extensions, pr fixes

* Change location of list

* List spacing

* Commented out Don't Ask Again prompt implementation.

* Uncommented header of a test file.

* Added Azure CLI arcdata extension to Prerequisites

* Reverted package.json and yarn.lock

* Took away casting of stderr and stdout in executeCommand.

* Deleted override function for initializeFields in connectControllerDialog.ts

* Removed fakeAzApi for testing and added back in (Preview)

* Removed en-us from python notebook links.

* Deleted azdata tool from tool tests in resource-deployment

* Deleted another instance of azdata in tool test

* Add back in azdata tooltype

* Remove en-us

* Replaced AzdataTool in typings

* Reverting adding azdata tool back in

* Changed Azdata to AzdataToolOld

* Added back azdata tool type

* Added AzdataToolOld to tool types

* fix test

Co-authored-by: Candice Ye <canye@microsoft.com>
Co-authored-by: nasc17 <nasc@microsoft.com>
Co-authored-by: nasc17 <69922333+nasc17@users.noreply.github.com>
Co-authored-by: chgagnon <chgagnon@microsoft.com>
This commit is contained in:
Candice Ye
2021-08-01 15:12:24 -07:00
committed by GitHub
parent 65cc61fdbd
commit 914fe8fc29
58 changed files with 1623 additions and 2032 deletions

View File

@@ -361,6 +361,11 @@ export interface AzureLocationsFieldInfo extends FieldInfo {
locations?: string[]
}
export interface InfrastructureFieldInfo extends FieldInfo {
infrastructureName?: string;
infrastructure?: string[]
}
export interface FilePickerFieldInfo extends FieldInfo {
filter: FilePickerFilter;
}
@@ -396,6 +401,7 @@ export enum FieldType {
Checkbox = 'checkbox',
AzureAccount = 'azure_account',
AzureLocations = 'azure_locations',
Infrastructure = 'infrastructure',
FilePicker = 'file_picker',
KubeClusterContextPicker = 'kube_cluster_context_picker',
KubeStorageClass = 'kube_storage_class'

View File

@@ -15,6 +15,7 @@ export const subscription = localize('azure.account.subscription', "Subscription
export const subscriptionDescription = localize('azure.account.subscriptionDescription', "Change the currently selected subscriptions through the 'Select Subscriptions' action on an account listed in the 'Azure' tree view of the 'Connections' viewlet");
export const resourceGroup = localize('azure.account.resourceGroup', "Resource Group");
export const location = localize('azure.account.location', "Azure Location");
export const infrastructure = localize('azure.account.infrastructure', "Infrastructure");
export const browse = localize('filePicker.browse', "Browse");
export const select = localize('button.label', "Select");
export const kubeConfigFilePath = localize('kubeConfigClusterPicker.kubeConfigFilePath', "Kube config file path");

View File

@@ -4,20 +4,20 @@
*--------------------------------------------------------------------------------------------*/
import * as arc from 'arc';
import * as azdataExt from 'azdata-ext';
import * as azExt from 'az-ext';
import * as azurecore from 'azurecore';
import * as vscode from 'vscode';
export interface IApiService {
readonly azurecoreApi: azurecore.IExtension;
readonly azdataApi: azdataExt.IExtension;
readonly azApi: azExt.IExtension;
readonly arcApi: arc.IExtension;
}
class ApiService implements IApiService {
constructor() { }
public get azurecoreApi() { return vscode.extensions.getExtension(azurecore.extension.name)?.exports; }
public get azdataApi() { return vscode.extensions.getExtension(azdataExt.extension.name)?.exports; }
public get azApi() { return vscode.extensions.getExtension(azExt.extension.name)?.exports; }
public get arcApi() { return vscode.extensions.getExtension(arc.extension.name)?.exports; }
}

View File

@@ -1,137 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdataExt from 'azdata-ext';
import { EOL } from 'os';
import * as path from 'path';
import { SemVer } from 'semver';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { Command, OsDistribution, ToolStatus, ToolType } from '../../interfaces';
import * as loc from '../../localizedConstants';
import { IPlatformService } from '../platformService';
import { ToolBase } from './toolBase';
const localize = nls.loadMessageBundle();
export const AzdataToolName = 'azdata';
const win32InstallationRoot = `${process.env['ProgramFiles(x86)']}\\Microsoft SDKs\\Azdata\\CLI\\wbin`;
const macInstallationRoot = '/usr/local/bin';
const debianInstallationRoot = '/usr/local/bin';
export class AzdataTool extends ToolBase {
private azdataApi!: azdataExt.IExtension;
constructor(platformService: IPlatformService) {
super(platformService);
}
get name(): string {
return AzdataToolName;
}
get description(): string {
return localize('resourceDeployment.AzdataDescription', "Azure Data command line interface");
}
get type(): ToolType {
return ToolType.Azdata;
}
get displayName(): string {
return localize('resourceDeployment.AzdataDisplayName', "Azure Data CLI");
}
get homePage(): string {
return 'https://docs.microsoft.com/sql/big-data-cluster/deploy-install-azdata';
}
public override async isEulaAccepted(): Promise<boolean> {
if (!this.azdataApi) {
return false;
}
if (await this.azdataApi.isEulaAccepted()) {
return true;
} else {
this.setStatusDescription(loc.azdataEulaNotAccepted);
return false;
}
}
public override async promptForEula(): Promise<boolean> {
const eulaAccepted = await this.azdataApi.promptForEula();
if (!eulaAccepted) {
this.setStatusDescription(loc.azdataEulaDeclined);
}
return eulaAccepted;
}
/* unused */
protected get versionCommand(): Command {
return {
command: ''
};
}
/* unused */
protected get discoveryCommand(): Command {
return {
command: ''
};
}
/**
* updates the version and status for the tool.
*/
protected override async updateVersionAndStatus(): Promise<void> {
this.azdataApi = await vscode.extensions.getExtension(azdataExt.extension.name)?.activate();
if (!this.azdataApi) {
this.setInstallationPathOrAdditionalInformation(localize('deploy.azdataExtMissing', "The Azure Data CLI extension must be installed to deploy this resource. Please install it through the extension gallery and try again."));
this.setStatus(ToolStatus.NotInstalled);
return;
}
this.setStatusDescription('');
await this.addInstallationSearchPathsToSystemPath();
const commandOutput = await this.azdataApi.azdata.version();
this.version = await this.azdataApi.azdata.getSemVersion();
if (this.version) {
if (this.autoInstallSupported) {
// set the installationPath
this.setInstallationPathOrAdditionalInformation(await this.azdataApi.azdata.getPath());
}
this.setStatus(ToolStatus.Installed);
}
else {
this.setInstallationPathOrAdditionalInformation(localize('deployCluster.GetToolVersionErrorInformation', "Error retrieving version information. See output channel '{0}' for more details", this.outputChannelName));
this.setStatusDescription(localize('deployCluster.GetToolVersionError', "Error retrieving version information.{0}Invalid output received, get version command output: '{1}' ", EOL, commandOutput.stderr.join(EOL)));
this.setStatus(ToolStatus.NotInstalled);
}
}
protected getVersionFromOutput(output: string): SemVer | Promise<SemVer> | undefined {
return this.azdataApi.azdata.getSemVersion();
}
protected override async getSearchPaths(): Promise<string[]> {
switch (this.osDistribution) {
case OsDistribution.win32:
return [win32InstallationRoot];
case OsDistribution.darwin:
return [macInstallationRoot];
case OsDistribution.debian:
return [debianInstallationRoot];
default:
const azdataCliInstallLocation = await this.getPip3InstallLocation('azdata-cli');
if (azdataCliInstallLocation) {
return [path.join(azdataCliInstallLocation, '..', 'Scripts'), path.join(azdataCliInstallLocation, '..', '..', '..', 'bin')];
} else {
return [];
}
}
}
protected get allInstallationCommands(): Map<OsDistribution, Command[]> {
return new Map<OsDistribution, Command[]>();
}
}

View File

@@ -5,7 +5,6 @@
import { ITool } from '../interfaces';
import { DockerTool } from './tools/dockerTool';
import { AzCliTool } from './tools/azCliTool';
import { AzdataTool } from './tools/azdataTool';
import { KubeCtlTool } from './tools/kubeCtlTool';
import { IPlatformService } from './platformService';
import { AzdataToolOld } from './tools/azdataToolOld';
@@ -24,7 +23,6 @@ export class ToolsService implements IToolsService {
[
new DockerTool(this._platformService),
new AzCliTool(this._platformService),
new AzdataTool(this._platformService),
new AzdataToolOld(this._platformService),
new KubeCtlTool(this._platformService)
].map<[string, ITool]>((tool: ITool) => [tool.name, tool])

View File

@@ -4,18 +4,19 @@
*--------------------------------------------------------------------------------------------*/
import 'mocha';
import assert = require('assert');
import * as assert from 'assert';
import * as TypeMoq from 'typemoq';
import { ToolsService } from '../../services/toolsService';
import { ITool, ToolType } from '../../interfaces';
import { IPlatformService } from '../../services/platformService';
import { AzdataToolName } from '../../services/tools/azdataToolOld';
const tools: { name: string; type: ToolType }[] = [
{ name: 'azure-cli', type: ToolType.AzCli },
{ name: 'docker', type: ToolType.Docker },
{ name: 'kubectl', type: ToolType.KubeCtl },
{ name: 'azdata', type: ToolType.Azdata }
{ name: AzdataToolName, type: ToolType.Azdata }
];
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
const toolsService = new ToolsService(mockPlatformService.object);
@@ -37,7 +38,7 @@ describe('Tools Service Tests', function (): void {
tools.forEach(toolInfo => {
const tool = toolsService.getToolByName(toolInfo.name);
assert(!!tool, `The tool: ${toolInfo.name} is not recognized`);
assert.equal(tool!.type, toolInfo.type, 'returned notebook name does not match expected value');
assert.equal(tool!.type, toolInfo.type, 'returned tool name does not match expected value');
});
});

View File

@@ -7,7 +7,7 @@
/// <reference path='../../../../src/sql/azdata.d.ts'/>
/// <reference path='../../../../src/sql/azdata.proposed.d.ts'/>
/// <reference path='../../../arc/src/typings/arc.d.ts'/>
/// <reference path='../../../azdata/src/typings/azdata-ext.d.ts'/>
/// <reference path='../../../azcli/src/typings/az-ext.d.ts'/>
/// <reference path='../../../azurecore/src/azurecore.d.ts'/>
/// <reference path='../../../azurecore/src/azureResource/azure-resource.d.ts'/>
/// <reference types='@types/node'/>

View File

@@ -11,7 +11,7 @@ import { IOptionsSourceProvider } from 'resource-deployment';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { getDateTimeString, getErrorMessage, isUserCancelledError, throwUnless } from '../common/utils';
import { AzureAccountFieldInfo, AzureLocationsFieldInfo, ComponentCSSStyles, DialogInfoBase, FieldInfo, FieldType, FilePickerFieldInfo, InitialVariableValues, instanceOfDynamicEnablementInfo, IOptionsSource, KubeClusterContextFieldInfo, LabelPosition, NoteBookEnvironmentVariablePrefix, OptionsInfo, OptionsType, PageInfoBase, RowInfo, SectionInfo, TextCSSStyles } from '../interfaces';
import { AzureAccountFieldInfo, AzureLocationsFieldInfo, ComponentCSSStyles, DialogInfoBase, FieldInfo, FieldType, FilePickerFieldInfo, InfrastructureFieldInfo, InitialVariableValues, instanceOfDynamicEnablementInfo, IOptionsSource, KubeClusterContextFieldInfo, LabelPosition, NoteBookEnvironmentVariablePrefix, OptionsInfo, OptionsType, PageInfoBase, RowInfo, SectionInfo, TextCSSStyles } from '../interfaces';
import * as loc from '../localizedConstants';
import { apiService } from '../services/apiService';
import { valueProviderService } from '../services/valueProviderService';
@@ -112,6 +112,10 @@ interface AzureLocationsFieldContext extends FieldContext {
fieldInfo: AzureLocationsFieldInfo;
}
interface InfrastructureFieldContext extends FieldContext {
fieldInfo: InfrastructureFieldInfo;
}
interface AzureAccountFieldContext extends FieldContext {
fieldInfo: AzureAccountFieldInfo;
}
@@ -573,6 +577,9 @@ async function processField(context: FieldContext): Promise<void> {
case FieldType.AzureLocations:
await processAzureLocationsField(context);
break;
case FieldType.Infrastructure:
await processInfrastructureField(context);
break;
case FieldType.FilePicker:
processFilePickerField(context);
break;
@@ -1526,6 +1533,55 @@ async function processAzureLocationsField(context: AzureLocationsFieldContext):
return locationInputInfo.component;
}
/**
* An Infrastructure field consists of a dropdown field for infrastructure types
* @param context The context to use to create the field
*/
async function processInfrastructureField(context: InfrastructureFieldContext): Promise<void> {
const label = createLabel(context.view, {
text: context.fieldInfo.label || loc.infrastructure,
required: context.fieldInfo.required,
width: context.fieldInfo.labelWidth,
cssStyles: context.fieldInfo.labelCSSStyles
});
const defaultValue = context.initialVariableValues?.[context.fieldInfo.infrastructureName || '']?.toString() ?? (context.fieldInfo.required ? undefined : '');
let infrastructureInputInfo: InputComponentInfo<AzureComponent>;
// If we have an default value then we don't allow users to modify it - so use a disabled text input box instead
if (defaultValue) {
infrastructureInputInfo = createInputBoxInputInfo(context.view, {
type: 'text',
defaultValue: defaultValue,
ariaLabel: loc.infrastructure,
required: context.fieldInfo.required,
width: context.fieldInfo.inputWidth,
enabled: false
});
} else {
const infrastructureValues = context.fieldInfo.infrastructure;
infrastructureInputInfo = createDropdownInputInfo(context.view, {
defaultValue: infrastructureValues?.find(l => l === context.fieldInfo.defaultValue),
width: context.fieldInfo.inputWidth,
editable: false,
required: context.fieldInfo.required,
label: loc.infrastructure,
values: infrastructureValues
});
(<InputComponentInfo<azdata.DropDownComponent>>infrastructureInputInfo).component.fireOnTextChange = true;
}
infrastructureInputInfo.labelComponent = label;
context.fieldInfo.subFields = context.fieldInfo.subFields || [];
if (context.fieldInfo.infrastructureName) {
context.fieldInfo.subFields!.push({
label: label.value!,
variableName: context.fieldInfo.infrastructureName
});
context.onNewInputComponentCreated(context.fieldInfo.infrastructureName, infrastructureInputInfo);
}
context.onNewInputComponentCreated(context.fieldInfo.variableName || context.fieldInfo.label, infrastructureInputInfo);
addLabelInputPairToContainer(context.view, context.components, label, infrastructureInputInfo.component, context.fieldInfo);
}
export function isValidSQLPassword(password: string, userName: string = 'sa'): boolean {
// Validate SQL Server password
const containsUserName = password && userName !== undefined && password.toUpperCase().includes(userName.toUpperCase());