Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Service Connector] az webapp connection create fabric-sql: Fix interactive mode & allow new parameters --fabric-workspace-uuid and fabric-sql-db-uuid #30881

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from azure.cli.core.commands.validators import get_default_location_from_resource_group

from ._validators import (
validate_connstr_props,
validate_params,
validate_kafka_params,
validate_local_params,
Expand All @@ -34,7 +35,7 @@
)
from ._addon_factory import AddonFactory
from knack.arguments import CLIArgumentType
from .action import AddCustomizedKeys, AddAdditionalConnectionStringProperties
from .action import AddAdditionalConnectionStringProperties, AddCustomizedKeys


def add_source_resource_block(context, source, enable_id=True, target=None):
Expand Down Expand Up @@ -184,7 +185,8 @@ def add_connstr_props_argument(context):
# linter: length '--additional-connection-string-properties' longer than 22, so use abbreviation
context.argument('connstr_props', options_list=['--connstr-props'],
action=AddAdditionalConnectionStringProperties, nargs='*',
help='The addtional connection string properties used to for building connection string.')
help='The additional connection string properties used to build connection string.',
validator=validate_connstr_props)


def add_target_type_argument(context, source):
Expand Down Expand Up @@ -317,6 +319,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements
add_customized_keys_argument(c)
add_opt_out_argument(c)
add_connstr_props_argument(c)

with self.argument_context('{} connection update {}'.format(source.value, target.value)) as c:
add_client_type_argument(c, source, target)
add_connection_name_argument(c, source)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ class CLIENT_TYPE(Enum):

RESOURCE.ContainerApp: '/subscriptions/{subscription}/resourceGroups/{target_resource_group}/providers/Microsoft.App/containerApps/{target_app_name}',

RESOURCE.FabricSql: 'https://api.fabric.microsoft.com/v1/workspaces/{workspace_id}/SqlDatabases/{sql_id}'
RESOURCE.FabricSql: 'https://api.fabric.microsoft.com/v1/workspaces/{fabric_workspace_uuid}/SqlDatabases/{fabric_sql_db_uuid}'
}


Expand Down Expand Up @@ -670,6 +670,16 @@ class CLIENT_TYPE(Enum):
}
},
RESOURCE.FabricSql: {
'fabric_workspace_uuid': {
'options': ['--fabric-workspace-uuid'],
'help': 'UUID of Fabric workspace which contains the target SQL database',
'placeholder': 'TargetFabricWorkspaceUUID'
},
'fabric_sql_db_uuid': {
'options': ['--fabric-sql-db-uuid'],
'help': 'UUID of the target Fabric SQL database',
'placeholder': 'TargetFabricSQLDatabaseUUID'
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# --------------------------------------------------------------------------------------------

import re
import requests
import random
import string

Expand Down Expand Up @@ -104,13 +105,39 @@ def check_required_args(resource, cmd_arg_values):
'''Check whether a resource's required arguments are in cmd_arg_values
'''
args = re.findall(r'\{([^\{\}]*)\}', resource)
args.remove('subscription')

if 'subscription' in args:
args.remove('subscription')
for arg in args:
if not cmd_arg_values.get(arg, None):
return False
return True


def get_fabric_access_token():
get_fabric_token_cmd = 'az account get-access-token --output json --resource https://api.fabric.microsoft.com/'
return run_cli_cmd(get_fabric_token_cmd).get('accessToken')


def generate_fabric_connstr_props(target_id):
fabric_token = get_fabric_access_token()
headers = {"Authorization": "Bearer {}".format(fabric_token)}
response = requests.get(target_id, headers=headers)

if response:
response_json = response.json()

if "properties" in response_json:
properties = response_json["properties"]
if "databaseName" in properties and "serverFqdn" in properties:
return {
"Server": properties["serverFqdn"],
"Database": properties["databaseName"]
}

return None


def generate_connection_name(cmd):
'''Generate connection name for users if not provided
'''
Expand Down Expand Up @@ -942,6 +969,25 @@ def _validate_and_apply(validate, apply):
namespace.client_type = get_client_type(cmd, namespace)


def validate_connstr_props(cmd, namespace):
if 'create {}'.format(RESOURCE.FabricSql.value) in cmd.name:
if getattr(namespace, 'connstr_props', None) is None:
namespace.connstr_props = generate_fabric_connstr_props(namespace.target_id)

if namespace.connstr_props is None:
e = InvalidArgumentValueError("Fabric Connection String Properties must be provided")
telemetry.set_exception('fabric-connstr-props-unavailable')
raise e
else:
fabric_server = namespace.connstr_props.get('Server') or namespace.connstr_props.get('Data Source')
fabric_database = namespace.connstr_props.get('Database') or namespace.connstr_props.get('Initial Catalog')

if not fabric_server or not fabric_database:
e = InvalidArgumentValueError("Fabric Connection String Properties must contain Server and Database")
telemetry.set_exception('fabric-connstr-props-invalid')
raise e


def validate_service_state(linker_parameters):
'''Validate whether user provided params are applicable to service state
'''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ def connection_create(cmd, client, # pylint: disable=too-many-locals,too-many-s
appinsights=None, # Resource.AppInsights
target_app_name=None, # Resource.ContainerApp
connstr_props=None, # Resource.FabricSql
fabric_workspace_uuid=None,
fabric_sql_db_uuid=None
):
auth_action = 'optOutAllAuth' if (opt_out_list is not None and
OPT_OUT_OPTION.AUTHENTICATION.value in opt_out_list) else None
Expand All @@ -336,15 +338,17 @@ def connection_create(cmd, client, # pylint: disable=too-many-locals,too-many-s
user_identity_auth_info, system_identity_auth_info,
service_principal_auth_info_secret,
key_vault_id,
app_config_id,
service_endpoint,
private_endpoint,
store_in_connection_string,
new_addon, no_wait,
cluster, scope, enable_csi,
cluster=cluster, scope=scope, enable_csi=enable_csi,
customized_keys=customized_keys,
opt_out_list=opt_out_list,
app_config_id=app_config_id,
connstr_props=connstr_props)
connstr_props=connstr_props,
fabric_workspace_uuid=fabric_workspace_uuid,
fabric_sql_db_uuid=fabric_sql_db_uuid)
raise CLIInternalError("Fail to install `serviceconnector-passwordless` extension. Please manually install it"
" with `az extension add --name serviceconnector-passwordless --upgrade`"
" and rerun the command")
Expand Down
Loading