Skip to content

Commit bace898

Browse files
Tonychen0227Tony Chen (DevDiv)
authored andcommitted
[Service Connector] az webapp connection create fabric-sql: Fix interactive mode & allow new parameters --fabric-workspace-uuid and fabric-sql-db-uuid (Azure#30881)
* Full solution with test success * Small fix * Remove unnecessary custom changes * Recording * Fix comment out unit test * Add app config id fix * add back custom.py changes * Review comments * style style --------- Co-authored-by: Tony Chen (DevDiv) <chentony@microsoft.com>
1 parent 3e1feab commit bace898

File tree

6 files changed

+939
-715
lines changed

6 files changed

+939
-715
lines changed

src/azure-cli/azure/cli/command_modules/serviceconnector/_params.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from azure.cli.core.commands.validators import get_default_location_from_resource_group
1212

1313
from ._validators import (
14+
validate_connstr_props,
1415
validate_params,
1516
validate_kafka_params,
1617
validate_local_params,
@@ -34,7 +35,7 @@
3435
)
3536
from ._addon_factory import AddonFactory
3637
from knack.arguments import CLIArgumentType
37-
from .action import AddCustomizedKeys, AddAdditionalConnectionStringProperties
38+
from .action import AddAdditionalConnectionStringProperties, AddCustomizedKeys
3839

3940

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

189191

190192
def add_target_type_argument(context, source):
@@ -317,6 +319,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements
317319
add_customized_keys_argument(c)
318320
add_opt_out_argument(c)
319321
add_connstr_props_argument(c)
322+
320323
with self.argument_context('{} connection update {}'.format(source.value, target.value)) as c:
321324
add_client_type_argument(c, source, target)
322325
add_connection_name_argument(c, source)

src/azure-cli/azure/cli/command_modules/serviceconnector/_resource_config.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class CLIENT_TYPE(Enum):
155155

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

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

161161

@@ -670,6 +670,16 @@ class CLIENT_TYPE(Enum):
670670
}
671671
},
672672
RESOURCE.FabricSql: {
673+
'fabric_workspace_uuid': {
674+
'options': ['--fabric-workspace-uuid'],
675+
'help': 'UUID of Fabric workspace which contains the target SQL database',
676+
'placeholder': 'TargetFabricWorkspaceUUID'
677+
},
678+
'fabric_sql_db_uuid': {
679+
'options': ['--fabric-sql-db-uuid'],
680+
'help': 'UUID of the target Fabric SQL database',
681+
'placeholder': 'TargetFabricSQLDatabaseUUID'
682+
}
673683
}
674684
}
675685

src/azure-cli/azure/cli/command_modules/serviceconnector/_validators.py

+47-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# --------------------------------------------------------------------------------------------
55

66
import re
7+
import requests
78
import random
89
import string
910

@@ -104,13 +105,39 @@ def check_required_args(resource, cmd_arg_values):
104105
'''Check whether a resource's required arguments are in cmd_arg_values
105106
'''
106107
args = re.findall(r'\{([^\{\}]*)\}', resource)
107-
args.remove('subscription')
108+
109+
if 'subscription' in args:
110+
args.remove('subscription')
108111
for arg in args:
109112
if not cmd_arg_values.get(arg, None):
110113
return False
111114
return True
112115

113116

117+
def get_fabric_access_token():
118+
get_fabric_token_cmd = 'az account get-access-token --output json --resource https://api.fabric.microsoft.com/'
119+
return run_cli_cmd(get_fabric_token_cmd).get('accessToken')
120+
121+
122+
def generate_fabric_connstr_props(target_id):
123+
fabric_token = get_fabric_access_token()
124+
headers = {"Authorization": "Bearer {}".format(fabric_token)}
125+
response = requests.get(target_id, headers=headers)
126+
127+
if response:
128+
response_json = response.json()
129+
130+
if "properties" in response_json:
131+
properties = response_json["properties"]
132+
if "databaseName" in properties and "serverFqdn" in properties:
133+
return {
134+
"Server": properties["serverFqdn"],
135+
"Database": properties["databaseName"]
136+
}
137+
138+
return None
139+
140+
114141
def generate_connection_name(cmd):
115142
'''Generate connection name for users if not provided
116143
'''
@@ -942,6 +969,25 @@ def _validate_and_apply(validate, apply):
942969
namespace.client_type = get_client_type(cmd, namespace)
943970

944971

972+
def validate_connstr_props(cmd, namespace):
973+
if 'create {}'.format(RESOURCE.FabricSql.value) in cmd.name:
974+
if getattr(namespace, 'connstr_props', None) is None:
975+
namespace.connstr_props = generate_fabric_connstr_props(namespace.target_id)
976+
977+
if namespace.connstr_props is None:
978+
e = InvalidArgumentValueError("Fabric Connection String Properties must be provided")
979+
telemetry.set_exception('fabric-connstr-props-unavailable')
980+
raise e
981+
else:
982+
fabric_server = namespace.connstr_props.get('Server') or namespace.connstr_props.get('Data Source')
983+
fabric_database = namespace.connstr_props.get('Database') or namespace.connstr_props.get('Initial Catalog')
984+
985+
if not fabric_server or not fabric_database:
986+
e = InvalidArgumentValueError("Fabric Connection String Properties must contain Server and Database")
987+
telemetry.set_exception('fabric-connstr-props-invalid')
988+
raise e
989+
990+
945991
def validate_service_state(linker_parameters):
946992
'''Validate whether user provided params are applicable to service state
947993
'''

src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ def connection_create(cmd, client, # pylint: disable=too-many-locals,too-many-s
316316
appinsights=None, # Resource.AppInsights
317317
target_app_name=None, # Resource.ContainerApp
318318
connstr_props=None, # Resource.FabricSql
319+
fabric_workspace_uuid=None,
320+
fabric_sql_db_uuid=None
319321
):
320322
auth_action = 'optOutAllAuth' if (opt_out_list is not None and
321323
OPT_OUT_OPTION.AUTHENTICATION.value in opt_out_list) else None
@@ -336,15 +338,17 @@ def connection_create(cmd, client, # pylint: disable=too-many-locals,too-many-s
336338
user_identity_auth_info, system_identity_auth_info,
337339
service_principal_auth_info_secret,
338340
key_vault_id,
341+
app_config_id,
339342
service_endpoint,
340343
private_endpoint,
341344
store_in_connection_string,
342345
new_addon, no_wait,
343-
cluster, scope, enable_csi,
346+
cluster=cluster, scope=scope, enable_csi=enable_csi,
344347
customized_keys=customized_keys,
345348
opt_out_list=opt_out_list,
346-
app_config_id=app_config_id,
347-
connstr_props=connstr_props)
349+
connstr_props=connstr_props,
350+
fabric_workspace_uuid=fabric_workspace_uuid,
351+
fabric_sql_db_uuid=fabric_sql_db_uuid)
348352
raise CLIInternalError("Fail to install `serviceconnector-passwordless` extension. Please manually install it"
349353
" with `az extension add --name serviceconnector-passwordless --upgrade`"
350354
" and rerun the command")

0 commit comments

Comments
 (0)