Skip to content

[ARO] Add az aro hcp subcommand to az aro - #34271

Draft
Kipp Morris (kimorris27) wants to merge 6 commits into
Azure:devfrom
kimorris27:aro-hcp
Draft

Kipp Morris (kimorris27) wants to merge 6 commits into
Azure:devfrom
kimorris27:aro-hcp

Conversation

@kimorris27

@kimorris27 Kipp Morris (kimorris27) commented Oct 24, 2026 •

Copy link
Copy Markdown

🤖 PR Validation — ⚠️ Review suggested

Breaking Changes Tests Suppressions
⚠️ None ️✔️ 130/130 ⚠️ 27 added
⚠️AzureCLI-BreakingChangeTest
⚠️aro
rule cmd_name rule_message suggest_message
⚠️ 1011 - SubgroupAdd aro hcp sub group aro hcp added

This PR adds warning or check suppressions. Fix the underlying warning where possible and justify each remaining suppression in a code comment or the PR description.

27 added suppressions
File Line Kind Code
linter_exclusions.yml 811 linter exclusion - parameter_should_not_end_in_resource_group
linter_exclusions.yml 816 linter exclusion - parameter_should_not_end_in_resource_group
linter_exclusions.yml 821 linter exclusion - parameter_should_not_end_in_resource_group
src/azure-cli/azure/cli/command_modules/aro/__init__.py 16 pylint from .azext_aro_hcp._help import helps as _helps # pylint: disable=unused-import
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/_help.py 8 pylint # pylint: disable=line-too-long
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/_help.py 9 pylint # pylint: disable=too-many-lines
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/_help.py 11 pylint from knack.help_files import helps # pylint: disable=unused-import
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/_kubeconfig.py 130 pylint except Exception as ex: # pylint: disable=broad-except
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/_params.py 8 pylint # pylint: disable=too-many-lines
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/_params.py 9 pylint # pylint: disable=too-many-statements
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/_params.py 12 pylint def load_arguments(self, _): # pylint: disable=unused-argument
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/commands.py 8 pylint # pylint: disable=too-many-lines
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/commands.py 9 pylint # pylint: disable=too-many-statements
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/commands.py 14 pylint def load_command_table(self, _): # pylint: disable=unused-argument
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/commands.py 30 pylint self.command_table["aro hcp cluster nodepool list"] = NodepoolList(loader=self, table_transformer=nodepool_list_table_f…
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/commands.py 31 pylint self.command_table["aro hcp cluster nodepool show"] = NodepoolShow(loader=self, table_transformer=nodepool_show_table_f…
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 8 pylint # pylint: disable=too-many-lines
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 9 pylint # pylint: disable=too-many-statements
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 42 pylint from azure.cli.core.aaz._arg_action import ( # pylint: disable=protected-access
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 178 pylint args_schema.key_management_mode._default = None # pylint: disable=protected-access
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 179 pylint args_schema.key_management_mode._required = True # pylint: disable=protected-access
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 181 pylint args_schema.user_assigned_identities._registered = False # pylint: disable=protected-access
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 182 pylint args_schema.operators_authentication._registered = False # pylint: disable=protected-access
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 183 pylint args_schema.container_registry_managed_identity._registered = False # pylint: disable=protected-access
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 292 pylint args_schema.user_assigned_identities._registered = False # pylint: disable=protected-access
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 293 pylint args_schema.operators_authentication._registered = False # pylint: disable=protected-access
src/azure-cli/azure/cli/command_modules/aro/azext_aro_hcp/custom.py 294 pylint args_schema.container_registry_managed_identity._registered = False # pylint: disable=protected-access

Related command

az aro

Description

This PR adds support for managing Azure Red Hat OpenShift HCP (hosted control plane) clusters via a new set of subcommands under az aro hcp. We released a preview API and have been in public preview for a bit, and we are now preparing for GA.

We used the azure-cli-extensions repo for our preview extension. This PR essentially moves the code from there to here, just without the preview messaging in the command help text. We will continue to use azure-cli-extensions for preview API versions and azure-cli for stable API versions, developing in azure-cli-extensions first and then moving things over here as we release new stable API versions.

Corresponding aaz PR: Azure/aaz#1140

Testing Guide

There are various subcommands under az aro hcp that need many arguments. It wouldn't make sense to list them all here. The integration tests have example commands, and we have tested the commands in internal hackathons.

History Notes

[ARO] az aro: Add the az aro hcp subcommand group for managing Azure Red Hat OpenShift with hosted control planes clusters


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

@azure-pipelines

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

@microsoft-github-policy-service microsoft-github-policy-service Bot added the customer-reported Issues that are reported by GitHub users external to the Azure organization. label Oct 24, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown
Contributor

Thank you for your contribution Kipp Morris (@kimorris27)! We will review the pull request and get back to you soon.

@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

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

@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

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

@JaysonTaiMicrosoft JaysonTaiMicrosoft added the Request X Engineering Agent Ask the agent to triage this issue or review this PR label Oct 25, 2026
@x-engineering-agent

x-engineering-agent Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

X Engineering Agent Pull request review: Comments

4 high findings 1 medium findings

Kipp Morris (@kimorris27) Reviewed head eee3c837b297fd337f6d816292974dca702f3079. Upstream CI passed, but required scenario regression coverage is not verified.

Paths below are relative to src/azure-cli/azure/cli/command_modules/aro/.

High 4 findings Explicit credential destination is overridden · Credential merge failures return success · Stdout credential export discards context selection · +1 more
Explicit credential destination is overridden

azext_aro_hcp/custom.py:531-534 — user-intent

With KUBECONFIG set elsewhere, explicitly passing the expanded $HOME/.kube/config through --file redirects administrator credentials to the environment-selected file. Comparing the path with its default cannot distinguish explicit input from omission.

Apply environment fallback only when --file was omitted. Extend tests/latest/hcp/unit/test_custom_commands.py::RequestCredentialTest to verify that an explicit default-path destination wins over KUBECONFIG.

Credential merge failures return success

azext_aro_hcp/_kubeconfig.py:175-176 — domain-edge-cases

Malformed existing YAML that raises ScannerError bypasses the narrower ParserError conversion at lines 41-42. This handler then logs the YAMLError without raising; RequestCredential._output returns normally at custom.py:538-539, although credentials were not saved.

Convert these failures into actionable CLI errors. Add malformed-existing-config cases to tests/latest/hcp/unit/test_kubeconfig.py, asserting command failure and unchanged file contents.

Stdout credential export discards context selection

azext_aro_hcp/_kubeconfig.py:151-154 — user-intent

request-credential --admin --file - --context chosen prints the original kubeconfig and returns before context renaming at lines 86-90. The accepted context selection is silently ignored.

Apply context normalization before either output branch. Extend PrintOrMergeCredentialsTest.test_dash_prints_kubeconfig in tests/latest/hcp/unit/test_kubeconfig.py to supply a context and assert both its name and current-context.

Version deduplication resets between pages

azext_aro_hcp/custom.py:423-439 — domain-edge-cases

Sorting and the seen set are page-local. The generated aaz/latest/aro/hcp/_get_versions.py:33-35 supplies this callback to paging; src/azure-cli-core/azure/cli/core/aaz/_paging.py:43-49 invokes it separately for each page. Consequently, pages containing 4.19.1 and 4.19.2 both emit 4.19 for --control-plane, contradicting the distinct-version contract.

Handle deduplication and ordering across the complete invocation, accounting for continuation behavior. Extend GetVersionsTest in tests/latest/hcp/unit/test_custom_commands.py with overlapping, out-of-order pages.

Medium Administrator credential example cannot execute

aaz/latest/aro/hcp/cluster/_request_credential.py:20-21 — command-help

The inherited example omits --admin, while the registered custom handler rejects that invocation at azext_aro_hcp/custom.py:490-493. The custom class does not override the example.

Provide a custom help example containing --admin. Add a focused assertion that displayed credential examples satisfy the handler's required arguments.

Test validation
  • Agent live test: Not run; this is a review-only PR. Check author-provided test evidence and upstream CI separately.
  • Regression coverage: For aro: 10 focused test file(s) and 5 recording file(s) changed. Scenario coverage is unverified; review the issue's required conditions, test setup, and assertions before approval. No linked issue was found in the PR timeline; inspect the source issue and its required scenario manually.
Focused author verification

Rerun the affected unit cases and both scenarios in tests/latest/hcp/integration/test_aro_hcp_scenario.py, with their recordings:

  • tests/latest/hcp/integration/recordings/test_aro_hcp_get_versions.yaml
  • tests/latest/hcp/integration/recordings/test_aro_hcp_cluster_lifecycle.yaml

The version scenario checks shape and version syntax, not pagination or distinct control-plane output. The lifecycle scenario submits identity, subnet and KMS fields but primarily asserts provisioning state; credential validation checks only file existence and size. Add assertions for those submitted fields and parsed credential context/key relationships, then update affected author recordings and verify playback. Also rerun tests/latest/hcp/integration/test_recording_processors.py.

These are requested author verifications, not Agent execution results.

⚖️ Risk assessment — 83/100 · Critical

The Critical rating is driven by security-sensitive behavior, public CLI behavior, failure-handling behavior and 1 additional signal(s).

  • Change scope: 67 changed files, 22012 changed lines (+21996 / -16), including 43 production files.
  • Affected components: aro
  • Risk drivers: security-sensitive behavior (+28); public CLI behavior (+18); failure-handling behavior (+12); generated output (+12)
  • Regression evidence: Changed regression tests are included, reducing risk.
  • Confidence: High because changed-line patches were available for every production file.
  • Required review: Owning-squad review is required for aro before merge.

X Engineering Agent · Reviewer · react 👍 / 👎 to train the agent


Ask the Agent

Tick a box to queue an action. Requires write access to this repository.

  • 🔁 Re-review this PR
  • 🧪 Run Agent live tests on this PR

@x-engineering-agent x-engineering-agent Bot added the X Engineering Agent Reviewed Agent reviewed this PR label Oct 25, 2026
@kimorris27

Copy link
Copy Markdown
Author

X Engineering Agent Report

Review — Comments

Kipp Morris (Kipp Morris (@kimorris27))

CI passed, but source-model ownership is missing, three source-traced defects remain, and HCP scenario coverage is unverified.

Upstream CI
52 upstream checks passed; none failed or pending. No Agent live tests ran.

Test validation

  • Agent live test: Not run; this is a review-only PR. Check author-provided test evidence and upstream CI separately.
  • Regression coverage: For aro: 10 focused test file(s) and 5 recording file(s) changed. Scenario coverage is unverified; review the issue's required conditions, test setup, and assertions before approval. No linked issue was found in the PR timeline; inspect the source issue and its required scenario manually.

Paths below use src/azure-cli/azure/cli/command_modules/aro/ as root.

Author evidence: tests/latest/hcp/integration/test_aro_hcp_scenario.py:313-405 and tests/latest/hcp/integration/recordings/test_aro_hcp_cluster_lifecycle.yaml exercise successful lifecycle requests, but update only changes drain timeout; credentials are checked only for a nonempty file. tests/latest/hcp/integration/recordings/test_aro_hcp_get_versions.yaml supplies version responses. These do not establish identity-update or multi-cluster credential correctness. Add the assertions below, refresh affected recordings, then rerun azdev test test_aro_hcp_cluster_lifecycle test_aro_hcp_get_versions plus tests/latest/hcp/unit/test_custom_commands.py and tests/latest/hcp/unit/test_kubeconfig.py.

Repository policy findings

Confirmed semantic findings

  • Domain edge cases (P1): identity updates crash. azext_aro_hcp/custom.py:375-377 puts AAZ dictionary values into sets; these are unhashable AAZSimpleValue objects. Even operator/service updates using full resource IDs fail before PUT. Plain-dictionary unit fixtures hide this. Serialize maps/scalars first; verify each identity flag using a real AAZ-deserialized instance and assert PUT content.
  • Domain edge cases (P1): cross-cluster credential collision. azext_aro_hcp/_kubeconfig.py:87-98 renames clusters/contexts but not the admin user (lifecycle recording:4917-4922). A second cluster fails on the user collision or, with --overwrite-existing, replaces credentials used by the first context. Rename the user and its context references uniquely; verify two distinct certificate/key pairs remain associated with their respective clusters.
  • User intent (P2): no-wait loses credentials. aaz/latest/aro/hcp/cluster/_request_credential.py:31-35 accepts --no-wait; azext_aro_hcp/custom.py:487-527 saves the in-memory private key only through _output. Core src/azure-cli-core/azure/cli/core/aaz/_command.py:234-243 skips that callback for no-wait, submitting the CSR without saving/printing a usable kubeconfig. Reject this combination before POST or provide secure resumable retrieval; verify rejection and normal admin file/stdout output.

Risk assessment — 83/100 · Critical
The Critical rating is driven by security-sensitive behavior, public CLI behavior, failure-handling behavior and 1 additional signal(s).

  • Change scope: 67 changed files, 21922 changed lines (+21906 / -16), including 43 production files.
  • Affected components: aro
  • Risk drivers: security-sensitive behavior (+28); public CLI behavior (+18); failure-handling behavior (+12); generated output (+12)
  • Regression evidence: Changed regression tests are included, reducing risk.
  • Confidence: High because changed-line patches were available for every production file.
  • Required review: Owning-squad review is required for aro before merge.

Posted by x-engineering-agent (Reviewer)

All three findings under "Confirmed semantic findings" are valid. I'm working on addressing them.

@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

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

This branch has not been deployed

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

Labels

act-codegen-extensibility-squad ARO az aro (Azure Redhat OpenShift) customer-reported Issues that are reported by GitHub users external to the Azure organization. Request X Engineering Agent Ask the agent to triage this issue or review this PR X Engineering Agent Reviewed Agent reviewed this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants