Skip to content

[health-models] Add experimental arrange command - #10145

Draft
Andre Bossard (abossard) wants to merge 6 commits into
Azure:mainfrom
abossard:health-models-arrange
Draft

[health-models] Add experimental arrange command#10145
Andre Bossard (abossard) wants to merge 6 commits into
Azure:mainfrom
abossard:health-models-arrange

Conversation

@abossard

@abossard Andre Bossard (abossard) commented Jul 27, 2026

Copy link
Copy Markdown
Member

🤖 PR Validation — ⚠️ Review suggested

Breaking Changes
⚠️ None
⚠️Azure CLI Extensions Breaking Change Test
⚠️health-models
rule cmd_name rule_message suggest_message
⚠️ 1001 - CmdAdd monitor health-models arrange cmd monitor health-models arrange added

Summary

  • Add an experimental az monitor health-models arrange command for layered Health Model layouts.
  • Support arranging the full model or a subtree selected with --entity-name.
  • Use a Portal-inspired layout: spacing and card-size defaults come from the Portal Designer, and the command warns that results may differ from Portal Arrange.
  • Persist positions immediately and warn that the CLI has no undo or revert operation.
  • List the entities that will be repositioned and confirm before writing; --yes/-y skips the prompt.
  • Add --priority to influence the left-to-right order of entities on a best-effort basis.
  • Skip entities whose names the entity update API rejects, instead of failing partway through.

Related command

az monitor health-models arrange

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 azdev required)
  • My extension version conforms to the Extension version schema

For new extensions:

  • N/A: this updates an existing extension.

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.

Add layered full-model and subtree layout with Portal-derived spacing and card-size defaults. Mark the command experimental and warn that persisted changes have no CLI undo.

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

Copilot-Session: 5627cdad-b2e4-4919-a756-73a4009cb10d
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).

… options

- Added `--priority` argument to `az monitor health-models arrange` to allow users to specify the left-to-right order of entities during layout.
- Introduced `--yes` flag to skip confirmation prompts, facilitating non-interactive usage in CI environments.
- Implemented validation for priority entities to ensure they are updatable and exist within the specified health model.
- Updated layout algorithm to respect priority ordering while maintaining the relative positions of non-listed entities.
- Enhanced tests to cover new functionality, including confirmation behavior and priority handling.
- Documented the layout process and priority handling in a new `LAYOUT.md` file for better understanding of the arrangement logic.

Signed-off-by: Andre Bossard <anbossar@microsoft.com>
@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).

@abossard
Andre Bossard (abossard) marked this pull request as ready for review July 29, 2026 07:19
Copilot AI review requested due to automatic review settings July 29, 2026 07:19
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@abossard

Copy link
Copy Markdown
Member Author

How to test this locally:

Build the wheel from the repo and install it:

git clone -b health-models-arrange https://github.com/abossard/azure-cli-extensions.git
cd azure-cli-extensions/src/health-models
python -m pip install wheel
python setup.py bdist_wheel
az extension add --source dist/health_models-1.0.0b3-py3-none-any.whl --yes

Or with azdev if you have the dev setup:

azdev extension add health-models

Then:

az monitor health-models arrange -g MyResourceGroup -n MyHealthModel

It lists every entity that will move and asks for confirmation. Add --yes to skip that.

A few things to try:

  • --node-sep 80 --rank-sep 150 for custom spacing
  • --entity-name MyRootEntity to arrange only that subtree
  • --priority MyFrontend MyApi MyDatabase to place those left to right

Note: it writes the new canvasPosition immediately and there is no undo, so use a test health model.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds an experimental az monitor health-models arrange command to the health-models Azure CLI extension, including a pure-Python layered layout engine (Portal-inspired defaults) and end-to-end + unit tests to validate handler wiring, subtree scoping, and layout properties.

Changes:

  • Introduce monitor health-models arrange (experimental) that computes and persists canvasPosition for the full model or a subtree via --entity-name, with confirmation / --yes.
  • Add a standalone layered layout implementation (_layout.py) with Portal-inspired spacing and node size defaults, plus --priority ordering support.
  • Add documentation, help text, and extensive unit + scenario coverage (including recordings) for arrange behavior.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/health-models/setup.py Bumps extension version to 1.0.0b3.
src/health-models/README.md Documents the new arrange command and links to layout documentation.
src/health-models/HISTORY.rst Adds release note entry for arrange.
src/health-models/azext_health_models/init.py Wires in custom command table, help registration, and argument loading.
src/health-models/azext_health_models/commands.py Registers arrange as an experimental custom command.
src/health-models/azext_health_models/_params.py Defines CLI arguments for arrange (scope, confirmation, sizing, spacing, priority).
src/health-models/azext_health_models/_help.py Adds command help text and examples for arrange.
src/health-models/azext_health_models/custom.py Implements the health_model_arrange handler (fetch graph, validate/scope, confirm, layout, persist).
src/health-models/azext_health_models/_layout.py Adds the pure-Python layered layout engine used by arrange.
src/health-models/azext_health_models/LAYOUT.md Documents the layout algorithm, defaults, and --priority semantics.
src/health-models/azext_health_models/tests/latest/test_commands.py Tests experimental registration of the arrange command.
src/health-models/azext_health_models/tests/latest/test_params_help.py Tests help/argument registration details for arrange params.
src/health-models/azext_health_models/tests/latest/test_layout.py Unit tests for layout engine behavior (spacing, hierarchy, cycles, components, priority).
src/health-models/azext_health_models/tests/latest/test_custom.py Unit tests for subtree selection + anchoring helpers.
src/health-models/azext_health_models/tests/latest/test_custom_handler.py Boundary tests for handler wiring (AAZ patching, confirmation, updates, priority, skipping invalid names).
src/health-models/azext_health_models/tests/latest/test_healthmodel_scenario.py Live scenario coverage ensuring arrange persists positions and subtree scoping works end-to-end.
src/health-models/azext_health_models/tests/latest/recordings/test_healthmodel_arrange_persists_canvas_position.yaml Adds recording for the new arrange scenario test.

Comment thread src/health-models/azext_health_models/_layout.py Outdated
Comment thread src/health-models/HISTORY.rst Outdated

1.0.0b3
++++++
* Adds ``monitor health-models arrange``: re-arranges and saves the entity positions.
@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).

Signed-off-by: Andre Bossard <anbossar@microsoft.com>
@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).

@abossard

Copy link
Copy Markdown
Member Author

Arrange example:
Before:
image

Command:
az monitor health-models arrange -g lab-finops-framework -n hm-ai-gateway

After:
image

Portal original:
image

Not ideal yet.

@x-engineering-agent

Copy link
Copy Markdown

Automated sensitive-information remediation ran on this pull request.

  • Detected categories: payment card
  • Replaced with typed [REDACTED:category] placeholders in: no writable PR fields
  • Could not edit: file changes on a fork branch
  • Comment/review owners notified because Agent Assist cannot edit another user's text: none

If a credential was exposed, rotate or revoke it immediately. Detected values are never copied into this comment.

✅ Keep the redaction · ❌ Dispute the redaction

GitHub only supports a fixed reaction set, so 👍 represents ✅ and 👎 represents ❌. The bot-created reactions are only poll choices.


Posted by agent-assist (autonomous bug-fix pipeline).

@x-engineering-agent

Copy link
Copy Markdown

Live test results — azdev test --live --series (changed test files only)

PASS

Selectors: test_commands test_custom_handler test_healthmodel_scenario test_layout test_params_help (extension)
PR head ref: health-models-arrange
PR head sha: e9aa318d89d3dc89c947332a975255cf3d2a8cda
PR base ref: main
New test files in PR: true

Changed test files run
src/health-models/azext_health_models/tests/latest/test_commands.py
src/health-models/azext_health_models/tests/latest/test_custom_handler.py
src/health-models/azext_health_models/tests/latest/test_healthmodel_scenario.py
src/health-models/azext_health_models/tests/latest/test_layout.py
src/health-models/azext_health_models/tests/latest/test_params_help.py

New test files
src/health-models/azext_health_models/tests/latest/test_commands.py
src/health-models/azext_health_models/tests/latest/test_custom_handler.py
src/health-models/azext_health_models/tests/latest/test_layout.py
src/health-models/azext_health_models/tests/latest/test_params_help.py

Workflow run: https://github.com/Azure/issue-sentinel/actions/runs/32345651657

Live-test recordings: 4 regenerated — archived in workflow artifact live-test-pr-10145 (recordings/).

ℹ️ This PR is from a fork, so recordings were not pushed automatically. Download them from the artifact and commit to your branch.

Recording files
src/health-models/azext_health_models/tests/latest/recordings/test_healthmodel_arrange_entity_name_scopes_to_subtree.yaml
src/health-models/azext_health_models/tests/latest/recordings/test_healthmodel_arrange_persists_canvas_position.yaml
src/health-models/azext_health_models/tests/latest/recordings/test_healthmodel_crud_cycle.yaml
src/health-models/azext_health_models/tests/latest/recordings/test_healthmodel_list_recorded.yaml
Last 80 lines of azdev output

=============
| Run Tests |
=============


=====================
| Discovering Tests |
=====================

/home/runner/work/issue-sentinel/issue-sentinel/azure-cli/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13705: SyntaxWarning: invalid escape sequence '\]'
  self.cmd('vmss application set -g {rg} -n {vmss} --app-version-ids {vid1} {vid2} --enable-automatic-upgrade True\]', checks=[
/home/runner/work/issue-sentinel/issue-sentinel/azure-cli/src/azure-cli/azure/cli/command_modules/identity/tests/latest/test_identity.py:18: SyntaxWarning: invalid escape sequence '\{'
  'resource_restriction_compute': '\{"providers":\["Microsoft.Compute"\]\}',
/home/runner/work/issue-sentinel/issue-sentinel/azure-cli/src/azure-cli/azure/cli/command_modules/identity/tests/latest/test_identity.py:19: SyntaxWarning: invalid escape sequence '\{'
  'resource_restriction_empty': '\{"providers":\[\]\}'

test index updated: /home/runner/.azdev/env_config/home/runner/work/issue-sentinel/issue-sentinel/.venv/test_index/latest.json

Test on modules: test_commands, test_custom_handler, test_healthmodel_scenario, test_layout, test_params_help

WARNING: RUNNING TESTS LIVE
The tests are set to run against current profile "latest"
============================= test session starts ==============================
platform linux -- Python 3.12.13, pytest-9.1.1, pluggy-1.6.0 -- /home/runner/work/issue-sentinel/issue-sentinel/.venv/bin/python
cachedir: .pytest_cache
rootdir: /home/runner/work/issue-sentinel/issue-sentinel/azure-cli-extensions
configfile: pytest.ini
plugins: forked-1.7.5, xdist-3.8.0
collecting ... collected 16 items

azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_commands.py::TestArrangeCommandRegistration::test_arrange_command_is_marked_experimental PASSED [  6%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_custom_handler.py::TestHealthModelArrangeHandlerBoundary::test_arrange_announces_and_confirms_before_persisting_anything PASSED [ 12%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_custom_handler.py::TestHealthModelArrangeHandlerBoundary::test_arrange_rejects_bad_arguments_before_issuing_any_update PASSED [ 18%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_custom_handler.py::TestHealthModelArrangeHandlerBoundary::test_arrange_scopes_to_the_subtree_and_anchors_it_on_the_root PASSED [ 25%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_custom_handler.py::TestHealthModelArrangeHandlerBoundary::test_arrange_skips_names_the_update_api_rejects_but_still_lays_out_the_real_graph PASSED [ 31%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_healthmodel_scenario.py::HealthModelScenarioTest::test_healthmodel_arrange_entity_name_scopes_to_subtree PASSED [ 37%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_healthmodel_scenario.py::HealthModelScenarioTest::test_healthmodel_arrange_persists_canvas_position PASSED [ 43%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_healthmodel_scenario.py::HealthModelScenarioTest::test_healthmodel_crud_cycle PASSED [ 50%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_healthmodel_scenario.py::HealthModelScenarioTest::test_healthmodel_list_recorded PASSED [ 56%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_layout.py::TestLayeredLayout::test_awkward_graphs_produce_a_position_for_every_node_without_raising PASSED [ 62%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_layout.py::TestLayeredLayout::test_children_are_placed_below_parents_using_portal_spacing PASSED [ 68%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_layout.py::TestLayeredLayout::test_priority_orders_listed_entities_left_to_right_and_leaves_the_rest_alone PASSED [ 75%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_layout.py::TestLayeredLayout::test_spacing_and_node_size_can_be_overridden PASSED [ 81%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_layout.py::TestLayeredLayout::test_the_same_model_lays_out_the_same_way_whatever_order_it_arrives_in PASSED [ 87%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_params_help.py::TestArrangeArgumentSurface::test_optional_arguments_are_registered_with_the_expected_option_names PASSED [ 93%]
azure-cli-extensions/src/health-models/azext_health_models/tests/latest/test_params_help.py::TestArrangeArgumentSurface::test_priority_help_promises_best_effort_rather_than_a_guarantee PASSED [100%]

- generated xml file: /home/runner/work/issue-sentinel/issue-sentinel/test-output/results.xml -
======================== 16 passed in 317.78s (0:05:17) ========================

Posted by agent-assist live-test workflow.

@x-engineering-agent x-engineering-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ All checks passed

  • Live test (Tester): passed (dispatched live-test.yml, run completed successfully).
  • CI checks: 28/28 completed checks passed, 0 failed, 0 pending.

This PR looks good from an automated review perspective. Handing back for maintainer merge decision.

Land the regenerated recordings from the live-test run for the two
arrange scenarios, and restore the two pre-existing recordings that
this branch had trimmed.

The regenerated arrange recordings arrived without the redaction the
rest of the repo applies, so x-ms-async-operation-timeout,
x-ms-operation-identifier, x-ms-providerhub-traffic,
x-ms-resource-provider-hint and x-msedge-ref are redacted, and the
createdBy/lastModifiedBy service-principal ids are replaced with
test@example.com, matching the recordings already on main.

test_healthmodel_crud_cycle and test_healthmodel_list_recorded are not
exercised by this feature; they are restored to their main versions so
the branch no longer carries unrelated changes to them.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 695f023a-5ee1-435a-8b63-42b9bea452d0
@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).

@a0x1ab Aditya Pujara (a0x1ab) added X Engineering Agent Reviewed Pull request reviewed by X Engineering Agent and removed azure-client-tools-agent labels Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

act-observability-squad Auto-Assign Auto assign by bot Monitor X Engineering Agent Reviewed Pull request reviewed by X Engineering Agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants