Aasim/fix/sqldbtypos (#13130)

* fixed some easy typos on sql db wizard.

* Fixed some instructions in the notebook

* - Added option to enable or disable firewall rules

* converted toggle firewall dropdown to checkbox
This commit is contained in:
Aasim Khan
2020-10-29 11:53:56 -07:00
committed by GitHub
parent 66da2a46c5
commit e15ad17967
10 changed files with 142 additions and 75 deletions

View File

@@ -2,7 +2,8 @@
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
"display_name": "Python 3",
"language": "python"
},
"language_info": {
"name": "python",
@@ -29,7 +30,7 @@
"Steps of this procedure include:\n",
"1. Set variables and set up Notebook\n",
"1. Connect to Azure account and subscription\n",
"1. Provision firewall rules to allow local access\n",
"1. Provision firewall rules\n",
"1. Create SQL database resource"
],
"metadata": {
@@ -41,12 +42,12 @@
"source": [
"## Set variables\r\n",
"These variables are set based on your inputs in the deployment wizard. You can make changes to these variables but be aware of possible validation errors caused by your changes.\r\n",
"\r\n",
"\r\n",
"\r\n",
"\r\n",
""
],
"\r\n",
"\r\n",
"\r\n",
"\r\n",
""
],
"metadata": {
"azdata_cell_guid": "b57c46c8-4a34-49af-9b62-aa5688a02002"
}
@@ -78,7 +79,7 @@
" try:\n",
" return json.loads(output)\n",
" except:\n",
" return output\r\n",
" return output\r\n"
],
"metadata": {
"azdata_cell_guid": "c320ffe2-c488-4bd8-9886-c7deeae02996",
@@ -91,7 +92,7 @@
"cell_type": "markdown",
"source": [
"## Connecting to your Azure account\r\n",
""
""
],
"metadata": {
"azdata_cell_guid": "e34334a7-0d55-4c18-8c0a-1c4a673629cd"
@@ -114,7 +115,7 @@
"cell_type": "markdown",
"source": [
"## Setting your Azure subscription\r\n",
""
""
],
"metadata": {
"azdata_cell_guid": "ed6b781d-ce7e-4b51-a7ec-1eeeb2032c73"
@@ -149,19 +150,20 @@
{
"cell_type": "code",
"source": [
"create_firewall_rule_result = run_command(\r\n",
" 'az sql server firewall-rule create '\r\n",
" '--start-ip-address {0} '\r\n",
" '--end-ip-address {1} '\r\n",
" '--server {2} '\r\n",
" '--name {3} '\r\n",
" '--resource-group {4} '\r\n",
" .format(\r\n",
" azure_sqldb_ip_start, \r\n",
" azure_sqldb_ip_end, \r\n",
" azure_sqldb_server_name, \r\n",
" azure_sqldb_firewall_name, \r\n",
" azure_sqldb_resource_group_name));"
"if azure_sqldb_enable_firewall_rule == True:\r\n",
" create_firewall_rule_result = run_command(\r\n",
" 'az sql server firewall-rule create '\r\n",
" '--start-ip-address {0} '\r\n",
" '--end-ip-address {1} '\r\n",
" '--server {2} '\r\n",
" '--name {3} '\r\n",
" '--resource-group {4} '\r\n",
" .format(\r\n",
" azure_sqldb_ip_start, \r\n",
" azure_sqldb_ip_end, \r\n",
" azure_sqldb_server_name, \r\n",
" azure_sqldb_firewall_name, \r\n",
" azure_sqldb_resource_group_name));"
],
"metadata": {
"azdata_cell_guid": "ceae5670-292f-4c45-9c10-4ac85baf2d07"
@@ -172,9 +174,9 @@
{
"cell_type": "markdown",
"source": [
"## Create Azure SQL Database\r\n",
"\r\n",
"The database will be created based on all the settings previously specified. [Learn more](https://docs.microsoft.com/en-us/cli/azure/sql/db?view=azure-cli-latest#az_sql_db_create) about additonal options for creating the database."
"## Create Azure SQL Database\n",
"\n",
"Learn more about the different [cost and performance options](https://go.microsoft.com/fwlink/?linkid=842067) and [other additional customizations](https://go.microsoft.com/fwlink/?linkid=2147212) for creating the database"
],
"metadata": {
"azdata_cell_guid": "b460ca8f-65a7-4d6c-94b7-6d7dd9655fad"
@@ -191,14 +193,14 @@
" '--compute-model Serverless '\r\n",
" '--family Gen5 '\r\n",
" '--resource-group {2} '\r\n",
" '--min-capacity 0.5 '\r\n",
" '--max-size 32GB '\r\n",
" '--capacity 1 '\r\n",
" '--collation {3} '\r\n",
" '--min-capacity 0.5 '\r\n",
" '--max-size 32GB '\r\n",
" '--capacity 1 '\r\n",
" '--collation {3} '\r\n",
" .format(\r\n",
" azure_sqldb_server_name, \r\n",
" azure_sqldb_database_name, \r\n",
" azure_sqldb_resource_group_name, \r\n",
" azure_sqldb_resource_group_name, \r\n",
" azure_sqldb_collation));"
],
"metadata": {
@@ -208,4 +210,4 @@
"execution_count": null
}
]
}
}

View File

@@ -70,10 +70,10 @@
"azure-sqlvm-password-label": "Password",
"azure-sqlvm-password-confirm-label": "Confirm password",
"azure-sqlvm-vm-summary-page-label": "Summary",
"azure-sqldb-display-name": "SQL Database on Azure Server",
"azure-sqldb-description": "Create SQL Databases on Azure. Best for new applications or existing on-premises applications.",
"azure-sqldb-display-name": "Azure SQL Database",
"azure-sqldb-description": "Create a SQL database, database server, or elastic pool in Azure.",
"azure-sqldb-portal-ok-button-text": "Create in Azure portal",
"azure-sqldb-notebook-ok-button-text": "Script to Notebook",
"azure-sqldb-notebook-ok-button-text": "Select",
"resource-type-display-name": "Resource Type",
"sql-azure-single-database-display-name": "Single Database",
"sql-azure-elastic-pool-display-name": "Elastic Pool",

View File

@@ -20,6 +20,8 @@ export const kubeConfigFilePath = localize('kubeConfigClusterPicker.kubeConfigFi
export const clusterContextNotFound = localize('kubeConfigClusterPicker.clusterContextNotFound', "No cluster context information found");
export const signIn = localize('azure.signin', "Sign in…");
export const refresh = localize('azure.refresh', "Refresh");
export const yes = localize('azure.yes', "Yes");
export const no = localize('azure.no', "No");
export const createNewResourceGroup = localize('azure.resourceGroup.createNewResourceGroup', "Create a new resource group");
export const NewResourceGroupAriaLabel = localize('azure.resourceGroup.NewResourceGroupAriaLabel', "New resource group name");
export const realm = localize('deployCluster.Realm', "Realm");

View File

@@ -14,12 +14,12 @@ export const WizardDoneButtonLabel = localize('deployAzureSQLDB.ScriptToNotebook
export const MissingRequiredInformationErrorMessage = localize('deployAzureSQLDB.MissingRequiredInfoError', "Please fill out the required fields marked with red asterisks.");
// Azure settings page constants
export const AzureSettingsPageTitle = localize('deployAzureSQLDB.AzureSettingsPageTitle', "Azure SQL Database - Azure Account Settings");
export const AzureSettingsSummaryPageTitle = localize('deployAzureSQLDB.AzureSettingsSummaryPageTitle', "Azure Account Settings");
export const AzureAccountDropdownLabel = localize('deployAzureSQLDB.AzureAccountDropdownLabel', "Azure Account");
export const AzureSettingsPageTitle = localize('deployAzureSQLDB.AzureSettingsPageTitle', "Azure SQL Database - Azure account settings");
export const AzureSettingsSummaryPageTitle = localize('deployAzureSQLDB.AzureSettingsSummaryPageTitle', "Azure account settings");
export const AzureAccountDropdownLabel = localize('deployAzureSQLDB.AzureAccountDropdownLabel', "Azure account");
export const AzureAccountSubscriptionDropdownLabel = localize('deployAzureSQLDB.AzureSubscriptionDropdownLabel', "Subscription");
export const AzureAccountDatabaseServersDropdownLabel = localize('deployAzureSQLDB.AzureDatabaseServersDropdownLabel', "Server");
export const AzureAccountResourceGroupDropdownLabel = localize('deployAzureSQLDB.ResourceGroup', "Resource Group");
export const AzureAccountResourceGroupDropdownLabel = localize('deployAzureSQLDB.ResourceGroup', "Resource group");
//@todo alma1 9/8/20 Region label used for upcoming server creation feature.
//export const AzureAccountRegionDropdownLabel = localize('deployAzureSQLDB.AzureRegionDropdownLabel', "Region (for Public IP Address)");
@@ -38,8 +38,10 @@ export const FirewallRuleNameLabel = localize('deployAzureSQLDB.FirewallRuleName
export const DatabaseNameLabel = localize('deployAzureSQLDB.DatabaseNameLabel', "SQL database name");
export const CollationNameLabel = localize('deployAzureSQLDB.CollationNameLabel', "Database collation");
export const CollationNameSummaryLabel = localize('deployAzureSQLDB.CollationNameSummaryLabel', "Collation for database");
export const IpAddressInfoLabel = localize('deployAzureSQLDB.IpAddressInfoLabel', "Enter IP Addresses in IPv4 format.");
export const StartIpAddressLabel = localize('deployAzureSQLDB.StartIpAddressLabel', "Min IP Address in firewall Ip Range");
export const EndIpAddressLabel = localize('deployAzureSQLDB.EndIpAddressLabel', "Max IP Address in firewall IP Range");
export const StartIpAddressShortLabel = localize('deployAzureSQLDB.StartIpAddressShortLabel', "Min IP Address");
export const EndIpAddressShortLabel = localize('deployAzureSQLDB.EndIpAddressShortLabel', "Max IP Address");
export const IpAddressInfoLabel = localize('deployAzureSQLDB.IpAddressInfoLabel', "Enter IP addresses in IPv4 format.");
export const StartIpAddressLabel = localize('deployAzureSQLDB.StartIpAddressLabel', "Min IP address in firewall IP range");
export const EndIpAddressLabel = localize('deployAzureSQLDB.EndIpAddressLabel', "Max IP address in firewall IP range");
export const StartIpAddressShortLabel = localize('deployAzureSQLDB.StartIpAddressShortLabel', "Min IP address");
export const EndIpAddressShortLabel = localize('deployAzureSQLDB.EndIpAddressShortLabel', "Max IP address");
export const FirewallRuleDescription = localize('deployAzureSQLDB.FirewallRuleDescription', "Create a firewall rule for your local client IP in order to connect to your database through Azure Data Studio after creation is completed.");
export const FirewallToggleLabel = localize('deployAzureSQLDB.FirewallToggleLabel', "Create a firewall rule");

View File

@@ -27,6 +27,7 @@ export class DeployAzureSQLDBWizardModel extends Model {
public endIpAddress!: string;
public firewallRuleName!: string;
public databaseCollation!: string;
public newFirewallRule!: boolean;
constructor() {
@@ -41,11 +42,14 @@ export class DeployAzureSQLDBWizardModel extends Model {
statements.push(`azure_sqldb_server_name = '${this.azureServerName}'`);
//statements.push(`azure_sqldb_database_edition = '${this.databaseEdition}'`); //@todo alma1 10/7/2020 used for upcoming datbase hardware creation feature.
statements.push(`azure_sqldb_database_name = '${this.databaseName}'`);
//statements.push(`azure_sqldb_location = '${this.azureRegion}'`); //@todo alma1 9/10/2020 used for upcoming server creation feature.
statements.push(`azure_sqldb_ip_start = '${this.startIpAddress}'`);
statements.push(`azure_sqldb_ip_end = '${this.endIpAddress}'`);
statements.push(`azure_sqldb_firewall_name = '${this.firewallRuleName}'`);
statements.push(`azure_sqldb_collation = '${this.databaseCollation}'`);
//statements.push(`azure_sqldb_location = '${this.azureRegion}'`); //@todo alma1 9/10/2020 used for upcoming server creation feature.
statements.push(`azure_sqldb_enable_firewall_rule = ${(this.newFirewallRule) ? 'True' : 'False'}`);
if (this.newFirewallRule) {
statements.push(`azure_sqldb_ip_start = '${this.startIpAddress}'`);
statements.push(`azure_sqldb_ip_end = '${this.endIpAddress}'`);
statements.push(`azure_sqldb_firewall_name = '${this.firewallRuleName}'`);
}
// statements.push(`azure_sqldb_family = '${this.databaseFamily}'`); //@todo alma1 10/7/2020 used for upcoming datbase hardware creation feature.
// statements.push(`azure_sqldb_vcore = '${this.vCoreNumber}'`);
// statements.push(`azure_sqldb_maxmemory = '${this.storageInGB}'`);

View File

@@ -12,6 +12,7 @@ import { azureResource } from 'azureResource';
import * as vscode from 'vscode';
import { BasePage } from './basePage';
import * as nls from 'vscode-nls';
import * as localizedConstants from '../../../localizedConstants';
const localize = nls.loadMessageBundle();
export class AzureSettingsPage extends BasePage {
@@ -166,11 +167,11 @@ export class AzureSettingsPage extends BasePage {
});
this.signInButton = view.modelBuilder.button().withProperties<azdata.ButtonProperties>({
label: 'Sign In',
label: localizedConstants.signIn,
width: '100px'
}).component();
this.refreshButton = view.modelBuilder.button().withProperties<azdata.ButtonProperties>({
label: 'Refresh',
label: localizedConstants.refresh,
width: '100px'
}).component();

View File

@@ -9,6 +9,7 @@ import { DeployAzureSQLDBWizard } from '../deployAzureSQLDBWizard';
import * as constants from '../constants';
import { BasePage } from './basePage';
import * as nls from 'vscode-nls';
import { createCheckbox, createFlexContainer, createLabel } from '../../modelViewUtils';
const localize = nls.loadMessageBundle();
export class DatabaseSettingsPage extends BasePage {
@@ -24,6 +25,10 @@ export class DatabaseSettingsPage extends BasePage {
private _collationTextbox!: azdata.InputBoxComponent;
private _collationTextRow!: azdata.FlexContainer;
private _IpInfoText!: azdata.TextComponent;
private _firewallToggleDropdown!: azdata.CheckBoxComponent;
private _firewallToggleLabel!: azdata.TextComponent;
private _form!: azdata.FormContainer;
@@ -39,6 +44,7 @@ export class DatabaseSettingsPage extends BasePage {
this.pageObject.registerContent(async (view: azdata.ModelView) => {
await Promise.all([
this.createIpAddressText(view),
this.createFirewallToggle(view),
this.createFirewallNameText(view),
this.createDatabaseNameText(view),
this.createCollationText(view)
@@ -52,6 +58,9 @@ export class DatabaseSettingsPage extends BasePage {
{
component: this._collationTextRow
},
{
component: createFlexContainer(view, [this._firewallToggleLabel, this._firewallToggleDropdown])
},
{
component: this._firewallRuleNameTextRow
},
@@ -128,6 +137,37 @@ export class DatabaseSettingsPage extends BasePage {
this._endIpAddressTextRow = this.wizard.createFormRowComponent(view, constants.EndIpAddressLabel, '', this._endIpAddressTextbox, true);
}
private createFirewallToggle(view: azdata.ModelView) {
this._firewallToggleDropdown = createCheckbox(view, {
initialValue: true,
label: '',
required: false
});
this._firewallToggleLabel = createLabel(view, {
text: constants.FirewallToggleLabel,
description: constants.FirewallRuleDescription,
required: false,
width: '250px',
cssStyles: {
'font-weight': '400',
'font-size': '13px',
}
});
this.wizard.model.newFirewallRule = true;
this._firewallToggleDropdown.onChanged((value) => {
let displayValue: 'block' | 'none' = (value) ? 'block' : 'none';
this.wizard.changeRowDisplay(this._firewallRuleNameTextRow, displayValue);
this.wizard.changeRowDisplay(this._endIpAddressTextRow, displayValue);
this.wizard.changeRowDisplay(this._startIpAddressTextRow, displayValue);
this.wizard.changeComponentDisplay(this._IpInfoText, displayValue);
this.wizard.model.newFirewallRule = value;
});
}
private createFirewallNameText(view: azdata.ModelView) {
this._firewallRuleNameTextbox = view.modelBuilder.inputBox().component();
@@ -173,25 +213,28 @@ export class DatabaseSettingsPage extends BasePage {
let databasename = this._databaseNameTextbox.value!;
let collationname = this._collationTextbox.value!;
if (!(ipRegex.test(startipvalue))) {
errorMessages.push(localize('deployAzureSQLDB.DBMinIpInvalidError', "Min Ip address is invalid"));
}
if (this.wizard.model.newFirewallRule) {
if (!(ipRegex.test(startipvalue))) {
errorMessages.push(localize('deployAzureSQLDB.DBMinIpInvalidError', "Min Ip address is invalid"));
}
if (!(ipRegex.test(endipvalue))) {
errorMessages.push(localize('deployAzureSQLDB.DBMaxIpInvalidError', "Max Ip address is invalid"));
}
if (!(ipRegex.test(endipvalue))) {
errorMessages.push(localize('deployAzureSQLDB.DBMaxIpInvalidError', "Max Ip address is invalid"));
}
if (/^\d+$/.test(firewallname)) {
errorMessages.push(localize('deployAzureSQLDB.DBFirewallOnlyNumericNameError', "Firewall name cannot contain only numbers."));
}
if (firewallname.length < 1 || firewallname.length > 100) {
errorMessages.push(localize('deployAzureSQLDB.DBFirewallLengthError', "Firewall name must be between 1 and 100 characters long."));
}
if (/[\\\/"\'\[\]:\|<>\+=;,\?\*@\&,]/g.test(firewallname)) {
errorMessages.push(localize('deployAzureSQLDB.DBFirewallSpecialCharError', "Firewall name cannot contain special characters \/\"\"[]:|<>+=;,?*@&, ."));
}
if (/[A-Z]/g.test(firewallname)) {
errorMessages.push(localize('deployAzureSQLDB.DBFirewallUpperCaseError', "Upper case letters are not allowed for firewall name"));
}
if (/^\d+$/.test(firewallname)) {
errorMessages.push(localize('deployAzureSQLDB.DBFirewallOnlyNumericNameError', "Firewall name cannot contain only numbers."));
}
if (firewallname.length < 1 || firewallname.length > 100) {
errorMessages.push(localize('deployAzureSQLDB.DBFirewallLengthError', "Firewall name must be between 1 and 100 characters long."));
}
if (/[\\\/"\'\[\]:\|<>\+=;,\?\*@\&,]/g.test(firewallname)) {
errorMessages.push(localize('deployAzureSQLDB.DBFirewallSpecialCharError', "Firewall name cannot contain special characters \/\"\"[]:|<>+=;,?*@&, ."));
}
if (/[A-Z]/g.test(firewallname)) {
errorMessages.push(localize('deployAzureSQLDB.DBFirewallUpperCaseError', "Upper case letters are not allowed for firealll name"));
}
if (/^\d+$/.test(databasename)) {

View File

@@ -7,6 +7,7 @@ import * as azdata from 'azdata';
import { WizardPageBase } from '../../wizardPageBase';
import { DeployAzureSQLDBWizard } from '../deployAzureSQLDBWizard';
import * as constants from '../constants';
import * as localizedConstants from '../../../localizedConstants';
import { SectionInfo, LabelPosition, FontWeight, FieldType } from '../../../interfaces';
import { createSection } from '../../modelViewUtils';
@@ -136,6 +137,17 @@ export class AzureSQLDBSummaryPage extends WizardPageBase<DeployAzureSQLDBWizard
defaultValue: model.databaseCollation,
labelCSSStyles: { fontWeight: FontWeight.Bold }
},
{
type: FieldType.ReadonlyText,
label: constants.FirewallToggleLabel,
defaultValue: model.newFirewallRule ? localizedConstants.yes : localizedConstants.no,
labelCSSStyles: { fontWeight: FontWeight.Bold }
}
]
};
if (model.newFirewallRule) {
databaseSettingSection.fields?.push(
{
type: FieldType.ReadonlyText,
label: constants.FirewallRuleNameLabel,
@@ -153,9 +165,8 @@ export class AzureSQLDBSummaryPage extends WizardPageBase<DeployAzureSQLDBWizard
label: constants.EndIpAddressShortLabel,
defaultValue: model.endIpAddress,
labelCSSStyles: { fontWeight: FontWeight.Bold }
}
]
};
});
}
const createSectionFunc = async (sectionInfo: SectionInfo): Promise<azdata.FormComponent> => {

View File

@@ -10,6 +10,7 @@ import { DeployAzureSQLVMWizard } from '../deployAzureSQLVMWizard';
import { apiService } from '../../../services/apiService';
import { azureResource } from 'azureResource';
import * as vscode from 'vscode';
import * as localizedConstants from '../../../localizedConstants';
export class AzureSettingsPage extends WizardPageBase<DeployAzureSQLVMWizard> {
// <- means depends on
@@ -105,11 +106,11 @@ export class AzureSettingsPage extends WizardPageBase<DeployAzureSQLVMWizard> {
});
this.signInButton = view.modelBuilder.button().withProperties<azdata.ButtonProperties>({
label: 'Sign In',
label: localizedConstants.signIn,
width: '100px'
}).component();
this.refreshButton = view.modelBuilder.button().withProperties<azdata.ButtonProperties>({
label: 'Refresh',
label: localizedConstants.refresh,
width: '100px'
}).component();

View File

@@ -9,6 +9,7 @@ import * as constants from '../constants';
import { DeployAzureSQLVMWizard } from '../deployAzureSQLVMWizard';
import { BasePage } from './basePage';
import * as nls from 'vscode-nls';
import * as localizedConstants from '../../../localizedConstants';
const localize = nls.loadMessageBundle();
export class SqlServerSettingsPage extends BasePage {
@@ -167,11 +168,11 @@ export class SqlServerSettingsPage extends BasePage {
this._sqlAuthenticationDropdown = view.modelBuilder.dropDown().withProperties(<azdata.DropDownComponent>{
values: [
{
displayName: localize('deployAzureSQLVM.EnableSqlAuthenticationYesOption', "Yes"),
displayName: localizedConstants.yes,
name: 'True'
},
{
displayName: localize('deployAzureSQLVM.EnableSqlAuthenticationNoOption', "No"),
displayName: localizedConstants.no,
name: 'False'
}
]