Skip to content

Commit e84f90e

Browse files
author
Bernd Verst
committed
Refactor params
1 parent 338e03d commit e84f90e

4 files changed

Lines changed: 63 additions & 62 deletions

File tree

src/durabletask/azext_durabletask/_help.py

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,17 @@
2323
- name: Attach a scheduler to a function app with the Worker role
2424
text: |
2525
az durabletask scheduler attach -g myResourceGroup -n myScheduler \\
26-
--task-hub-name myTaskHub --target-type functionapp \\
27-
--target-name myFunctionApp --role-type worker
26+
--task-hub-name myTaskHub --role-type worker \\
27+
--target /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRG/providers/Microsoft.Web/sites/myFunctionApp
2828
- name: Attach a scheduler to a container app with the Data Contributor role
2929
text: |
3030
az durabletask scheduler attach -g myResourceGroup -n myScheduler \\
31-
--task-hub-name myTaskHub --target-type containerapp \\
32-
--target-name myContainerApp --role-type contributor
33-
- name: Attach with the Data Reader role and a different resource group
34-
text: |
35-
az durabletask scheduler attach -g schedulerRG -n myScheduler \\
36-
--task-hub-name myTaskHub --target-type functionapp \\
37-
--target-name myFunctionApp --role-type reader \\
38-
--target-resource-group appRG
39-
- name: Attach a scheduler to a target in a different subscription
40-
text: |
41-
az durabletask scheduler attach -g schedulerRG -n myScheduler \\
42-
--task-hub-name myTaskHub --target-type containerapp \\
43-
--target-name myContainerApp --role-type contributor \\
44-
--target-resource-group appRG \\
45-
--target-subscription 00000000-0000-0000-0000-000000000000
31+
--task-hub-name myTaskHub --role-type contributor \\
32+
--target /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRG/providers/Microsoft.App/containerApps/myContainerApp
4633
- name: Attach using a user-assigned managed identity
4734
text: |
4835
az durabletask scheduler attach -g myResourceGroup -n myScheduler \\
49-
--task-hub-name myTaskHub --target-type functionapp \\
50-
--target-name myFunctionApp --role-type worker \\
36+
--task-hub-name myTaskHub --role-type worker \\
37+
--target /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRG/providers/Microsoft.Web/sites/myFunctionApp \\
5138
--identity /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity
5239
"""

src/durabletask/azext_durabletask/_params.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,8 @@ def load_arguments(self, _): # pylint: disable=unused-argument
1717
help='Name of the Durable Task scheduler.')
1818
c.argument('task_hub_name', options_list=['--task-hub-name'],
1919
help='Name of the Durable Task task hub.')
20-
c.argument('target_type', options_list=['--target-type'],
21-
help='The type of compute resource to attach.',
22-
choices=['functionapp', 'containerapp'], required=True)
23-
c.argument('target_name', options_list=['--target-name'],
24-
help='Name of the target resource (Function App or Container App) to attach.')
25-
c.argument('target_resource_group', options_list=['--target-resource-group'],
26-
help='Resource group of the target resource. Defaults to the scheduler resource group.')
27-
c.argument('target_subscription', options_list=['--target-subscription'],
28-
help='Subscription ID of the target resource. Defaults to the current subscription.')
20+
c.argument('target', options_list=['--target'],
21+
help='Resource ID of the target Function App or Container App.')
2922
c.argument('role_type', options_list=['--role-type'],
3023
help='The type of role to assign to the target managed identity.',
3124
choices=['worker', 'contributor', 'reader'], required=True)

src/durabletask/azext_durabletask/_scheduler.py

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,33 @@
1212
import logging
1313
logger = 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+
1542
ROLE_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

296318
def _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

370392
def 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
}

src/durabletask/azext_durabletask/commands.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ def load_command_table(self, _): # pylint: disable=unused-argument
1515
from ._format import (scheduler_table_format, scheduler_list_table_format,
1616
taskhub_table_format, taskhub_list_table_format)
1717

18-
with self.command_group('durabletask scheduler'):
18+
with self.command_group(
19+
'durabletask scheduler',
20+
custom_command_type=self.module_kwargs['custom_command_type']) as g:
1921
from .custom import CreateScheduler, UpdateScheduler
2022
from .aaz.latest.durabletask.scheduler import Show as _SchedulerShow, List as _SchedulerList
2123
self.command_table["durabletask scheduler create"] = CreateScheduler(
@@ -26,6 +28,7 @@ def load_command_table(self, _): # pylint: disable=unused-argument
2628
loader=self, table_transformer=scheduler_table_format)
2729
self.command_table["durabletask scheduler list"] = _SchedulerList(
2830
loader=self, table_transformer=scheduler_list_table_format)
31+
g.custom_command('attach', 'attach_scheduler')
2932

3033
with self.command_group('durabletask taskhub'):
3134
from .aaz.latest.durabletask.taskhub import (
@@ -40,8 +43,3 @@ def load_command_table(self, _): # pylint: disable=unused-argument
4043
with self.command_group('durabletask retention-policy'):
4144
from .custom import CreatePolicy
4245
self.command_table["durabletask retention-policy create"] = CreatePolicy(loader=self)
43-
44-
with self.command_group(
45-
'durabletask scheduler',
46-
custom_command_type=self.module_kwargs['custom_command_type']) as g:
47-
g.custom_command('attach', 'attach_scheduler')

0 commit comments

Comments
 (0)