mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Remove all Big Data Cluster features (#21369)
This commit is contained in:
@@ -77,10 +77,6 @@ export interface DialogDeploymentProvider extends DeploymentProviderBase {
|
||||
dialog: DialogInfo;
|
||||
}
|
||||
|
||||
export interface BdcWizardDeploymentProvider extends DeploymentProviderBase {
|
||||
bdcWizard: BdcWizardInfo;
|
||||
}
|
||||
|
||||
export interface NotebookWizardDeploymentProvider extends DeploymentProviderBase {
|
||||
notebookWizard: NotebookWizardInfo;
|
||||
}
|
||||
@@ -113,10 +109,6 @@ export function instanceOfDialogDeploymentProvider(obj: any): obj is DialogDeplo
|
||||
return obj && 'dialog' in obj;
|
||||
}
|
||||
|
||||
export function instanceOfWizardDeploymentProvider(obj: any): obj is BdcWizardDeploymentProvider {
|
||||
return obj && 'bdcWizard' in obj;
|
||||
}
|
||||
|
||||
export function instanceOfNotebookWizardDeploymentProvider(obj: any): obj is NotebookWizardDeploymentProvider {
|
||||
return obj && 'notebookWizard' in obj;
|
||||
}
|
||||
@@ -151,12 +143,8 @@ export interface DeploymentProviderBase {
|
||||
when: string;
|
||||
}
|
||||
|
||||
export type DeploymentProvider = DialogDeploymentProvider | BdcWizardDeploymentProvider | NotebookWizardDeploymentProvider | NotebookDeploymentProvider | WebPageDeploymentProvider | DownloadDeploymentProvider | CommandDeploymentProvider | AzureSQLVMDeploymentProvider | AzureSQLDBDeploymentProvider;
|
||||
export type DeploymentProvider = DialogDeploymentProvider | NotebookWizardDeploymentProvider | NotebookDeploymentProvider | WebPageDeploymentProvider | DownloadDeploymentProvider | CommandDeploymentProvider | AzureSQLVMDeploymentProvider | AzureSQLDBDeploymentProvider;
|
||||
|
||||
export interface BdcWizardInfo {
|
||||
notebook: string | NotebookPathInfo;
|
||||
type: BdcDeploymentType;
|
||||
}
|
||||
/**
|
||||
* An object that configures Script and Done buttons of the wizard.
|
||||
*/
|
||||
@@ -183,7 +171,6 @@ export interface NotebookWizardInfo extends WizardInfoBase {
|
||||
}
|
||||
|
||||
export interface WizardInfoBase extends FieldInfoBase {
|
||||
type?: DeploymentType;
|
||||
/**
|
||||
* done button attributes.
|
||||
*/
|
||||
@@ -461,7 +448,6 @@ export enum ToolType {
|
||||
AzCli,
|
||||
KubeCtl,
|
||||
Docker,
|
||||
Azdata
|
||||
}
|
||||
|
||||
export const enum ToolStatus {
|
||||
@@ -497,16 +483,6 @@ export interface ITool {
|
||||
promptForEula(): Promise<boolean>;
|
||||
}
|
||||
|
||||
export const enum BdcDeploymentType {
|
||||
NewAKS = 'new-aks',
|
||||
ExistingAKS = 'existing-aks',
|
||||
ExistingKubeAdm = 'existing-kubeadm',
|
||||
ExistingARO = 'existing-aro',
|
||||
ExistingOpenShift = 'existing-openshift'
|
||||
}
|
||||
|
||||
export type DeploymentType = BdcDeploymentType;
|
||||
|
||||
export interface Command {
|
||||
command: string;
|
||||
sudo?: boolean;
|
||||
|
||||
@@ -49,9 +49,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<rd.IEx
|
||||
vscode.commands.registerCommand('azdata.resource.sql-image.deploy', () => {
|
||||
openDialog('sql-image');
|
||||
});
|
||||
vscode.commands.registerCommand('azdata.resource.sql-bdc.deploy', () => {
|
||||
openDialog('sql-bdc');
|
||||
});
|
||||
|
||||
/**
|
||||
* Command to open the Resource Deployment wizard - with options to filter the values shown
|
||||
* @param defaultResourceTypeName - The default resourceType to be selected
|
||||
|
||||
@@ -1,75 +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 path from 'path';
|
||||
import { IPlatformService } from './platformService';
|
||||
import { BigDataClusterDeploymentProfile } from './bigDataClusterDeploymentProfile';
|
||||
import { BdcDeploymentType } from '../interfaces';
|
||||
|
||||
interface BdcConfigListOutput {
|
||||
result: string[];
|
||||
}
|
||||
|
||||
export interface BdcEndpoint {
|
||||
endpoint: string;
|
||||
name: 'sql-server-master';
|
||||
}
|
||||
|
||||
export interface IAzdataService {
|
||||
getDeploymentProfiles(deploymentType: BdcDeploymentType): Promise<BigDataClusterDeploymentProfile[]>;
|
||||
}
|
||||
|
||||
export class AzdataService implements IAzdataService {
|
||||
constructor(private platformService: IPlatformService) {
|
||||
}
|
||||
|
||||
public async getDeploymentProfiles(deploymentType: BdcDeploymentType): Promise<BigDataClusterDeploymentProfile[]> {
|
||||
let profilePrefix: string;
|
||||
switch (deploymentType) {
|
||||
case BdcDeploymentType.NewAKS:
|
||||
case BdcDeploymentType.ExistingAKS:
|
||||
profilePrefix = 'aks';
|
||||
break;
|
||||
case BdcDeploymentType.ExistingKubeAdm:
|
||||
profilePrefix = 'kubeadm';
|
||||
break;
|
||||
case BdcDeploymentType.ExistingARO:
|
||||
profilePrefix = 'aro';
|
||||
break;
|
||||
case BdcDeploymentType.ExistingOpenShift:
|
||||
profilePrefix = 'openshift';
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown deployment type: ${deploymentType}`);
|
||||
}
|
||||
const profileNames = await this.getDeploymentProfileNames();
|
||||
return await Promise.all(profileNames.filter(profile => profile.startsWith(profilePrefix)).map(profile => this.getDeploymentProfileInfo(profile)));
|
||||
}
|
||||
|
||||
private async getDeploymentProfileNames(): Promise<string[]> {
|
||||
const env: NodeJS.ProcessEnv = {};
|
||||
// azdata requires this environment variables to be set
|
||||
env['ACCEPT_EULA'] = 'yes';
|
||||
const cmd = 'azdata bdc config list -o json';
|
||||
const stdout = await this.platformService.runCommand(cmd, { additionalEnvironmentVariables: env });
|
||||
const output = <BdcConfigListOutput>JSON.parse(stdout);
|
||||
return output.result;
|
||||
}
|
||||
|
||||
private async getDeploymentProfileInfo(profileName: string): Promise<BigDataClusterDeploymentProfile> {
|
||||
const env: NodeJS.ProcessEnv = {};
|
||||
// azdata requires this environment variables to be set
|
||||
env['ACCEPT_EULA'] = 'yes';
|
||||
await this.platformService.runCommand(`azdata bdc config init --source ${profileName} --path ${profileName} --force`, { workingDirectory: this.platformService.storagePath(), additionalEnvironmentVariables: env });
|
||||
const configObjects = await Promise.all([
|
||||
this.getJsonObjectFromFile(path.join(this.platformService.storagePath(), profileName, 'bdc.json')),
|
||||
this.getJsonObjectFromFile(path.join(this.platformService.storagePath(), profileName, 'control.json'))
|
||||
]);
|
||||
return new BigDataClusterDeploymentProfile(profileName, configObjects[0], configObjects[1]);
|
||||
}
|
||||
|
||||
private async getJsonObjectFromFile(path: string): Promise<any> {
|
||||
return JSON.parse(await this.platformService.readTextFile(path));
|
||||
}
|
||||
}
|
||||
@@ -1,349 +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 { AuthenticationMode } from '../ui/deployClusterWizard/deployClusterWizardModel';
|
||||
export const SqlServerMasterResource = 'master';
|
||||
export const DataResource = 'data-0';
|
||||
export const HdfsResource = 'storage-0';
|
||||
export const ComputeResource = 'compute-0';
|
||||
export const NameNodeResource = 'nmnode-0';
|
||||
export const SparkHeadResource = 'sparkhead';
|
||||
export const ZooKeeperResource = 'zookeeper';
|
||||
export const SparkResource = 'spark-0';
|
||||
|
||||
interface ServiceEndpoint {
|
||||
port: number;
|
||||
serviceType: ServiceType;
|
||||
name: EndpointName;
|
||||
dnsName?: string;
|
||||
}
|
||||
type ServiceType = 'NodePort' | 'LoadBalancer';
|
||||
type EndpointName = 'Controller' | 'Master' | 'Knox' | 'MasterSecondary' | 'AppServiceProxy' | 'ServiceProxy';
|
||||
|
||||
export interface ActiveDirectorySettings {
|
||||
organizationalUnit: string;
|
||||
domainControllerFQDNs: string;
|
||||
dnsIPAddresses: string;
|
||||
domainDNSName: string;
|
||||
realm?: string;
|
||||
clusterUsers: string;
|
||||
clusterAdmins: string;
|
||||
appReaders?: string;
|
||||
appOwners?: string;
|
||||
subdomain?: string;
|
||||
accountPrefix?: string;
|
||||
}
|
||||
|
||||
export class BigDataClusterDeploymentProfile {
|
||||
constructor(private _profileName: string, private _bdcConfig: any, private _controlConfig: any) {
|
||||
// TODO: add validation logic for these 2 objects
|
||||
// https://github.com/microsoft/azuredatastudio/issues/7344
|
||||
}
|
||||
|
||||
public get profileName(): string {
|
||||
return this._profileName;
|
||||
}
|
||||
|
||||
public get clusterName(): string {
|
||||
return this._bdcConfig.metadata.name;
|
||||
}
|
||||
|
||||
public set clusterName(value: string) {
|
||||
this._bdcConfig.metadata.name = value;
|
||||
}
|
||||
|
||||
public get registry(): string {
|
||||
return this._controlConfig.spec.docker.registry;
|
||||
}
|
||||
|
||||
public set registry(value: string) {
|
||||
this._controlConfig.spec.docker.registry = value;
|
||||
}
|
||||
|
||||
public get repository(): string {
|
||||
return this._controlConfig.spec.docker.repository;
|
||||
}
|
||||
|
||||
public set repository(value: string) {
|
||||
this._controlConfig.spec.docker.repository = value;
|
||||
}
|
||||
|
||||
public get imageTag(): string {
|
||||
return this._controlConfig.spec.docker.imageTag;
|
||||
}
|
||||
|
||||
public set imageTag(value: string) {
|
||||
this._controlConfig.spec.docker.imageTag = value;
|
||||
}
|
||||
|
||||
public get bdcConfig(): any {
|
||||
return this._bdcConfig;
|
||||
}
|
||||
|
||||
public get controlConfig(): any {
|
||||
return this._controlConfig;
|
||||
}
|
||||
|
||||
public get sqlServerReplicas(): number {
|
||||
return this.getReplicas(SqlServerMasterResource);
|
||||
}
|
||||
|
||||
public set sqlServerReplicas(replicas: number) {
|
||||
this.setReplicas(SqlServerMasterResource, replicas);
|
||||
}
|
||||
|
||||
public get hdfsNameNodeReplicas(): number {
|
||||
return this.getReplicas(NameNodeResource);
|
||||
}
|
||||
|
||||
public set hdfsNameNodeReplicas(replicas: number) {
|
||||
this.setReplicas(NameNodeResource, replicas);
|
||||
}
|
||||
|
||||
public get sparkHeadReplicas(): number {
|
||||
return this.getReplicas(SparkHeadResource);
|
||||
}
|
||||
|
||||
public set sparkHeadReplicas(replicas: number) {
|
||||
this.setReplicas(SparkHeadResource, replicas);
|
||||
}
|
||||
|
||||
public get dataReplicas(): number {
|
||||
return this.getReplicas(DataResource);
|
||||
}
|
||||
|
||||
public set dataReplicas(replicas: number) {
|
||||
this.setReplicas(SparkHeadResource, replicas);
|
||||
}
|
||||
|
||||
public get hdfsReplicas(): number {
|
||||
return this.getReplicas(HdfsResource);
|
||||
}
|
||||
|
||||
public set hdfsReplicas(replicas: number) {
|
||||
this.setReplicas(HdfsResource, replicas);
|
||||
}
|
||||
|
||||
public get zooKeeperReplicas(): number {
|
||||
return this.getReplicas(ZooKeeperResource);
|
||||
}
|
||||
|
||||
public set zooKeeperReplicas(replicas: number) {
|
||||
this.setReplicas(ZooKeeperResource, replicas);
|
||||
}
|
||||
|
||||
public get computeReplicas(): number {
|
||||
return this.getReplicas(ComputeResource);
|
||||
}
|
||||
|
||||
public set computeReplicas(replicas: number) {
|
||||
this.setReplicas(ComputeResource, replicas);
|
||||
}
|
||||
|
||||
public get sparkReplicas(): number {
|
||||
return this._bdcConfig.spec.resources[SparkResource] ? this.getReplicas(SparkResource) : 0;
|
||||
}
|
||||
|
||||
public get includeSpark(): boolean {
|
||||
return <boolean>this._bdcConfig.spec.resources[HdfsResource].spec.settings.spark.includeSpark;
|
||||
}
|
||||
|
||||
public set includeSpark(value: boolean) {
|
||||
this._bdcConfig.spec.resources[HdfsResource].spec.settings.spark.includeSpark = value;
|
||||
}
|
||||
|
||||
public get controllerDataStorageClass(): string {
|
||||
return <string>this._controlConfig.spec.storage.data.className;
|
||||
}
|
||||
|
||||
public set controllerDataStorageClass(value: string) {
|
||||
this._controlConfig.spec.storage.data.className = value;
|
||||
}
|
||||
|
||||
public get controllerDataStorageSize(): number {
|
||||
return <number>this._controlConfig.spec.storage.data.size.replace('Gi', '');
|
||||
}
|
||||
|
||||
public set controllerDataStorageSize(value: number) {
|
||||
this._controlConfig.spec.storage.data.size = `${value}Gi`;
|
||||
}
|
||||
|
||||
public get controllerLogsStorageClass(): string {
|
||||
return <string>this._controlConfig.spec.storage.logs.className;
|
||||
}
|
||||
|
||||
public set controllerLogsStorageClass(value: string) {
|
||||
this._controlConfig.spec.storage.logs.className = value;
|
||||
}
|
||||
|
||||
public get controllerLogsStorageSize(): number {
|
||||
return <number>this._controlConfig.spec.storage.logs.size.replace('Gi', '');
|
||||
}
|
||||
|
||||
public set controllerLogsStorageSize(value: number) {
|
||||
this._controlConfig.spec.storage.logs.size = `${value}Gi`;
|
||||
}
|
||||
|
||||
public setResourceStorage(resourceName: 'data-0' | 'master' | 'storage-0', dataStorageClass: string, dataStorageSize: number, logsStorageClass: string, logsStorageSize: number) {
|
||||
this.bdcConfig.spec.resources[resourceName].spec.storage = {
|
||||
data: {
|
||||
size: `${dataStorageSize}Gi`,
|
||||
className: dataStorageClass,
|
||||
accessMode: 'ReadWriteOnce'
|
||||
},
|
||||
logs: {
|
||||
size: `${logsStorageSize}Gi`,
|
||||
className: logsStorageClass,
|
||||
accessMode: 'ReadWriteOnce'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public get controllerPort(): number {
|
||||
return this.getEndpointPort(this._controlConfig.spec.endpoints, 'Controller', 30080);
|
||||
}
|
||||
|
||||
public setControllerEndpoint(port: number, dnsName?: string) {
|
||||
this.setEndpoint(this._controlConfig.spec.endpoints, 'Controller', port, dnsName);
|
||||
}
|
||||
|
||||
public get serviceProxyPort(): number {
|
||||
return this.getEndpointPort(this._controlConfig.spec.endpoints, 'ServiceProxy', 30080);
|
||||
}
|
||||
|
||||
public setServiceProxyEndpoint(port: number, dnsName?: string) {
|
||||
this.setEndpoint(this._controlConfig.spec.endpoints, 'ServiceProxy', port, dnsName);
|
||||
}
|
||||
|
||||
public get appServiceProxyPort(): number {
|
||||
return this.getEndpointPort(this._bdcConfig.spec.resources.appproxy.spec.endpoints, 'AppServiceProxy', 30777);
|
||||
}
|
||||
|
||||
public setAppServiceProxyEndpoint(port: number, dnsName?: string) {
|
||||
this.setEndpoint(this._bdcConfig.spec.resources.appproxy.spec.endpoints, 'AppServiceProxy', port, dnsName);
|
||||
}
|
||||
|
||||
public get sqlServerPort(): number {
|
||||
return this.getEndpointPort(this._bdcConfig.spec.resources.master.spec.endpoints, 'Master', 31433);
|
||||
}
|
||||
|
||||
public setSqlServerEndpoint(port: number, dnsName?: string) {
|
||||
this.setEndpoint(this._bdcConfig.spec.resources.master.spec.endpoints, 'Master', port, dnsName);
|
||||
}
|
||||
|
||||
public get sqlServerReadableSecondaryPort(): number {
|
||||
return this.getEndpointPort(this._bdcConfig.spec.resources.master.spec.endpoints, 'MasterSecondary', 31436);
|
||||
}
|
||||
|
||||
public setSqlServerReadableSecondaryEndpoint(port: number, dnsName?: string) {
|
||||
this.setEndpoint(this._bdcConfig.spec.resources.master.spec.endpoints, 'MasterSecondary', port, dnsName);
|
||||
}
|
||||
|
||||
public get gatewayPort(): number {
|
||||
return this.getEndpointPort(this._bdcConfig.spec.resources.gateway.spec.endpoints, 'Knox', 30443);
|
||||
}
|
||||
|
||||
public setGatewayEndpoint(port: number, dnsName?: string) {
|
||||
this.setEndpoint(this._bdcConfig.spec.resources.gateway.spec.endpoints, 'Knox', port, dnsName);
|
||||
}
|
||||
|
||||
public addSparkResource(replicas: number): void {
|
||||
this._bdcConfig.spec.resources[SparkResource] = {
|
||||
metadata: {
|
||||
kind: 'Pool',
|
||||
name: 'default'
|
||||
},
|
||||
spec: {
|
||||
type: 'Spark',
|
||||
replicas: replicas
|
||||
}
|
||||
};
|
||||
|
||||
this._bdcConfig.spec.services.spark.resources.push(SparkResource);
|
||||
this._bdcConfig.spec.services.hdfs.resources.push(SparkResource);
|
||||
}
|
||||
|
||||
public get activeDirectorySupported(): boolean {
|
||||
// The profiles that highlight the AD authentication feature will have a security secion in the control.json for the AD settings.
|
||||
return 'security' in this._controlConfig;
|
||||
}
|
||||
|
||||
public setAuthenticationMode(mode: string): void {
|
||||
// If basic authentication is picked, the activeDirectory security section must be removed
|
||||
// otherwise azdata will throw validation error
|
||||
if (mode === AuthenticationMode.Basic && 'security' in this._controlConfig && 'activeDirectory' in this._controlConfig.security) {
|
||||
delete this._controlConfig.security.activeDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
public setActiveDirectorySettings(adSettings: ActiveDirectorySettings): void {
|
||||
const activeDirectoryObject: any = {};
|
||||
activeDirectoryObject.ouDistinguishedName = adSettings.organizationalUnit;
|
||||
activeDirectoryObject.dnsIpAddresses = this.splitByComma(adSettings.dnsIPAddresses);
|
||||
activeDirectoryObject.domainControllerFullyQualifiedDns = this.splitByComma(adSettings.domainControllerFQDNs.toLowerCase());
|
||||
activeDirectoryObject.domainDnsName = adSettings.domainDNSName;
|
||||
activeDirectoryObject.subdomain = adSettings.subdomain;
|
||||
activeDirectoryObject.accountPrefix = adSettings.accountPrefix;
|
||||
activeDirectoryObject.realm = adSettings.realm ?? adSettings.domainDNSName.toUpperCase();
|
||||
activeDirectoryObject.clusterAdmins = this.splitByComma(adSettings.clusterAdmins);
|
||||
activeDirectoryObject.clusterUsers = this.splitByComma(adSettings.clusterUsers);
|
||||
if (adSettings.appReaders) {
|
||||
activeDirectoryObject.appReaders = this.splitByComma(adSettings.appReaders);
|
||||
}
|
||||
if (adSettings.appOwners) {
|
||||
activeDirectoryObject.appOwners = this.splitByComma(adSettings.appOwners);
|
||||
}
|
||||
|
||||
this._controlConfig.security.activeDirectory = activeDirectoryObject;
|
||||
}
|
||||
|
||||
public getBdcJson(readable: boolean = true): string {
|
||||
return this.stringifyJson(this._bdcConfig, readable);
|
||||
}
|
||||
|
||||
public getControlJson(readable: boolean = true): string {
|
||||
return this.stringifyJson(this._controlConfig, readable);
|
||||
}
|
||||
|
||||
private stringifyJson(obj: any, readable: boolean): string {
|
||||
return JSON.stringify(obj, undefined, readable ? 4 : 0);
|
||||
}
|
||||
|
||||
private getReplicas(resourceName: string): number {
|
||||
return <number>this._bdcConfig.spec.resources[resourceName].spec.replicas;
|
||||
}
|
||||
|
||||
private setReplicas(resourceName: string, replicas: number): void {
|
||||
this._bdcConfig.spec.resources[resourceName].spec.replicas = replicas;
|
||||
}
|
||||
|
||||
private getEndpointPort(endpoints: ServiceEndpoint[], name: EndpointName, defaultValue: number): number {
|
||||
const endpoint = endpoints.find(endpoint => endpoint.name === name);
|
||||
return endpoint ? endpoint.port : defaultValue;
|
||||
}
|
||||
|
||||
private setEndpoint(endpoints: ServiceEndpoint[], name: EndpointName, port: number, dnsName?: string): void {
|
||||
const endpoint = endpoints.find(endpoint => endpoint.name === name);
|
||||
if (endpoint) {
|
||||
endpoint.port = port;
|
||||
endpoint.dnsName = dnsName;
|
||||
} else {
|
||||
const newEndpoint: ServiceEndpoint = {
|
||||
name: name,
|
||||
serviceType: 'NodePort',
|
||||
port: port
|
||||
};
|
||||
// for newly added endpoint, we cannot have blank value for the dnsName, only set it if it is not empty
|
||||
if (dnsName) {
|
||||
newEndpoint.dnsName = dnsName;
|
||||
}
|
||||
endpoints.push(newEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
private splitByComma(value: string): string[] {
|
||||
// split by comma, then remove trailing spaces for each item and finally remove the empty values.
|
||||
return value.split(',').map(v => v && v.trim()).filter(v => v !== '' && v !== undefined);
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,7 @@ import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { DeploymentProvider, instanceOfAzureSQLVMDeploymentProvider, instanceOfAzureSQLDBDeploymentProvider, instanceOfCommandDeploymentProvider, instanceOfDialogDeploymentProvider, instanceOfDownloadDeploymentProvider, instanceOfNotebookBasedDialogInfo, instanceOfNotebookDeploymentProvider, instanceOfNotebookWizardDeploymentProvider, instanceOfWebPageDeploymentProvider, instanceOfWizardDeploymentProvider, NotebookInfo, NotebookPathInfo, ResourceType, ResourceTypeOption, ResourceSubType, AgreementInfo, HelpText, InitialVariableValues } from '../interfaces';
|
||||
import { AzdataService } from './azdataService';
|
||||
import { DeploymentProvider, instanceOfAzureSQLVMDeploymentProvider, instanceOfAzureSQLDBDeploymentProvider, instanceOfCommandDeploymentProvider, instanceOfDialogDeploymentProvider, instanceOfDownloadDeploymentProvider, instanceOfNotebookBasedDialogInfo, instanceOfNotebookDeploymentProvider, instanceOfNotebookWizardDeploymentProvider, instanceOfWebPageDeploymentProvider, NotebookInfo, NotebookPathInfo, ResourceType, ResourceTypeOption, ResourceSubType, AgreementInfo, HelpText, InitialVariableValues } from '../interfaces';
|
||||
import { KubeService } from './kubeService';
|
||||
import { INotebookService } from './notebookService';
|
||||
import { IPlatformService } from './platformService';
|
||||
@@ -116,9 +115,6 @@ export class ResourceTypeService implements IResourceTypeService {
|
||||
} else if (instanceOfDialogDeploymentProvider(provider) && instanceOfNotebookBasedDialogInfo(provider.dialog)) {
|
||||
this.updateNotebookPath(provider.dialog, extensionPath);
|
||||
}
|
||||
else if ('bdcWizard' in provider) {
|
||||
this.updateNotebookPath(provider.bdcWizard, extensionPath);
|
||||
}
|
||||
else if ('notebookWizard' in provider) {
|
||||
this.updateNotebookPath(provider.notebookWizard, extensionPath);
|
||||
}
|
||||
@@ -245,8 +241,7 @@ export class ResourceTypeService implements IResourceTypeService {
|
||||
let providerIndex = 1;
|
||||
resourceType.providers.forEach(provider => {
|
||||
const providerPositionInfo = `${positionInfo}, provider index: ${providerIndex} `;
|
||||
if (!instanceOfWizardDeploymentProvider(provider)
|
||||
&& !instanceOfNotebookWizardDeploymentProvider(provider)
|
||||
if (!instanceOfNotebookWizardDeploymentProvider(provider)
|
||||
&& !instanceOfDialogDeploymentProvider(provider)
|
||||
&& !instanceOfNotebookDeploymentProvider(provider)
|
||||
&& !instanceOfDownloadDeploymentProvider(provider)
|
||||
@@ -328,7 +323,7 @@ export class ResourceTypeService implements IResourceTypeService {
|
||||
}
|
||||
|
||||
public startDeployment(resourceType: ResourceType, optionValuesFilter?: OptionValuesFilter, initialVariableValues?: InitialVariableValues): void {
|
||||
const wizard = new ResourceTypeWizard(resourceType, new KubeService(), new AzdataService(this.platformService), this.notebookService, this.toolsService, this.platformService, this, optionValuesFilter, initialVariableValues);
|
||||
const wizard = new ResourceTypeWizard(resourceType, new KubeService(), this.notebookService, this.toolsService, this.platformService, this, optionValuesFilter, initialVariableValues);
|
||||
wizard.open();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,182 +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 { EOL } from 'os';
|
||||
import * as path from 'path';
|
||||
import { SemVer } from 'semver';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { AzdataInstallLocationKey, DeploymentConfigurationKey } from '../../constants';
|
||||
import { Command, OsDistribution, ToolType } from '../../interfaces';
|
||||
import { IPlatformService } from '../platformService';
|
||||
import { dependencyType, ToolBase } from './toolBase';
|
||||
import { SemVerProxy } from './SemVerProxy';
|
||||
|
||||
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 {
|
||||
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';
|
||||
}
|
||||
|
||||
protected get versionCommand(): Command {
|
||||
return {
|
||||
command: 'azdata -v'
|
||||
};
|
||||
}
|
||||
|
||||
protected get discoveryCommand(): Command {
|
||||
return {
|
||||
command: this.discoveryCommandString('azdata')
|
||||
};
|
||||
}
|
||||
|
||||
protected getVersionFromOutput(output: string): SemVer | undefined {
|
||||
let version: SemVer | undefined = undefined;
|
||||
if (output && output.split(EOL).length > 0) {
|
||||
version = new SemVerProxy(output.split(EOL)[0].replace(/ /g, ''));
|
||||
}
|
||||
return version;
|
||||
}
|
||||
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[]>([
|
||||
[OsDistribution.debian, this.debianInstallationCommands],
|
||||
[OsDistribution.win32, this.win32InstallationCommands],
|
||||
[OsDistribution.darwin, this.macOsInstallationCommands],
|
||||
[OsDistribution.others, []]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
private get azdataInstallLocation(): string {
|
||||
return vscode.workspace.getConfiguration(DeploymentConfigurationKey)[AzdataInstallLocationKey] || this.defaultInstallLocationByDistribution.get(this.osDistribution);
|
||||
}
|
||||
|
||||
private defaultInstallLocationByDistribution: Map<OsDistribution, string> = new Map<OsDistribution, string>([
|
||||
[OsDistribution.debian, 'https://packages.microsoft.com/config/ubuntu/16.04/mssql-server-2019.list'],
|
||||
[OsDistribution.win32, 'https://aka.ms/azdata-msi'],
|
||||
[OsDistribution.darwin, 'microsoft/azdata-cli-release'],
|
||||
[OsDistribution.others, '']
|
||||
]);
|
||||
|
||||
protected override dependenciesByOsType: Map<OsDistribution, dependencyType[]> = new Map<OsDistribution, dependencyType[]>([
|
||||
[OsDistribution.debian, []],
|
||||
[OsDistribution.win32, []],
|
||||
[OsDistribution.darwin, [dependencyType.Brew]],
|
||||
[OsDistribution.others, []]
|
||||
]);
|
||||
|
||||
private get win32InstallationCommands() {
|
||||
return [
|
||||
{
|
||||
comment: localize('resourceDeployment.Azdata.DeletingPreviousAzdata.msi', "deleting previously downloaded Azdata.msi if one exists …"),
|
||||
command: `IF EXIST .\\Azdata.msi DEL /F .\\Azdata.msi`
|
||||
},
|
||||
{
|
||||
sudo: true,
|
||||
comment: localize('resourceDeployment.Azdata.DownloadingAndInstallingAzdata', "downloading Azdata.msi and installing azdata-cli …"),
|
||||
command: `powershell -NoLogo -NonInteractive -NoProfile -Command "& {try {(New-Object System.Net.WebClient).DownloadFile('${this.azdataInstallLocation}', 'Azdata.msi'); Start-Process msiexec.exe -Wait -ArgumentList '/I Azdata.msi /passive /quiet /lvx ADS_AzdataInstall.log'} catch { Write-Error $_.Exception; exit 1 }}"`
|
||||
},
|
||||
{
|
||||
comment: localize('resourceDeployment.Azdata.DisplayingInstallationLog', "displaying the installation log …"),
|
||||
command: `type ADS_AzdataInstall.log | findstr /i /v ^MSI"`,
|
||||
ignoreError: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
private get macOsInstallationCommands() {
|
||||
return [
|
||||
{
|
||||
comment: localize('resourceDeployment.Azdata.TappingBrewRepository', "tapping into the brew repository for azdata-cli …"),
|
||||
command: `brew tap ${this.azdataInstallLocation}`
|
||||
},
|
||||
{
|
||||
comment: localize('resourceDeployment.Azdata.UpdatingBrewRepository', "updating the brew repository for azdata-cli installation …"),
|
||||
command: 'brew update'
|
||||
},
|
||||
{
|
||||
comment: localize('resourceDeployment.Azdata.InstallingAzdata', "installing azdata …"),
|
||||
command: 'brew install azdata-cli'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
private get debianInstallationCommands() {
|
||||
return [
|
||||
{
|
||||
sudo: true,
|
||||
comment: localize('resourceDeployment.Azdata.AptGetUpdate', "updating repository information …"),
|
||||
command: 'apt-get update'
|
||||
},
|
||||
{
|
||||
sudo: true,
|
||||
comment: localize('resourceDeployment.Azdata.AptGetPackages', "getting packages needed for azdata installation …"),
|
||||
command: 'apt-get install gnupg ca-certificates curl apt-transport-https lsb-release -y'
|
||||
},
|
||||
{
|
||||
sudo: true,
|
||||
comment: localize('resourceDeployment.Azdata.DownloadAndInstallingSigningKey', "downloading and installing the signing key for azdata …"),
|
||||
command: 'wget -qO- https://packages.microsoft.com/keys/microsoft.asc | apt-key add -'
|
||||
},
|
||||
{
|
||||
sudo: true,
|
||||
comment: localize('resourceDeployment.Azdata.AddingAzdataRepositoryInformation', "adding the azdata repository information …"),
|
||||
command: `add-apt-repository "$(wget -qO- ${this.azdataInstallLocation})"`
|
||||
},
|
||||
{
|
||||
sudo: true,
|
||||
comment: localize('resourceDeployment.Azdata.AptGetUpdate', "updating repository information …"),
|
||||
command: 'apt-get update'
|
||||
},
|
||||
{
|
||||
sudo: true,
|
||||
comment: localize('resourceDeployment.Azdata.InstallingAzdata', "installing azdata …"),
|
||||
command: 'apt-get install -y azdata-cli'
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import { DockerTool } from './tools/dockerTool';
|
||||
import { AzCliTool } from './tools/azCliTool';
|
||||
import { KubeCtlTool } from './tools/kubeCtlTool';
|
||||
import { IPlatformService } from './platformService';
|
||||
import { AzdataTool } from './tools/azdataTool';
|
||||
|
||||
export interface IToolsService {
|
||||
getToolByName(toolName: string): ITool | undefined;
|
||||
@@ -23,7 +22,6 @@ export class ToolsService implements IToolsService {
|
||||
[
|
||||
new DockerTool(this._platformService),
|
||||
new AzCliTool(this._platformService),
|
||||
new AzdataTool(this._platformService),
|
||||
new KubeCtlTool(this._platformService)
|
||||
].map<[string, ITool]>((tool: ITool) => [tool.name, tool])
|
||||
);
|
||||
|
||||
@@ -1,57 +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 'mocha';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import * as should from 'should';
|
||||
import { IPlatformService, CommandOptions } from '../../services/platformService';
|
||||
import { AzdataService } from '../../services/azdataService';
|
||||
import { BdcDeploymentType } from '../../interfaces';
|
||||
|
||||
describe('azdata service Tests', function (): void {
|
||||
it('azdata service handles deployment types properly', async () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const azdataService = new AzdataService(mockPlatformService.object);
|
||||
mockPlatformService.setup((service) => service.runCommand(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns((command: string, options: CommandOptions | undefined) => {
|
||||
return new Promise<string>((resolve) => {
|
||||
resolve('{"result":[]}');
|
||||
});
|
||||
});
|
||||
|
||||
azdataService.getDeploymentProfiles(BdcDeploymentType.ExistingAKS);
|
||||
azdataService.getDeploymentProfiles(BdcDeploymentType.ExistingARO);
|
||||
azdataService.getDeploymentProfiles(BdcDeploymentType.ExistingKubeAdm);
|
||||
azdataService.getDeploymentProfiles(BdcDeploymentType.ExistingOpenShift);
|
||||
azdataService.getDeploymentProfiles(BdcDeploymentType.NewAKS);
|
||||
|
||||
should(azdataService.getDeploymentProfiles(<BdcDeploymentType>'no-such-type')).rejected();
|
||||
mockPlatformService.verify((service) => service.runCommand(TypeMoq.It.isAnyString(), TypeMoq.It.isAny()), TypeMoq.Times.exactly(5));
|
||||
});
|
||||
|
||||
it('azdata service returns correct deployment profiles', async () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const azdataService = new AzdataService(mockPlatformService.object);
|
||||
mockPlatformService.setup((service => service.storagePath())).returns(() => {
|
||||
return '';
|
||||
});
|
||||
mockPlatformService.setup((service => service.readTextFile(TypeMoq.It.isAnyString()))).returns((path: string) => {
|
||||
return new Promise<string>((resolve) => {
|
||||
resolve('{}');
|
||||
});
|
||||
});
|
||||
mockPlatformService.setup((service) => service.runCommand(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns((command: string, options: CommandOptions | undefined) => {
|
||||
if (command === 'azdata bdc config list -o json') {
|
||||
return Promise.resolve('{"result":["aks-1","profile-2"]}');
|
||||
} else if (command.startsWith('azdata bdc config init')) {
|
||||
return Promise.resolve('');
|
||||
}
|
||||
else {
|
||||
return Promise.reject(`unexpected command: ${command}`);
|
||||
}
|
||||
});
|
||||
const profiles = await azdataService.getDeploymentProfiles(BdcDeploymentType.NewAKS);
|
||||
should(profiles.length).be.exactly(1);
|
||||
});
|
||||
});
|
||||
@@ -24,13 +24,13 @@ describe('Resource Type Service Tests', function (): void {
|
||||
// index 0: platform name, index 1: expected resource types
|
||||
const platforms: { platform: string; resourceTypes: string[] }[] = [
|
||||
{
|
||||
platform: 'win32', resourceTypes: ['sql-image', 'sql-bdc', 'sql-windows-setup']
|
||||
platform: 'win32', resourceTypes: ['sql-image', 'sql-windows-setup']
|
||||
},
|
||||
{
|
||||
platform: 'darwin', resourceTypes: ['sql-image', 'sql-bdc']
|
||||
platform: 'darwin', resourceTypes: ['sql-image']
|
||||
},
|
||||
{
|
||||
platform: 'linux', resourceTypes: ['sql-image', 'sql-bdc']
|
||||
platform: 'linux', resourceTypes: ['sql-image']
|
||||
}
|
||||
];
|
||||
platforms.forEach(platformInfo => {
|
||||
|
||||
@@ -9,14 +9,12 @@ 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/azdataTool';
|
||||
|
||||
|
||||
const tools: { name: string; type: ToolType }[] = [
|
||||
{ name: 'azure-cli', type: ToolType.AzCli },
|
||||
{ name: 'docker', type: ToolType.Docker },
|
||||
{ name: 'kubectl', type: ToolType.KubeCtl },
|
||||
{ name: AzdataToolName, type: ToolType.Azdata }
|
||||
{ name: 'kubectl', type: ToolType.KubeCtl }
|
||||
];
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const toolsService = new ToolsService(mockPlatformService.object);
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export const DeploymentProfile_VariableName = 'AZDATA_NB_VAR_BDC_DEPLOYMENT_PROFILE';
|
||||
export const ClusterName_VariableName = 'AZDATA_NB_VAR_BDC_CLUSTER_NAME';
|
||||
export const AdminUserName_VariableName = 'AZDATA_NB_VAR_BDC_CONTROLLER_USERNAME';
|
||||
export const AdminPassword_VariableName = 'AZDATA_NB_VAR_BDC_ADMIN_PASSWORD';
|
||||
export const AuthenticationMode_VariableName = 'AZDATA_NB_VAR_BDC_AUTHENTICATION_MODE';
|
||||
export const OrganizationalUnitDistinguishedName_VariableName = 'AZDATA_NB_VAR_BDC_AD_OUDN';
|
||||
export const ClusterAdmins_VariableName = 'AZDATA_NB_VAR_BDC_AD_CLUSTER_ADMINS';
|
||||
export const ClusterUsers_VariableName = 'AZDATA_NB_VAR_BDC_AD_CLUSTER_USERS';
|
||||
export const DomainDNSIPAddresses_VariableName = 'AZDATA_NB_VAR_BDC_AD_UPSTREAM_IPADDRESSES';
|
||||
export const DomainControllerFQDNs_VariableName = 'AZDATA_NB_VAR_BDC_AD_DC_FQDNs';
|
||||
export const DomainDNSName_VariableName = 'AZDATA_NB_VAR_BDC_AD_DOMAIN_DNS_NAME';
|
||||
export const Realm_VariableName = 'AZDATA_NB_VAR_BDC_AD_REALM';
|
||||
export const DomainServiceAccountUserName_VariableName = 'AZDATA_NB_VAR_BDC_AD_DOMAIN_SVC_USERNAME';
|
||||
export const DomainServiceAccountPassword_VariableName = 'AZDATA_NB_VAR_BDC_AD_DOMAIN_SVC_PASSWORD';
|
||||
export const AppOwners_VariableName = 'AZDATA_NB_VAR_BDC_AD_APP_OWNERS';
|
||||
export const AppReaders_VariableName = 'AZDATA_NB_VAR_AD_BDC_AD_APP_READERS';
|
||||
export const Subdomain_VariableName = 'AZDATA_NB_VAR_BDC_AD_SUBDOMAIN';
|
||||
export const AccountPrefix_VariableName = 'AZDATA_NB_VAR_BDC_AD_ACCOUNTPREFIX';
|
||||
export const SubscriptionId_VariableName = 'AZDATA_NB_VAR_BDC_AZURE_SUBSCRIPTION';
|
||||
export const ResourceGroup_VariableName = 'AZDATA_NB_VAR_BDC_RESOURCEGROUP_NAME';
|
||||
export const Location_VariableName = 'AZDATA_NB_VAR_BDC_AZURE_REGION';
|
||||
export const AksName_VariableName = 'AZDATA_NB_VAR_BDC_AKS_NAME';
|
||||
export const VMSize_VariableName = 'AZDATA_NB_VAR_BDC_AZURE_VM_SIZE';
|
||||
export const VMCount_VariableName = 'AZDATA_NB_VAR_BDC_VM_COUNT';
|
||||
export const KubeConfigPath_VariableName = 'AZDATA_NB_VAR_BDC_KUBECONFIG_PATH';
|
||||
export const ClusterContext_VariableName = 'AZDATA_NB_VAR_BDC_CLUSTER_CONTEXT';
|
||||
export const SQLServerScale_VariableName = 'AZDATA_NB_VAR_BDC_SQLSERVER_SCALE';
|
||||
export const HDFSPoolScale_VariableName = 'AZDATA_NB_VAR_BDC_HDFSPOOL_SCALE';
|
||||
export const HDFSNameNodeScale_VariableName = 'AZDATA_NB_VAR_BDC_NAMENODE_SCALE';
|
||||
export const ZooKeeperScale_VariableName = 'AZDATA_NB_VAR_BDC_ZOOKEEPER_SCALE';
|
||||
export const SparkHeadScale_VariableName = 'AZDATA_NB_VAR_BDC_SPARKHEAD_SCALE';
|
||||
export const IncludeSpark_VariableName = 'AZDATA_NB_VAR_BDC_INCLUDESPARK';
|
||||
export const ComputePoolScale_VariableName = 'AZDATA_NB_VAR_BDC_COMPUTEPOOL_SCALE';
|
||||
export const DataPoolScale_VariableName = 'AZDATA_NB_VAR_BDC_DATAPOOL_SCALE';
|
||||
export const SparkPoolScale_VariableName = 'AZDATA_NB_VAR_BDC_SPARKPOOL_SCALE';
|
||||
export const ControllerDataStorageClassName_VariableName = 'AZDATA_NB_VAR_BDC_CONTROLLER_DATA_STORAGE_CLASS';
|
||||
export const ControllerDataStorageSize_VariableName = 'AZDATA_NB_VAR_BDC_CONTROLLER_DATA_STORAGE_SIZE';
|
||||
export const ControllerLogsStorageClassName_VariableName = 'AZDATA_NB_VAR_BDC_CONTROLLER_LOGS_STORAGE_CLASS';
|
||||
export const ControllerLogsStorageSize_VariableName = 'AZDATA_NB_VAR_BDC_CONTROLLER_LOGS_STORAGE_SIZE';
|
||||
export const DataPoolDataStorageClassName_VariableName = 'AZDATA_NB_VAR_BDC_DATA_DATA_STORAGE_CLASS';
|
||||
export const DataPoolDataStorageSize_VariableName = 'AZDATA_NB_VAR_BDC_DATA_DATA_STORAGE_SIZE';
|
||||
export const DataPoolLogsStorageClassName_VariableName = 'AZDATA_NB_VAR_BDC_DATA_LOGS_STORAGE_CLASS';
|
||||
export const DataPoolLogsStorageSize_VariableName = 'AZDATA_NB_VAR_BDC_DATA_LOGS_STORAGE_SIZE';
|
||||
export const HDFSDataStorageClassName_VariableName = 'AZDATA_NB_VAR_BDC_HDFS_DATA_STORAGE_CLASS';
|
||||
export const HDFSDataStorageSize_VariableName = 'AZDATA_NB_VAR_BDC_HDFS_DATA_STORAGE_SIZE';
|
||||
export const HDFSLogsStorageClassName_VariableName = 'AZDATA_NB_VAR_BDC_HDFS_LOGS_STORAGE_CLASS';
|
||||
export const HDFSLogsStorageSize_VariableName = 'AZDATA_NB_VAR_BDC_HDFS_LOGS_STORAGE_SIZE';
|
||||
export const SQLServerDataStorageClassName_VariableName = 'AZDATA_NB_VAR_BDC_SQL_DATA_STORAGE_CLASS';
|
||||
export const SQLServerDataStorageSize_VariableName = 'AZDATA_NB_VAR_BDC_SQL_DATA_STORAGE_SIZE';
|
||||
export const SQLServerLogsStorageClassName_VariableName = 'AZDATA_NB_VAR_BDC_SQL_LOGS_STORAGE_CLASS';
|
||||
export const SQLServerLogsStorageSize_VariableName = 'AZDATA_NB_VAR_BDC_SQL_LOGS_STORAGE_SIZE';
|
||||
export const ControllerDNSName_VariableName = 'AZDATA_NB_VAR_BDC_CONTROLLER_DNS';
|
||||
export const ControllerPort_VariableName = 'AZDATA_NB_VAR_BDC_CONTROLLER_PORT';
|
||||
export const SQLServerDNSName_VariableName = 'AZDATA_NB_VAR_BDC_SQL_DNS';
|
||||
export const SQLServerPort_VariableName = 'AZDATA_NB_VAR_BDC_SQL_PORT';
|
||||
export const GatewayDNSName_VariableName = 'AZDATA_NB_VAR_BDC_GATEWAY_DNS';
|
||||
export const GateWayPort_VariableName = 'AZDATA_NB_VAR_BDC_GATEWAY_PORT';
|
||||
export const ReadableSecondaryDNSName_VariableName = 'AZDATA_NB_VAR_BDC_READABLE_SECONDARY_DNS';
|
||||
export const ReadableSecondaryPort_VariableName = 'AZDATA_NB_VAR_BDC_READABLE_SECONDARY_PORT';
|
||||
export const ServiceProxyDNSName_VariableName = 'AZDATA_NB_VAR_BDC_SERVICEPROXY_DNS';
|
||||
export const ServiceProxyPort_VariableName = 'AZDATA_NB_VAR_BDC_SERVICEPROXY_PORT';
|
||||
export const AppServiceProxyDNSName_VariableName = 'AZDATA_NB_VAR_BDC_APPSERVICEPROXY_DNS';
|
||||
export const AppServiceProxyPort_VariableName = 'AZDATA_NB_VAR_BDC_APPSERVICEPROXY_PORT';
|
||||
export const DockerRepository_VariableName = 'AZDATA_NB_VAR_BDC_REPOSITORY';
|
||||
export const DockerRegistry_VariableName = 'AZDATA_NB_VAR_BDC_REGISTRY';
|
||||
export const DockerImageTag_VariableName = 'AZDATA_NB_VAR_BDC_DOCKER_IMAGE_TAG';
|
||||
export const DockerUsername_VariableName = 'AZDATA_NB_VAR_BDC_DOCKER_USERNAME';
|
||||
export const DockerPassword_VariableName = 'AZDATA_NB_VAR_BDC_DOCKER_PASSWORD';
|
||||
@@ -1,356 +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 azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { delimiter, join } from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import { BdcDeploymentType, BdcWizardDeploymentProvider, ITool } from '../../interfaces';
|
||||
import { BigDataClusterDeploymentProfile, DataResource, HdfsResource, SqlServerMasterResource } from '../../services/bigDataClusterDeploymentProfile';
|
||||
import { KubeCtlToolName } from '../../services/tools/kubeCtlTool';
|
||||
import { getErrorMessage, getRuntimeBinaryPathEnvironmentVariableName, setEnvironmentVariablesForInstallPaths } from '../../common/utils';
|
||||
import { ToolsInstallPath } from '../../constants';
|
||||
import * as VariableNames from './constants';
|
||||
import { ResourceTypeWizard } from '../resourceTypeWizard';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { InputComponents } from '../modelViewUtils';
|
||||
import { INotebookService } from '../../services/notebookService';
|
||||
import { IAzdataService } from '../../services/azdataService';
|
||||
import { IKubeService } from '../../services/kubeService';
|
||||
import { DeploymentProfilePage } from './pages/deploymentProfilePage';
|
||||
import { AzureSettingsPage } from './pages/azureSettingsPage';
|
||||
import { ClusterSettingsPage } from './pages/clusterSettingsPage';
|
||||
import { ServiceSettingsPage } from './pages/serviceSettingsPage';
|
||||
import { SummaryPage } from './pages/summaryPage';
|
||||
import { TargetClusterContextPage } from './pages/targetClusterPage';
|
||||
import { IToolsService } from '../../services/toolsService';
|
||||
import { ResourceTypeModel } from '../resourceTypeModel';
|
||||
import { ResourceTypePage } from '../resourceTypePage';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class DeployClusterWizardModel extends ResourceTypeModel {
|
||||
private _inputComponents: InputComponents = {};
|
||||
private _kubeService: IKubeService;
|
||||
private _azdataService: IAzdataService;
|
||||
private _notebookService: INotebookService;
|
||||
private toolsService: IToolsService;
|
||||
|
||||
private _saveConfigButton: azdata.window.Button;
|
||||
|
||||
public get kubeService(): IKubeService {
|
||||
return this._kubeService;
|
||||
}
|
||||
|
||||
public get azdataService(): IAzdataService {
|
||||
return this._azdataService;
|
||||
}
|
||||
|
||||
public get notebookService(): INotebookService {
|
||||
return this._notebookService;
|
||||
}
|
||||
|
||||
public get inputComponents(): InputComponents {
|
||||
return this._inputComponents;
|
||||
}
|
||||
|
||||
public showCustomButtons(): void {
|
||||
this._saveConfigButton.hidden = false;
|
||||
}
|
||||
|
||||
public hideCustomButtons(): void {
|
||||
this._saveConfigButton.hidden = true;
|
||||
}
|
||||
|
||||
|
||||
public get deploymentType(): BdcDeploymentType {
|
||||
return this.bdcProvider.bdcWizard.type;
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
this.wizard.setPages(this.getPages());
|
||||
this.wizard.wizardObject.generateScriptButton.hidden = true;
|
||||
this.wizard.wizardObject.doneButton.label = localize('deployCluster.ScriptToNotebook', "Script to Notebook");
|
||||
}
|
||||
|
||||
async onOk(): Promise<void> {
|
||||
await this.scriptToNotebook();
|
||||
}
|
||||
|
||||
constructor(public bdcProvider: BdcWizardDeploymentProvider, wizard: ResourceTypeWizard) {
|
||||
super(bdcProvider, wizard);
|
||||
this._kubeService = this.wizard._kubeService;
|
||||
this._azdataService = this.wizard.azdataService;
|
||||
this._notebookService = this.wizard.notebookService;
|
||||
this.toolsService = this.wizard.toolsService;
|
||||
this.wizard.wizardObject.title = this.getTitle(this.deploymentType);
|
||||
this._saveConfigButton = azdata.window.createButton(localize('deployCluster.SaveConfigFiles', "Save config files"), 'left');
|
||||
this._saveConfigButton.hidden = true;
|
||||
this.wizard.addButton(this._saveConfigButton);
|
||||
this.wizard.registerDisposable(this._saveConfigButton.onClick(() => this.saveConfigFiles()));
|
||||
}
|
||||
public adAuthSupported: boolean = false;
|
||||
|
||||
public get authenticationMode(): string | undefined {
|
||||
return this.getStringValue(VariableNames.AuthenticationMode_VariableName);
|
||||
}
|
||||
|
||||
public set authenticationMode(value: string | undefined) {
|
||||
this.setPropertyValue(VariableNames.AuthenticationMode_VariableName, value);
|
||||
}
|
||||
|
||||
public getStorageSettingValue(propertyName: string, defaultValuePropertyName: string): string | undefined {
|
||||
const value = this.getStringValue(propertyName);
|
||||
return (value === undefined || value === '') ? this.getStringValue(defaultValuePropertyName) : value;
|
||||
}
|
||||
|
||||
private setStorageSettingValue(propertyName: string, defaultValuePropertyName: string): void {
|
||||
const value = this.getStringValue(propertyName);
|
||||
if (value === undefined || value === '') {
|
||||
this.setPropertyValue(propertyName, this.getStringValue(defaultValuePropertyName));
|
||||
}
|
||||
}
|
||||
|
||||
private setStorageSettingValues(): void {
|
||||
this.setStorageSettingValue(VariableNames.DataPoolDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.DataPoolDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.DataPoolLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.DataPoolLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName);
|
||||
|
||||
this.setStorageSettingValue(VariableNames.HDFSDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.HDFSDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.HDFSLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.HDFSLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName);
|
||||
|
||||
this.setStorageSettingValue(VariableNames.SQLServerDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.SQLServerDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.SQLServerLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName);
|
||||
this.setStorageSettingValue(VariableNames.SQLServerLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName);
|
||||
}
|
||||
|
||||
public override setEnvironmentVariables(): void {
|
||||
this.setStorageSettingValues();
|
||||
}
|
||||
|
||||
public selectedProfile: BigDataClusterDeploymentProfile | undefined;
|
||||
|
||||
public createTargetProfile(): BigDataClusterDeploymentProfile {
|
||||
// create a copy of the source files to avoid changing the source profile values
|
||||
const sourceBdcJson = Object.assign({}, this.selectedProfile!.bdcConfig);
|
||||
const sourceControlJson = Object.assign({}, this.selectedProfile!.controlConfig);
|
||||
const targetDeploymentProfile = new BigDataClusterDeploymentProfile('', sourceBdcJson, sourceControlJson);
|
||||
// docker settings
|
||||
targetDeploymentProfile.controlConfig.spec.docker = {
|
||||
registry: this.getStringValue(VariableNames.DockerRegistry_VariableName),
|
||||
repository: this.getStringValue(VariableNames.DockerRepository_VariableName),
|
||||
imageTag: this.getStringValue(VariableNames.DockerImageTag_VariableName),
|
||||
imagePullPolicy: 'Always'
|
||||
};
|
||||
// cluster name
|
||||
targetDeploymentProfile.clusterName = this.getStringValue(VariableNames.ClusterName_VariableName)!;
|
||||
// storage settings
|
||||
targetDeploymentProfile.controllerDataStorageClass = this.getStringValue(VariableNames.ControllerDataStorageClassName_VariableName)!;
|
||||
targetDeploymentProfile.controllerDataStorageSize = this.getIntegerValue(VariableNames.ControllerDataStorageSize_VariableName)!;
|
||||
targetDeploymentProfile.controllerLogsStorageClass = this.getStringValue(VariableNames.ControllerLogsStorageClassName_VariableName)!;
|
||||
targetDeploymentProfile.controllerLogsStorageSize = this.getIntegerValue(VariableNames.ControllerLogsStorageSize_VariableName)!;
|
||||
targetDeploymentProfile.setResourceStorage(DataResource,
|
||||
this.getStorageSettingValue(VariableNames.DataPoolDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName)!,
|
||||
Number.parseInt(this.getStorageSettingValue(VariableNames.DataPoolDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName)!),
|
||||
this.getStorageSettingValue(VariableNames.DataPoolLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName)!,
|
||||
Number.parseInt(this.getStorageSettingValue(VariableNames.DataPoolLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName)!)
|
||||
);
|
||||
targetDeploymentProfile.setResourceStorage(SqlServerMasterResource,
|
||||
this.getStorageSettingValue(VariableNames.SQLServerDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName)!,
|
||||
Number.parseInt(this.getStorageSettingValue(VariableNames.SQLServerDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName)!),
|
||||
this.getStorageSettingValue(VariableNames.SQLServerLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName)!,
|
||||
Number.parseInt(this.getStorageSettingValue(VariableNames.SQLServerLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName)!)
|
||||
);
|
||||
targetDeploymentProfile.setResourceStorage(HdfsResource,
|
||||
this.getStorageSettingValue(VariableNames.HDFSDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName)!,
|
||||
Number.parseInt(this.getStorageSettingValue(VariableNames.HDFSDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName)!),
|
||||
this.getStorageSettingValue(VariableNames.HDFSLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName)!,
|
||||
Number.parseInt(this.getStorageSettingValue(VariableNames.HDFSLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName)!)
|
||||
);
|
||||
|
||||
// scale settings
|
||||
targetDeploymentProfile.dataReplicas = this.getIntegerValue(VariableNames.DataPoolScale_VariableName);
|
||||
targetDeploymentProfile.computeReplicas = this.getIntegerValue(VariableNames.ComputePoolScale_VariableName);
|
||||
targetDeploymentProfile.hdfsReplicas = this.getIntegerValue(VariableNames.HDFSPoolScale_VariableName);
|
||||
targetDeploymentProfile.sqlServerReplicas = this.getIntegerValue(VariableNames.SQLServerScale_VariableName);
|
||||
targetDeploymentProfile.hdfsNameNodeReplicas = this.getIntegerValue(VariableNames.HDFSNameNodeScale_VariableName);
|
||||
targetDeploymentProfile.sparkHeadReplicas = this.getIntegerValue(VariableNames.SparkHeadScale_VariableName);
|
||||
targetDeploymentProfile.zooKeeperReplicas = this.getIntegerValue(VariableNames.ZooKeeperScale_VariableName);
|
||||
const sparkScale = this.getIntegerValue(VariableNames.SparkPoolScale_VariableName);
|
||||
if (sparkScale > 0) {
|
||||
targetDeploymentProfile.addSparkResource(sparkScale);
|
||||
}
|
||||
|
||||
targetDeploymentProfile.includeSpark = this.getBooleanValue(VariableNames.IncludeSpark_VariableName);
|
||||
|
||||
// endpoint settings
|
||||
targetDeploymentProfile.setGatewayEndpoint(this.getIntegerValue(VariableNames.GateWayPort_VariableName), this.getStringValue(VariableNames.GatewayDNSName_VariableName));
|
||||
targetDeploymentProfile.setSqlServerEndpoint(this.getIntegerValue(VariableNames.SQLServerPort_VariableName), this.getStringValue(VariableNames.SQLServerDNSName_VariableName));
|
||||
targetDeploymentProfile.setControllerEndpoint(this.getIntegerValue(VariableNames.ControllerPort_VariableName), this.getStringValue(VariableNames.ControllerDNSName_VariableName));
|
||||
targetDeploymentProfile.setSqlServerReadableSecondaryEndpoint(this.getIntegerValue(VariableNames.ReadableSecondaryPort_VariableName), this.getStringValue(VariableNames.ReadableSecondaryDNSName_VariableName));
|
||||
targetDeploymentProfile.setServiceProxyEndpoint(this.getIntegerValue(VariableNames.ServiceProxyPort_VariableName), this.getStringValue(VariableNames.ServiceProxyDNSName_VariableName));
|
||||
targetDeploymentProfile.setAppServiceProxyEndpoint(this.getIntegerValue(VariableNames.AppServiceProxyPort_VariableName), this.getStringValue(VariableNames.AppServiceProxyDNSName_VariableName));
|
||||
|
||||
targetDeploymentProfile.setAuthenticationMode(this.authenticationMode!);
|
||||
if (this.authenticationMode === AuthenticationMode.ActiveDirectory) {
|
||||
targetDeploymentProfile.setActiveDirectorySettings({
|
||||
organizationalUnit: this.getStringValue(VariableNames.OrganizationalUnitDistinguishedName_VariableName)!,
|
||||
domainControllerFQDNs: this.getStringValue(VariableNames.DomainControllerFQDNs_VariableName)!,
|
||||
domainDNSName: this.getStringValue(VariableNames.DomainDNSName_VariableName)!,
|
||||
realm: this.getStringValue(VariableNames.Realm_VariableName),
|
||||
dnsIPAddresses: this.getStringValue(VariableNames.DomainDNSIPAddresses_VariableName)!,
|
||||
clusterAdmins: this.getStringValue(VariableNames.ClusterAdmins_VariableName)!,
|
||||
clusterUsers: this.getStringValue(VariableNames.ClusterUsers_VariableName)!,
|
||||
appOwners: this.getStringValue(VariableNames.AppOwners_VariableName),
|
||||
appReaders: this.getStringValue(VariableNames.AppReaders_VariableName),
|
||||
subdomain: this.getStringValue(VariableNames.Subdomain_VariableName),
|
||||
accountPrefix: this.getStringValue(VariableNames.AccountPrefix_VariableName)
|
||||
});
|
||||
}
|
||||
return targetDeploymentProfile;
|
||||
}
|
||||
|
||||
public override getCodeCellContentForNotebook(tools: ITool[]): string[] {
|
||||
const profile = this.createTargetProfile();
|
||||
const statements: string[] = [];
|
||||
if (this.deploymentType === BdcDeploymentType.NewAKS) {
|
||||
statements.push(`azure_subscription_id = '${this.getStringValue(VariableNames.SubscriptionId_VariableName, '')}'`);
|
||||
statements.push(`azure_region = '${this.getStringValue(VariableNames.Location_VariableName)}'`);
|
||||
statements.push(`azure_resource_group = '${this.getStringValue(VariableNames.ResourceGroup_VariableName)}'`);
|
||||
statements.push(`azure_vm_size = '${this.getStringValue(VariableNames.VMSize_VariableName)}'`);
|
||||
statements.push(`azure_vm_count = '${this.getStringValue(VariableNames.VMCount_VariableName)}'`);
|
||||
statements.push(`aks_cluster_name = '${this.getStringValue(VariableNames.AksName_VariableName)}'`);
|
||||
} else if (this.deploymentType === BdcDeploymentType.ExistingAKS
|
||||
|| this.deploymentType === BdcDeploymentType.ExistingKubeAdm
|
||||
|| this.deploymentType === BdcDeploymentType.ExistingARO
|
||||
|| this.deploymentType === BdcDeploymentType.ExistingOpenShift) {
|
||||
statements.push(`mssql_kube_config_path = '${this.escapeForNotebookCodeCell(this.getStringValue(VariableNames.KubeConfigPath_VariableName)!)}'`);
|
||||
statements.push(`mssql_cluster_context = '${this.getStringValue(VariableNames.ClusterContext_VariableName)}'`);
|
||||
statements.push('os.environ["KUBECONFIG"] = mssql_kube_config_path');
|
||||
}
|
||||
if (this.authenticationMode === AuthenticationMode.ActiveDirectory) {
|
||||
statements.push(`mssql_domain_service_account_username = '${this.escapeForNotebookCodeCell(this.getStringValue(VariableNames.DomainServiceAccountUserName_VariableName)!)}'`);
|
||||
}
|
||||
statements.push(`mssql_cluster_name = '${this.getStringValue(VariableNames.ClusterName_VariableName)}'`);
|
||||
statements.push(`mssql_username = '${this.getStringValue(VariableNames.AdminUserName_VariableName)}'`);
|
||||
statements.push(`mssql_auth_mode = '${this.authenticationMode}'`);
|
||||
statements.push(`bdc_json = '${profile.getBdcJson(false)}'`);
|
||||
statements.push(`control_json = '${profile.getControlJson(false)}'`);
|
||||
if (this.getStringValue(VariableNames.DockerUsername_VariableName) && this.getStringValue(VariableNames.DockerPassword_VariableName)) {
|
||||
statements.push(`os.environ["DOCKER_USERNAME"] = '${this.getStringValue(VariableNames.DockerUsername_VariableName)}'`);
|
||||
statements.push(`os.environ["DOCKER_PASSWORD"] = os.environ["${VariableNames.DockerPassword_VariableName}"]`);
|
||||
}
|
||||
const kubeCtlEnvVarName: string = getRuntimeBinaryPathEnvironmentVariableName(KubeCtlToolName);
|
||||
const env: NodeJS.ProcessEnv = {};
|
||||
setEnvironmentVariablesForInstallPaths(tools, env);
|
||||
statements.push(`os.environ["${kubeCtlEnvVarName}"] = "${this.escapeForNotebookCodeCell(env[kubeCtlEnvVarName]!)}"`);
|
||||
statements.push(`os.environ["PATH"] = os.environ["PATH"] + "${delimiter}" + "${this.escapeForNotebookCodeCell(env[ToolsInstallPath]!)}"`);
|
||||
statements.push(`print('Variables have been set successfully.')`);
|
||||
return statements.map(line => line + os.EOL);
|
||||
}
|
||||
|
||||
private async saveConfigFiles(): Promise<void> {
|
||||
const options: vscode.OpenDialogOptions = {
|
||||
defaultUri: vscode.Uri.file(os.homedir()),
|
||||
canSelectFiles: false,
|
||||
canSelectFolders: true,
|
||||
canSelectMany: false,
|
||||
openLabel: localize('deployCluster.SelectConfigFileFolder', "Save config files")
|
||||
};
|
||||
const pathArray = await vscode.window.showOpenDialog(options);
|
||||
if (pathArray && pathArray[0]) {
|
||||
const targetFolder = pathArray[0].fsPath;
|
||||
try {
|
||||
const profile = this.createTargetProfile();
|
||||
await fs.promises.writeFile(join(targetFolder, 'bdc.json'), profile.getBdcJson());
|
||||
await fs.promises.writeFile(join(targetFolder, 'control.json'), profile.getControlJson());
|
||||
this.wizard.wizardObject.message = {
|
||||
text: localize('deployCluster.SaveConfigFileSucceeded', "Config files saved to {0}", targetFolder),
|
||||
level: azdata.window.MessageLevel.Information
|
||||
};
|
||||
}
|
||||
catch (error) {
|
||||
this.wizard.wizardObject.message = {
|
||||
text: error.message,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getPages(): ResourceTypePage[] {
|
||||
const pages: ResourceTypePage[] = [];
|
||||
switch (this.deploymentType) {
|
||||
case BdcDeploymentType.NewAKS:
|
||||
pages.push(
|
||||
new DeploymentProfilePage(this),
|
||||
new AzureSettingsPage(this),
|
||||
new ClusterSettingsPage(this),
|
||||
new ServiceSettingsPage(this),
|
||||
new SummaryPage(this));
|
||||
break;
|
||||
case BdcDeploymentType.ExistingAKS:
|
||||
case BdcDeploymentType.ExistingKubeAdm:
|
||||
case BdcDeploymentType.ExistingARO:
|
||||
case BdcDeploymentType.ExistingOpenShift:
|
||||
pages.push(
|
||||
new DeploymentProfilePage(this),
|
||||
new TargetClusterContextPage(this),
|
||||
new ClusterSettingsPage(this),
|
||||
new ServiceSettingsPage(this),
|
||||
new SummaryPage(this));
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown deployment type: ${this.deploymentType}`);
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
|
||||
private async scriptToNotebook(): Promise<void> {
|
||||
this.setNotebookEnvironmentVariables(process.env);
|
||||
const variableValueStatements = this.getCodeCellContentForNotebook(this.toolsService.toolsForCurrentProvider);
|
||||
const insertionPosition = 5; // Cell number 5 is the position where the python variable setting statements need to be inserted in this.wizardInfo.notebook.
|
||||
try {
|
||||
await this.notebookService.openNotebookWithEdits(this.bdcProvider.bdcWizard.notebook, variableValueStatements, insertionPosition);
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(getErrorMessage(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private setNotebookEnvironmentVariables(env: NodeJS.ProcessEnv): void {
|
||||
env[VariableNames.AdminPassword_VariableName] = this.getStringValue(VariableNames.AdminPassword_VariableName);
|
||||
env[VariableNames.DockerPassword_VariableName] = this.getStringValue(VariableNames.DockerPassword_VariableName);
|
||||
if (this.authenticationMode === AuthenticationMode.ActiveDirectory) {
|
||||
env[VariableNames.DomainServiceAccountPassword_VariableName] = this.getStringValue(VariableNames.DomainServiceAccountPassword_VariableName);
|
||||
}
|
||||
}
|
||||
|
||||
private getTitle(type: BdcDeploymentType): string {
|
||||
switch (type) {
|
||||
case BdcDeploymentType.NewAKS:
|
||||
return localize('deployCluster.NewAKSWizardTitle', "Deploy SQL Server 2019 Big Data Cluster on a new AKS cluster");
|
||||
case BdcDeploymentType.ExistingAKS:
|
||||
return localize('deployCluster.ExistingAKSWizardTitle', "Deploy SQL Server 2019 Big Data Cluster on an existing AKS cluster");
|
||||
case BdcDeploymentType.ExistingKubeAdm:
|
||||
return localize('deployCluster.ExistingKubeAdm', "Deploy SQL Server 2019 Big Data Cluster on an existing kubeadm cluster");
|
||||
case BdcDeploymentType.ExistingARO:
|
||||
return localize('deployCluster.ExistingARO', "Deploy SQL Server 2019 Big Data Cluster on an existing Azure Red Hat OpenShift cluster");
|
||||
case BdcDeploymentType.ExistingOpenShift:
|
||||
return localize('deployCluster.ExistingOpenShift', "Deploy SQL Server 2019 Big Data Cluster on an existing OpenShift cluster");
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown deployment type: ${type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export enum AuthenticationMode {
|
||||
ActiveDirectory = 'ad',
|
||||
Basic = 'basic'
|
||||
}
|
||||
@@ -1,186 +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 azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { FieldType, LabelPosition, SectionInfo } from '../../../interfaces';
|
||||
import { createSection, getDropdownComponent, InputComponent, InputComponentInfo, InputComponents, setModelValues, Validator } from '../../modelViewUtils';
|
||||
import { AksName_VariableName, Location_VariableName, ResourceGroup_VariableName, SubscriptionId_VariableName, VMCount_VariableName, VMSize_VariableName } from '../constants';
|
||||
import { AzureRegion } from 'azurecore';
|
||||
import { DeployClusterWizardModel } from '../deployClusterWizardModel';
|
||||
import { ResourceTypePage } from '../../resourceTypePage';
|
||||
const localize = nls.loadMessageBundle();
|
||||
const MissingRequiredInformationErrorMessage = localize('deployCluster.MissingRequiredInfoError', "Please fill out the required fields marked with red asterisks.");
|
||||
|
||||
export class AzureSettingsPage extends ResourceTypePage {
|
||||
private inputComponents: InputComponents = {};
|
||||
|
||||
constructor(private _model: DeployClusterWizardModel) {
|
||||
super(localize('deployCluster.AzureSettingsPageTitle', "Azure settings"),
|
||||
localize('deployCluster.AzureSettingsPageDescription', "Configure the settings to create an Azure Kubernetes Service cluster"), _model.wizard);
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
const self = this;
|
||||
const azureSection: SectionInfo = {
|
||||
title: '',
|
||||
labelPosition: LabelPosition.Left,
|
||||
spaceBetweenFields: '5px',
|
||||
rows: [{
|
||||
items: [{
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.SubscriptionField', "Subscription id"),
|
||||
required: false,
|
||||
variableName: SubscriptionId_VariableName,
|
||||
placeHolder: localize('deployCluster.SubscriptionPlaceholder', "Use my default Azure subscription"),
|
||||
description: localize('deployCluster.SubscriptionDescription', "The default subscription will be used if you leave this field blank.")
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: '{0}',
|
||||
links: [
|
||||
{
|
||||
text: localize('deployCluster.SubscriptionHelpLink', "View available Azure subscriptions"),
|
||||
url: 'https://portal.azure.com/#blade/Microsoft_Azure_Billing/SubscriptionsBlade'
|
||||
}
|
||||
]
|
||||
}]
|
||||
}, {
|
||||
items: [{
|
||||
type: FieldType.DateTimeText,
|
||||
label: localize('deployCluster.ResourceGroupName', "New resource group name"),
|
||||
required: true,
|
||||
variableName: ResourceGroup_VariableName,
|
||||
defaultValue: 'mssql-'
|
||||
}]
|
||||
}, {
|
||||
items: [{
|
||||
type: FieldType.Options,
|
||||
label: localize('deployCluster.Location', "Location"),
|
||||
required: true,
|
||||
variableName: Location_VariableName,
|
||||
defaultValue: AzureRegion.eastus,
|
||||
editable: true,
|
||||
// The options are not localized because this is an editable dropdown,
|
||||
// It would cause confusion to user about what value to type in, if they type in the localized value, we don't know how to process.
|
||||
options: [
|
||||
AzureRegion.centralus,
|
||||
AzureRegion.eastus,
|
||||
AzureRegion.eastus2,
|
||||
AzureRegion.northcentralus,
|
||||
AzureRegion.southcentralus,
|
||||
AzureRegion.westus,
|
||||
AzureRegion.westus2,
|
||||
AzureRegion.canadacentral,
|
||||
AzureRegion.canadaeast
|
||||
]
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: '{0}',
|
||||
links: [
|
||||
{
|
||||
text: localize('deployCluster.AzureLocationHelpLink', "View available Azure locations"),
|
||||
url: 'https://azure.microsoft.com/global-infrastructure/services/?products=kubernetes-service'
|
||||
}
|
||||
]
|
||||
}]
|
||||
}, {
|
||||
items: [{
|
||||
type: FieldType.DateTimeText,
|
||||
label: localize('deployCluster.AksName', "AKS cluster name"),
|
||||
required: true,
|
||||
variableName: AksName_VariableName,
|
||||
defaultValue: 'mssql-',
|
||||
}]
|
||||
}, {
|
||||
items: [
|
||||
{
|
||||
type: FieldType.Number,
|
||||
label: localize('deployCluster.VMCount', "VM count"),
|
||||
required: true,
|
||||
variableName: VMCount_VariableName,
|
||||
defaultValue: '5',
|
||||
min: 1,
|
||||
max: 999
|
||||
}
|
||||
]
|
||||
}, {
|
||||
items: [{
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.VMSize', "VM size"),
|
||||
required: true,
|
||||
variableName: VMSize_VariableName,
|
||||
defaultValue: 'Standard_E8s_v3'
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: '{0}',
|
||||
links: [
|
||||
{
|
||||
text: localize('deployCluster.VMSizeHelpLink', "View available VM sizes"),
|
||||
url: 'https://docs.microsoft.com/azure/virtual-machines/linux/sizes'
|
||||
}
|
||||
]
|
||||
}]
|
||||
}]
|
||||
};
|
||||
this.pageObject.registerContent(async (view: azdata.ModelView) => {
|
||||
const azureGroup = await createSection({
|
||||
sectionInfo: azureSection,
|
||||
view: view,
|
||||
onNewDisposableCreated: (disposable: vscode.Disposable): void => {
|
||||
self.wizard.registerDisposable(disposable);
|
||||
},
|
||||
onNewInputComponentCreated: (name: string, inputComponentInfo: InputComponentInfo<InputComponent>): void => {
|
||||
self.inputComponents[name] = inputComponentInfo;
|
||||
self._model.inputComponents[name] = inputComponentInfo;
|
||||
},
|
||||
onNewValidatorCreated: (validator: Validator): void => {
|
||||
self.validators.push(validator);
|
||||
},
|
||||
container: this.wizard.wizardObject,
|
||||
inputComponents: this._model.inputComponents,
|
||||
toolsService: this.wizard.toolsService
|
||||
});
|
||||
const formBuilder = view.modelBuilder.formContainer().withFormItems(
|
||||
[{
|
||||
title: '',
|
||||
component: azureGroup
|
||||
}],
|
||||
{
|
||||
horizontal: false,
|
||||
componentWidth: '100%'
|
||||
}
|
||||
);
|
||||
|
||||
const form = formBuilder.withLayout({ width: '100%' }).component();
|
||||
return view.initializeModel(form);
|
||||
});
|
||||
}
|
||||
|
||||
public override async onEnter(): Promise<void> {
|
||||
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
|
||||
this.wizard.wizardObject.message = { text: '' };
|
||||
if (pcInfo.newPage > pcInfo.lastPage) {
|
||||
const location = getDropdownComponent(Location_VariableName, this.inputComponents).value;
|
||||
if (!location) {
|
||||
this.wizard.wizardObject.message = {
|
||||
text: MissingRequiredInformationErrorMessage,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
}
|
||||
return !!location;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override async onLeave(): Promise<void> {
|
||||
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
|
||||
return true;
|
||||
});
|
||||
await setModelValues(this.inputComponents, this.wizard.model);
|
||||
}
|
||||
}
|
||||
@@ -1,367 +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 azdata from 'azdata';
|
||||
import { EOL } from 'os';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { FieldType, LabelPosition, SectionInfo } from '../../../interfaces';
|
||||
import * as localizedConstants from '../../../localizedConstants';
|
||||
import { createSection, getInputBoxComponent, getInvalidSQLPasswordMessage, getPasswordMismatchMessage, InputComponent, InputComponentInfo, InputComponents, isValidSQLPassword, setModelValues, Validator } from '../../modelViewUtils';
|
||||
import { ResourceTypePage } from '../../resourceTypePage';
|
||||
import { ValidationType } from '../../validation/validations';
|
||||
import * as VariableNames from '../constants';
|
||||
import { AuthenticationMode, DeployClusterWizardModel } from '../deployClusterWizardModel';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
const ConfirmPasswordName = 'ConfirmPassword';
|
||||
const clusterNameFieldDescription = localize('deployCluster.ClusterNameDescription', "The cluster name must consist only of alphanumeric lowercase characters or '-' and must start and end with an alphanumeric character.");
|
||||
|
||||
export class ClusterSettingsPage extends ResourceTypePage {
|
||||
private inputComponents: InputComponents = {};
|
||||
private activeDirectorySection!: azdata.FormComponent;
|
||||
private formBuilder!: azdata.FormBuilder;
|
||||
|
||||
constructor(private _model: DeployClusterWizardModel) {
|
||||
super(localize('deployCluster.ClusterSettingsPageTitle', "Cluster settings"),
|
||||
localize('deployCluster.ClusterSettingsPageDescription', "Configure the SQL Server Big Data Cluster settings"), _model.wizard);
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
const self = this;
|
||||
const basicSection: SectionInfo = {
|
||||
labelPosition: LabelPosition.Left,
|
||||
title: '',
|
||||
fields: [
|
||||
{
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.ClusterName', "Cluster name"),
|
||||
required: true,
|
||||
variableName: VariableNames.ClusterName_VariableName,
|
||||
defaultValue: 'mssql-cluster',
|
||||
validations: [{
|
||||
type: ValidationType.Regex,
|
||||
regex: new RegExp('^[a-z0-9]$|^[a-z0-9][a-z0-9-]*[a-z0-9]$'),
|
||||
description: clusterNameFieldDescription
|
||||
}],
|
||||
description: clusterNameFieldDescription
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.AdminUsername', "Admin username"),
|
||||
required: true,
|
||||
variableName: VariableNames.AdminUserName_VariableName,
|
||||
defaultValue: 'admin',
|
||||
description: localize('deployCluster.AdminUsernameDescription', "This username will be used for controller and SQL Server. Username for the gateway will be root.")
|
||||
}, {
|
||||
type: FieldType.Password,
|
||||
label: localize('deployCluster.AdminPassword', "Password"),
|
||||
required: true,
|
||||
variableName: VariableNames.AdminPassword_VariableName,
|
||||
defaultValue: '',
|
||||
description: localize('deployCluster.AdminPasswordDescription', "This password can be used to access the controller, SQL Server and gateway.")
|
||||
}, {
|
||||
type: FieldType.Password,
|
||||
label: localize('deployCluster.ConfirmPassword', "Confirm password"),
|
||||
required: true,
|
||||
variableName: ConfirmPasswordName,
|
||||
defaultValue: ''
|
||||
}, {
|
||||
type: FieldType.Options,
|
||||
label: localize('deployCluster.AuthenticationMode', "Authentication mode"),
|
||||
variableName: VariableNames.AuthenticationMode_VariableName,
|
||||
defaultValue: AuthenticationMode.Basic,
|
||||
options: [
|
||||
{
|
||||
name: AuthenticationMode.Basic,
|
||||
displayName: localize('deployCluster.AuthenticationMode.Basic', "Basic")
|
||||
},
|
||||
{
|
||||
name: AuthenticationMode.ActiveDirectory,
|
||||
displayName: localize('deployCluster.AuthenticationMode.ActiveDirectory', "Active Directory")
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const dockerSection: SectionInfo = {
|
||||
labelPosition: LabelPosition.Left,
|
||||
collapsed: true,
|
||||
collapsible: true,
|
||||
title: localize('deployCluster.DockerSettings', "Docker settings"),
|
||||
fields: [
|
||||
{
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.DockerRegistry', "Registry"),
|
||||
required: true,
|
||||
variableName: VariableNames.DockerRegistry_VariableName
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.DockerRepository', "Repository"),
|
||||
required: true,
|
||||
variableName: VariableNames.DockerRepository_VariableName
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.DockerImageTag', "Image tag"),
|
||||
required: true,
|
||||
variableName: VariableNames.DockerImageTag_VariableName
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.DockerUsername', "Username"),
|
||||
required: false,
|
||||
variableName: VariableNames.DockerUsername_VariableName
|
||||
}, {
|
||||
type: FieldType.Password,
|
||||
label: localize('deployCluster.DockerPassword', "Password"),
|
||||
required: false,
|
||||
variableName: VariableNames.DockerPassword_VariableName
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const activeDirectorySection: SectionInfo = {
|
||||
labelPosition: LabelPosition.Left,
|
||||
title: localize('deployCluster.ActiveDirectorySettings', "Active Directory settings"),
|
||||
fields: [
|
||||
{
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.OuDistinguishedName', "Organizational unit"),
|
||||
required: true,
|
||||
variableName: VariableNames.OrganizationalUnitDistinguishedName_VariableName,
|
||||
description: localize('deployCluster.OuDistinguishedNameDescription', "Distinguished name for the organizational unit. For example: OU=bdc,DC=contoso,DC=com.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.DomainControllerFQDNs', "Domain controller FQDNs"),
|
||||
required: true,
|
||||
variableName: VariableNames.DomainControllerFQDNs_VariableName,
|
||||
placeHolder: localize('deployCluster.DomainControllerFQDNsPlaceHolder', "Use comma to separate the values."),
|
||||
description: localize('deployCluster.DomainControllerFQDNDescription', "Fully qualified domain names for the domain controller. For example: DC1.CONTOSO.COM. Use comma to separate multiple FQDNs.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.DomainDNSIPAddresses', "Domain DNS IP addresses"),
|
||||
required: true,
|
||||
variableName: VariableNames.DomainDNSIPAddresses_VariableName,
|
||||
placeHolder: localize('deployCluster.DomainDNSIPAddressesPlaceHolder', "Use comma to separate the values."),
|
||||
description: localize('deployCluster.DomainDNSIPAddressesDescription', "Domain DNS servers' IP Addresses. Use comma to separate multiple IP addresses.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.DomainDNSName', "Domain DNS name"),
|
||||
required: true,
|
||||
variableName: VariableNames.DomainDNSName_VariableName
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localizedConstants.realm,
|
||||
required: false,
|
||||
variableName: VariableNames.Realm_VariableName,
|
||||
description: localize('deployCluster.RealmDescription', "If not provided, the domain DNS name will be used as the default value.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.ClusterAdmins', "Cluster admin group"),
|
||||
required: true,
|
||||
variableName: VariableNames.ClusterAdmins_VariableName,
|
||||
description: localize('deployCluster.ClusterAdminsDescription', "The Active Directory group for cluster admin.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.ClusterUsers', "Cluster users"),
|
||||
required: true,
|
||||
variableName: VariableNames.ClusterUsers_VariableName,
|
||||
placeHolder: localize('deployCluster.ClusterUsersPlaceHolder', "Use comma to separate the values."),
|
||||
description: localize('deployCluster.ClusterUsersDescription', "The Active Directory users/groups with cluster users role. Use comma to separate multiple users/groups.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.DomainServiceAccountUserName', "Service account username"),
|
||||
required: true,
|
||||
variableName: VariableNames.DomainServiceAccountUserName_VariableName,
|
||||
description: localize('deployCluster.DomainServiceAccountUserNameDescription', "Domain service account for Big Data Cluster")
|
||||
}, {
|
||||
type: FieldType.Password,
|
||||
label: localize('deployCluster.DomainServiceAccountPassword', "Service account password"),
|
||||
required: true,
|
||||
variableName: VariableNames.DomainServiceAccountPassword_VariableName
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.AppOwners', "App owners"),
|
||||
required: false,
|
||||
variableName: VariableNames.AppOwners_VariableName,
|
||||
placeHolder: localize('deployCluster.AppOwnersPlaceHolder', "Use comma to separate the values."),
|
||||
description: localize('deployCluster.AppOwnersDescription', "The Active Directory users or groups with app owners role. Use comma to separate multiple users/groups.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.AppReaders', "App readers"),
|
||||
required: false,
|
||||
variableName: VariableNames.AppReaders_VariableName,
|
||||
placeHolder: localize('deployCluster.AppReadersPlaceHolder', "Use comma to separate the values."),
|
||||
description: localize('deployCluster.AppReadersDescription', "The Active Directory users or groups of app readers. Use comma as separator them if there are multiple users/groups.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.Subdomain', "Subdomain"),
|
||||
required: false,
|
||||
variableName: VariableNames.Subdomain_VariableName,
|
||||
description: localize('deployCluster.SubdomainDescription', "A unique DNS subdomain to use for this SQL Server Big Data Cluster. If not provided, the cluster name will be used as the default value.")
|
||||
}, {
|
||||
type: FieldType.Text,
|
||||
label: localize('deployCluster.AccountPrefix', "Account prefix"),
|
||||
required: false,
|
||||
variableName: VariableNames.AccountPrefix_VariableName,
|
||||
description: localize('deployCluster.AccountPrefixDescription', "A unique prefix for AD accounts SQL Server Big Data Cluster will generate. If not provided, the subdomain name will be used as the default value. If a subdomain is not provided, the cluster name will be used as the default value.")
|
||||
}
|
||||
]
|
||||
};
|
||||
this.pageObject.registerContent(async (view: azdata.ModelView) => {
|
||||
const basicSettingsGroup = await createSection({
|
||||
view: view,
|
||||
container: self.wizard.wizardObject,
|
||||
inputComponents: this._model.inputComponents,
|
||||
sectionInfo: basicSection,
|
||||
onNewDisposableCreated: (disposable: vscode.Disposable): void => {
|
||||
self.wizard.registerDisposable(disposable);
|
||||
},
|
||||
onNewInputComponentCreated: (name: string, inputComponentInfo: InputComponentInfo<InputComponent>): void => {
|
||||
self.inputComponents[name] = inputComponentInfo;
|
||||
self._model.inputComponents[name] = inputComponentInfo;
|
||||
},
|
||||
onNewValidatorCreated: (validator: Validator): void => {
|
||||
self.validators.push(validator);
|
||||
},
|
||||
toolsService: this.wizard.toolsService
|
||||
});
|
||||
const activeDirectorySettingsGroup = await createSection({
|
||||
view: view,
|
||||
container: self.wizard.wizardObject,
|
||||
inputComponents: this._model.inputComponents,
|
||||
sectionInfo: activeDirectorySection,
|
||||
onNewDisposableCreated: (disposable: vscode.Disposable): void => {
|
||||
self.wizard.registerDisposable(disposable);
|
||||
},
|
||||
onNewInputComponentCreated: (name: string, inputComponentInfo: InputComponentInfo<InputComponent>): void => {
|
||||
self.inputComponents[name] = inputComponentInfo;
|
||||
self._model.inputComponents[name] = inputComponentInfo;
|
||||
},
|
||||
onNewValidatorCreated: (validator: Validator): void => {
|
||||
self.validators.push(validator);
|
||||
},
|
||||
toolsService: this.wizard.toolsService
|
||||
});
|
||||
const dockerSettingsGroup = await createSection({
|
||||
view: view,
|
||||
container: self.wizard.wizardObject,
|
||||
inputComponents: this._model.inputComponents,
|
||||
sectionInfo: dockerSection,
|
||||
onNewDisposableCreated: (disposable: vscode.Disposable): void => {
|
||||
self.wizard.registerDisposable(disposable);
|
||||
},
|
||||
onNewInputComponentCreated: (name: string, inputComponentInfo: InputComponentInfo<InputComponent>): void => {
|
||||
self.inputComponents[name] = inputComponentInfo;
|
||||
self._model.inputComponents[name] = inputComponentInfo;
|
||||
},
|
||||
onNewValidatorCreated: (validator: Validator): void => {
|
||||
self.validators.push(validator);
|
||||
},
|
||||
toolsService: this.wizard.toolsService
|
||||
});
|
||||
const basicSettingsFormItem = { title: '', component: basicSettingsGroup };
|
||||
const dockerSettingsFormItem = { title: '', component: dockerSettingsGroup };
|
||||
this.activeDirectorySection = { title: '', component: activeDirectorySettingsGroup };
|
||||
const authModeDropdown = <azdata.DropDownComponent>this.inputComponents[VariableNames.AuthenticationMode_VariableName].component;
|
||||
this.formBuilder = view.modelBuilder.formContainer().withFormItems(
|
||||
[basicSettingsFormItem, dockerSettingsFormItem],
|
||||
{
|
||||
horizontal: false,
|
||||
componentWidth: '100%'
|
||||
}
|
||||
);
|
||||
this.wizard.registerDisposable(authModeDropdown.onValueChanged(() => {
|
||||
const isBasicAuthMode = (<azdata.CategoryValue>authModeDropdown.value).name === 'basic';
|
||||
getInputBoxComponent(VariableNames.OrganizationalUnitDistinguishedName_VariableName, this.inputComponents).required = !isBasicAuthMode;
|
||||
getInputBoxComponent(VariableNames.DomainControllerFQDNs_VariableName, this.inputComponents).required = !isBasicAuthMode;
|
||||
getInputBoxComponent(VariableNames.DomainDNSIPAddresses_VariableName, this.inputComponents).required = !isBasicAuthMode;
|
||||
getInputBoxComponent(VariableNames.DomainDNSName_VariableName, this.inputComponents).required = !isBasicAuthMode;
|
||||
getInputBoxComponent(VariableNames.ClusterAdmins_VariableName, this.inputComponents).required = !isBasicAuthMode;
|
||||
getInputBoxComponent(VariableNames.ClusterUsers_VariableName, this.inputComponents).required = !isBasicAuthMode;
|
||||
getInputBoxComponent(VariableNames.DomainServiceAccountUserName_VariableName, this.inputComponents).required = !isBasicAuthMode;
|
||||
getInputBoxComponent(VariableNames.DomainServiceAccountPassword_VariableName, this.inputComponents).required = !isBasicAuthMode;
|
||||
if (isBasicAuthMode) {
|
||||
this.formBuilder.removeFormItem(this.activeDirectorySection);
|
||||
} else {
|
||||
this.formBuilder.insertFormItem(this.activeDirectorySection);
|
||||
}
|
||||
}));
|
||||
const form = this.formBuilder.withLayout({ width: '100%' }).component();
|
||||
return view.initializeModel(form);
|
||||
});
|
||||
}
|
||||
|
||||
public override async onLeave(): Promise<void> {
|
||||
await setModelValues(this.inputComponents, this.wizard.model);
|
||||
if (this._model.authenticationMode === AuthenticationMode.ActiveDirectory) {
|
||||
const variableDNSPrefixMapping: { [s: string]: string } = {};
|
||||
variableDNSPrefixMapping[VariableNames.AppServiceProxyDNSName_VariableName] = 'bdc-appproxy';
|
||||
variableDNSPrefixMapping[VariableNames.ControllerDNSName_VariableName] = 'bdc-control';
|
||||
variableDNSPrefixMapping[VariableNames.GatewayDNSName_VariableName] = 'bdc-gateway';
|
||||
variableDNSPrefixMapping[VariableNames.ReadableSecondaryDNSName_VariableName] = 'bdc-sqlread';
|
||||
variableDNSPrefixMapping[VariableNames.SQLServerDNSName_VariableName] = 'bdc-sql';
|
||||
variableDNSPrefixMapping[VariableNames.ServiceProxyDNSName_VariableName] = 'bdc-proxy';
|
||||
|
||||
const subdomain = this.wizard.model.getStringValue(VariableNames.Subdomain_VariableName) || this.wizard.model.getStringValue(VariableNames.ClusterName_VariableName);
|
||||
Object.keys(variableDNSPrefixMapping).forEach((variableName: string) => {
|
||||
this.wizard.model.setPropertyValue(variableName, `${variableDNSPrefixMapping[variableName]}.${subdomain}.${this.wizard.model.getStringValue(VariableNames.DomainDNSName_VariableName)}`);
|
||||
});
|
||||
}
|
||||
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public override async onEnter(): Promise<void> {
|
||||
getInputBoxComponent(VariableNames.DockerRegistry_VariableName, this.inputComponents).value = this.wizard.model.getStringValue(VariableNames.DockerRegistry_VariableName);
|
||||
getInputBoxComponent(VariableNames.DockerRepository_VariableName, this.inputComponents).value = this.wizard.model.getStringValue(VariableNames.DockerRepository_VariableName);
|
||||
getInputBoxComponent(VariableNames.DockerImageTag_VariableName, this.inputComponents).value = this.wizard.model.getStringValue(VariableNames.DockerImageTag_VariableName);
|
||||
const authModeDropdown = <azdata.DropDownComponent>this.inputComponents[VariableNames.AuthenticationMode_VariableName].component;
|
||||
if (authModeDropdown) {
|
||||
authModeDropdown.enabled = this._model.adAuthSupported;
|
||||
const adAuthSelected = (<azdata.CategoryValue>authModeDropdown.value).name === 'ad';
|
||||
if (!this._model.adAuthSupported && adAuthSelected) {
|
||||
this.formBuilder.removeFormItem(this.activeDirectorySection);
|
||||
authModeDropdown.value = {
|
||||
name: AuthenticationMode.Basic,
|
||||
displayName: localize('deployCluster.AuthenticationMode.Basic', "Basic")
|
||||
};
|
||||
}
|
||||
|
||||
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
|
||||
this.wizard.wizardObject.message = { text: '' };
|
||||
if (pcInfo.newPage > pcInfo.lastPage) {
|
||||
const messages: string[] = [];
|
||||
const password = getInputBoxComponent(VariableNames.AdminPassword_VariableName, this.inputComponents).value!;
|
||||
const confirmPassword = getInputBoxComponent(ConfirmPasswordName, this.inputComponents).value!;
|
||||
if (password !== confirmPassword) {
|
||||
messages.push(getPasswordMismatchMessage(localize('deployCluster.AdminPasswordField', "Password")));
|
||||
}
|
||||
if (!isValidSQLPassword(password, getInputBoxComponent(VariableNames.AdminUserName_VariableName, this.inputComponents).value!)) {
|
||||
messages.push(getInvalidSQLPasswordMessage(localize('deployCluster.AdminPasswordField', "Password")));
|
||||
}
|
||||
|
||||
this.validators.forEach(validator => {
|
||||
const result = validator();
|
||||
if (!result.valid) {
|
||||
messages.push(result.message);
|
||||
}
|
||||
});
|
||||
|
||||
if (messages.length > 0) {
|
||||
this._model.wizard.wizardObject.message = {
|
||||
text: messages.length === 1 ? messages[0] : localizedConstants.multipleValidationErrors,
|
||||
description: messages.length === 1 ? undefined : messages.join(EOL),
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
}
|
||||
return messages.length === 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,257 +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 azdata from 'azdata';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { BdcDeploymentType } from '../../../interfaces';
|
||||
import { BigDataClusterDeploymentProfile } from '../../../services/bigDataClusterDeploymentProfile';
|
||||
import { createFlexContainer, createLabel } from '../../modelViewUtils';
|
||||
import { ResourceTypePage } from '../../resourceTypePage';
|
||||
import * as VariableNames from '../constants';
|
||||
import { DeployClusterWizardModel } from '../deployClusterWizardModel';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
const serviceScaleTableTitle = localize('deployCluster.serviceScaleTableTitle', "Service scale settings (Instances)");
|
||||
const storageTableTitle = localize('deployCluster.storageTableTitle', "Service storage settings (GB per Instance)");
|
||||
const featureTableTitle = localize('deployCluster.featureTableTitle', "Features");
|
||||
const YesText = localize('deployCluster.yesText', "Yes");
|
||||
const NoText = localize('deployCluster.noText', "No");
|
||||
|
||||
export class DeploymentProfilePage extends ResourceTypePage {
|
||||
private _loadingComponent: azdata.LoadingComponent | undefined;
|
||||
private _container: azdata.FlexContainer | undefined;
|
||||
|
||||
constructor(private _model: DeployClusterWizardModel) {
|
||||
super(localize('deployCluster.summaryPageTitle', "Deployment configuration profile"),
|
||||
localize('deployCluster.summaryPageDescription', "Select the target configuration profile"), _model.wizard);
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
this.pageObject.registerContent(async (view: azdata.ModelView): Promise<void> => {
|
||||
this._container = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
|
||||
const hintText = view.modelBuilder.text().withProps({
|
||||
value: localize('deployCluster.ProfileHintText', "Note: The settings of the deployment profile can be customized in later steps.")
|
||||
}).component();
|
||||
const container = createFlexContainer(view, [this._container, hintText], false);
|
||||
this._loadingComponent = view.modelBuilder.loadingComponent().withItem(container).withProps({
|
||||
loading: true,
|
||||
loadingText: localize('deployCluster.loadingProfiles', "Loading profiles"),
|
||||
loadingCompletedText: localize('deployCluster.loadingProfilesCompleted', "Loading profiles completed"),
|
||||
showText: true
|
||||
}).component();
|
||||
let formBuilder = view.modelBuilder.formContainer().withFormItems(
|
||||
[
|
||||
{
|
||||
title: '',
|
||||
component: this._loadingComponent
|
||||
}
|
||||
],
|
||||
{
|
||||
horizontal: false
|
||||
}
|
||||
).withLayout({ width: '100%', height: '100%' });
|
||||
const form = formBuilder.withLayout({ width: '100%' }).component();
|
||||
await view.initializeModel(form);
|
||||
await this.loadProfiles(view);
|
||||
});
|
||||
}
|
||||
|
||||
private setModelValuesByProfile(selectedProfile: BigDataClusterDeploymentProfile): void {
|
||||
this._model.setPropertyValue(VariableNames.DeploymentProfile_VariableName, selectedProfile.profileName);
|
||||
this._model.setPropertyValue(VariableNames.SparkPoolScale_VariableName, selectedProfile.sparkReplicas);
|
||||
this._model.setPropertyValue(VariableNames.DataPoolScale_VariableName, selectedProfile.dataReplicas);
|
||||
this._model.setPropertyValue(VariableNames.HDFSPoolScale_VariableName, selectedProfile.hdfsReplicas);
|
||||
this._model.setPropertyValue(VariableNames.ComputePoolScale_VariableName, selectedProfile.computeReplicas);
|
||||
this._model.setPropertyValue(VariableNames.HDFSNameNodeScale_VariableName, selectedProfile.hdfsNameNodeReplicas);
|
||||
this._model.setPropertyValue(VariableNames.SQLServerScale_VariableName, selectedProfile.sqlServerReplicas);
|
||||
this._model.setPropertyValue(VariableNames.SparkHeadScale_VariableName, selectedProfile.sparkHeadReplicas);
|
||||
this._model.setPropertyValue(VariableNames.ZooKeeperScale_VariableName, selectedProfile.zooKeeperReplicas);
|
||||
this._model.setPropertyValue(VariableNames.ControllerDataStorageSize_VariableName, selectedProfile.controllerDataStorageSize);
|
||||
this._model.setPropertyValue(VariableNames.ControllerLogsStorageSize_VariableName, selectedProfile.controllerLogsStorageSize);
|
||||
this._model.setPropertyValue(VariableNames.SQLServerPort_VariableName, selectedProfile.sqlServerPort);
|
||||
this._model.setPropertyValue(VariableNames.GateWayPort_VariableName, selectedProfile.gatewayPort);
|
||||
this._model.setPropertyValue(VariableNames.ControllerPort_VariableName, selectedProfile.controllerPort);
|
||||
this._model.setPropertyValue(VariableNames.ServiceProxyPort_VariableName, selectedProfile.serviceProxyPort);
|
||||
this._model.setPropertyValue(VariableNames.AppServiceProxyPort_VariableName, selectedProfile.appServiceProxyPort);
|
||||
this._model.setPropertyValue(VariableNames.IncludeSpark_VariableName, selectedProfile.includeSpark);
|
||||
this._model.setPropertyValue(VariableNames.ControllerDataStorageClassName_VariableName, selectedProfile.controllerDataStorageClass);
|
||||
this._model.setPropertyValue(VariableNames.ControllerLogsStorageClassName_VariableName, selectedProfile.controllerLogsStorageClass);
|
||||
this._model.setPropertyValue(VariableNames.ReadableSecondaryPort_VariableName, selectedProfile.sqlServerReadableSecondaryPort);
|
||||
this._model.setPropertyValue(VariableNames.DockerRegistry_VariableName, selectedProfile.registry);
|
||||
this._model.setPropertyValue(VariableNames.DockerRepository_VariableName, selectedProfile.repository);
|
||||
this._model.setPropertyValue(VariableNames.DockerImageTag_VariableName, selectedProfile.imageTag);
|
||||
this._model.adAuthSupported = selectedProfile.activeDirectorySupported;
|
||||
this._model.selectedProfile = selectedProfile;
|
||||
}
|
||||
|
||||
private async loadProfiles(view: azdata.ModelView): Promise<void> {
|
||||
try {
|
||||
const profiles = await this.wizard.azdataService.getDeploymentProfiles(this._model.deploymentType);
|
||||
const radioButtonGroup = this.createRadioButtonGroup(view, profiles);
|
||||
const serviceScaleTable = this.createServiceScaleTable(view, profiles);
|
||||
const storageTable = this.createStorageTable(view, profiles);
|
||||
const featuresTable = this.createFeaturesTable(view, profiles);
|
||||
this._container!.addItem(createLabel(view, { text: localize('deployCluster.profileRadioGroupLabel', "Deployment configuration profile") }), {
|
||||
CSSStyles: { 'margin-bottom': '5px' }
|
||||
});
|
||||
this._container!.addItem(radioButtonGroup, {
|
||||
CSSStyles: { 'margin-bottom': '20px' }
|
||||
});
|
||||
this._container!.addItems([
|
||||
this.createTableGroup(view, serviceScaleTableTitle, serviceScaleTable),
|
||||
this.createTableGroup(view, storageTableTitle, storageTable),
|
||||
this.createTableGroup(view, featureTableTitle, featuresTable)
|
||||
], {
|
||||
CSSStyles: { 'margin-bottom': '10px' }
|
||||
});
|
||||
this._loadingComponent!.loading = false;
|
||||
} catch (error) {
|
||||
this.wizard.wizardObject.message = {
|
||||
level: azdata.window.MessageLevel.Error,
|
||||
text: localize('deployCluster.loadProfileFailed', "Failed to load the deployment profiles: {0}", error.message)
|
||||
};
|
||||
this._loadingComponent!.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private createRadioButtonGroup(view: azdata.ModelView, profiles: BigDataClusterDeploymentProfile[]): azdata.FlexContainer {
|
||||
const defaultProfile: string = this.getDefaultProfile();
|
||||
const groupName = 'profileGroup';
|
||||
const radioButtons = profiles.map(profile => {
|
||||
const checked = profile.profileName === defaultProfile;
|
||||
const radioButton = view.modelBuilder.radioButton().withProps({
|
||||
label: profile.profileName,
|
||||
checked: checked,
|
||||
name: groupName
|
||||
}).component();
|
||||
if (checked) {
|
||||
this.setModelValuesByProfile(profile);
|
||||
radioButton.focus();
|
||||
}
|
||||
this.wizard.registerDisposable(radioButton.onDidClick(() => {
|
||||
this.wizard.wizardObject.message = { text: '' };
|
||||
this.setModelValuesByProfile(profile);
|
||||
}));
|
||||
return radioButton;
|
||||
});
|
||||
return view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row' }).withItems(radioButtons, { flex: '0 0 auto', CSSStyles: { 'margin-right': '20px' } }).component();
|
||||
}
|
||||
|
||||
private createServiceScaleTable(view: azdata.ModelView, profiles: BigDataClusterDeploymentProfile[]): azdata.TableComponent {
|
||||
const data = [
|
||||
[localize('deployCluster.masterPoolLabel', "SQL Server Master"), ...profiles.map(profile => profile.sqlServerReplicas.toString())],
|
||||
[localize('deployCluster.computePoolLable', "Compute"), ...profiles.map(profile => profile.computeReplicas.toString())],
|
||||
[localize('deployCluster.dataPoolLabel', "Data"), ...profiles.map(profile => profile.dataReplicas.toString())],
|
||||
[localize('deployCluster.hdfsLabel', "HDFS + Spark"), ...profiles.map(profile => profile.hdfsReplicas.toString())]
|
||||
];
|
||||
|
||||
return view.modelBuilder.table().withProps({
|
||||
columns: [this.createDescriptionColumn(localize('deployCluster.ServiceName', "Service")), ...this.createProfileColumns(profiles)],
|
||||
data: data,
|
||||
title: serviceScaleTableTitle,
|
||||
ariaLabel: serviceScaleTableTitle,
|
||||
height: 140,
|
||||
width: 200 + 150 * profiles.length
|
||||
}).component();
|
||||
}
|
||||
|
||||
private createStorageTable(view: azdata.ModelView, profiles: BigDataClusterDeploymentProfile[]): azdata.TableComponent {
|
||||
const data = [
|
||||
[localize('deployCluster.dataStorageType', "Data"), ...profiles.map(profile => profile.controllerDataStorageSize.toString())],
|
||||
[localize('deployCluster.logsStorageType', "Logs"), ...profiles.map(profile => profile.controllerLogsStorageSize.toString())]
|
||||
];
|
||||
return view.modelBuilder.table().withProps({
|
||||
columns: [this.createDescriptionColumn(localize('deployCluster.StorageType', "Storage type")), ...this.createProfileColumns(profiles)],
|
||||
data: data,
|
||||
title: storageTableTitle,
|
||||
ariaLabel: storageTableTitle,
|
||||
height: 80,
|
||||
width: 200 + 150 * profiles.length
|
||||
}).component();
|
||||
}
|
||||
|
||||
private createFeaturesTable(view: azdata.ModelView, profiles: BigDataClusterDeploymentProfile[]): azdata.TableComponent {
|
||||
const data = [
|
||||
[localize('deployCluster.basicAuthentication', "Basic authentication"), ...profiles.map(profile => YesText)],
|
||||
];
|
||||
if (profiles.findIndex(profile => profile.activeDirectorySupported) !== -1) {
|
||||
data.push([localize('deployCluster.activeDirectoryAuthentication', "Active Directory authentication"), ...profiles.map(profile => profile.activeDirectorySupported ? YesText : NoText)]);
|
||||
}
|
||||
|
||||
if (profiles.findIndex(profile => profile.sqlServerReplicas > 1) !== -1) {
|
||||
data.push([localize('deployCluster.hadr', "High Availability"), ...profiles.map(profile => profile.sqlServerReplicas > 1 ? YesText : NoText)]);
|
||||
}
|
||||
|
||||
return view.modelBuilder.table().withProps({
|
||||
columns: [this.createDescriptionColumn(localize('deployCluster.featureText', "Feature")), ...this.createProfileColumns(profiles)],
|
||||
data: data,
|
||||
title: featureTableTitle,
|
||||
ariaLabel: featureTableTitle,
|
||||
height: 30 + data.length * 25,
|
||||
width: 200 + 150 * profiles.length
|
||||
}).component();
|
||||
}
|
||||
|
||||
private createDescriptionColumn(header: string): azdata.TableColumn {
|
||||
return {
|
||||
value: header,
|
||||
width: 150
|
||||
};
|
||||
}
|
||||
|
||||
private createProfileColumns(profiles: BigDataClusterDeploymentProfile[]): azdata.TableColumn[] {
|
||||
return profiles.map(profile => {
|
||||
return {
|
||||
value: profile.profileName,
|
||||
width: 100
|
||||
};
|
||||
});
|
||||
}
|
||||
private createTableGroup(view: azdata.ModelView, title: string, table: azdata.TableComponent): azdata.FlexContainer {
|
||||
return view.modelBuilder.flexContainer()
|
||||
.withItems([createLabel(view, { text: title }), table], { CSSStyles: { 'margin-bottom': '5px' } })
|
||||
.withLayout({ flexFlow: 'column' })
|
||||
.component();
|
||||
}
|
||||
|
||||
public override async onEnter(): Promise<void> {
|
||||
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
|
||||
this.wizard.wizardObject.message = { text: '' };
|
||||
if (pcInfo.newPage > pcInfo.lastPage) {
|
||||
const isValid = this.wizard.model.getStringValue(VariableNames.DeploymentProfile_VariableName) !== undefined;
|
||||
if (!isValid) {
|
||||
this.wizard.wizardObject.message = {
|
||||
text: localize('deployCluster.ProfileNotSelectedError', "Please select a deployment profile."),
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public override async onLeave(): Promise<void> {
|
||||
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private getDefaultProfile(): string {
|
||||
switch (this._model.deploymentType) {
|
||||
case BdcDeploymentType.NewAKS:
|
||||
case BdcDeploymentType.ExistingAKS:
|
||||
return 'aks-dev-test';
|
||||
case BdcDeploymentType.ExistingKubeAdm:
|
||||
return 'kubeadm-dev-test';
|
||||
case BdcDeploymentType.ExistingARO:
|
||||
return 'aro-dev-test';
|
||||
case BdcDeploymentType.ExistingOpenShift:
|
||||
return 'openshift-dev-test';
|
||||
default:
|
||||
throw new Error(`Unknown deployment type: ${this._model.deploymentType}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,448 +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 azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { FieldType, SectionInfo } from '../../../interfaces';
|
||||
import { createFlexContainer, createGroupContainer, createLabel, createNumberInputBoxInputInfo, createSection, createInputBoxInputInfo, getCheckboxComponent, getDropdownComponent, getInputBoxComponent, InputComponentInfo, InputComponents, setModelValues, Validator, InputComponent } from '../../modelViewUtils';
|
||||
import { ResourceTypePage } from '../../resourceTypePage';
|
||||
import * as VariableNames from '../constants';
|
||||
import { AuthenticationMode, DeployClusterWizardModel } from '../deployClusterWizardModel';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
const NumberInputWidth = '100px';
|
||||
const inputWidth = '180px';
|
||||
const labelWidth = '200px';
|
||||
|
||||
export class ServiceSettingsPage extends ResourceTypePage {
|
||||
private inputComponents: InputComponents = {};
|
||||
private endpointHeaderRow!: azdata.FlexContainer;
|
||||
private dnsColumnHeader!: azdata.TextComponent;
|
||||
private portColumnHeader!: azdata.TextComponent;
|
||||
private controllerDNSInput!: azdata.InputBoxComponent;
|
||||
private controllerPortInput!: azdata.InputBoxComponent;
|
||||
private controllerEndpointRow!: azdata.FlexContainer;
|
||||
private sqlServerDNSInput!: azdata.InputBoxComponent;
|
||||
private sqlServerEndpointRow!: azdata.FlexContainer;
|
||||
private sqlServerPortInput!: azdata.InputBoxComponent;
|
||||
private gatewayDNSInput!: azdata.InputBoxComponent;
|
||||
private gatewayPortInput!: azdata.InputBoxComponent;
|
||||
private gatewayEndpointRow!: azdata.FlexContainer;
|
||||
private serviceProxyDNSInput!: azdata.InputBoxComponent;
|
||||
private serviceProxyPortInput!: azdata.InputBoxComponent;
|
||||
private serviceProxyEndpointRow!: azdata.FlexContainer;
|
||||
private appServiceProxyDNSInput!: azdata.InputBoxComponent;
|
||||
private appServiceProxyPortInput!: azdata.InputBoxComponent;
|
||||
private appServiceProxyEndpointRow!: azdata.FlexContainer;
|
||||
private readableSecondaryDNSInput!: azdata.InputBoxComponent;
|
||||
private readableSecondaryPortInput!: azdata.InputBoxComponent;
|
||||
private readableSecondaryEndpointRow!: azdata.FlexContainer;
|
||||
private endpointNameColumnHeader!: azdata.TextComponent;
|
||||
private controllerNameLabel!: azdata.TextComponent;
|
||||
private SqlServerNameLabel!: azdata.TextComponent;
|
||||
private gatewayNameLabel!: azdata.TextComponent;
|
||||
private serviceProxyNameLabel!: azdata.TextComponent;
|
||||
private appServiceProxyNameLabel!: azdata.TextComponent;
|
||||
private readableSecondaryNameLabel!: azdata.TextComponent;
|
||||
private endpointSection!: azdata.GroupContainer;
|
||||
|
||||
constructor(private _model: DeployClusterWizardModel) {
|
||||
super(localize('deployCluster.ServiceSettingsPageTitle', "Service settings"), '', _model.wizard);
|
||||
}
|
||||
public initialize(): void {
|
||||
const self = this;
|
||||
const scaleSectionInfo: SectionInfo = {
|
||||
title: localize('deployCluster.scaleSectionTitle', "Scale settings"),
|
||||
labelWidth: labelWidth,
|
||||
inputWidth: NumberInputWidth,
|
||||
spaceBetweenFields: '40px',
|
||||
rows: [{
|
||||
items: [{
|
||||
type: FieldType.Options,
|
||||
label: localize('deployCluster.MasterSqlServerInstances', "SQL Server master instances"),
|
||||
options: ['1', '3', '4', '5', '6', '7', '8', '9'],
|
||||
defaultValue: '1',
|
||||
variableName: VariableNames.SQLServerScale_VariableName,
|
||||
}, {
|
||||
type: FieldType.Number,
|
||||
label: localize('deployCluster.ComputePoolInstances', "Compute pool instances"),
|
||||
min: 1,
|
||||
max: 100,
|
||||
defaultValue: '1',
|
||||
required: true,
|
||||
variableName: VariableNames.ComputePoolScale_VariableName,
|
||||
}]
|
||||
}, {
|
||||
items: [{
|
||||
type: FieldType.Number,
|
||||
label: localize('deployCluster.DataPoolInstances', "Data pool instances"),
|
||||
min: 1,
|
||||
max: 100,
|
||||
defaultValue: '1',
|
||||
required: true,
|
||||
variableName: VariableNames.DataPoolScale_VariableName,
|
||||
}, {
|
||||
type: FieldType.Number,
|
||||
label: localize('deployCluster.SparkPoolInstances', "Spark pool instances"),
|
||||
min: 0,
|
||||
max: 100,
|
||||
defaultValue: '0',
|
||||
required: true,
|
||||
variableName: VariableNames.SparkPoolScale_VariableName
|
||||
}]
|
||||
}, {
|
||||
items: [
|
||||
{
|
||||
type: FieldType.Number,
|
||||
label: localize('deployCluster.StoragePoolInstances', "Storage pool (HDFS) instances"),
|
||||
min: 1,
|
||||
max: 100,
|
||||
defaultValue: '1',
|
||||
required: true,
|
||||
variableName: VariableNames.HDFSPoolScale_VariableName
|
||||
}, {
|
||||
type: FieldType.Checkbox,
|
||||
label: localize('deployCluster.IncludeSparkInStoragePool', "Include Spark in storage pool"),
|
||||
defaultValue: 'true',
|
||||
variableName: VariableNames.IncludeSpark_VariableName,
|
||||
required: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
this.pageObject.registerContent(async (view: azdata.ModelView) => {
|
||||
const createSectionFunc = async (sectionInfo: SectionInfo): Promise<azdata.GroupContainer> => {
|
||||
return await createSection({
|
||||
view: view,
|
||||
container: this.wizard.wizardObject,
|
||||
inputComponents: this._model.inputComponents,
|
||||
sectionInfo: sectionInfo,
|
||||
onNewDisposableCreated: (disposable: vscode.Disposable): void => {
|
||||
self.wizard.registerDisposable(disposable);
|
||||
},
|
||||
onNewInputComponentCreated: (name: string, inputComponentInfo: InputComponentInfo<InputComponent>): void => {
|
||||
self.onNewInputComponentCreated(name, inputComponentInfo);
|
||||
},
|
||||
onNewValidatorCreated: (validator: Validator): void => {
|
||||
},
|
||||
toolsService: this.wizard.toolsService
|
||||
});
|
||||
};
|
||||
const scaleSection = await createSectionFunc(scaleSectionInfo);
|
||||
this.endpointSection = this.createEndpointSection(view);
|
||||
const storageSection = this.createStorageSection(view);
|
||||
|
||||
this.handleSparkSettingEvents();
|
||||
const form = view.modelBuilder.formContainer().withFormItems([
|
||||
{
|
||||
title: '',
|
||||
component: scaleSection
|
||||
}, {
|
||||
title: '',
|
||||
component: this.endpointSection
|
||||
}, {
|
||||
title: '',
|
||||
component: storageSection
|
||||
}
|
||||
]).withLayout({ width: '100%' }).component();
|
||||
return view.initializeModel(form);
|
||||
});
|
||||
}
|
||||
|
||||
private onNewInputComponentCreated(name: string, inputComponentInfo: InputComponentInfo<InputComponent>) {
|
||||
this.inputComponents[name] = inputComponentInfo;
|
||||
this._model.inputComponents[name] = inputComponentInfo;
|
||||
}
|
||||
|
||||
private handleSparkSettingEvents(): void {
|
||||
const sparkInstanceInput = getInputBoxComponent(VariableNames.SparkPoolScale_VariableName, this.inputComponents);
|
||||
const includeSparkCheckbox = getCheckboxComponent(VariableNames.IncludeSpark_VariableName, this.inputComponents);
|
||||
this.wizard.registerDisposable(includeSparkCheckbox.onChanged(() => {
|
||||
if (!includeSparkCheckbox.checked && !(sparkInstanceInput.value && Number.parseInt(sparkInstanceInput.value) > 0)) {
|
||||
sparkInstanceInput.value = '1';
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private createEndpointSection(view: azdata.ModelView): azdata.GroupContainer {
|
||||
this.endpointNameColumnHeader = createLabel(view, { text: '', width: labelWidth });
|
||||
this.dnsColumnHeader = createLabel(view, { text: localize('deployCluster.DNSNameHeader', "DNS name"), width: inputWidth });
|
||||
this.portColumnHeader = createLabel(view, { text: localize('deployCluster.PortHeader', "Port"), width: NumberInputWidth });
|
||||
this.endpointHeaderRow = createFlexContainer(view, [this.endpointNameColumnHeader, this.dnsColumnHeader, this.portColumnHeader]);
|
||||
|
||||
this.controllerNameLabel = createLabel(view, { text: localize('deployCluster.ControllerText', "Controller"), width: labelWidth, required: true });
|
||||
const controllerDNSInput = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.ControllerDNSName', "Controller DNS name"), required: false, width: inputWidth });
|
||||
this.controllerDNSInput = controllerDNSInput.component;
|
||||
const controllerPortInput = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.ControllerPortName', "Controller port"), required: true, width: NumberInputWidth, min: 1 });
|
||||
this.controllerPortInput = controllerPortInput.component;
|
||||
this.controllerEndpointRow = createFlexContainer(view, [this.controllerNameLabel, this.controllerDNSInput, this.controllerPortInput]);
|
||||
this.onNewInputComponentCreated(VariableNames.ControllerDNSName_VariableName, controllerDNSInput);
|
||||
this.onNewInputComponentCreated(VariableNames.ControllerPort_VariableName, controllerPortInput);
|
||||
|
||||
this.SqlServerNameLabel = createLabel(view, { text: localize('deployCluster.MasterSqlText', "SQL Server Master"), width: labelWidth, required: true });
|
||||
const sqlServerDNSInput = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.MasterSQLServerDNSName', "SQL Server Master DNS name"), required: false, width: inputWidth });
|
||||
this.sqlServerDNSInput = sqlServerDNSInput.component;
|
||||
const sqlServerPortInput = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.MasterSQLServerPortName', "SQL Server Master port"), required: true, width: NumberInputWidth, min: 1 });
|
||||
this.sqlServerPortInput = sqlServerPortInput.component;
|
||||
this.sqlServerEndpointRow = createFlexContainer(view, [this.SqlServerNameLabel, this.sqlServerDNSInput, this.sqlServerPortInput]);
|
||||
this.onNewInputComponentCreated(VariableNames.SQLServerDNSName_VariableName, sqlServerDNSInput);
|
||||
this.onNewInputComponentCreated(VariableNames.SQLServerPort_VariableName, sqlServerPortInput);
|
||||
|
||||
this.gatewayNameLabel = createLabel(view, { text: localize('deployCluster.GatewayText', "Gateway"), width: labelWidth, required: true });
|
||||
const gatewayDNSInput = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.GatewayDNSName', "Gateway DNS name"), required: false, width: inputWidth });
|
||||
this.gatewayDNSInput = gatewayDNSInput.component;
|
||||
const gatewayPortInput = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.GatewayPortName', "Gateway port"), required: true, width: NumberInputWidth, min: 1 });
|
||||
this.gatewayPortInput = gatewayPortInput.component;
|
||||
this.gatewayEndpointRow = createFlexContainer(view, [this.gatewayNameLabel, this.gatewayDNSInput, this.gatewayPortInput]);
|
||||
this.onNewInputComponentCreated(VariableNames.GatewayDNSName_VariableName, gatewayDNSInput);
|
||||
this.onNewInputComponentCreated(VariableNames.GateWayPort_VariableName, gatewayPortInput);
|
||||
|
||||
this.serviceProxyNameLabel = createLabel(view, { text: localize('deployCluster.ServiceProxyText', "Management proxy"), width: labelWidth, required: true });
|
||||
const serviceProxyDNSInput = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.ServiceProxyDNSName', "Management proxy DNS name"), required: false, width: inputWidth });
|
||||
this.serviceProxyDNSInput = serviceProxyDNSInput.component;
|
||||
const serviceProxyPortInput = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.ServiceProxyPortName', "Management proxy port"), required: true, width: NumberInputWidth, min: 1 });
|
||||
this.serviceProxyPortInput = serviceProxyPortInput.component;
|
||||
this.serviceProxyEndpointRow = createFlexContainer(view, [this.serviceProxyNameLabel, this.serviceProxyDNSInput, this.serviceProxyPortInput]);
|
||||
this.onNewInputComponentCreated(VariableNames.ServiceProxyDNSName_VariableName, serviceProxyDNSInput);
|
||||
this.onNewInputComponentCreated(VariableNames.ServiceProxyPort_VariableName, serviceProxyPortInput);
|
||||
|
||||
this.appServiceProxyNameLabel = createLabel(view, { text: localize('deployCluster.AppServiceProxyText', "Application proxy"), width: labelWidth, required: true });
|
||||
const appServiceProxyDNSInput = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.AppServiceProxyDNSName', "Application proxy DNS name"), required: false, width: inputWidth });
|
||||
this.appServiceProxyDNSInput = appServiceProxyDNSInput.component;
|
||||
const appServiceProxyPortInput = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.AppServiceProxyPortName', "Application proxy port"), required: true, width: NumberInputWidth, min: 1 });
|
||||
this.appServiceProxyPortInput = appServiceProxyPortInput.component;
|
||||
this.appServiceProxyEndpointRow = createFlexContainer(view, [this.appServiceProxyNameLabel, this.appServiceProxyDNSInput, this.appServiceProxyPortInput]);
|
||||
this.onNewInputComponentCreated(VariableNames.AppServiceProxyDNSName_VariableName, appServiceProxyDNSInput);
|
||||
this.onNewInputComponentCreated(VariableNames.AppServiceProxyPort_VariableName, appServiceProxyPortInput);
|
||||
|
||||
this.readableSecondaryNameLabel = createLabel(view, { text: localize('deployCluster.ReadableSecondaryText', "Readable secondary"), width: labelWidth, required: true });
|
||||
const readableSecondaryDNSInput = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.ReadableSecondaryDNSName', "Readable secondary DNS name"), required: false, width: inputWidth });
|
||||
this.readableSecondaryDNSInput = readableSecondaryDNSInput.component;
|
||||
const readableSecondaryPortInput = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.ReadableSecondaryPortName', "Readable secondary port"), required: false, width: NumberInputWidth, min: 1 });
|
||||
this.readableSecondaryPortInput = readableSecondaryPortInput.component;
|
||||
this.readableSecondaryEndpointRow = createFlexContainer(view, [this.readableSecondaryNameLabel, this.readableSecondaryDNSInput, this.readableSecondaryPortInput]);
|
||||
this.onNewInputComponentCreated(VariableNames.ReadableSecondaryDNSName_VariableName, readableSecondaryDNSInput);
|
||||
this.onNewInputComponentCreated(VariableNames.ReadableSecondaryPort_VariableName, readableSecondaryPortInput);
|
||||
|
||||
return createGroupContainer(view, [this.endpointHeaderRow, this.controllerEndpointRow, this.sqlServerEndpointRow, this.gatewayEndpointRow, this.serviceProxyEndpointRow, this.appServiceProxyEndpointRow, this.readableSecondaryEndpointRow], {
|
||||
header: localize('deployCluster.EndpointSettings', "Endpoint settings"),
|
||||
collapsible: true
|
||||
});
|
||||
}
|
||||
|
||||
private createStorageSection(view: azdata.ModelView): azdata.GroupContainer {
|
||||
const hintTextForStorageFields = localize('deployCluster.storageFieldTooltip', "Use controller settings");
|
||||
const controllerLabel = createLabel(view,
|
||||
{
|
||||
text: localize('deployCluster.ControllerText', "Controller"),
|
||||
width: inputWidth,
|
||||
required: true,
|
||||
description: localize('deployCluster.AdvancedStorageDescription', "By default Controller storage settings will be applied to other services as well, you can expand the advanced storage settings to configure storage for other services.")
|
||||
});
|
||||
const controllerDataStorageClassInputInfo = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.controllerDataStorageClass', "Controller's data storage class"), width: inputWidth, required: true });
|
||||
const controllerDataStorageClaimSizeInputInfo = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.controllerDataStorageClaimSize', "Controller's data storage claim size (Gigabytes)"), width: inputWidth, required: true, min: 1 });
|
||||
const controllerLogsStorageClassInputInfo = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.controllerLogsStorageClass', "Controller's logs storage class"), width: inputWidth, required: true });
|
||||
const controllerLogsStorageClaimSizeInputInfo = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.controllerLogsStorageClaimSize', "Controller's logs storage claim size (Gigabytes)"), width: inputWidth, required: true, min: 1 });
|
||||
|
||||
const storagePoolLabel = createLabel(view,
|
||||
{
|
||||
text: localize('deployCluster.StoragePool', "Storage pool (HDFS)"),
|
||||
width: inputWidth,
|
||||
required: false
|
||||
});
|
||||
|
||||
const storagePoolDataStorageClassInputInfo = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.storagePoolDataStorageClass', "Storage pool's data storage class"), width: inputWidth, required: false, placeHolder: hintTextForStorageFields });
|
||||
const storagePoolDataStorageClaimSizeInputInfo = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.storagePoolDataStorageClaimSize', "Storage pool's data storage claim size (Gigabytes)"), width: inputWidth, required: false, min: 1, placeHolder: hintTextForStorageFields });
|
||||
const storagePoolLogsStorageClassInputInfo = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.storagePoolLogsStorageClass', "Storage pool's logs storage class"), width: inputWidth, required: false, placeHolder: hintTextForStorageFields });
|
||||
const storagePoolLogsStorageClaimSizeInputInfo = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.storagePoolLogsStorageClaimSize', "Storage pool's logs storage claim size (Gigabytes)"), width: inputWidth, required: false, min: 1, placeHolder: hintTextForStorageFields });
|
||||
|
||||
const dataPoolLabel = createLabel(view,
|
||||
{
|
||||
text: localize('deployCluster.DataPool', "Data pool"),
|
||||
width: inputWidth,
|
||||
required: false
|
||||
});
|
||||
const dataPoolDataStorageClassInputInfo = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.dataPoolDataStorageClass', "Data pool's data storage class"), width: inputWidth, required: false, placeHolder: hintTextForStorageFields });
|
||||
const dataPoolDataStorageClaimSizeInputInfo = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.dataPoolDataStorageClaimSize', "Data pool's data storage claim size (Gigabytes)"), width: inputWidth, required: false, min: 1, placeHolder: hintTextForStorageFields });
|
||||
const dataPoolLogsStorageClassInputInfo = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.dataPoolLogsStorageClass', "Data pool's logs storage class"), width: inputWidth, required: false, placeHolder: hintTextForStorageFields });
|
||||
const dataPoolLogsStorageClaimSizeInputInfo = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.dataPoolLogsStorageClaimSize', "Data pool's logs storage claim size (Gigabytes)"), width: inputWidth, required: false, min: 1, placeHolder: hintTextForStorageFields });
|
||||
|
||||
|
||||
const sqlServerMasterLabel = createLabel(view,
|
||||
{
|
||||
text: localize('deployCluster.MasterSqlText', "SQL Server Master"),
|
||||
width: inputWidth,
|
||||
required: false
|
||||
});
|
||||
|
||||
const sqlServerMasterDataStorageClassInputInfo = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.sqlServerMasterDataStorageClass', "SQL Server master's data storage class"), width: inputWidth, required: false, placeHolder: hintTextForStorageFields });
|
||||
const sqlServerMasterDataStorageClaimSizeInputInfo = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.sqlServerMasterDataStorageClaimSize', "SQL Server master's data storage claim size (Gigabytes)"), width: inputWidth, required: false, min: 1, placeHolder: hintTextForStorageFields });
|
||||
const sqlServerMasterLogsStorageClassInputInfo = createInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.sqlServerMasterLogsStorageClass', "SQL Server master's logs storage class"), width: inputWidth, required: false, placeHolder: hintTextForStorageFields });
|
||||
const sqlServerMasterLogsStorageClaimSizeInputInfo = createNumberInputBoxInputInfo(view, { ariaLabel: localize('deployCluster.sqlServerMasterLogsStorageClaimSize', "SQL Server master's logs storage claim size (Gigabytes)"), width: inputWidth, required: false, min: 1, placeHolder: hintTextForStorageFields });
|
||||
|
||||
this.onNewInputComponentCreated(VariableNames.ControllerDataStorageClassName_VariableName, controllerDataStorageClassInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.ControllerDataStorageSize_VariableName, controllerDataStorageClaimSizeInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.ControllerLogsStorageClassName_VariableName, controllerLogsStorageClassInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.ControllerLogsStorageSize_VariableName, controllerLogsStorageClaimSizeInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.HDFSDataStorageClassName_VariableName, storagePoolDataStorageClassInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.HDFSDataStorageSize_VariableName, storagePoolDataStorageClaimSizeInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.HDFSLogsStorageClassName_VariableName, storagePoolLogsStorageClassInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.HDFSLogsStorageSize_VariableName, storagePoolLogsStorageClaimSizeInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.DataPoolDataStorageClassName_VariableName, dataPoolDataStorageClassInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.DataPoolDataStorageSize_VariableName, dataPoolDataStorageClaimSizeInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.DataPoolLogsStorageClassName_VariableName, dataPoolLogsStorageClassInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.DataPoolLogsStorageSize_VariableName, dataPoolLogsStorageClaimSizeInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.SQLServerDataStorageClassName_VariableName, sqlServerMasterDataStorageClassInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.SQLServerDataStorageSize_VariableName, sqlServerMasterDataStorageClaimSizeInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.SQLServerLogsStorageClassName_VariableName, sqlServerMasterLogsStorageClassInputInfo);
|
||||
this.onNewInputComponentCreated(VariableNames.SQLServerLogsStorageSize_VariableName, sqlServerMasterLogsStorageClaimSizeInputInfo);
|
||||
|
||||
const storageSettingTable = view.modelBuilder.declarativeTable()
|
||||
.withProps(
|
||||
{
|
||||
columns: [
|
||||
this.createStorageSettingColumn(localize('deployCluster.ServiceName', "Service name"), false),
|
||||
this.createStorageSettingColumn(localize('deployCluster.DataStorageClassName', "Storage class for data")),
|
||||
this.createStorageSettingColumn(localize('deployCluster.DataClaimSize', "Claim size for data (GB)")),
|
||||
this.createStorageSettingColumn(localize('deployCluster.LogStorageClassName', "Storage class for logs")),
|
||||
this.createStorageSettingColumn(localize('deployCluster.LogsClaimSize', "Claim size for logs (GB)"))
|
||||
],
|
||||
dataValues: [
|
||||
[{ value: controllerLabel }, { value: controllerDataStorageClassInputInfo.component }, { value: controllerDataStorageClaimSizeInputInfo.component }, { value: controllerLogsStorageClassInputInfo.component }, { value: controllerLogsStorageClaimSizeInputInfo.component }],
|
||||
[{ value: storagePoolLabel }, { value: storagePoolDataStorageClassInputInfo.component }, { value: storagePoolDataStorageClaimSizeInputInfo.component }, { value: storagePoolLogsStorageClassInputInfo.component }, { value: storagePoolLogsStorageClaimSizeInputInfo.component }],
|
||||
[{ value: dataPoolLabel }, { value: dataPoolDataStorageClassInputInfo.component }, { value: dataPoolDataStorageClaimSizeInputInfo.component }, { value: dataPoolLogsStorageClassInputInfo.component }, { value: dataPoolLogsStorageClaimSizeInputInfo.component }],
|
||||
[{ value: sqlServerMasterLabel }, { value: sqlServerMasterDataStorageClassInputInfo.component }, { value: sqlServerMasterDataStorageClaimSizeInputInfo.component }, { value: sqlServerMasterLogsStorageClassInputInfo.component }, { value: sqlServerMasterLogsStorageClaimSizeInputInfo.component }]
|
||||
],
|
||||
ariaLabel: localize('deployCluster.StorageSettings', "Storage settings")
|
||||
})
|
||||
.component();
|
||||
return createGroupContainer(view, [storageSettingTable], {
|
||||
header: localize('deployCluster.StorageSectionTitle', "Storage settings"),
|
||||
collapsible: true,
|
||||
collapsed: false
|
||||
});
|
||||
}
|
||||
|
||||
private createStorageSettingColumn(title: string, showText: boolean = true): azdata.DeclarativeTableColumn {
|
||||
return {
|
||||
displayName: showText ? title : '',
|
||||
ariaLabel: title,
|
||||
valueType: azdata.DeclarativeDataType.component,
|
||||
isReadOnly: true,
|
||||
width: inputWidth,
|
||||
headerCssStyles: {
|
||||
'border': 'none',
|
||||
'font-weight': 'inherit'
|
||||
},
|
||||
rowCssStyles: {
|
||||
'border': 'none'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override async onEnter(): Promise<void> {
|
||||
this.setInputBoxValue(VariableNames.ComputePoolScale_VariableName);
|
||||
this.setInputBoxValue(VariableNames.DataPoolScale_VariableName);
|
||||
this.setInputBoxValue(VariableNames.HDFSPoolScale_VariableName);
|
||||
this.setInputBoxValue(VariableNames.SparkPoolScale_VariableName);
|
||||
this.setCheckboxValue(VariableNames.IncludeSpark_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ControllerPort_VariableName);
|
||||
this.setInputBoxValue(VariableNames.SQLServerPort_VariableName);
|
||||
this.setInputBoxValue(VariableNames.GateWayPort_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ServiceProxyPort_VariableName);
|
||||
this.setInputBoxValue(VariableNames.AppServiceProxyPort_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ReadableSecondaryPort_VariableName);
|
||||
this.setInputBoxValue(VariableNames.GatewayDNSName_VariableName);
|
||||
this.setInputBoxValue(VariableNames.AppServiceProxyDNSName_VariableName);
|
||||
this.setInputBoxValue(VariableNames.SQLServerDNSName_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ReadableSecondaryDNSName_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ServiceProxyDNSName_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ControllerDNSName_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ControllerDataStorageClassName_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ControllerDataStorageSize_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ControllerLogsStorageClassName_VariableName);
|
||||
this.setInputBoxValue(VariableNames.ControllerLogsStorageSize_VariableName);
|
||||
this.endpointHeaderRow.clearItems();
|
||||
const adAuth = this._model.authenticationMode === AuthenticationMode.ActiveDirectory;
|
||||
const sqlServerScale = this.wizard.model.getIntegerValue(VariableNames.SQLServerScale_VariableName);
|
||||
|
||||
this.endpointSection.collapsed = !adAuth;
|
||||
if (adAuth) {
|
||||
this.endpointHeaderRow.addItems([this.endpointNameColumnHeader, this.dnsColumnHeader, this.portColumnHeader]);
|
||||
} else {
|
||||
this.endpointHeaderRow.addItems([this.endpointNameColumnHeader, this.portColumnHeader]);
|
||||
}
|
||||
|
||||
getInputBoxComponent(VariableNames.ControllerDNSName_VariableName, this.inputComponents).required = adAuth;
|
||||
getInputBoxComponent(VariableNames.GatewayDNSName_VariableName, this.inputComponents).required = adAuth;
|
||||
getInputBoxComponent(VariableNames.AppServiceProxyDNSName_VariableName, this.inputComponents).required = adAuth;
|
||||
getInputBoxComponent(VariableNames.ServiceProxyDNSName_VariableName, this.inputComponents).required = adAuth;
|
||||
getInputBoxComponent(VariableNames.SQLServerDNSName_VariableName, this.inputComponents).required = adAuth;
|
||||
getInputBoxComponent(VariableNames.ReadableSecondaryDNSName_VariableName, this.inputComponents).required = adAuth && sqlServerScale > 1;
|
||||
getInputBoxComponent(VariableNames.ReadableSecondaryPort_VariableName, this.inputComponents).required = sqlServerScale > 1;
|
||||
this.loadEndpointRow(this.controllerEndpointRow, this.controllerNameLabel, this.controllerDNSInput, this.controllerPortInput);
|
||||
this.loadEndpointRow(this.gatewayEndpointRow, this.gatewayNameLabel, this.gatewayDNSInput, this.gatewayPortInput);
|
||||
this.loadEndpointRow(this.sqlServerEndpointRow, this.SqlServerNameLabel, this.sqlServerDNSInput, this.sqlServerPortInput);
|
||||
this.loadEndpointRow(this.appServiceProxyEndpointRow, this.appServiceProxyNameLabel, this.appServiceProxyDNSInput, this.appServiceProxyPortInput);
|
||||
this.loadEndpointRow(this.serviceProxyEndpointRow, this.serviceProxyNameLabel, this.serviceProxyDNSInput, this.serviceProxyPortInput);
|
||||
const sqlServerScaleDropdown = getDropdownComponent(VariableNames.SQLServerScale_VariableName, this.inputComponents);
|
||||
if (sqlServerScale > 1) {
|
||||
sqlServerScaleDropdown.values = ['3', '4', '5', '6', '7', '8', '9'];
|
||||
this.loadEndpointRow(this.readableSecondaryEndpointRow, this.readableSecondaryNameLabel, this.readableSecondaryDNSInput, this.readableSecondaryPortInput);
|
||||
} else {
|
||||
this.readableSecondaryEndpointRow.clearItems();
|
||||
sqlServerScaleDropdown.values = ['1'];
|
||||
}
|
||||
sqlServerScaleDropdown.value = sqlServerScale.toString();
|
||||
|
||||
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
|
||||
this.wizard.wizardObject.message = { text: '' };
|
||||
if (pcInfo.newPage > pcInfo.lastPage) {
|
||||
const sparkEnabled = Number.parseInt(getInputBoxComponent(VariableNames.SparkPoolScale_VariableName, this.inputComponents).value!) !== 0
|
||||
|| getCheckboxComponent(VariableNames.IncludeSpark_VariableName, this.inputComponents).checked!;
|
||||
|
||||
let errorMessage: string | undefined;
|
||||
if (!sparkEnabled) {
|
||||
errorMessage = localize('deployCluster.SparkMustBeIncluded', "Invalid Spark configuration, you must check the 'Include Spark' checkbox or set the 'Spark pool instances' to at least 1.");
|
||||
}
|
||||
if (errorMessage) {
|
||||
this.wizard.wizardObject.message = {
|
||||
text: errorMessage,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
}
|
||||
return sparkEnabled;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public override async onLeave(): Promise<void> {
|
||||
await setModelValues(this.inputComponents, this.wizard.model);
|
||||
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private setInputBoxValue(variableName: string): void {
|
||||
getInputBoxComponent(variableName, this.inputComponents).value = this.wizard.model.getStringValue(variableName);
|
||||
}
|
||||
|
||||
private setCheckboxValue(variableName: string): void {
|
||||
getCheckboxComponent(variableName, this.inputComponents).checked = this.wizard.model.getBooleanValue(variableName);
|
||||
}
|
||||
|
||||
private loadEndpointRow(row: azdata.FlexContainer, label: azdata.TextComponent, dnsInput: azdata.InputBoxComponent, portInput: azdata.InputBoxComponent): void {
|
||||
row.clearItems();
|
||||
const itemLayout: azdata.FlexItemLayout = { CSSStyles: { 'margin-right': '20px' } };
|
||||
row.addItem(label);
|
||||
if (this._model.authenticationMode === AuthenticationMode.ActiveDirectory) {
|
||||
row.addItem(dnsInput, itemLayout);
|
||||
}
|
||||
row.addItem(portInput);
|
||||
}
|
||||
}
|
||||
@@ -1,434 +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 azdata from 'azdata';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { SectionInfo, FieldType, LabelPosition, BdcDeploymentType, FontWeight } from '../../../interfaces';
|
||||
import { createSection, createGroupContainer, createFlexContainer, createLabel } from '../../modelViewUtils';
|
||||
import * as VariableNames from '../constants';
|
||||
import { AuthenticationMode, DeployClusterWizardModel } from '../deployClusterWizardModel';
|
||||
import * as localizedConstants from '../../../localizedConstants';
|
||||
import { ResourceTypePage } from '../../resourceTypePage';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class SummaryPage extends ResourceTypePage {
|
||||
private formItems: azdata.FormComponent[] = [];
|
||||
private form!: azdata.FormBuilder;
|
||||
private view!: azdata.ModelView;
|
||||
|
||||
constructor(private _model: DeployClusterWizardModel) {
|
||||
super(localize('deployCluster.summaryPageTitle', "Summary"), '', _model.wizard);
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
this.pageObject.registerContent((view: azdata.ModelView) => {
|
||||
this.view = view;
|
||||
this.form = view.modelBuilder.formContainer();
|
||||
return view.initializeModel(this.form!.withLayout({ width: '100%' }).component());
|
||||
});
|
||||
}
|
||||
|
||||
public override async onEnter(): Promise<void> {
|
||||
this._model.showCustomButtons();
|
||||
this.formItems.forEach(item => {
|
||||
this.form!.removeFormItem(item);
|
||||
});
|
||||
this.formItems = [];
|
||||
|
||||
const deploymentTargetSectionInfo: SectionInfo = {
|
||||
labelPosition: LabelPosition.Left,
|
||||
labelWidth: '150px',
|
||||
inputWidth: '200px',
|
||||
title: localize('deployCluster.DeploymentTarget', "Deployment target"),
|
||||
rows: [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.Kubeconfig', "Kube config"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.KubeConfigPath_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
},
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.ClusterContext', "Cluster context"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.ClusterContext_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const clusterSectionInfo: SectionInfo = {
|
||||
labelPosition: LabelPosition.Left,
|
||||
labelWidth: '150px',
|
||||
inputWidth: '200px',
|
||||
title: localize('deployCluster.ClusterSettings', "Cluster settings"),
|
||||
rows: [
|
||||
{
|
||||
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.DeploymentProfile', "Deployment profile"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.DeploymentProfile_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
},
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.ClusterName', "Cluster name"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.ClusterName_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
}, {
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.ControllerUsername', "Controller username"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.AdminUserName_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.AuthenticationMode', "Authentication mode"),
|
||||
defaultValue: this._model.authenticationMode === AuthenticationMode.ActiveDirectory ?
|
||||
localize('deployCluster.AuthenticationMode.ActiveDirectory', "Active Directory") :
|
||||
localize('deployCluster.AuthenticationMode.Basic', "Basic"),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
if (this._model.authenticationMode === AuthenticationMode.ActiveDirectory) {
|
||||
clusterSectionInfo.rows!.push({
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.OuDistinguishedName', "Organizational unit"),
|
||||
defaultValue: this._model.getStringValue(VariableNames.OrganizationalUnitDistinguishedName_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
},
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.DomainControllerFQDNs', "Domain controller FQDNs"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.DomainControllerFQDNs_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
});
|
||||
clusterSectionInfo.rows!.push({
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.DomainDNSIPAddresses', "Domain DNS IP addresses"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.DomainDNSIPAddresses_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
},
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.DomainDNSName', "Domain DNS name"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.DomainDNSName_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
});
|
||||
clusterSectionInfo.rows!.push({
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.ClusterAdmins', "Cluster admin group"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.ClusterAdmins_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
},
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.ClusterUsers', "Cluster users"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.ClusterUsers_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
});
|
||||
clusterSectionInfo.rows!.push({
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.AppOwners', "App owners"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.AppOwners_VariableName, ''),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
},
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.AppReaders', "App readers"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.AppReaders_VariableName, ''),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
});
|
||||
clusterSectionInfo.rows!.push({
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.Subdomain', "Subdomain"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.Subdomain_VariableName, ''),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
},
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.AccountPrefix', "Account prefix"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.AccountPrefix_VariableName, ''),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
});
|
||||
clusterSectionInfo.rows!.push({
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.DomainServiceAccountUserName', "Service account username"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.DomainServiceAccountUserName_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localizedConstants.realm,
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.Realm_VariableName, ''),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
const azureSectionInfo: SectionInfo = {
|
||||
labelPosition: LabelPosition.Left,
|
||||
labelWidth: '150px',
|
||||
inputWidth: '200px',
|
||||
title: localize('deployCluster.AzureSettings', "Azure settings"),
|
||||
rows: [{
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.SubscriptionId', "Subscription id"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.SubscriptionId_VariableName) || localize('deployCluster.DefaultSubscription', "Default Azure Subscription"),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.ResourceGroup', "Resource group"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.ResourceGroup_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}
|
||||
]
|
||||
}, {
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.Location', "Location"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.Location_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.AksClusterName', "AKS cluster name"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.AksName_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}
|
||||
]
|
||||
}, {
|
||||
items: [
|
||||
{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.VMSize', "VM size"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.VMSize_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.VMCount', "VM count"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.VMCount_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const scaleSectionInfo: SectionInfo = {
|
||||
labelPosition: LabelPosition.Left,
|
||||
labelWidth: '150px',
|
||||
inputWidth: '200px',
|
||||
title: localize('deployCluster.ScaleSettings', "Scale settings"),
|
||||
rows: [
|
||||
{
|
||||
items: [{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.MasterSqlServerInstances', "SQL Server master instances"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.SQLServerScale_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.ComputePoolInstances', "Compute pool instances"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.ComputePoolScale_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
}, {
|
||||
items: [{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.DataPoolInstances', "Data pool instances"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.DataPoolScale_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}, {
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.SparkPoolInstances', "Spark pool instances"),
|
||||
defaultValue: this.wizard.model.getStringValue(VariableNames.SparkPoolScale_VariableName),
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
}, {
|
||||
items: [{
|
||||
type: FieldType.ReadonlyText,
|
||||
label: localize('deployCluster.StoragePoolInstances', "Storage pool (HDFS) instances"),
|
||||
defaultValue: `${this.wizard.model.getStringValue(VariableNames.HDFSPoolScale_VariableName)} ${this.wizard.model.getBooleanValue(VariableNames.IncludeSpark_VariableName) ? localize('deployCluster.WithSpark', "(Spark included)") : ''}`,
|
||||
labelCSSStyles: { fontWeight: FontWeight.Bold }
|
||||
}]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const createSectionFunc = async (sectionInfo: SectionInfo): Promise<azdata.FormComponent> => {
|
||||
return {
|
||||
title: '',
|
||||
component: await createSection({
|
||||
container: this.wizard.wizardObject,
|
||||
inputComponents: this._model.inputComponents,
|
||||
sectionInfo: sectionInfo,
|
||||
view: this.view,
|
||||
onNewDisposableCreated: () => { },
|
||||
onNewInputComponentCreated: () => { },
|
||||
onNewValidatorCreated: () => { },
|
||||
toolsService: this.wizard.toolsService
|
||||
})
|
||||
};
|
||||
};
|
||||
|
||||
if (this._model.deploymentType === BdcDeploymentType.ExistingAKS || this._model.deploymentType === BdcDeploymentType.ExistingKubeAdm) {
|
||||
const deploymentTargetSection = await createSectionFunc(deploymentTargetSectionInfo);
|
||||
this.formItems.push(deploymentTargetSection);
|
||||
}
|
||||
|
||||
const clusterSection = await createSectionFunc(clusterSectionInfo);
|
||||
const scaleSection = await createSectionFunc(scaleSectionInfo);
|
||||
const endpointSection = {
|
||||
title: '',
|
||||
component: this.createEndpointSection()
|
||||
};
|
||||
const storageSection = {
|
||||
title: '',
|
||||
component: this.createStorageSection()
|
||||
};
|
||||
if (this.wizard.model.getStringValue(VariableNames.AksName_VariableName)) {
|
||||
const azureSection = await createSectionFunc(azureSectionInfo);
|
||||
this.formItems.push(azureSection);
|
||||
}
|
||||
|
||||
this.formItems.push(clusterSection, scaleSection, endpointSection, storageSection);
|
||||
this.form.addFormItems(this.formItems);
|
||||
}
|
||||
|
||||
public override async onLeave(): Promise<void> {
|
||||
this._model.hideCustomButtons();
|
||||
this.wizard.wizardObject.message = { text: '' };
|
||||
}
|
||||
|
||||
private getStorageSettingValue(propertyName: string, defaultValuePropertyName: string): string | undefined {
|
||||
const value = this.wizard.model.getStringValue(propertyName);
|
||||
return (value === undefined || value === '') ? this.wizard.model.getStringValue(defaultValuePropertyName) : value;
|
||||
}
|
||||
|
||||
private createStorageSection(): azdata.GroupContainer {
|
||||
const serviceNameColumn: azdata.TableColumn = {
|
||||
value: localize('deployCluster.ServiceName', "Service"),
|
||||
width: 150
|
||||
};
|
||||
const dataStorageClassColumn: azdata.TableColumn = {
|
||||
value: localize('deployCluster.DataStorageClassName', "Storage class for data"),
|
||||
width: 180
|
||||
};
|
||||
const dataStorageSizeColumn: azdata.TableColumn = {
|
||||
value: localize('deployCluster.DataClaimSize', "Claim size for data (GB)"),
|
||||
width: 180
|
||||
};
|
||||
const logStorageClassColumn: azdata.TableColumn = {
|
||||
value: localize('deployCluster.LogStorageClassName', "Storage class for logs"),
|
||||
width: 180
|
||||
};
|
||||
const logStorageSizeColumn: azdata.TableColumn = {
|
||||
value: localize('deployCluster.LogsClaimSize', "Claim size for logs (GB)"),
|
||||
width: 180
|
||||
};
|
||||
|
||||
const storageTableTitle = localize('deployCluster.StorageSettings', "Storage settings");
|
||||
const storageTable = this.view.modelBuilder.table().withProps({
|
||||
title: storageTableTitle,
|
||||
ariaLabel: storageTableTitle,
|
||||
data: [
|
||||
[
|
||||
localize('deployCluster.ControllerText', "Controller"),
|
||||
this.wizard.model.getStringValue(VariableNames.ControllerDataStorageClassName_VariableName),
|
||||
this.wizard.model.getStringValue(VariableNames.ControllerDataStorageSize_VariableName),
|
||||
this.wizard.model.getStringValue(VariableNames.ControllerLogsStorageClassName_VariableName),
|
||||
this.wizard.model.getStringValue(VariableNames.ControllerLogsStorageSize_VariableName)],
|
||||
[
|
||||
localize('deployCluster.StoragePool', "Storage pool (HDFS)"),
|
||||
this.getStorageSettingValue(VariableNames.HDFSDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.HDFSDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.HDFSLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.HDFSLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName)
|
||||
], [
|
||||
localize('deployCluster.DataText', "Data"),
|
||||
this.getStorageSettingValue(VariableNames.DataPoolDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.DataPoolDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.DataPoolLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.DataPoolLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName)
|
||||
], [
|
||||
localize('deployCluster.MasterSqlText', "SQL Server Master"),
|
||||
this.getStorageSettingValue(VariableNames.SQLServerDataStorageClassName_VariableName, VariableNames.ControllerDataStorageClassName_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.SQLServerDataStorageSize_VariableName, VariableNames.ControllerDataStorageSize_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.SQLServerLogsStorageClassName_VariableName, VariableNames.ControllerLogsStorageClassName_VariableName),
|
||||
this.getStorageSettingValue(VariableNames.SQLServerLogsStorageSize_VariableName, VariableNames.ControllerLogsStorageSize_VariableName)
|
||||
]
|
||||
],
|
||||
columns: [serviceNameColumn, dataStorageClassColumn, dataStorageSizeColumn, logStorageClassColumn, logStorageSizeColumn],
|
||||
width: '1000px',
|
||||
height: '140px'
|
||||
}).component();
|
||||
return createGroupContainer(this.view, [storageTable], {
|
||||
header: localize('deployCluster.StorageSettings', "Storage settings"),
|
||||
collapsible: true
|
||||
});
|
||||
}
|
||||
|
||||
private createEndpointSection(): azdata.GroupContainer {
|
||||
const endpointRows = [
|
||||
this.createEndpointRow(localize('deployCluster.ControllerText', "Controller"), VariableNames.ControllerDNSName_VariableName, VariableNames.ControllerPort_VariableName),
|
||||
this.createEndpointRow(localize('deployCluster.SqlServerText', "SQL Server Master"), VariableNames.SQLServerDNSName_VariableName, VariableNames.SQLServerPort_VariableName),
|
||||
this.createEndpointRow(localize('deployCluster.GatewayText', "Gateway"), VariableNames.GatewayDNSName_VariableName, VariableNames.GateWayPort_VariableName),
|
||||
this.createEndpointRow(localize('deployCluster.AppServiceProxyText', "Application proxy"), VariableNames.AppServiceProxyDNSName_VariableName, VariableNames.AppServiceProxyPort_VariableName),
|
||||
this.createEndpointRow(localize('deployCluster.ServiceProxyText', "Management proxy"), VariableNames.ServiceProxyDNSName_VariableName, VariableNames.ServiceProxyPort_VariableName)
|
||||
];
|
||||
|
||||
if (this.wizard.model.getIntegerValue(VariableNames.SQLServerScale_VariableName) > 1) {
|
||||
endpointRows.push(
|
||||
this.createEndpointRow(localize('deployCluster.ReadableSecondaryText', "Readable secondary"), VariableNames.ReadableSecondaryDNSName_VariableName, VariableNames.ReadableSecondaryPort_VariableName)
|
||||
);
|
||||
}
|
||||
return createGroupContainer(this.view, endpointRows, {
|
||||
header: localize('deployCluster.EndpointSettings', "Endpoint settings"),
|
||||
collapsible: true
|
||||
});
|
||||
}
|
||||
|
||||
private createEndpointRow(name: string, dnsVariableName: string, portVariableName: string): azdata.FlexContainer {
|
||||
const items = [];
|
||||
items.push(createLabel(this.view, { text: name, width: '150px', cssStyles: { fontWeight: FontWeight.Bold } }));
|
||||
if (this._model.authenticationMode === AuthenticationMode.ActiveDirectory) {
|
||||
items.push(createLabel(this.view, {
|
||||
text: this.wizard.model.getStringValue(dnsVariableName)!, width: '200px'
|
||||
}));
|
||||
}
|
||||
items.push(createLabel(this.view, {
|
||||
text: this.wizard.model.getStringValue(portVariableName)!, width: '100px'
|
||||
}));
|
||||
return createFlexContainer(this.view, items);
|
||||
}
|
||||
}
|
||||
@@ -1,176 +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 azdata from 'azdata';
|
||||
import * as os from 'os';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { KubeClusterContext } from '../../../services/kubeService';
|
||||
import { ResourceTypePage } from '../../resourceTypePage';
|
||||
import { ClusterContext_VariableName, KubeConfigPath_VariableName } from '../constants';
|
||||
import { DeployClusterWizardModel } from '../deployClusterWizardModel';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
const ClusterRadioButtonGroupName = 'ClusterRadioGroup';
|
||||
|
||||
export class TargetClusterContextPage extends ResourceTypePage {
|
||||
private existingClusterControl: azdata.FlexContainer | undefined;
|
||||
private clusterContextsLabel: azdata.TextComponent | undefined;
|
||||
private errorLoadingClustersLabel: azdata.TextComponent | undefined;
|
||||
private clusterContextList: azdata.DivContainer | undefined;
|
||||
private clusterContextLoadingComponent: azdata.LoadingComponent | undefined;
|
||||
private configFileInput: azdata.InputBoxComponent | undefined;
|
||||
private browseFileButton: azdata.ButtonComponent | undefined;
|
||||
private loadDefaultKubeConfigFile: boolean = true;
|
||||
private view: azdata.ModelView | undefined;
|
||||
|
||||
constructor(private _model: DeployClusterWizardModel) {
|
||||
super(localize('deployCluster.TargetClusterContextPageTitle', "Target cluster context"),
|
||||
localize('deployCluster.TargetClusterContextPageDescription', "Select the kube config file and then select a cluster context from the list"), _model.wizard);
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
this.pageObject.registerContent((view: azdata.ModelView) => {
|
||||
this.view = view;
|
||||
this.initExistingClusterControl();
|
||||
let formBuilder = view.modelBuilder.formContainer().withFormItems(
|
||||
[
|
||||
{
|
||||
component: this.existingClusterControl!,
|
||||
title: ''
|
||||
}
|
||||
],
|
||||
{
|
||||
horizontal: false
|
||||
}
|
||||
).withLayout({ width: '100%', height: '100%' });
|
||||
const form = formBuilder.withLayout({ width: '100%' }).component();
|
||||
return view.initializeModel(form);
|
||||
});
|
||||
}
|
||||
|
||||
public override async onEnter(): Promise<void> {
|
||||
if (this.loadDefaultKubeConfigFile) {
|
||||
let defaultKubeConfigPath = this._model.kubeService.getDefaultConfigPath();
|
||||
this.loadClusterContexts(defaultKubeConfigPath);
|
||||
this.loadDefaultKubeConfigFile = false;
|
||||
}
|
||||
|
||||
this.wizard.wizardObject.registerNavigationValidator((e) => {
|
||||
if (e.lastPage > e.newPage) {
|
||||
this.wizard.wizardObject.message = { text: '' };
|
||||
return true;
|
||||
}
|
||||
let clusterSelected = this.wizard.model.getStringValue(ClusterContext_VariableName) !== undefined;
|
||||
if (!clusterSelected) {
|
||||
this.wizard.wizardObject.message = {
|
||||
text: localize('deployCluster.ClusterContextNotSelectedMessage', "Please select a cluster context."),
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
}
|
||||
return clusterSelected;
|
||||
});
|
||||
}
|
||||
|
||||
public override async onLeave(): Promise<void> {
|
||||
this.wizard.wizardObject.registerNavigationValidator((e) => {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private initExistingClusterControl(): void {
|
||||
let self = this;
|
||||
const labelWidth = '150px';
|
||||
let configFileLabel = this.view!.modelBuilder.text().withProps({ value: localize('deployCluster.kubeConfigFileLabelText', "Kube config file path") }).component();
|
||||
configFileLabel.width = labelWidth;
|
||||
this.configFileInput = this.view!.modelBuilder.inputBox().withProps({ width: '300px' }).component();
|
||||
this.configFileInput.enabled = false;
|
||||
this.browseFileButton = this.view!.modelBuilder.button().withProps({ label: localize('deployCluster.browseText', "Browse"), width: '100px', secondary: true }).component();
|
||||
let configFileContainer = this.view!.modelBuilder.flexContainer()
|
||||
.withLayout({ flexFlow: 'row', alignItems: 'baseline' })
|
||||
.withItems([configFileLabel, this.configFileInput, this.browseFileButton], { CSSStyles: { 'margin-right': '10px' } }).component();
|
||||
this.clusterContextsLabel = this.view!.modelBuilder.text().withProps({ value: localize('deployCluster.clusterContextsLabelText', "Cluster Contexts") }).component();
|
||||
this.clusterContextsLabel.width = labelWidth;
|
||||
this.errorLoadingClustersLabel = this.view!.modelBuilder.text().withProps({ value: localize('deployCluster.errorLoadingClustersText', "No cluster information is found in the config file or an error ocurred while loading the config file") }).component();
|
||||
this.clusterContextList = this.view!.modelBuilder.divContainer().component();
|
||||
this.clusterContextLoadingComponent = this.view!.modelBuilder.loadingComponent().withItem(this.clusterContextList).component();
|
||||
this.existingClusterControl = this.view!.modelBuilder.divContainer().withProps({ clickable: false }).component();
|
||||
let clusterContextContainer = this.view!.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', alignItems: 'start' }).component();
|
||||
clusterContextContainer.addItem(this.clusterContextsLabel, { flex: '0 0 auto' });
|
||||
clusterContextContainer.addItem(this.clusterContextLoadingComponent, { flex: '0 0 auto', CSSStyles: { 'width': '400px', 'margin-left': '10px', 'margin-top': '10px' } });
|
||||
|
||||
this.existingClusterControl.addItem(configFileContainer, { CSSStyles: { 'margin-top': '0px' } });
|
||||
this.existingClusterControl.addItem(clusterContextContainer, {
|
||||
CSSStyles: { 'margin- top': '10px' }
|
||||
});
|
||||
|
||||
this.wizard.registerDisposable(this.browseFileButton.onDidClick(async () => {
|
||||
let fileUris = await vscode.window.showOpenDialog(
|
||||
{
|
||||
canSelectFiles: true,
|
||||
canSelectFolders: false,
|
||||
canSelectMany: false,
|
||||
defaultUri: vscode.Uri.file(os.homedir()),
|
||||
openLabel: localize('deployCluster.selectKubeConfigFileText', "Select"),
|
||||
filters: {
|
||||
'Config Files': ['*'],
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (!fileUris || fileUris.length === 0) {
|
||||
return;
|
||||
}
|
||||
self.clusterContextList!.clearItems();
|
||||
|
||||
let fileUri = fileUris[0];
|
||||
|
||||
self.loadClusterContexts(fileUri.fsPath);
|
||||
}));
|
||||
}
|
||||
|
||||
private async loadClusterContexts(configPath: string): Promise<void> {
|
||||
this.clusterContextLoadingComponent!.loading = true;
|
||||
this.wizard.model.setPropertyValue(ClusterContext_VariableName, undefined);
|
||||
this.wizard.wizardObject.message = { text: '' };
|
||||
let self = this;
|
||||
this.configFileInput!.value = configPath;
|
||||
|
||||
let clusterContexts: KubeClusterContext[] = [];
|
||||
try {
|
||||
clusterContexts = await this._model.kubeService.getClusterContexts(configPath);
|
||||
} catch (error) {
|
||||
this.wizard.wizardObject.message = {
|
||||
text: localize('deployCluster.ConfigParseError', "Failed to load the config file"),
|
||||
description: error.message || error, level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
}
|
||||
if (clusterContexts.length !== 0) {
|
||||
self.wizard.model.setPropertyValue(KubeConfigPath_VariableName, configPath);
|
||||
let options = clusterContexts.map(clusterContext => {
|
||||
let option = this.view!.modelBuilder.radioButton().withProps({
|
||||
label: clusterContext.name,
|
||||
checked: clusterContext.isCurrentContext,
|
||||
name: ClusterRadioButtonGroupName
|
||||
}).component();
|
||||
|
||||
if (clusterContext.isCurrentContext) {
|
||||
self.wizard.model.setPropertyValue(ClusterContext_VariableName, clusterContext.name);
|
||||
self.wizard.wizardObject.message = { text: '' };
|
||||
}
|
||||
|
||||
this.wizard.registerDisposable(option.onDidClick(() => {
|
||||
self.wizard.model.setPropertyValue(ClusterContext_VariableName, clusterContext.name);
|
||||
self.wizard.wizardObject.message = { text: '' };
|
||||
}));
|
||||
return option;
|
||||
});
|
||||
self.clusterContextList!.addItems(options);
|
||||
} else {
|
||||
self.clusterContextList!.addItem(this.errorLoadingClustersLabel!);
|
||||
}
|
||||
this.clusterContextLoadingComponent!.loading = false;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import { IToolsService } from '../../services/toolsService';
|
||||
import { InputComponents, setModelValues } from '../modelViewUtils';
|
||||
import { ResourceTypeModel } from '../resourceTypeModel';
|
||||
import { ResourceTypeWizard } from '../resourceTypeWizard';
|
||||
import { DeploymentType, NotebookWizardDeploymentProvider, NotebookWizardInfo } from '../../interfaces';
|
||||
import { NotebookWizardDeploymentProvider, NotebookWizardInfo } from '../../interfaces';
|
||||
import { IPlatformService } from '../../services/platformService';
|
||||
import { NotebookWizardAutoSummaryPage } from './notebookWizardAutoSummaryPage';
|
||||
import { NotebookWizardPage } from './notebookWizardPage';
|
||||
@@ -47,10 +47,6 @@ export class NotebookWizardModel extends ResourceTypeModel {
|
||||
this.wizard.wizardObject.generateScriptButton.label = this.notebookProvider.notebookWizard.scriptAction?.label || loc.scriptToNotebook;
|
||||
}
|
||||
|
||||
public get deploymentType(): DeploymentType | undefined {
|
||||
return this.notebookProvider.notebookWizard.type;
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
this.wizard.setPages(this.getPages());
|
||||
}
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { DeploymentProvider, InitialVariableValues, instanceOfAzureSQLDBDeploymentProvider, instanceOfAzureSQLVMDeploymentProvider, instanceOfNotebookWizardDeploymentProvider, instanceOfWizardDeploymentProvider, ResourceType, ResourceTypeOptionValue } from '../interfaces';
|
||||
import { DeployClusterWizardModel } from './deployClusterWizard/deployClusterWizardModel';
|
||||
import { DeploymentProvider, InitialVariableValues, instanceOfAzureSQLDBDeploymentProvider, instanceOfAzureSQLVMDeploymentProvider, instanceOfNotebookWizardDeploymentProvider, ResourceType, ResourceTypeOptionValue } from '../interfaces';
|
||||
import { DeployAzureSQLVMWizardModel } from './deployAzureSQLVMWizard/deployAzureSQLVMWizardModel';
|
||||
import { WizardPageInfo } from './wizardPageInfo';
|
||||
import { IKubeService } from '../services/kubeService';
|
||||
import { IAzdataService } from '../services/azdataService';
|
||||
import { INotebookService } from '../services/notebookService';
|
||||
import { IToolsService } from '../services/toolsService';
|
||||
import { IPlatformService } from '../services/platformService';
|
||||
@@ -55,7 +53,6 @@ export class ResourceTypeWizard {
|
||||
constructor(
|
||||
public resourceType: ResourceType,
|
||||
public _kubeService: IKubeService,
|
||||
public azdataService: IAzdataService,
|
||||
public notebookService: INotebookService,
|
||||
public toolsService: IToolsService,
|
||||
public platformService: IPlatformService,
|
||||
@@ -124,9 +121,7 @@ export class ResourceTypeWizard {
|
||||
|
||||
|
||||
private getResourceProviderModel(): ResourceTypeModel {
|
||||
if (instanceOfWizardDeploymentProvider(this.provider)) {
|
||||
return new DeployClusterWizardModel(this.provider, this);
|
||||
} else if (instanceOfAzureSQLVMDeploymentProvider(this.provider)) {
|
||||
if (instanceOfAzureSQLVMDeploymentProvider(this.provider)) {
|
||||
return new DeployAzureSQLVMWizardModel(this.provider, this);
|
||||
} else if (instanceOfNotebookWizardDeploymentProvider(this.provider)) {
|
||||
return new NotebookWizardModel(this.provider, this);
|
||||
|
||||
Reference in New Issue
Block a user