use required attribute (#7850)

* use required attribute

* readable sql port
This commit is contained in:
Alan Ren
2019-10-21 09:53:12 -07:00
committed by GitHub
parent 6c5aa6b367
commit a05edc619c
4 changed files with 43 additions and 92 deletions

View File

@@ -160,7 +160,6 @@ export interface FieldInfo {
labelWidth?: string;
inputWidth?: string;
description?: string;
useCustomValidator?: boolean;
labelPosition?: LabelPosition; // overwrite the labelPosition of SectionInfo.
fontStyle?: FontStyle;
labelFontWeight?: FontWeight;

View File

@@ -8,7 +8,7 @@ import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { DeployClusterWizard } from '../deployClusterWizard';
import { SectionInfo, FieldType, LabelPosition } from '../../../interfaces';
import { createSection, InputComponents, setModelValues, Validator, isInputBoxEmpty, getInputBoxComponent, isValidSQLPassword, getInvalidSQLPasswordMessage, getPasswordMismatchMessage, MissingRequiredInformationErrorMessage } from '../../modelViewUtils';
import { createSection, InputComponents, setModelValues, Validator, getInputBoxComponent, isValidSQLPassword, getInvalidSQLPasswordMessage, getPasswordMismatchMessage } from '../../modelViewUtils';
import { WizardPageBase } from '../../wizardPageBase';
import * as VariableNames from '../constants';
import { EOL } from 'os';
@@ -37,15 +37,13 @@ export class ClusterSettingsPage extends WizardPageBase<DeployClusterWizard> {
label: localize('deployCluster.ClusterName', "Cluster name"),
required: true,
variableName: VariableNames.ClusterName_VariableName,
defaultValue: 'mssql-cluster',
useCustomValidator: true
defaultValue: 'mssql-cluster'
}, {
type: FieldType.Text,
label: localize('deployCluster.AdminUsername', "Admin username"),
required: true,
variableName: VariableNames.AdminUserName_VariableName,
defaultValue: 'admin',
useCustomValidator: true,
description: localize('deployCluster.AdminUsernameDescription', "This username will be used for controller and SQL Server. Username for the gateway will be root.")
}, {
type: FieldType.Password,
@@ -53,19 +51,16 @@ export class ClusterSettingsPage extends WizardPageBase<DeployClusterWizard> {
required: true,
variableName: VariableNames.AdminPassword_VariableName,
defaultValue: '',
useCustomValidator: true,
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: '',
useCustomValidator: true,
defaultValue: ''
}, {
type: FieldType.Options,
label: localize('deployCluster.AuthenticationMode', "Authentication mode"),
required: true,
variableName: VariableNames.AuthenticationMode_VariableName,
defaultValue: AuthenticationMode.Basic,
options: [
@@ -127,14 +122,12 @@ export class ClusterSettingsPage extends WizardPageBase<DeployClusterWizard> {
label: localize('deployCluster.OuDistinguishedName', "Organizational unit"),
required: true,
variableName: VariableNames.OrganizationalUnitDistinguishedName_VariableName,
useCustomValidator: true,
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,
useCustomValidator: true,
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.")
}, {
@@ -142,28 +135,24 @@ export class ClusterSettingsPage extends WizardPageBase<DeployClusterWizard> {
label: localize('deployCluster.DomainDNSIPAddresses', "Domain DNS IP addresses"),
required: true,
variableName: VariableNames.DomainDNSIPAddresses_VariableName,
useCustomValidator: true,
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,
useCustomValidator: true
variableName: VariableNames.DomainDNSName_VariableName
}, {
type: FieldType.Text,
label: localize('deployCluster.ClusterAdmins', "Cluster admin group"),
required: true,
variableName: VariableNames.ClusterAdmins_VariableName,
useCustomValidator: true,
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,
useCustomValidator: true,
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.")
}, {
@@ -171,20 +160,17 @@ export class ClusterSettingsPage extends WizardPageBase<DeployClusterWizard> {
label: localize('deployCluster.DomainServiceAccountUserName', "Service account username"),
required: true,
variableName: VariableNames.DomainServiceAccountUserName_VariableName,
useCustomValidator: true,
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,
useCustomValidator: true
variableName: VariableNames.DomainServiceAccountPassword_VariableName
}, {
type: FieldType.Text,
label: localize('deployCluster.AppOwers', "App owners"),
required: false,
variableName: VariableNames.AppOwners_VariableName,
useCustomValidator: true,
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.")
}, {
@@ -192,7 +178,6 @@ export class ClusterSettingsPage extends WizardPageBase<DeployClusterWizard> {
label: localize('deployCluster.AppReaders', "App readers"),
required: false,
variableName: VariableNames.AppReaders_VariableName,
useCustomValidator: true,
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.")
}
@@ -254,6 +239,14 @@ export class ClusterSettingsPage extends WizardPageBase<DeployClusterWizard> {
);
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 {
@@ -307,33 +300,13 @@ export class ClusterSettingsPage extends WizardPageBase<DeployClusterWizard> {
this.wizard.wizardObject.message = { text: '' };
if (pcInfo.newPage > pcInfo.lastPage) {
const messages: string[] = [];
const authMode = typeof authModeDropdown.value === 'string' ? authModeDropdown.value : authModeDropdown.value!.name;
const requiredFieldsFilled: boolean = !isInputBoxEmpty(getInputBoxComponent(VariableNames.ClusterName_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.AdminUserName_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.AdminPassword_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(ConfirmPasswordName, this.inputComponents))
&& (!(authMode === AuthenticationMode.ActiveDirectory) || (
!isInputBoxEmpty(getInputBoxComponent(VariableNames.OrganizationalUnitDistinguishedName_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.DomainControllerFQDNs_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.ClusterAdmins_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.ClusterUsers_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.DomainDNSIPAddresses_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.DomainDNSName_VariableName, this.inputComponents))));
if (!requiredFieldsFilled) {
messages.push(MissingRequiredInformationErrorMessage);
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 (!isInputBoxEmpty(getInputBoxComponent(VariableNames.AdminUserName_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.AdminPassword_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(ConfirmPasswordName, this.inputComponents))) {
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")));
}
if (!isValidSQLPassword(password, getInputBoxComponent(VariableNames.AdminUserName_VariableName, this.inputComponents).value!)) {
messages.push(getInvalidSQLPasswordMessage(localize('deployCluster.AdminPasswordField', "Password")));
}
if (messages.length > 0) {

View File

@@ -7,7 +7,7 @@ import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { DeployClusterWizard } from '../deployClusterWizard';
import { SectionInfo, FieldType } from '../../../interfaces';
import { Validator, InputComponents, createSection, createGroupContainer, createLabel, createFlexContainer, createTextInput, createNumberInput, setModelValues, getInputBoxComponent, getCheckboxComponent, isInputBoxEmpty, getDropdownComponent, MissingRequiredInformationErrorMessage } from '../../modelViewUtils';
import { Validator, InputComponents, createSection, createGroupContainer, createLabel, createFlexContainer, createTextInput, createNumberInput, setModelValues, getInputBoxComponent, getCheckboxComponent, getDropdownComponent } from '../../modelViewUtils';
import { WizardPageBase } from '../../wizardPageBase';
import * as VariableNames from '../constants';
import { AuthenticationMode } from '../deployClusterWizardModel';
@@ -65,7 +65,6 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
label: localize('deployCluster.MasterSqlServerInstances', "SQL Server master instances"),
options: ['1', '3', '4', '5', '6', '7', '8', '9'],
defaultValue: '1',
required: true,
variableName: VariableNames.SQLServerScale_VariableName,
}, {
type: FieldType.Number,
@@ -73,7 +72,6 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
min: 1,
max: 100,
defaultValue: '1',
useCustomValidator: true,
required: true,
variableName: VariableNames.ComputePoolScale_VariableName,
}]
@@ -84,7 +82,6 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
min: 1,
max: 100,
defaultValue: '1',
useCustomValidator: true,
required: true,
variableName: VariableNames.DataPoolScale_VariableName,
}, {
@@ -93,7 +90,6 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
min: 0,
max: 100,
defaultValue: '0',
useCustomValidator: true,
required: true,
variableName: VariableNames.SparkPoolScale_VariableName
}]
@@ -105,7 +101,6 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
min: 1,
max: 100,
defaultValue: '1',
useCustomValidator: true,
required: true,
variableName: VariableNames.HDFSPoolScale_VariableName
}, {
@@ -161,7 +156,6 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
{
type: FieldType.Text,
label: localize('deployCluster.ControllerText', "Controller"),
useCustomValidator: true,
variableName: VariableNames.ControllerDataStorageClassName_VariableName,
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."),
@@ -169,19 +163,19 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
}, {
type: FieldType.Number,
label: '',
useCustomValidator: true,
required: true,
min: 1,
variableName: VariableNames.ControllerDataStorageSize_VariableName,
}, {
type: FieldType.Text,
label: '',
useCustomValidator: true,
required: true,
min: 1,
variableName: VariableNames.ControllerLogsStorageClassName_VariableName,
}, {
type: FieldType.Number,
label: '',
useCustomValidator: true,
required: true,
min: 1,
variableName: VariableNames.ControllerLogsStorageSize_VariableName,
}
@@ -421,17 +415,27 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
this.setInputBoxValue(VariableNames.ControllerLogsStorageClassName_VariableName);
this.setInputBoxValue(VariableNames.ControllerLogsStorageSize_VariableName);
this.endpointHeaderRow.clearItems();
this.endpointSection.collapsed = this.wizard.model.authenticationMode !== AuthenticationMode.ActiveDirectory;
if (this.wizard.model.authenticationMode === AuthenticationMode.ActiveDirectory) {
const adAuth = this.wizard.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]);
}
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);
const sqlServerScale = this.wizard.model.getIntegerValue(VariableNames.SQLServerScale_VariableName);
if (sqlServerScale > 1) {
sqlServerScaleDropdown.values = ['3', '4', '5', '6', '7', '8', '9'];
this.loadEndpointRow(this.readableSecondaryEndpointRow, this.readableSecondaryNameLabel, this.readableSecondaryDNSInput, this.readableSecondaryPortInput);
@@ -444,36 +448,11 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
this.wizard.wizardObject.registerNavigationValidator((pcInfo) => {
this.wizard.wizardObject.message = { text: '' };
if (pcInfo.newPage > pcInfo.lastPage) {
const allInputFilled: boolean = !isInputBoxEmpty(getInputBoxComponent(VariableNames.ComputePoolScale_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.DataPoolScale_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.HDFSPoolScale_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.SparkPoolScale_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.ControllerDataStorageClassName_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.ControllerDataStorageSize_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.ControllerLogsStorageClassName_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.ControllerLogsStorageSize_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.ControllerPort_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.SQLServerPort_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.GateWayPort_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.AppServiceProxyPort_VariableName, this.inputComponents))
&& !isInputBoxEmpty(getInputBoxComponent(VariableNames.ServiceProxyPort_VariableName, this.inputComponents))
&& (getDropdownComponent(VariableNames.SQLServerScale_VariableName, this.inputComponents).value === '1'
|| (!isInputBoxEmpty(this.readableSecondaryPortInput)
&& (this.wizard.model.authenticationMode !== AuthenticationMode.ActiveDirectory || !isInputBoxEmpty(this.readableSecondaryDNSInput))))
&& (this.wizard.model.authenticationMode !== AuthenticationMode.ActiveDirectory
|| (!isInputBoxEmpty(this.gatewayDNSInput)
&& !isInputBoxEmpty(this.controllerDNSInput)
&& !isInputBoxEmpty(this.sqlServerDNSInput)
&& !isInputBoxEmpty(this.appServiceProxyDNSInput)
&& !isInputBoxEmpty(this.serviceProxyDNSInput)
));
const sparkEnabled = Number.parseInt(getInputBoxComponent(VariableNames.SparkPoolScale_VariableName, this.inputComponents).value!) !== 0
|| getCheckboxComponent(VariableNames.IncludeSpark_VariableName, this.inputComponents).checked!;
let errorMessage: string | undefined;
if (!allInputFilled) {
errorMessage = MissingRequiredInformationErrorMessage;
} else if (!sparkEnabled) {
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) {
@@ -482,7 +461,7 @@ export class ServiceSettingsPage extends WizardPageBase<DeployClusterWizard> {
level: azdata.window.MessageLevel.Error
};
}
return allInputFilled && sparkEnabled;
return sparkEnabled;
}
return true;
});

View File

@@ -284,7 +284,7 @@ function processDateTimeTextField(context: FieldContext): void {
value: defaultValue,
ariaLabel: context.fieldInfo.label,
inputType: 'text',
required: !context.fieldInfo.useCustomValidator && context.fieldInfo.required,
required: context.fieldInfo.required,
placeHolder: context.fieldInfo.placeHolder
}).component();
input.width = context.fieldInfo.inputWidth;
@@ -299,7 +299,7 @@ function processNumberField(context: FieldContext): void {
ariaLabel: context.fieldInfo.label,
min: context.fieldInfo.min,
max: context.fieldInfo.max,
required: !context.fieldInfo.useCustomValidator && context.fieldInfo.required,
required: context.fieldInfo.required,
width: context.fieldInfo.inputWidth,
placeHolder: context.fieldInfo.placeHolder
});
@@ -312,7 +312,7 @@ function processTextField(context: FieldContext): void {
const input = createTextInput(context.view, {
defaultValue: context.fieldInfo.defaultValue,
ariaLabel: context.fieldInfo.label,
required: !context.fieldInfo.useCustomValidator && context.fieldInfo.required,
required: context.fieldInfo.required,
placeHolder: context.fieldInfo.placeHolder,
width: context.fieldInfo.inputWidth
});
@@ -325,7 +325,7 @@ function processPasswordField(context: FieldContext): void {
const passwordInput = context.view.modelBuilder.inputBox().withProperties<azdata.InputBoxProperties>({
ariaLabel: context.fieldInfo.label,
inputType: 'password',
required: !context.fieldInfo.useCustomValidator && context.fieldInfo.required,
required: context.fieldInfo.required,
placeHolder: context.fieldInfo.placeHolder,
width: context.fieldInfo.inputWidth
}).component();
@@ -351,7 +351,7 @@ function processPasswordField(context: FieldContext): void {
const confirmPasswordInput = context.view.modelBuilder.inputBox().withProperties<azdata.InputBoxProperties>({
ariaLabel: context.fieldInfo.confirmationLabel,
inputType: 'password',
required: !context.fieldInfo.useCustomValidator,
required: true,
width: context.fieldInfo.inputWidth
}).component();