Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
613590f
start SWA hawaii commands
StrawnSC Aug 31, 2022
8bfad38
TODO
StrawnSC Nov 30, 2022
8568d17
refactor DB-dependent logic
StrawnSC Dec 1, 2022
845b6b4
add connection string logic for non-pgsql databases
StrawnSC Dec 1, 2022
72fd1dd
add params and pgsql flex connection string logic
StrawnSC Dec 2, 2022
1e4b2c7
add connection string logic for pgsql single; minor refactor
StrawnSC Dec 2, 2022
b3bcaae
finish DB connection string logic; add warning text for providing unn…
StrawnSC Dec 2, 2022
8ba5377
start style fixes
StrawnSC Dec 13, 2022
3714589
merge
StrawnSC Dec 13, 2022
448677a
Merge branch 'main' into swa-dbconnection
StrawnSC Dec 14, 2022
ebe018e
remove connection string overriding; use DB server RIDs instead of DB…
StrawnSC Dec 15, 2022
86fd990
update for change in detailed show API
StrawnSC Dec 15, 2022
ed5ea02
bump version for test
StrawnSC Dec 15, 2022
845ef3d
allow creating db connection on the site and not just the build
StrawnSC Dec 15, 2022
d58d7c6
connection string auth tests
StrawnSC Dec 15, 2022
7243217
fix
StrawnSC Dec 19, 2022
bfc0d43
mark command group as preview
StrawnSC Jan 24, 2023
2016b07
Merge branch 'swa-dbconnection-builds' into swa-dbconnection
StrawnSC Jan 30, 2023
07f6f21
change logic for SWA builds
StrawnSC Jan 30, 2023
b293ffe
fix style/linter issues
StrawnSC Jan 31, 2023
c950bd2
fix codeowners
StrawnSC Jan 31, 2023
2dccd53
update connection string formats
StrawnSC Feb 1, 2023
e314e1a
fix exception on delete
StrawnSC Feb 13, 2023
b754af2
update initial release version
StrawnSC Feb 13, 2023
d89fb2b
Update src/staticwebapp/azext_staticwebapp/_help.py
zhoxing-ms Mar 14, 2023
11b3ba3
Apply suggestions from code review
zhoxing-ms Mar 14, 2023
8b80723
Apply suggestions from code review
zhoxing-ms Mar 14, 2023
0046229
Update src/staticwebapp/azext_staticwebapp/azext_metadata.json
zhoxing-ms Mar 14, 2023
da969a2
rerecord failing tests
StrawnSC Mar 14, 2023
6e62dcc
add confirmation to delete command; inform user of the supported conn…
StrawnSC Mar 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@

/src/fleet/ @pdaru

/src/staticwebapp/ @strawnsc

/src/traffic-collector/ @rmodh @japani @kukulkarni1

/src/nginx/ @liftr-nginx
Expand Down
8 changes: 8 additions & 0 deletions src/staticwebapp/HISTORY.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.. :changelog:

Release History
===============

1.0.0
++++++
* Add commands to manage Static Web App database connections: `az staticwebapp dbconnection create/show/delete`
5 changes: 5 additions & 0 deletions src/staticwebapp/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Microsoft Azure CLI 'staticwebapp' Extension
==========================================

This package is for the 'staticwebapp' extension.
i.e. 'az staticwebapp'
31 changes: 31 additions & 0 deletions src/staticwebapp/azext_staticwebapp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azure.cli.core import AzCommandsLoader

from azext_staticwebapp._help import helps # pylint: disable=unused-import


class StaticwebappCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
staticwebapp_custom = CliCommandType(
operations_tmpl='azext_staticwebapp.custom#{}',
client_factory=None)
super(StaticwebappCommandsLoader, self).__init__(cli_ctx=cli_ctx,
custom_command_type=staticwebapp_custom)

def load_command_table(self, args):
from azext_staticwebapp.commands import load_command_table
load_command_table(self, args)
return self.command_table

def load_arguments(self, command):
from azext_staticwebapp._params import load_arguments
load_arguments(self, command)


COMMAND_LOADER_CLS = StaticwebappCommandsLoader
4 changes: 4 additions & 0 deletions src/staticwebapp/azext_staticwebapp/_client_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
138 changes: 138 additions & 0 deletions src/staticwebapp/azext_staticwebapp/_clients.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import json

from azure.cli.core.util import send_raw_request
from azure.cli.core.commands.client_factory import get_subscription_id


API_VERSION = "2022-03-01"


class DbConnectionClient():
@classmethod
def create_or_update(cls, cmd, resource_group_name, name, environment, connection_name="default",
db_connection=None):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
if environment:
url_fmt = ("{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Web/staticsites/{}/builds/{}"
"/databaseConnections/{}?api-version={}")
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
environment,
connection_name,
api_version)
Comment thread
zhoxing-ms marked this conversation as resolved.
else:
url_fmt = ("{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Web/staticsites/{}"
"/databaseConnections/{}?api-version={}")
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
connection_name,
api_version)

r = send_raw_request(cmd.cli_ctx, "PUT", request_url, body=json.dumps(db_connection))
return r.json()

@classmethod
def show(cls, cmd, resource_group_name, name, environment, connection_name="default", detailed=False):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
if environment:
url_fmt = ("{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Web/staticsites/{}/builds/{}"
"/databaseConnections/{}?api-version={}")
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
environment,
connection_name,
api_version)
else:
url_fmt = ("{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Web/staticsites/{}"
"/databaseConnections/{}?api-version={}")
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
connection_name,
api_version)

verb = "GET" if not detailed else "POST"

r = send_raw_request(cmd.cli_ctx, verb, request_url)
return r.json()

@classmethod
def list(cls, cmd, resource_group_name, name, environment, connection_name="default", detailed=False):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
if environment:
url_fmt = ("{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Web/staticsites/{}/builds/{}"
"/databaseConnections/{}?api-version={}")
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
environment,
connection_name if not detailed else f"{connection_name}/show",
api_version)
else:
url_fmt = ("{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Web/staticsites/{}"
"/databaseConnections/{}?api-version={}")
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
connection_name if not detailed else f"{connection_name}/show",
api_version)

verb = "GET" if not detailed else "POST"

r = send_raw_request(cmd.cli_ctx, verb, request_url)
return r.json()

@classmethod
def delete(cls, cmd, resource_group_name, name, environment, connection_name="default"):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
if environment:
url_fmt = ("{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Web/staticsites/{}/builds/{}"
"/databaseConnections/{}?api-version={}")
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
environment,
connection_name,
api_version)
else:
url_fmt = ("{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Web/staticsites/{}"
"/databaseConnections/{}?api-version={}")
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
connection_name,
api_version)

send_raw_request(cmd.cli_ctx, "DELETE", request_url)
28 changes: 28 additions & 0 deletions src/staticwebapp/azext_staticwebapp/_help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# coding=utf-8
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from knack.help_files import helps # pylint: disable=unused-import


helps['staticwebapp dbconnection'] = """
type: group
short-summary: Manage Static Web App database connections.
"""

helps['staticwebapp dbconnection create'] = """
type: command
short-summary: Create a Static Web App database connection.
"""

helps['staticwebapp dbconnection show'] = """
type: command
short-summary: Get details for a Static Web App database connection.
"""

helps['staticwebapp dbconnection delete'] = """
type: command
short-summary: Delete a Static Web App database connection.
"""
14 changes: 14 additions & 0 deletions src/staticwebapp/azext_staticwebapp/_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------


DbConnection = {
"properties": {
"resourceId": None,
"connectionIdentity": None,
"region": None,
"connectionString": None,
}
}
28 changes: 28 additions & 0 deletions src/staticwebapp/azext_staticwebapp/_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------


def load_arguments(self, _):

from azure.cli.core.commands.parameters import resource_group_name_type

with self.argument_context('staticwebapp dbconnection') as c:
c.argument('name', options_list=['--name', '-n'], help="Name of the Static Web App.")
c.argument('resource_group_name', resource_group_name_type)
c.argument('environment', help="Name of the environment of Static Web App.",
options_list=["--environment", "-e"])

with self.argument_context('staticwebapp dbconnection create') as c:
c.argument('db_resource_id', options_list=['--db-resource-id', '-d'],
help="The azure resource ID for the database server/account to connect to e.g. '/subscriptions/MySubId/resourceGroups/MyResourceGroup/providers/Microsoft.Sql/servers/MyServer' for an Azure SQL database.")
c.argument('db_name', options_list=['--db-name', '-b'], help="The name of the database to connect to. Not required for CosmosDB.")
c.argument('username', options_list=["--username", "-u"], help="The username to use for authentication with the database. Not required for all databases.")
c.argument('password', options_list=["--password", "-p"], help="The password to use for authentication with the database. Not required for all databases.")
c.argument('mi_user_assigned', options_list=["--mi-user-assigned", "-i"], help="A resource ID for a user-assigned managed identity to use for auth with the database. Must be assigned to the Static Web App and have the right permissions on the database.")
Comment thread
zhoxing-ms marked this conversation as resolved.
c.argument('mi_system_assigned', options_list=["--mi-system-assigned", "-s"], help="Use the Static Web App's system-assigned identity for auth with the database. Must be assigned to the Static Web App and have the right permissions on the database.")

with self.argument_context('staticwebapp dbconnection show') as c:
c.argument('detailed', options_list=['--detailed', '-d'], action='store_true',
default=False, help="Get detailed information on database connections.")
Loading