deploy BDC wizard improvement for CU1 (#7756)

* unified admin user account (#7485)

* azdata changes

* spaces

* error message

* comments

* support AD authentication for bdc deployment (#7518)

* enable ad authentication

* remove export for internal interface

* add comments

* more changes after testing

* update notebooks

* escape slash

* more comments

* Update deploy-bdc-aks.ipynb

* Update deploy-bdc-existing-aks.ipynb

* Update deploy-bdc-existing-kubeadm.ipynb

* AD changes and review feedback (#7618)

* enable ad authentication

* remove export for internal interface

* add comments

* more changes after testing

* update notebooks

* escape slash

* more comments

* Update deploy-bdc-aks.ipynb

* Update deploy-bdc-existing-aks.ipynb

* Update deploy-bdc-existing-kubeadm.ipynb

* address comments from scenario review (#7546)

* support AD authentication for bdc deployment (#7518)

* enable ad authentication

* remove export for internal interface

* add comments

* more changes after testing

* update notebooks

* escape slash

* more comments

* Update deploy-bdc-aks.ipynb

* Update deploy-bdc-existing-aks.ipynb

* Update deploy-bdc-existing-kubeadm.ipynb

* scenario review feedbacks

* more fixes

* adjust the display order of resource types

* different way to implement left side buttons

* revert unwanted changes

* rename variable

* more fixes for the scenario review feedback (#7589)

* fix more issues

* add help links

* model view readonly text with links

* fix size string

* address comments

* update notebooks

* text update

* address the feedback of 2nd round of deploy BDC wizard review (#7646)

* 2nd review meeting comments

* fix the unit test failure

* recent changes in azdata

* notebook background execution with azdata (#7741)

* notebook background execution with azdata

* prompt to open notebook in case of failure

* fix path quote issue

* better temp file handling

* expose docker settings (#7751)

* add docker settings

* new icon for container image
This commit is contained in:
Alan Ren
2019-10-16 20:41:15 -07:00
committed by GitHub
parent 5d4da455bd
commit 2ab7a47353
40 changed files with 2019 additions and 730 deletions

View File

@@ -4,24 +4,18 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as nls from 'vscode-nls';
import * as vscode from 'vscode';
import { DeployClusterWizard } from '../deployClusterWizard';
import { SectionInfo, FieldType, LabelPosition, FontStyle, BdcDeploymentType } from '../../../interfaces';
import { SectionInfo, FieldType, LabelPosition, BdcDeploymentType, FontWeight } from '../../../interfaces';
import { createSection, createGroupContainer, createFlexContainer, createLabel } from '../../modelViewUtils';
import { WizardPageBase } from '../../wizardPageBase';
import * as VariableNames from '../constants';
import * as os from 'os';
import { join } from 'path';
import * as fs from 'fs';
import { AuthenticationMode } from '../deployClusterWizardModel';
import { BigDataClusterDeploymentProfile } from '../../../services/bigDataClusterDeploymentProfile';
const localize = nls.loadMessageBundle();
export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
private formItems: azdata.FormComponent[] = [];
private form!: azdata.FormBuilder;
private view!: azdata.ModelView;
private targetDeploymentProfile!: BigDataClusterDeploymentProfile;
constructor(wizard: DeployClusterWizard) {
super(localize('deployCluster.summaryPageTitle', "Summary"), '', wizard);
@@ -30,30 +24,20 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
public initialize(): void {
this.pageObject.registerContent((view: azdata.ModelView) => {
this.view = view;
const deploymentJsonSection = createGroupContainer(view, [
view.modelBuilder.flexContainer().withItems([
this.createSaveJsonButton(localize('deployCluster.SaveBdcJson', "Save bdc.json"), 'bdc.json', () => { return this.targetDeploymentProfile.getBdcJson(); }),
this.createSaveJsonButton(localize('deployCluster.SaveControlJson', "Save control.json"), 'control.json', () => { return this.targetDeploymentProfile.getControlJson(); })
], {
CSSStyles: { 'margin-right': '10px' }
}).withLayout({ flexFlow: 'row', alignItems: 'center' }).component()
], {
header: localize('deployCluster.DeploymentJSON', "Deployment JSON files"),
collapsible: true
});
this.form = view.modelBuilder.formContainer().withFormItems([
{
title: '',
component: deploymentJsonSection
}
]);
this.form = view.modelBuilder.formContainer();
return view.initializeModel(this.form!.withLayout({ width: '100%' }).component());
});
}
public onEnter() {
this.targetDeploymentProfile = this.wizard.model.createTargetProfile();
if (this.wizard.model.deploymentTarget === BdcDeploymentType.NewAKS) {
this.wizard.wizardObject.message = {
level: azdata.window.MessageLevel.Information,
text: localize('resourceDeployment.NewAKSBrowserWindowPrompt', "A browser window for logging to Azure will be opened during the SQL Server Big Data Cluster deployment.")
};
}
this.wizard.saveConfigButton.hidden = false;
this.wizard.scriptToNotebookButton.hidden = false;
this.formItems.forEach(item => {
this.form!.removeFormItem(item);
});
@@ -71,13 +55,13 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
type: FieldType.ReadonlyText,
label: localize('deployCluster.Kubeconfig', "Kube config"),
defaultValue: this.wizard.model.getStringValue(VariableNames.KubeConfigPath_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
},
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.ClusterContext', "Cluster context"),
defaultValue: this.wizard.model.getStringValue(VariableNames.ClusterContext_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}]
}
]
@@ -96,13 +80,13 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
type: FieldType.ReadonlyText,
label: localize('deployCluster.DeploymentProfile', "Deployment profile"),
defaultValue: this.wizard.model.getStringValue(VariableNames.DeploymentProfile_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
},
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.ClusterName', "Cluster name"),
defaultValue: this.wizard.model.getStringValue(VariableNames.ClusterName_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}]
}, {
fields: [
@@ -110,20 +94,92 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
type: FieldType.ReadonlyText,
label: localize('deployCluster.ControllerUsername', "Controller username"),
defaultValue: this.wizard.model.getStringValue(VariableNames.AdminUserName_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.AuthenticationMode', "Authentication mode"),
defaultValue: this.wizard.model.authenticationMode === AuthenticationMode.ActiveDirectory ?
localize('deployCluster.AuthenticationMode.ActiveDirectory', "Active Directory") :
localize('deployCluster.AuthenticationMode.Basic', "Basic"),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}
]
}
]
};
if (this.wizard.model.authenticationMode === AuthenticationMode.ActiveDirectory) {
clusterSectionInfo.rows!.push({
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.OuDistinguishedName', "Organizational unit"),
defaultValue: this.wizard.model.getStringValue(VariableNames.OrganizationalUnitDistinguishedName_VariableName),
labelFontWeight: FontWeight.Bold
},
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.DomainControllerFQDNs', "Domain controller FQDNs"),
defaultValue: this.wizard.model.getStringValue(VariableNames.DomainControllerFQDNs_VariableName),
labelFontWeight: FontWeight.Bold
}]
});
clusterSectionInfo.rows!.push({
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.DomainDNSIPAddresses', "Domain DNS IP addresses"),
defaultValue: this.wizard.model.getStringValue(VariableNames.DomainDNSIPAddresses_VariableName),
labelFontWeight: FontWeight.Bold
},
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.DomainDNSName', "Domain DNS name"),
defaultValue: this.wizard.model.getStringValue(VariableNames.DomainDNSName_VariableName),
labelFontWeight: FontWeight.Bold
}]
});
clusterSectionInfo.rows!.push({
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.ClusterAdmins', "Cluster admin group"),
defaultValue: this.wizard.model.getStringValue(VariableNames.ClusterAdmins_VariableName),
labelFontWeight: FontWeight.Bold
},
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.ClusterUsers', "Cluster users"),
defaultValue: this.wizard.model.getStringValue(VariableNames.ClusterUsers_VariableName),
labelFontWeight: FontWeight.Bold
}]
});
clusterSectionInfo.rows!.push({
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.AppOwers', "App owners"),
defaultValue: this.wizard.model.getStringValue(VariableNames.AppOwners_VariableName),
labelFontWeight: FontWeight.Bold
},
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.AppReaders', "App readers"),
defaultValue: this.wizard.model.getStringValue(VariableNames.AppReaders_VariableName),
labelFontWeight: FontWeight.Bold
}]
});
clusterSectionInfo.rows!.push({
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.DomainServiceAccountUserName', "Service account username"),
defaultValue: this.wizard.model.getStringValue(VariableNames.DomainServiceAccountUserName_VariableName),
labelFontWeight: FontWeight.Bold
}]
});
}
const azureSectionInfo: SectionInfo = {
labelPosition: LabelPosition.Left,
labelWidth: '150px',
@@ -135,26 +191,26 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
type: FieldType.ReadonlyText,
label: localize('deployCluster.SubscriptionId', "Subscription id"),
defaultValue: this.wizard.model.getStringValue(VariableNames.SubscriptionId_VariableName) || localize('deployCluster.DefaultSubscription', "Default Azure Subscription"),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.ResourceGroup', "Resource group"),
defaultValue: this.wizard.model.getStringValue(VariableNames.ResourceGroup_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}
]
}, {
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.Region', "Region"),
defaultValue: this.wizard.model.getStringValue(VariableNames.Region_VariableName),
fontStyle: FontStyle.Italic
label: localize('deployCluster.Location', "Location"),
defaultValue: this.wizard.model.getStringValue(VariableNames.Location_VariableName),
labelFontWeight: FontWeight.Bold
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.AksClusterName', "AKS cluster name"),
defaultValue: this.wizard.model.getStringValue(VariableNames.AksName_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}
]
}, {
@@ -163,12 +219,12 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
type: FieldType.ReadonlyText,
label: localize('deployCluster.VMSize', "VM size"),
defaultValue: this.wizard.model.getStringValue(VariableNames.VMSize_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.VMCount', "VM count"),
defaultValue: this.wizard.model.getStringValue(VariableNames.VMCount_VariableName),
fontStyle: FontStyle.Italic
labelFontWeight: FontWeight.Bold
}
]
}
@@ -184,68 +240,34 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
{
fields: [{
type: FieldType.ReadonlyText,
label: localize('deployCluster.ComputeText', "Compute"),
defaultValue: this.wizard.model.getStringValue(VariableNames.ComputePoolScale_VariableName),
fontStyle: FontStyle.Italic
label: localize('deployCluster.MasterSqlServerInstances', "SQL Server master instances"),
defaultValue: this.wizard.model.getStringValue(VariableNames.SQLServerScale_VariableName),
labelFontWeight: FontWeight.Bold
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.DataText', "Data"),
label: localize('deployCluster.ComputePoolInstances', "Compute pool instances"),
defaultValue: this.wizard.model.getStringValue(VariableNames.ComputePoolScale_VariableName),
labelFontWeight: FontWeight.Bold
}]
}, {
fields: [{
type: FieldType.ReadonlyText,
label: localize('deployCluster.DataPoolInstances', "Data pool instances"),
defaultValue: this.wizard.model.getStringValue(VariableNames.DataPoolScale_VariableName),
fontStyle: FontStyle.Italic
}
]
labelFontWeight: FontWeight.Bold
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.SparkPoolInstances', "Spark pool instances"),
defaultValue: this.wizard.model.getStringValue(VariableNames.SparkPoolScale_VariableName),
labelFontWeight: FontWeight.Bold
}]
}, {
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.HDFSText', "HDFS"),
defaultValue: `${this.wizard.model.getStringValue(VariableNames.HDFSPoolScale_VariableName)} ${this.wizard.model.getBooleanValue(VariableNames.IncludeSpark_VariableName) ? localize('deployCluster.WithSpark', "(Spark included)") : ''}`,
fontStyle: FontStyle.Italic
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.SparkText', "Spark"),
defaultValue: this.wizard.model.getStringValue(VariableNames.SparkPoolScale_VariableName),
fontStyle: FontStyle.Italic
}
]
}
]
};
const hadrSectionInfo: SectionInfo = {
labelPosition: LabelPosition.Left,
labelWidth: '150px',
inputWidth: '200px',
title: localize('deployCluster.HadrSection', "High availability settings"),
rows: [
{
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.SqlServerText', "SQL Server Master"),
defaultValue: `${this.wizard.model.getStringValue(VariableNames.SQLServerScale_VariableName)} ${this.wizard.model.hadrEnabled ? localize('deployCluster.WithHADR', "(Availability Groups Enabled)") : ''}`,
fontStyle: FontStyle.Italic
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.HDFSNameNodeText', "HDFS name node"),
defaultValue: this.wizard.model.getStringValue(VariableNames.HDFSNameNodeScale_VariableName),
fontStyle: FontStyle.Italic
}
]
}, {
fields: [
{
type: FieldType.ReadonlyText,
label: localize('deployCluster.ZooKeeperText', "ZooKeeper"),
defaultValue: this.wizard.model.getStringValue(VariableNames.ZooKeeperScale_VariableName),
fontStyle: FontStyle.Italic
}, {
type: FieldType.ReadonlyText,
label: localize('deployCluster.SparkHeadText', "SparkHead"),
defaultValue: this.wizard.model.getStringValue(VariableNames.SparkHeadScale_VariableName),
fontStyle: FontStyle.Italic
}
]
fields: [{
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)") : ''}`,
labelFontWeight: FontWeight.Bold
}]
}
]
};
@@ -271,7 +293,6 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
const clusterSection = createSectionFunc(clusterSectionInfo);
const scaleSection = createSectionFunc(scaleSectionInfo);
const hadrSection = createSectionFunc(hadrSectionInfo);
const endpointSection = {
title: '',
component: this.createEndpointSection()
@@ -285,10 +306,16 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
this.formItems.push(azureSection);
}
this.formItems.push(clusterSection, scaleSection, hadrSection, endpointSection, storageSection);
this.formItems.push(clusterSection, scaleSection, endpointSection, storageSection);
this.form.addFormItems(this.formItems);
}
public onLeave() {
this.wizard.saveConfigButton.hidden = true;
this.wizard.scriptToNotebookButton.hidden = true;
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;
@@ -324,7 +351,7 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
this.wizard.model.getStringValue(VariableNames.ControllerLogsStorageClassName_VariableName),
this.wizard.model.getStringValue(VariableNames.ControllerLogsStorageSize_VariableName)],
[
localize('deployCluster.HDFSText', "HDFS"),
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),
@@ -357,10 +384,12 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
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.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.hadrEnabled) {
if (this.wizard.model.getIntegerValue(VariableNames.SQLServerScale_VariableName) > 1) {
endpointRows.push(
this.createEndpointRow(localize('deployCluster.ReadableSecondaryText', "Readable secondary"), VariableNames.ReadableSecondaryDNSName_VariableName, VariableNames.ReadableSecondaryPort_VariableName)
);
@@ -373,43 +402,15 @@ export class SummaryPage extends WizardPageBase<DeployClusterWizard> {
private createEndpointRow(name: string, dnsVariableName: string, portVariableName: string): azdata.FlexContainer {
const items = [];
items.push(createLabel(this.view, { text: name, width: '150px' }));
items.push(createLabel(this.view, { text: name, width: '150px', fontWeight: FontWeight.Bold }));
if (this.wizard.model.authenticationMode === AuthenticationMode.ActiveDirectory) {
items.push(createLabel(this.view, { text: this.wizard.model.getStringValue(dnsVariableName)!, width: '200px', fontStyle: FontStyle.Italic }));
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', fontStyle: FontStyle.Italic }));
items.push(createLabel(this.view, {
text: this.wizard.model.getStringValue(portVariableName)!, width: '100px'
}));
return createFlexContainer(this.view, items);
}
private createSaveJsonButton(label: string, fileName: string, getContent: () => string): azdata.ButtonComponent {
const button = this.view.modelBuilder.button().withProperties<azdata.ButtonProperties>({
title: label,
label: fileName,
ariaLabel: label,
width: '150px'
}).component();
this.wizard.registerDisposable(button.onDidClick(() => {
vscode.window.showSaveDialog({
defaultUri: vscode.Uri.file(join(os.homedir(), fileName)),
filters: {
'JSON': ['json']
}
}).then((path) => {
if (path) {
fs.promises.writeFile(path.fsPath, getContent()).then(() => {
this.wizard.wizardObject.message = {
text: localize('deployCluster.SaveJsonFileMessage', "File saved: {0}", path.fsPath),
level: azdata.window.MessageLevel.Information
};
}).catch((error) => {
this.wizard.wizardObject.message = {
text: error.message,
level: azdata.window.MessageLevel.Error
};
});
}
});
}));
return button;
}
}