diff --git a/build/lib/extensions.js b/build/lib/extensions.js
index 2207bdbfb4..90dca3bd61 100644
--- a/build/lib/extensions.js
+++ b/build/lib/extensions.js
@@ -209,7 +209,8 @@ const externalExtensions = [
'liveshare',
'sql-database-projects',
'machine-learning',
- 'sql-assessment'
+ 'sql-assessment',
+ 'asde-deployment'
];
// extensions that require a rebuild since they have native parts
const rebuildExtensions = [
diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts
index f414359288..755f7af2c6 100644
--- a/build/lib/extensions.ts
+++ b/build/lib/extensions.ts
@@ -244,7 +244,8 @@ const externalExtensions = [
'liveshare',
'sql-database-projects',
'machine-learning',
- 'sql-assessment'
+ 'sql-assessment',
+ 'asde-deployment'
];
// extensions that require a rebuild since they have native parts
diff --git a/extensions/asde-deployment/images/extension.png b/extensions/asde-deployment/images/extension.png
new file mode 100644
index 0000000000..c86d6d1e00
Binary files /dev/null and b/extensions/asde-deployment/images/extension.png differ
diff --git a/extensions/asde-deployment/images/sqldb_edge.svg b/extensions/asde-deployment/images/sqldb_edge.svg
new file mode 100644
index 0000000000..234992e168
--- /dev/null
+++ b/extensions/asde-deployment/images/sqldb_edge.svg
@@ -0,0 +1,80 @@
+
+
+
diff --git a/extensions/asde-deployment/images/sqldb_edge_inverse.svg b/extensions/asde-deployment/images/sqldb_edge_inverse.svg
new file mode 100644
index 0000000000..234992e168
--- /dev/null
+++ b/extensions/asde-deployment/images/sqldb_edge_inverse.svg
@@ -0,0 +1,80 @@
+
+
+
diff --git a/extensions/asde-deployment/notebooks/edge/deploy-sql-edge-local.ipynb b/extensions/asde-deployment/notebooks/edge/deploy-sql-edge-local.ipynb
new file mode 100644
index 0000000000..c9db3fb69a
--- /dev/null
+++ b/extensions/asde-deployment/notebooks/edge/deploy-sql-edge-local.ipynb
@@ -0,0 +1,261 @@
+{
+ "metadata": {
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python",
+ "version": "3.6.6",
+ "mimetype": "text/x-python",
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "pygments_lexer": "ipython3",
+ "nbconvert_exporter": "python",
+ "file_extension": ".py"
+ }
+ },
+ "nbformat_minor": 2,
+ "nbformat": 4,
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Run Azure SQL Edge image locally with Docker\n",
+ "This notebook will use Docker to pull and run the Azure SQL Edge image and connect to it in Azure Data Studio\n",
+ "\n",
+ "### Dependencies\n",
+ "- Docker Engine. For more information, see [Install Docker](https://docs.docker.com/engine/installation/).\n",
+ "\n",
+ "Please press the \"Run all\" button to run the notebook"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "565693e5-39d7-46cf-b0a1-3aa9945c3eed"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Check dependencies"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "b9e09157-54b4-4358-90a2-1a54419bd2cc"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import pandas,sys,getpass,os,json,html,time\n",
+ "pandas_version = pandas.__version__.split('.')\n",
+ "pandas_major = int(pandas_version[0])\n",
+ "pandas_minor = int(pandas_version[1])\n",
+ "pandas_patch = int(pandas_version[2])\n",
+ "if not (pandas_major > 0 or (pandas_major == 0 and pandas_minor > 24) or (pandas_major == 0 and pandas_minor == 24 and pandas_patch >= 2)):\n",
+ " sys.exit('Please upgrade the Notebook dependency before you can proceed, you can do it by running the \"Reinstall Notebook dependencies\" command in command palette (View menu -> Command Paletteā¦).')\n",
+ "\n",
+ "def run_command():\n",
+ " print(\"Executing: \" + cmd)\n",
+ " !{cmd}\n",
+ " if _exit_code != 0:\n",
+ " sys.exit(f'Command execution failed with exit code: {str(_exit_code)}.\\n\\t{cmd}\\n')\n",
+ " print(f'Successfully executed: {cmd}')\n",
+ "\n",
+ "cmd = 'docker version'\n",
+ "run_command()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "a0a8cd9b-ab0f-4ba2-b568-0c68d950c8bf"
+ },
+ "outputs": [],
+ "execution_count": 1
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### List existing containers\n",
+ "You can view the ports that have been used by existing containers"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "b5a3c41c-a2c3-44a7-94cc-9f1f61d0151d"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "cmd = f'docker ps -a'\n",
+ "run_command()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "5a253372-1a98-4b07-a3e0-9ae5f47cb0a5"
+ },
+ "outputs": [],
+ "execution_count": 2
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Setting variables"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "7c476b13-05f7-4975-bcb0-8c596bc01e6c"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "env_var_flag = \"AZDATA_NB_VAR_SA_PASSWORD\" in os.environ\n",
+ "password_name = 'SQL Server sa account password'\n",
+ "if env_var_flag:\n",
+ " container_name = os.environ[\"AZDATA_NB_VAR_DOCKER_CONTAINER_NAME\"]\n",
+ " sql_password = os.environ[\"AZDATA_NB_VAR_SA_PASSWORD\"]\n",
+ " sql_port = os.environ[\"AZDATA_NB_VAR_DOCKER_PORT\"]\n",
+ " docker_registry = os.environ[\"AZDATA_NB_VAR_DOCKER_REGISTRY\"]\n",
+ " docker_repository = os.environ[\"AZDATA_NB_VAR_DOCKER_REPOSITORY\"]\n",
+ " docker_imagetag = os.environ[\"AZDATA_NB_VAR_DOCKER_IMAGETAG\"]\n",
+ " docker_username = os.environ[\"AZDATA_NB_VAR_DOCKER_USERNAME\"]\n",
+ " docker_password = os.environ[\"AZDATA_NB_VAR_DOCKER_PASSWORD\"]\n",
+ "else:\n",
+ " container_name = 'SQLEDGE-' + time.strftime(\"%Y%m%d%H%M%S\", time.localtime())\n",
+ " docker_registry = 'mcr.microsoft.com'\n",
+ " docker_repository = 'azure-sql-edge-developer'\n",
+ " docker_imagetag = 'latest'\n",
+ " docker_username = ''\n",
+ " docker_password = ''\n",
+ " sql_password = getpass.getpass(prompt = password_name)\n",
+ " password_confirm = getpass.getpass(prompt = f'Confirm {password_name}')\n",
+ " if sql_password != password_confirm:\n",
+ " sys.exit(f'{password_name} does not match the confirmation password.')\n",
+ " sql_port = input('SQL Server port, default value is 1433')\n",
+ " if len(sql_port) == 0:\n",
+ " sql_port = '1433'\n",
+ "print(f'{password_name}: ******')\n",
+ "print(f'Container name: {container_name}')\n",
+ "print(f'Port: {sql_port}')\n",
+ "print(f'Docker registry: {docker_registry}')\n",
+ "print(f'Docker repository: {docker_repository}')\n",
+ "print(f'Image tag: {docker_imagetag}')"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "c0af4e4e-4232-4a67-9a21-05a4d54fd0f4"
+ },
+ "outputs": [],
+ "execution_count": 3
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Pull the container image"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "92acb1bf-590d-426e-a9ee-2643c56dcdbe"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "if docker_username != '':\n",
+ " cmd = f'docker login {docker_registry} -u {docker_username} -p {docker_password}'\n",
+ " run_command()\n",
+ "cmd = f'docker pull {docker_registry}/{docker_repository}:{docker_imagetag}'\n",
+ "run_command()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "58b2156b-da0c-47d5-9706-4bd9f630d28b"
+ },
+ "outputs": [],
+ "execution_count": 4
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Start a new container"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "442e71cd-551b-4b37-8b5a-b814efd27908"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "cmd = f'docker run -e ACCEPT_EULA=Y -e \"SA_PASSWORD={sql_password}\" -p {sql_port}:1433 --name {container_name} -d {docker_registry}/{docker_repository}:{docker_imagetag}'\n",
+ "run_command()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "4cdcf011-06fd-4df4-bd20-3024d0a5ab9d"
+ },
+ "outputs": [],
+ "execution_count": 5
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### List all the containers"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "072a9d13-4fb1-4114-9637-5255be9fcc81"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "cmd = f'docker ps -a'\n",
+ "run_command()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "345dc24f-0028-47b4-b35b-aaac047b7a62"
+ },
+ "outputs": [],
+ "execution_count": 6
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Connect to SQL Server in Azure Data Studio\n",
+ "It might take a couple minutes for SQL Server to launch"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "c84bc075-f8b2-48a3-bfc7-f07a5b8be7a0"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from IPython.display import *\n",
+ "connectionParameter = '{\"serverName\":\"localhost,' + sql_port + '\",\"providerName\":\"MSSQL\",\"authenticationType\":\"SqlLogin\",\"userName\":\"sa\",\"password\":' + json.dumps(sql_password) + '}'\n",
+ "display(HTML('
Click here to connect to SQL Server
'))"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "187a0067-a04c-4afb-a684-3103bb4522ae"
+ },
+ "outputs": [],
+ "execution_count": 7
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Stop and remove the container"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "94322968-02f5-49e5-8ff1-47a9af3c5e83"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "stop_container_command = f'docker stop {container_name}'\n",
+ "remove_container_command = f'docker rm {container_name}'\n",
+ "display(HTML(\"Use this link to: open the terminal window in Azure Data Studio and use the links below to paste the command to the terminal.\"))\n",
+ "display(HTML(\"Stop the container: \" + stop_container_command + \"\"))\n",
+ "display(HTML(\"Remove the container: \" + remove_container_command + \"\"))"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "9b6c34c2-7a47-43f5-971d-ce9768fec587"
+ },
+ "outputs": [],
+ "execution_count": 8
+ }
+ ]
+}
\ No newline at end of file
diff --git a/extensions/asde-deployment/notebooks/edge/deploy-sql-edge-remote.ipynb b/extensions/asde-deployment/notebooks/edge/deploy-sql-edge-remote.ipynb
new file mode 100644
index 0000000000..58ec30f1e0
--- /dev/null
+++ b/extensions/asde-deployment/notebooks/edge/deploy-sql-edge-remote.ipynb
@@ -0,0 +1,366 @@
+{
+ "metadata": {
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python",
+ "version": "3.6.6",
+ "mimetype": "text/x-python",
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "pygments_lexer": "ipython3",
+ "nbconvert_exporter": "python",
+ "file_extension": ".py"
+ }
+ },
+ "nbformat_minor": 2,
+ "nbformat": 4,
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Run Azure SQL DB Edge image on a remote machine with Docker\n",
+ "This notebook will use SSH to connect to the remote machine, use Docker to pull and run the Azure SQL Edge image and connect to it in Azure Data Studio\n",
+ "\n",
+ "\n",
+ "Please press the \"Run all\" button to run the notebook"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "565693e5-39d7-46cf-b0a1-3aa9945c3eed"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Install dependencies"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "b9e09157-54b4-4358-90a2-1a54419bd2cc"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import pandas,sys,getpass,os,json,html,time\n",
+ "pandas_version = pandas.__version__.split('.')\n",
+ "pandas_major = int(pandas_version[0])\n",
+ "pandas_minor = int(pandas_version[1])\n",
+ "pandas_patch = int(pandas_version[2])\n",
+ "if not (pandas_major > 0 or (pandas_major == 0 and pandas_minor > 24) or (pandas_major == 0 and pandas_minor == 24 and pandas_patch >= 2)):\n",
+ " sys.exit('Please upgrade the Notebook dependency before you can proceed, you can do it by running the \"Reinstall Notebook dependencies\" command in command palette (View menu -> Command Paletteā¦).')\n",
+ "\n",
+ "def run_command():\n",
+ " print(\"Executing: \" + cmd)\n",
+ " !{cmd}\n",
+ " if _exit_code != 0:\n",
+ " sys.exit(f'Command execution failed with exit code: {str(_exit_code)}.\\n\\t{cmd}\\n')\n",
+ " print(f'Successfully executed: {cmd}')\n",
+ "\n",
+ "cmd = 'pip install paramiko'\n",
+ "run_command()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "a0a8cd9b-ab0f-4ba2-b568-0c68d950c8bf",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Setting variables"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "7c476b13-05f7-4975-bcb0-8c596bc01e6c"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "env_var_flag = \"AZDATA_NB_VAR_SA_PASSWORD\" in os.environ\n",
+ "password_name = 'SQL Server sa account password'\n",
+ "if env_var_flag:\n",
+ " container_name = os.environ[\"AZDATA_NB_VAR_DOCKER_CONTAINER_NAME\"]\n",
+ " sql_password = os.environ[\"AZDATA_NB_VAR_SA_PASSWORD\"]\n",
+ " sql_port = os.environ[\"AZDATA_NB_VAR_DOCKER_PORT\"]\n",
+ " docker_registry = os.environ[\"AZDATA_NB_VAR_DOCKER_REGISTRY\"]\n",
+ " docker_repository = os.environ[\"AZDATA_NB_VAR_DOCKER_REPOSITORY\"]\n",
+ " docker_imagetag = os.environ[\"AZDATA_NB_VAR_DOCKER_IMAGETAG\"]\n",
+ " docker_username = os.environ[\"AZDATA_NB_VAR_DOCKER_USERNAME\"]\n",
+ " docker_password = os.environ[\"AZDATA_NB_VAR_DOCKER_PASSWORD\"]\n",
+ " ssh_target = os.environ[\"AZDATA_NB_VAR_SSH_TARGET\"]\n",
+ " ssh_username = os.environ[\"AZDATA_NB_VAR_SSH_USERNAME\"]\n",
+ " ssh_password = os.environ[\"AZDATA_NB_VAR_SSH_PASSWORD\"]\n",
+ "else:\n",
+ " container_name = 'SQLEDGE-' + time.strftime(\"%Y%m%d%H%M%S\", time.localtime())\n",
+ " docker_registry = 'mcr.microsoft.com'\n",
+ " docker_repository = 'azure-sql-edge-developer'\n",
+ " docker_imagetag = 'latest'\n",
+ " docker_username = ''\n",
+ " docker_password = ''\n",
+ " sql_password = getpass.getpass(prompt = password_name)\n",
+ " password_confirm = getpass.getpass(prompt = f'Confirm {password_name}')\n",
+ " if sql_password != password_confirm:\n",
+ " sys.exit(f'{password_name} does not match the confirmation password.')\n",
+ " sql_port = input('SQL Server port, default value is 1433')\n",
+ " if len(sql_port) == 0:\n",
+ " sql_port = '1433'\n",
+ " ssh_target = input('Remote machine name or address')\n",
+ " ssh_username = input('Username for remote machine')\n",
+ " ssh_password = input('Password for remote machine')\n",
+ "\n",
+ "print(f'{password_name}: ******')\n",
+ "print(f'Remote machine: {ssh_target}')\n",
+ "print(f'Remote machine username: {ssh_username}')\n",
+ "print(f'Container name: {container_name}')\n",
+ "print(f'Port: {sql_port}')\n",
+ "print(f'Docker registry: {docker_registry}')\n",
+ "print(f'Docker repository: {docker_repository}')\n",
+ "print(f'Image tag: {docker_imagetag}')"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "c0af4e4e-4232-4a67-9a21-05a4d54fd0f4",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Log in to remote machine"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "28593625-0d7a-4dd0-b3bc-fdc3a5500d55"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import paramiko\n",
+ "client = paramiko.SSHClient()\n",
+ "client.set_missing_host_key_policy(paramiko.AutoAddPolicy())\n",
+ "client.connect(ssh_target,username=ssh_username, password=ssh_password)\n",
+ "\n",
+ "def run_command_remote():\n",
+ " stdin, stdout, stderr = client.exec_command(f'bash --login -c \"{cmd}\"')\n",
+ " for line in stdout:\n",
+ " print(line.strip('\\n'))\n",
+ " stderr = stderr.readlines()\n",
+ " if len(stderr) != 0:\n",
+ " for line in stderr:\n",
+ " print(line.strip('\\n'))\n",
+ " sys.exit(f'Command execution failed')\n",
+ " else:\n",
+ " print(f'Command executed successfully')"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "aadaa458-8c23-4b7a-a87e-cb2ee82046cf",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Check dependencies on remote machine"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "20d6ec5d-b706-4086-b583-6175c44740f2"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "cmd = 'docker version'\n",
+ "run_command_remote()\n",
+ ""
+ ],
+ "metadata": {
+ "azdata_cell_guid": "f3f3946b-d950-477d-83d6-8bae320f619f",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### List all the containers"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "85a12b48-3f7b-4181-bf91-90d3069bd0d8"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "cmd = 'docker ps -a'\n",
+ "run_command_remote()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "8b2874af-de7e-4a0a-9cad-3be397eaa3e9",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Pull the container image"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "92acb1bf-590d-426e-a9ee-2643c56dcdbe"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "if docker_username != '':\n",
+ " cmd = f'docker login {docker_registry} -u {docker_username} -p {docker_password}'\n",
+ " run_command_remote()\n",
+ "cmd = f'docker pull {docker_registry}/{docker_repository}:{docker_imagetag}'\n",
+ "run_command_remote()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "58b2156b-da0c-47d5-9706-4bd9f630d28b",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Start a new container"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "442e71cd-551b-4b37-8b5a-b814efd27908"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "cmd = f'docker run -e ACCEPT_EULA=Y -e \"SA_PASSWORD={sql_password}\" -p {sql_port}:1433 --name {container_name} -d {docker_registry}/{docker_repository}:{docker_imagetag}'\n",
+ "run_command_remote()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "4cdcf011-06fd-4df4-bd20-3024d0a5ab9d",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### List all the containers"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "072a9d13-4fb1-4114-9637-5255be9fcc81"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "cmd = f'docker ps -a'\n",
+ "run_command_remote()"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "345dc24f-0028-47b4-b35b-aaac047b7a62",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Connect to SQL Server in Azure Data Studio\n",
+ "It might take a couple minutes for SQL Server to launch"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "c84bc075-f8b2-48a3-bfc7-f07a5b8be7a0"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from IPython.display import *\n",
+ "connectionParameter = '{\"serverName\":\"' + ssh_target + ',' + sql_port + '\",\"providerName\":\"MSSQL\",\"authenticationType\":\"SqlLogin\",\"userName\":\"sa\",\"password\":' + json.dumps(sql_password) + '}'\n",
+ "display(HTML('
Click here to connect to SQL Server
'))"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "187a0067-a04c-4afb-a684-3103bb4522ae",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### Stop and remove the container\n",
+ "Please copy the output of this cell into the next empty code cell and run the cell to stop and remove the container"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "94322968-02f5-49e5-8ff1-47a9af3c5e83"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "remove_container_command = f'cmd = f\\'docker rm {container_name}\\'\\nrun_command_remote()'\n",
+ "stop_container_command = f'cmd = f\\'docker stop {container_name}\\'\\nrun_command_remote()'\n",
+ "print(stop_container_command)\n",
+ "print(remove_container_command)"
+ ],
+ "metadata": {
+ "azdata_cell_guid": "9b6c34c2-7a47-43f5-971d-ce9768fec587",
+ "tags": [
+ "hide_input"
+ ]
+ },
+ "outputs": [],
+ "execution_count": null
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ ""
+ ],
+ "metadata": {
+ "azdata_cell_guid": "9f2c9d3a-b996-4977-81f5-05a79a2e0e12",
+ "tags": []
+ },
+ "outputs": [],
+ "execution_count": null
+ }
+ ]
+}
\ No newline at end of file
diff --git a/extensions/asde-deployment/package.json b/extensions/asde-deployment/package.json
new file mode 100644
index 0000000000..3fb7578a79
--- /dev/null
+++ b/extensions/asde-deployment/package.json
@@ -0,0 +1,276 @@
+{
+ "name": "asde-deployment",
+ "displayName": "%extension-displayName%",
+ "description": "%extension-description%",
+ "version": "0.1.0",
+ "publisher": "Microsoft",
+ "preview": true,
+ "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
+ "icon": "images/extension.png",
+ "aiKey": "AIF-444c3af9-8e69-4462-ab49-4191e6ad1916",
+ "engines": {
+ "vscode": "*",
+ "azdata": "*"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Microsoft/azuredatastudio.git"
+ },
+ "forceReload": true,
+ "contributes": {
+ "resourceDeploymentTypes": [
+ {
+ "name": "sql-edge",
+ "enabled": false,
+ "displayName": "%resource-type-sql-edge-display-name%",
+ "description": "%resource-type-sql-edge-description%",
+ "platforms": "*",
+ "icon": {
+ "light": "./images/sqldb_edge.svg",
+ "dark": "./images/sqldb_edge_inverse.svg"
+ },
+ "options": [
+ {
+ "name": "type",
+ "displayName": "%sql-edge-type-display-name%",
+ "values": [
+ {
+ "name": "local",
+ "displayName": "%sql-edge-local-display-name%"
+ },
+ {
+ "name": "remote",
+ "displayName": "%sql-edge-remote-display-name%"
+ }
+ ]
+ }
+ ],
+ "providers": [
+ {
+ "dialog": {
+ "notebook": "%sql-edge-local-notebook%",
+ "title": "%sql-edge-local-title%",
+ "name": "sql-edge-local-dialog",
+ "tabs": [
+ {
+ "title": "",
+ "sections": [
+ {
+ "title": "",
+ "fields": [
+ {
+ "label": "%docker-container-name-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_CONTAINER_NAME",
+ "type": "datetime_text",
+ "defaultValue": "SQLEDGE-",
+ "required": true
+ },
+ {
+ "label": "%docker-sql-password-field%",
+ "variableName": "AZDATA_NB_VAR_SA_PASSWORD",
+ "type": "sql_password",
+ "userName": "sa",
+ "confirmationRequired": true,
+ "confirmationLabel": "%docker-confirm-sql-password-field%",
+ "defaultValue": "",
+ "required": true
+ },
+ {
+ "label": "%docker-sql-port-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_PORT",
+ "type": "number",
+ "defaultValue": "1433",
+ "required": true,
+ "min": 1,
+ "max": 65535
+ }
+ ]
+ },
+ {
+ "title": "%docker-settings-section-title%",
+ "collapsible": true,
+ "collapsed": true,
+ "fields": [
+ {
+ "label": "%docker-registry-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_REGISTRY",
+ "type": "text",
+ "defaultValue": "mcr.microsoft.com",
+ "required": true
+ },
+ {
+ "label": "%docker-repository-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_REPOSITORY",
+ "type": "text",
+ "defaultValue": "azure-sql-edge-developer",
+ "required": true
+ },
+ {
+ "label": "%docker-imagetag-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_IMAGETAG",
+ "type": "text",
+ "defaultValue": "latest",
+ "required": true
+ },
+ {
+ "label": "%docker-username-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_USERNAME",
+ "type": "text",
+ "defaultValue": "",
+ "required": false
+ },
+ {
+ "label": "%docker-password-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_PASSWORD",
+ "type": "password",
+ "defaultValue": "",
+ "required": false
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "requiredTools": [
+ {
+ "name": "docker"
+ }
+ ],
+ "when": "type=local"
+ },
+ {
+ "dialog": {
+ "notebook": "%sql-edge-remote-notebook%",
+ "title": "%sql-edge-remote-title%",
+ "name": "sql-edge-remote-dialog",
+ "tabs": [
+ {
+ "title": "",
+ "sections": [
+ {
+ "title": "",
+ "fields": [
+ {
+ "label": "%docker-container-name-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_CONTAINER_NAME",
+ "type": "datetime_text",
+ "defaultValue": "SQLEDGE-",
+ "required": true
+ },
+ {
+ "label": "%docker-sql-password-field%",
+ "variableName": "AZDATA_NB_VAR_SA_PASSWORD",
+ "type": "sql_password",
+ "userName": "sa",
+ "confirmationRequired": true,
+ "confirmationLabel": "%docker-confirm-sql-password-field%",
+ "defaultValue": "",
+ "required": true
+ },
+ {
+ "label": "%docker-sql-port-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_PORT",
+ "type": "number",
+ "defaultValue": "1433",
+ "required": true,
+ "min": 1,
+ "max": 65535
+ }
+ ]
+ },
+ {
+ "title": "%remote-info-section-title%",
+ "collapsible": true,
+ "collapsed": false,
+ "fields": [
+ {
+ "label": "%edge-remote-target-field%",
+ "variableName": "AZDATA_NB_VAR_SSH_TARGET",
+ "type": "text",
+ "defaultValue": "",
+ "required": true
+ },
+ {
+ "label": "%edge-remote-username-field%",
+ "variableName": "AZDATA_NB_VAR_SSH_USERNAME",
+ "type": "text",
+ "defaultValue": "",
+ "required": true
+ },
+ {
+ "label": "%edge-remote-password-field%",
+ "variableName": "AZDATA_NB_VAR_SSH_PASSWORD",
+ "type": "password",
+ "defaultValue": "",
+ "required": true
+ }
+ ]
+ },
+ {
+ "title": "%docker-settings-section-title%",
+ "collapsible": true,
+ "collapsed": true,
+ "fields": [
+ {
+ "label": "%docker-registry-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_REGISTRY",
+ "type": "text",
+ "defaultValue": "mcr.microsoft.com",
+ "required": true
+ },
+ {
+ "label": "%docker-repository-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_REPOSITORY",
+ "type": "text",
+ "defaultValue": "azure-sql-edge-developer",
+ "required": true
+ },
+ {
+ "label": "%docker-imagetag-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_IMAGETAG",
+ "type": "text",
+ "defaultValue": "latest",
+ "required": true
+ },
+ {
+ "label": "%docker-username-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_USERNAME",
+ "type": "text",
+ "defaultValue": "",
+ "required": false
+ },
+ {
+ "label": "%docker-password-field%",
+ "variableName": "AZDATA_NB_VAR_DOCKER_PASSWORD",
+ "type": "password",
+ "defaultValue": "",
+ "required": false
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "requiredTools": [],
+ "when": "type=remote"
+ }
+ ],
+ "agreement": {
+ "template": "%edge-agreement%",
+ "links": [
+ {
+ "text": "%microsoft-privacy-statement%",
+ "url": "https://go.microsoft.com/fwlink/?LinkId=853010"
+ },
+ {
+ "text": "%edge-eula%",
+ "url": "https://go.microsoft.com/fwlink/?LinkId=746388"
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
diff --git a/extensions/asde-deployment/package.nls.json b/extensions/asde-deployment/package.nls.json
new file mode 100644
index 0000000000..63f548e556
--- /dev/null
+++ b/extensions/asde-deployment/package.nls.json
@@ -0,0 +1,30 @@
+{
+ "extension-displayName": "Azure SQL DB Edge Deployment Extension",
+ "extension-description": "Provides a notebook-based experience to deploy Azure SQL DB Edge",
+ "docker-container-name-field": "Container name",
+ "docker-sql-password-field": "SQL Server password",
+ "docker-confirm-sql-password-field": "Confirm password",
+ "docker-sql-port-field": "Port",
+ "microsoft-privacy-statement": "Microsoft Privacy Statement",
+ "resource-type-sql-edge-display-name": "Azure SQL DB Edge",
+ "resource-type-sql-edge-description": "Deploy Azure SQL DB Edge (Preview)",
+ "sql-edge-type-display-name": "Type",
+ "sql-edge-local-display-name": "Local",
+ "sql-edge-remote-display-name": "Remote",
+ "sql-edge-local-notebook": "./notebooks/edge/deploy-sql-edge-local.ipynb",
+ "sql-edge-local-title": "Deploy Azure SQL DB Edge locally",
+ "docker-settings-section-title": "Docker settings",
+ "docker-registry-field": "Registry",
+ "docker-repository-field": "Repository",
+ "docker-imagetag-field": "Image tag",
+ "docker-username-field": "Username",
+ "docker-password-field": "Password",
+ "edge-agreement": "I accept {0} and {1}.",
+ "edge-eula": "Microsoft SQL Server License Agreement",
+ "sql-edge-remote-notebook": "./notebooks/edge/deploy-sql-edge-remote.ipynb",
+ "sql-edge-remote-title": "Deploy Azure SQL DB Edge on a remote machine",
+ "remote-info-section-title": "Target machine information",
+ "edge-remote-target-field": "Name or IP address",
+ "edge-remote-username-field": "Username",
+ "edge-remote-password-field": "Password"
+}
diff --git a/extensions/resource-deployment/package.json b/extensions/resource-deployment/package.json
index fd46c1bc52..f1b1e66ec8 100644
--- a/extensions/resource-deployment/package.json
+++ b/extensions/resource-deployment/package.json
@@ -291,7 +291,7 @@
"template": "%bdc-agreement%",
"links": [
{
- "text": "%bdc-agreement-privacy-statement%",
+ "text": "%microsoft-privacy-statement%",
"url": "https://go.microsoft.com/fwlink/?LinkId=853010"
},
{
diff --git a/extensions/resource-deployment/package.nls.json b/extensions/resource-deployment/package.nls.json
index db2223270a..44e2438a22 100644
--- a/extensions/resource-deployment/package.nls.json
+++ b/extensions/resource-deployment/package.nls.json
@@ -45,7 +45,7 @@
"resource-type-sql-windows-setup-display-name": "SQL Server on Windows",
"resource-type-sql-windows-setup-description": "Run SQL Server on Windows, select a version to get started.",
"bdc-agreement": "I accept {0}, {1} and {2}.",
- "bdc-agreement-privacy-statement": "Microsoft Privacy Statement",
+ "microsoft-privacy-statement": "Microsoft Privacy Statement",
"bdc-agreement-azdata-eula": "azdata License Terms",
"bdc-agreement-bdc-eula": "SQL Server License Terms",
"deployment.configuration.title": "Deployment configuration",
diff --git a/extensions/resource-deployment/src/test/resourceTypeService.test.ts b/extensions/resource-deployment/src/test/resourceTypeService.test.ts
index b2396599cb..38af15a48b 100644
--- a/extensions/resource-deployment/src/test/resourceTypeService.test.ts
+++ b/extensions/resource-deployment/src/test/resourceTypeService.test.ts
@@ -19,23 +19,29 @@ suite('Resource Type Service Tests', function (): void {
const toolsService = new ToolsService(mockPlatformService.object);
const notebookService = new NotebookService(mockPlatformService.object, '');
const resourceTypeService = new ResourceTypeService(mockPlatformService.object, toolsService, notebookService);
- // index 0: platform name, index 1: number of expected resource types
- const platforms: { platform: string; resourceTypeCount: number }[] = [
- { platform: 'win32', resourceTypeCount: 3 },
- { platform: 'darwin', resourceTypeCount: 2 },
- { platform: 'linux', resourceTypeCount: 2 }];
- const totalResourceTypeCount = 3;
+ // 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: 'darwin', resourceTypes: ['sql-image', 'sql-bdc']
+ },
+ {
+ platform: 'linux', resourceTypes: ['sql-image', 'sql-bdc']
+ }
+ ];
platforms.forEach(platformInfo => {
mockPlatformService.reset();
mockPlatformService.setup(service => service.platform()).returns(() => platformInfo.platform);
mockPlatformService.setup(service => service.showErrorMessage(TypeMoq.It.isAnyString()));
- const resourceTypes = resourceTypeService.getResourceTypes(true);
- assert.equal(resourceTypes.length, platformInfo.resourceTypeCount, `number of resource types for platform:${platformInfo.resourceTypeCount} does not meet expected value:${resourceTypes.length}.`);
+ const resourceTypes = resourceTypeService.getResourceTypes(true).map(rt => rt.name);
+ for (let i = 0; i < platformInfo.resourceTypes.length; i++) {
+ assert(resourceTypes.indexOf(platformInfo.resourceTypes[i]) !== -1, `resource type '${platformInfo.resourceTypes[i]}' should be available for platform: ${platformInfo.platform}.`);
+ }
});
const allResourceTypes = resourceTypeService.getResourceTypes(false);
- assert.equal(allResourceTypes.length, totalResourceTypeCount, `number of resource types:${allResourceTypes.length} does not meet expected value:${totalResourceTypeCount}.`);
-
const validationErrors = resourceTypeService.validateResourceTypes(allResourceTypes);
assert(validationErrors.length === 0, `Validation errors detected in the package.json: ${validationErrors.join(EOL)}.`);
});