1212import logging
1313logger = logging .getLogger (__name__ )
1414
15+ RESOURCE_TYPE_MAP = {
16+ "microsoft.web/sites" : "functionapp" ,
17+ "microsoft.app/containerapps" : "containerapp" ,
18+ }
19+
20+
21+ def _parse_target (target ):
22+ """Parse a target resource ID and return (target_type, name, rg, subscription)."""
23+ from azure .mgmt .core .tools import parse_resource_id
24+
25+ parsed = parse_resource_id (target )
26+ name = parsed .get ("name" )
27+ rg = parsed .get ("resource_group" )
28+ sub = parsed .get ("subscription" )
29+ namespace = parsed .get ("namespace" , "" )
30+ rtype = parsed .get ("type" , "" )
31+ provider_key = f"{ namespace } /{ rtype } " .lower ()
32+ target_type = RESOURCE_TYPE_MAP .get (provider_key )
33+ if not target_type or not name or not rg or not sub :
34+ raise ValidationError (
35+ f"Invalid target resource ID: '{ target } '. "
36+ "Expected a Function App (Microsoft.Web/sites) or "
37+ "Container App (Microsoft.App/containerApps) resource ID."
38+ )
39+ return target_type , name , rg , sub
40+
41+
1542ROLE_TYPE_MAP = {
1643 "worker" : "Durable Task Worker" ,
1744 "contributor" : "Durable Task Data Contributor" ,
@@ -270,27 +297,22 @@ def _get_containerapp_identity(cli_ctx, target_name, target_resource_group, targ
270297 return identity .principal_id
271298
272299
273- def _check_target_permissions (cli_ctx , target_type , target_name , target_resource_group , target_subscription ):
300+ def _check_target_permissions (cli_ctx , target_type , target_id ):
274301 """Check that the caller has the required permissions on the target resource."""
275- sub = target_subscription or cli_ctx .data .get ("subscription_id" , "" )
276-
277302 if target_type == "functionapp" :
278- scope = (f"/subscriptions/{ sub } /resourceGroups/{ target_resource_group } "
279- f"/providers/Microsoft.Web/sites/{ target_name } " )
280303 required_actions = [
281304 "Microsoft.Web/sites/config/list/action" ,
282305 "Microsoft.Web/sites/config/write" ,
283306 ]
284307 else : # containerapp
285- scope = (f"/subscriptions/{ sub } /resourceGroups/{ target_resource_group } "
286- f"/providers/Microsoft.App/containerApps/{ target_name } " )
287308 required_actions = [
288309 "Microsoft.App/containerApps/read" ,
289310 "Microsoft.App/containerApps/write" ,
290311 ]
291312
292- logger .info ("Checking permissions on %s '%s'..." , target_type , target_name )
293- _check_access (cli_ctx , scope , required_actions , f"{ target_type } '{ target_name } '" )
313+ logger .info ("Checking permissions on target..." )
314+ _check_access (cli_ctx , target_id , required_actions ,
315+ f"{ target_type } '{ target_id } '" )
294316
295317
296318def _update_functionapp_settings (cli_ctx , target_name , target_resource_group , target_subscription ,
@@ -368,9 +390,7 @@ def _update_containerapp_env_vars(cli_ctx, target_name, target_resource_group, t
368390
369391
370392def attach_scheduler (cmd , resource_group_name , scheduler_name , task_hub_name , # pylint: disable=too-many-locals
371- target_type , target_name , role_type ,
372- target_resource_group = None , target_subscription = None ,
373- identity = None ):
393+ target , role_type , identity = None ):
374394 """Attach a Durable Task scheduler to a Function App or Container App."""
375395 from azure .cli .core .commands .client_factory import get_mgmt_service_client
376396 from azure .cli .core .commands .arm import resolve_role_id
@@ -379,12 +399,12 @@ def attach_scheduler(cmd, resource_group_name, scheduler_name, task_hub_name, #
379399 from azure .core .exceptions import ResourceExistsError , HttpResponseError
380400 import uuid
381401
382- if target_resource_group is None :
383- target_resource_group = resource_group_name
384-
385402 cli_ctx = cmd .cli_ctx
386403 client_id = None
387404
405+ # Parse the target resource ID
406+ target_type , target_name , target_rg , target_sub = _parse_target (target )
407+
388408 # Step 1: Get the scheduler to retrieve its endpoint
389409 logger .info ("Retrieving scheduler '%s' in resource group '%s'..." , scheduler_name , resource_group_name )
390410 scheduler = _SchedulerShow (cli_ctx = cli_ctx )(command_args = {
@@ -429,24 +449,26 @@ def attach_scheduler(cmd, resource_group_name, scheduler_name, task_hub_name, #
429449 logger .info ("Ensuring identity is attached to %s '%s'..." , target_type , target_name )
430450 if target_type == "functionapp" :
431451 _ensure_identity_on_functionapp (
432- cli_ctx , target_name , target_resource_group ,
433- target_subscription , identity )
452+ cli_ctx , target_name , target_rg ,
453+ target_sub , identity )
434454 else :
435455 _ensure_identity_on_containerapp (
436- cli_ctx , target_name , target_resource_group ,
437- target_subscription , identity )
456+ cli_ctx , target_name , target_rg ,
457+ target_sub , identity )
438458 else :
439459 # System-assigned identity: retrieve from the target resource
440460 logger .info ("Retrieving %s '%s' in resource group '%s'..." ,
441- target_type , target_name , target_resource_group )
461+ target_type , target_name , target_rg )
442462 if target_type == "functionapp" :
443- principal_id = _get_functionapp_identity (cli_ctx , target_name , target_resource_group , target_subscription )
463+ principal_id = _get_functionapp_identity (
464+ cli_ctx , target_name , target_rg , target_sub )
444465 else :
445- principal_id = _get_containerapp_identity (cli_ctx , target_name , target_resource_group , target_subscription )
466+ principal_id = _get_containerapp_identity (
467+ cli_ctx , target_name , target_rg , target_sub )
446468 logger .info ("Managed identity principal ID: %s" , principal_id )
447469
448470 # Step 2b: Check permissions on the target and scheduler
449- _check_target_permissions (cli_ctx , target_type , target_name , target_resource_group , target_subscription )
471+ _check_target_permissions (cli_ctx , target_type , target )
450472
451473 scheduler_id = scheduler .get ("id" )
452474 logger .info ("Checking permissions on scheduler '%s'..." , scheduler_name )
@@ -486,21 +508,22 @@ def attach_scheduler(cmd, resource_group_name, scheduler_name, task_hub_name, #
486508 logger .info ("Updating settings for %s '%s'..." , target_type , target_name )
487509 if target_type == "functionapp" :
488510 _update_functionapp_settings (
489- cli_ctx , target_name , target_resource_group ,
490- target_subscription , endpoint , task_hub_name , client_id )
511+ cli_ctx , target_name , target_rg ,
512+ target_sub , endpoint , task_hub_name , client_id )
491513 else :
492514 _update_containerapp_env_vars (
493- cli_ctx , target_name , target_resource_group ,
494- target_subscription , endpoint , task_hub_name , client_id )
515+ cli_ctx , target_name , target_rg ,
516+ target_sub , endpoint , task_hub_name , client_id )
495517
496518 result = {
497519 "scheduler" : scheduler_name ,
498520 "resourceGroup" : resource_group_name ,
499521 "taskHubName" : task_hub_name ,
500522 "schedulerEndpoint" : endpoint ,
523+ "target" : target ,
501524 "targetType" : target_type ,
502525 "targetName" : target_name ,
503- "targetResourceGroup" : target_resource_group ,
526+ "targetResourceGroup" : target_rg ,
504527 "identityPrincipalId" : principal_id ,
505528 "roleAssigned" : role_name ,
506529 }
0 commit comments