Skip to content

WO CLI Release/april2026#9854

Merged
necusjz merged 103 commits intoAzure:mainfrom
manaswita-chichili:release/april2026
May 7, 2026
Merged

WO CLI Release/april2026#9854
necusjz merged 103 commits intoAzure:mainfrom
manaswita-chichili:release/april2026

Conversation

@atharvau
Copy link
Copy Markdown
Member

@atharvau atharvau commented May 7, 2026


This checklist is used to make sure that common guidelines for a pull request are followed.

Related command

General Guidelines

  • Have you run azdev style <YOUR_EXT> locally? (pip install azdev required)
  • Have you run python scripts/ci/test_index.py -q locally? (pip install wheel==0.30.0 required)
  • My extension version conforms to the Extension version schema

For new extensions:

About Extension Publish

There is a pipeline to automatically build, upload and publish extension wheels.
Once your pull request is merged into main branch, a new pull request will be created to update src/index.json automatically.
You only need to update the version information in file setup.py and historical information in file HISTORY.rst in your PR but do not modify src/index.json.

Atharva and others added 30 commits April 14, 2026 11:03
Add --init-extended-location, --init-context, --init-hierarchy, --service-group,
and --release-train flags to 'az workload-orchestration target create' to reduce
onboarding from 15+ manual steps to a single command.

New commands:
- target prepare: Prepares Arc cluster (cert-mgr, trust-mgr, extension, CL)
- hierarchy create: Creates site hierarchy (SG, Site, Config, SiteRef)

Pre-operation hooks in target create:
1. --init-extended-location: calls target_prepare to set up cluster + CL
2. --init-context: discovers/creates WO context with capability injection
3. --init-hierarchy: creates site hierarchy linked to context
4. Default target-specification: injects Helm v3 in-cluster if not provided

Post-operation hook:
5. --service-group: links target to a service group after creation

8 flag combinations supported (from vanilla to full onboarding).
Includes unit tests for hierarchy, SG link, utils, and target prepare.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Extract _handle_init_context (150 lines) → context_init.py
- Extract _handle_init_hierarchy (100 lines) → hierarchy_init.py
- Add parse_arm_id() to utils.py (replaces 6 inline ARM ID parsers)
- Add invoke_silent() to utils.py (replaces 4 stdout suppression blocks)
- Use DEFAULT_TARGET_SPECIFICATION from consts.py
- _create.py custom code: 400 lines → 60 lines (orchestration only)
- Each onboarding module now has a single clear responsibility

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move context_id config resolution before --init-hierarchy (hierarchy
  needs context_id for site-reference linking)
- Extract _resolve_context_id_from_config() for clarity
- Fix hierarchy_init.py sub_id: parse from context_id ARM ID or fall
  back to CLI Profile instead of cli_ctx.data (which returns None)

Tested: all 7 flag combinations pass on live AKS cluster

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The cluster preparation logic is now only accessible via
'target create --init-extended-location'. The underlying target_prepare
module is retained as an internal dependency.

Removed from: commands.py, _params.py, _help.py, custom.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Hierarchy creation is now only accessible via 'target create --init-hierarchy'.
The underlying modules are retained as internal dependencies.

Removed from: commands.py, _params.py, _help.py, custom.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix --release-train help text: 'dev' -> 'stable' to match DEFAULT_RELEASE_TRAIN
- Remove unused imports: PropertyMock from test_target_prepare, json/call from test_sg_link_and_utils
- Fix hierarchy_create.py docstring: remove claim about updating capabilities
- Preserve tags in target_sg_link refresh PUT to avoid dropping metadata

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t flags from target create

- Remove --init-extended-location, --init-context, --init-hierarchy, --release-train from target create
- Add 'target init' as standalone command (wraps target_prepare)
- Keep --service-group and default target-spec on target create
- Aligns with team decision: cluster setup and hierarchy as separate commands

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements 'az workload-orchestration target deploy' that chains
review, publish, and install into a single command with LRO polling.

- Supports --skip-review and --skip-install flags
- Supports --config-file for pre-review configuration
- Uses send_raw_request with ARM resource auth
- Polls LRO via Location/Azure-AsyncOperation headers

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add --solution-template-name + --solution-template-version (friendly name)
  as alternative to --solution-template-version-id (ARM ID)
- Add --solution-template-rg for cross-RG templates
- Add --resume-from publish|install with --solution-version-id
- Add --solution-dependencies pass-through to review
- Add --config for pre-review configuration set
- Proper mutual exclusivity validation between ARM ID and friendly name
- Dynamic step counter adjusts based on active steps

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The review LRO response nests the solution version ARM ID at
properties.id, not properties.properties.id or the top-level id.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Config set needs --solution flag to use solution templates (not config templates)
- Improved solutionVersionId extraction debug logging

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove --skip-review, --skip-install, --no-wait from target deploy
- Fix disallowed HTML tags in help (wrap placeholders in backticks)
- Add short aliases: --stv-id, --stv, --ct-version for long options
- Remove --no-wait example from help

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove 'Next steps' and 'Extended Location JSON' print lines
- Keep diagnostic summary and success message
- CLI framework already prints the return dict as JSON

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Counter now increments only on step start, not on status update.
Shows [1/3]...[1/3] OK, [2/3]...[2/3] OK, [3/3]...[3/3] OK.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep it only on error paths for debugging.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When --site-id is provided, automatically creates a site-reference
linking the site to the context after creation. Site reference name
is derived from the site name (e.g., mySite -> mySite-ref).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…deploy

Users can use individual commands (target review/publish/install) for
partial operations. Deploy is now always a full chain.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
target install now supports two flows:
1. Full deploy: --solution-template-name + --stv (or --stv-id)
   Runs: config-set (opt) → review → publish → install
2. Direct install: --solution-version-id (old flow)
   Runs: install only

Removed: target deploy command, _params, _help, commands.py registration.
Kept: target_deploy.py module (used internally by install pre_operations).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…late

Config-set now auto-derives template info from solution template args:
  config-template-rg → solution-template-rg or --resource-group
  config-template-name → solution-template-name
  config-template-version → solution-template-version

Usage simplified to:
  az wo target install -g rg -n target --solution-template-name X --stv 1.0.0 --configuration values.yaml

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Better reflects the command's purpose - it prepares the cluster,
not a specific target.

Command: az workload-orchestration cluster init -c cluster -g rg -l region

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Per Shubham's feedback: don't touch --target-specification.
Upcoming non-K8s workloads may change this, marked as future work.
Users must provide --target-specification explicitly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Solution templates can be in any RG, so friendly name resolution
uses the target's --resource-group. For cross-RG templates, use
the full ARM ID via --solution-template-version-id.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removed --stv-id and --stv aliases. Use full names:
  --solution-template-version-id
  --solution-template-version

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removed:
- --skip-cert-manager, --skip-trust-manager
- --kube-config, --kube-context
- Failed extension auto-reinstall logic

Kept args: -c, -g, -l, --release-train, --extension-version,
--extension-name, --custom-location-name

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Creates full resource stack in one command:
  1. Site (with level label)
  2. Configuration (in specified region)
  3. ConfigurationReference (links site to config)

Supports:
  - ResourceGroup: single site via --resource-group + shorthand/YAML
  - ServiceGroup: nested hierarchy up to 3 levels via YAML file

Usage:
  az wo hierarchy create -g rg --configuration-location eastus2euap --hierarchy-spec 'name=X level=factory'
  az wo hierarchy create --configuration-location eastus2euap --hierarchy-spec hierarchy.yaml

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…onfigs

- ResourceGroup flow: Site + Config + ConfigRef (3 resources)
- ServiceGroup flow: recursive SG + Site + Config + ConfigRef (up to 3 levels, 12 resources)
- Configs are always RG-scoped (--resource-group required)
- RBAC propagation wait after each SG creation (polls site list)
- Removed old hierarchy_create.py, using clean v2

E2E tested: 3-level SG hierarchy created successfully.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… from target install

These are review-specific args. Users can use standalone 'target review'
for advanced scenarios. Keeps target install clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Atharva and others added 13 commits April 30, 2026 16:27
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When a site is reused during hierarchy create, the log now shows
what was actually patched (e.g., labels.level='factory') instead of
just saying '(updated)'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace hardcoded ARM_ENDPOINT constant with dynamic get_arm_endpoint()
and get_regional_arm_endpoint() helpers that read from
cmd.cli_ctx.cloud.endpoints.resource_manager.

This enables correct behavior for:
- Sovereign clouds (Gov, China, Germany)
- Custom az cloud update --endpoint-resource-manager configs
- Regional endpoints (https://{location}.{domain})

Files changed: consts.py, hierarchy.py, target.py, context.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ts.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- add-capability: use only --capabilities (JSON array of {name, description?})
  description defaults to name when omitted
- remove-capability: use only --capabilities (string array [name1,name2])
- Remove redundant --cap-name, --description, --names parameters
- Remove list-capability and show-capability commands (unnecessary)
- All standard Azure CLI shorthand syntax supported (partial value, @file, full JSON)
- E2E tested: 7 input forms verified against live ARM

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Align with AAZ MgmtClient pattern: use active_directory_resource_id
(https://management.core.windows.net/) for token acquisition instead
of resource_manager endpoint which may be a regional URL
(e.g. https://eastus2.management.azure.com) not registered as an
OAuth resource in all tenants.

Also remove explicit resource= from send_raw_request calls — the
framework auto-resolves to active_directory_resource_id when the URL
starts with the resource_manager endpoint (see util.py L1007-1012).

Fixes AADSTS500011 errors for customers with regional ARM endpoints
configured in their az cloud settings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nt OAuth

Same bug as hierarchy.py fix (988a9f0): passing resource=get_arm_endpoint(cmd)
to send_raw_request/az-rest causes AADSTS500011 when users have a regional
ARM endpoint configured (e.g. eastus2.management.azure.com).

The framework auto-resolves active_directory_resource_id when resource= is
omitted and the URL starts with resource_manager - matching AAZ MgmtClient
behavior.

Removed 14 instances across target.py (13) and context.py (1).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The ServiceGroup flow was printing site status twice per level:
1. Right after the PUT/patch call (early print)
2. In the summary block at the end of the function

Removed the early prints (lines 312, 323) since the summary block
already handles both fresh and reused cases with proper labels.

Tested: fresh 2-level, reuse 2-level, fresh RG, reuse RG, fresh 3-level.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-client-tools-bot-prd
Copy link
Copy Markdown

azure-client-tools-bot-prd Bot commented May 7, 2026

⚠️Azure CLI Extensions Breaking Change Test
⚠️workload-orchestration
rule cmd_name rule_message suggest_message
⚠️ 1011 - SubgroupAdd workload-orchestration cluster sub group workload-orchestration cluster added
⚠️ 1001 - CmdAdd workload-orchestration context add-capability cmd workload-orchestration context add-capability added
⚠️ 1006 - ParaAdd workload-orchestration context create cmd workload-orchestration context create added parameter site_id
⚠️ 1001 - CmdAdd workload-orchestration context remove-capability cmd workload-orchestration context remove-capability added
⚠️ 1011 - SubgroupAdd workload-orchestration hierarchy sub group workload-orchestration hierarchy added
⚠️ 1001 - CmdAdd workload-orchestration sync cmd workload-orchestration sync added
⚠️ 1006 - ParaAdd workload-orchestration target create cmd workload-orchestration target create added parameter service_group
⚠️ 1006 - ParaAdd workload-orchestration target install cmd workload-orchestration target install added parameter config
⚠️ 1006 - ParaAdd workload-orchestration target install cmd workload-orchestration target install added parameter solution_template_name
⚠️ 1006 - ParaAdd workload-orchestration target install cmd workload-orchestration target install added parameter solution_template_rg
⚠️ 1006 - ParaAdd workload-orchestration target install cmd workload-orchestration target install added parameter solution_template_version
⚠️ 1009 - ParaPropRemove workload-orchestration target install cmd workload-orchestration target install update parameter solution_version_id: removed property required=True

@yonzhan
Copy link
Copy Markdown
Collaborator

yonzhan commented May 7, 2026

Thank you for your contribution! We will review the pull request and get back to you soon.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

@atharvau
Copy link
Copy Markdown
Member Author

atharvau commented May 7, 2026

@necusjz can run /azp run

Copilot AI review requested due to automatic review settings May 7, 2026 06:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR bumps the workload-orchestration extension version to 5.2.0 and adds several new “onboarding simplification” commands and helpers (cluster initialization, hierarchy creation, context capability management, improved target install/create flows, and a new sync command).

Changes:

  • Added new command groups/commands: cluster init, hierarchy create, context add-capability/remove-capability, and sync.
  • Enhanced existing commands: target install (full deploy chain support), target create (optional service-group link), context create (optional site-reference creation).
  • Introduced shared common/* helper modules for REST calls, id parsing, orchestration logic, and constants.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/workload-orchestration/setup.py Version bump to 5.2.0.
src/workload-orchestration/HISTORY.rst Release notes for 5.2.0 features.
src/workload-orchestration/linter_exclusions.yml Adds linter exclusions for new parameters/commands.
src/workload-orchestration/azext_workload_orchestration/common/utils.py New shared CLI invocation + stderr progress utilities.
src/workload-orchestration/azext_workload_orchestration/common/consts.py Centralizes API versions, endpoints, and defaults.
src/workload-orchestration/azext_workload_orchestration/common/target.py New cluster prep, deploy-chain helpers, and SG-link helper.
src/workload-orchestration/azext_workload_orchestration/common/hierarchy.py New hierarchy creation orchestration (RG + ServiceGroup).
src/workload-orchestration/azext_workload_orchestration/common/context.py New context capability add/remove/list/show helpers.
src/workload-orchestration/azext_workload_orchestration/common/init.py Exposes target_init + hierarchy_create entrypoints for AAZ.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/target/_install.py Extends target install to support full deploy chain.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/target/_create.py Adds --service-group linking + refactors context-id fallback logic.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/context/_create.py Adds --site-id post-create site-reference linking.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/context/init.py Imports capability submodule so new commands register.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/context/capability/_add.py New context add-capability AAZ command.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/context/capability/_remove.py New context remove-capability AAZ command.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/context/capability/init.py Registers capability commands.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/cluster/_init.py New cluster init command delegating to target_prepare.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/cluster/init.py Registers cluster commands.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/cluster/__cmd_group.py New workload-orchestration cluster command group.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/hierarchy/_create.py New hierarchy create command delegating to hierarchy orchestrator.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/hierarchy/init.py Registers hierarchy commands.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/hierarchy/__cmd_group.py New workload-orchestration hierarchy command group.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/_sync.py New interactive sync orchestration command.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/_resync_target_helper.py Parallelized per-target resync/install helper logic.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/_resource_validator.py Makes resource validation API-version configurable.
src/workload-orchestration/azext_workload_orchestration/aaz/latest/workload_orchestration/init.py Registers new modules/commands (sync, cluster, hierarchy).

resp = send_raw_request(
cli_ctx,
method="PATCH",
url=url,
Comment on lines 112 to +132
def pre_operations(self):
pass
"""If template args provided, run config-set → review → publish before install."""
args = self.ctx.args
has_template = bool(args.solution_template_name)
has_direct = args.solution_version_id

# Validate: need either template args OR solution-version-id
if not has_template and not has_direct:
raise ValidationError(
"Provide either --solution-template-name + --solution-template-version "
"for full deploy, or --solution-version-id for direct install."
)

if has_template and has_direct:
raise ValidationError(
"Provide either solution template args (for full deploy) or "
"--solution-version-id (for direct install), not both."
)

if has_template:
self._run_deploy_chain()
Comment on lines +189 to +190
except configparser.NoSectionError as e:
logger.debug("Config section 'workload_orchestration' not found: %s", e)
Comment on lines +125 to +132
# Step 2: Determine which targets to sync
_log_step("[Step 2/3] Determining which targets to sync...")
selected_targets = self._targets
from knack.prompting import prompt
user_input = prompt(
"\nEnter the numbers of the targets to sync (e.g. 1,3) or press Enter to sync all: "
)
if user_input.strip():
Comment on lines +122 to +131
def _handler(self, command_args):
super()._handler(command_args)
args = self.ctx.args

from azext_workload_orchestration.common import target_init
return target_init(
cmd=self,
cluster_name=args.cluster_name.to_serialized_data(),
resource_group=args.resource_group.to_serialized_data(),
location=args.location.to_serialized_data(),
@necusjz
Copy link
Copy Markdown
Member

necusjz commented May 7, 2026

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

@yonzhan yonzhan requested a review from necusjz May 7, 2026 06:27
@atharvau
Copy link
Copy Markdown
Member Author

atharvau commented May 7, 2026

@necusjz pr is green

@necusjz necusjz merged commit 714db43 into Azure:main May 7, 2026
34 of 35 checks passed
@azclibot
Copy link
Copy Markdown
Collaborator

azclibot commented May 7, 2026

[Release] Update index.json for extension [ workload-orchestration-5.2.0 ] : https://dev.azure.com/msazure/One/_build/results?buildId=163241744&view=results

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants