Skip to content

[MulticloudConnector] Target HybridConnectivity 2027-01-01 GA and add GCP support - #10267

Open
alexmahonic (alexmahonic) wants to merge 4 commits into
Azure:mainfrom
alexmahonic:alexmahonic-multicloud-connector-2027-01-01
Open

[MulticloudConnector] Target HybridConnectivity 2027-01-01 GA and add GCP support#10267
alexmahonic (alexmahonic) wants to merge 4 commits into
Azure:mainfrom
alexmahonic:alexmahonic-multicloud-connector-2027-01-01

Conversation

@alexmahonic

@alexmahonic alexmahonic (alexmahonic) commented Aug 27, 2026

Copy link
Copy Markdown
Member

🤖 PR Validation — ⚠️ Review suggested

Breaking Changes
⚠️ None
⚠️Azure CLI Extensions Breaking Change Test
⚠️multicloud-connector
rule cmd_name rule_message suggest_message
⚠️ 1001 - CmdAdd arc-multicloud generate-gcp-template cmd arc-multicloud generate-gcp-template added
⚠️ 1006 - ParaAdd arc-multicloud public-cloud-connector create cmd arc-multicloud public-cloud-connector create added parameter gcp_cloud_profile
⚠️ 1010 - ParaPropUpdate arc-multicloud public-cloud-connector create cmd arc-multicloud public-cloud-connector create update parameter host_type: updated property choices from ['AWS'] to ['AWS', 'GCP']
⚠️ 1006 - ParaAdd arc-multicloud public-cloud-connector update cmd arc-multicloud public-cloud-connector update added parameter gcp_cloud_profile

Related command

  • az arc-multicloud generate-gcp-template (new)
  • az arc-multicloud public-cloud-connector create / update
  • az arc-multicloud solution-type show / list

Description

Targets the 2027-01-01 GA version of the Microsoft.HybridConnectivity API (previously 2024-12-01) and adds GCP support to the multicloud-connector extension. The API change is purely additive.

Spec: stable/2027-01-01/hybridconnectivity.json

API version

  • Bumped 2024-12-012027-01-01 in every generated AAZ command file (17 files).

New command

  • az arc-multicloud generate-gcp-template (GenerateGcpTemplate_Post), mirroring the existing generate-aws-template: --connector-id (required), --solution-types, --gcp-cloud-profile, --gcp-template-format (terraform | shellscript), plus the --output-directory customization that writes the response to disk.

Public cloud connector

  • --host-type now accepts GCP in addition to AWS.
  • create: new --gcp-cloud-profile with project-properties (project-number, project-id) and organization-properties (organization-id, management-project-number, management-project-id, excluded-project-numbers, excluded-folder-ids).
  • update: new --gcp-cloud-profile restricted to the updatable subset — organization-properties.excluded-project-numbers and organization-properties.excluded-folder-ids (per GcpOrganizationPropertiesUpdate).
  • New read-only kind property surfaced on connector responses.
  • awsCloudProfile is no longer required. In 2027-01-01, PublicCloudConnectorProperties.required changed from ["awsCloudProfile", "hostType"] to ["hostType"]. The generated code hard-required it, which made a GCP-only connector impossible to create, so the required flag was removed from the request builder and all response schemas.

Help examples

  • Following the convention already used for AWS on main, every object argument is documented twice: once in the nested {...} brace form and once in the equivalent flat key=value form (create, update, generate-gcp-template). Each example string was executed and its serialized request body compared against the nested form to confirm the two produce identical payloads.

Solution types

  • hostTypes added to SolutionTypeProperties and to SolutionTypeSettingsProperties (required in the new spec) for solution-type show / list.

Packaging / docs / tests

  • Extension version 1.0.11.1.0 with a matching HISTORY.rst entry and README examples.
  • New test_gcp_public_cloud_connector scenario, marked @live_only() so no recording is fabricated — it can be recorded on a live run.
  • The three existing recordings pinned api-version=2024-12-01, so their recorded request URIs were updated to 2027-01-01. Only the query-string version was changed; no request or response payloads were altered or invented.

Review feedback (ebf9738)

  • generate-gcp-template test used a connector ID without the leading /. Fixed. It was copied from the pre-existing cid kwargs, but those feed solution-configuration, where the connector ID is interpolated into the request path; here it is a request body property and must be a fully-qualified ARM ID. Added a comment at the call site.
  • _output() swallowed failures and returned {"status": "error"} with exit code 0. Fixed by dropping the try/exceptoutput_response_to_file() already raises ValidationError with a useful message, so it now propagates and the command exits non-zero.
    • Note: I applied the same fix to the pre-existing generate-aws-template block, since the GCP block is a copy of it and two sibling commands with opposite failure semantics seemed worse than a small out-of-scope diff. Only the failure path changes. Happy to split that out if you'd prefer.

CI: recorded tests were already failing on main

The first /azp run failed Integration Tests, Build Tests on Python 3.10–3.14. This is not caused by this PR — it is a pre-existing break in these recordings, and I've included a fix.

Every command in this extension calls register_providers_if_needed(), which talks to Microsoft.Resources via ResourceType.MGMT_RESOURCE_RESOURCES. That api-version is pinned by azure-cli-core, not by this extension. The recordings captured it as 2022-09-01; azure-cli dev now pins 2024-11-01, so the RP-registration request no longer matches the cassette, _is_resource_provider_registered swallows the miss, the follow-up register POST also misses, and every test dies with:

ValidationError: This operation requires registering the resource provider Microsoft.HybridConnectivity.
Server responded with error message: Can't overwrite existing cassette (...test_public_cloud_connector.yaml)
in your current record mode (<RecordMode.ONCE: 'once'>).

Reproduced against unmodified main (a2266a60c), changing nothing but that api-version:

Tree MGMT_RESOURCE_RESOURCES Result
main, untouched 2022-09-01 (matches recordings) 3 passed
main, untouched shifted away from 2022-09-01 3 failed, identical error
this branch shifted away from 2022-09-01 3 passed, 1 skipped

Fix: a small RecordingProcessor on the replay path that normalises the api-version on the RP-registration requests only (Microsoft.HybridConnectivity / Microsoft.AwsConnector / Microsoft.HybridCompute, with or without /register). Nothing is recorded, fabricated, or altered in the stored responses — it only makes the incoming request matchable again, and it stops these recordings from breaking every time core bumps a version that has nothing to do with this extension.

Testing Guide

Build and install locally:

cd src/multicloud-connector
python setup.py bdist_wheel
az extension add --source ./dist/multicloud_connector-1.1.0-py3-none-any.whl --upgrade -y

Create a GCP connector and generate its template:

# nested brace form
az arc-multicloud public-cloud-connector create -g <rg> -n gcpConnector --location eastus \
  --host-type GCP \
  --gcp-cloud-profile "{project-properties:{project-number:<num>,project-id:<id>},organization-properties:{organization-id:<org>,management-project-number:<num>,management-project-id:<id>}}"

# equivalent flat form
az arc-multicloud public-cloud-connector create -g <rg> -n gcpConnector --location eastus \
  --host-type GCP \
  --gcp-cloud-profile project-properties.project-number=<num> project-properties.project-id=<id> \
                      organization-properties.organization-id=<org> \
                      organization-properties.management-project-number=<num> \
                      organization-properties.management-project-id=<id>

az arc-multicloud generate-gcp-template --connector-id <connector-arm-id> --gcp-template-format terraform --output-directory ./out

az arc-multicloud public-cloud-connector update -g <rg> -n gcpConnector \
  --gcp-cloud-profile "{organization-properties:{excluded-folder-ids:[folder-1]}}"

# equivalent flat form
az arc-multicloud public-cloud-connector update -g <rg> -n gcpConnector \
  --gcp-cloud-profile organization-properties.excluded-folder-ids[0]=folder-1

Run the recorded scenarios in playback:

pytest src/multicloud-connector/azext_multicloud_connector/tests/latest/test_multicloud_connector.py

AWS scenarios are unchanged and still pass against the existing recordings. The new GCP scenario is @live_only() and reports as skipped in playback.


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

General Guidelines

  • Have you run azdev style <YOUR_EXT> locally? (pip install azdev required) — azdev is installed but not configured on this machine (azdev setup has not been run), so the equivalent checks were run directly with the repo configs: flake8 src/multicloud-connector (0 issues) and pylint src/multicloud-connector/azext_multicloud_connector --rcfile=./pylintrc (10.00/10).
  • Have you run python scripts/ci/test_index.py -q locally? (pip install azdev required) — Ran 9 tests ... OK (skipped=2). Extension tests also re-run in playback: 3 passed, 1 skipped.
  • My extension version conforms to the Extension version schema — minor bump 1.0.11.1.0 for backward-compatible new arguments and a new command.

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.

… GCP support

* Bump the api-version of every generated AAZ command from 2024-12-01 to 2027-01-01
* Add `az arc-multicloud generate-gcp-template`
* Add `--gcp-cloud-profile` to public-cloud-connector create/update and GCP to --host-type
* Surface the read-only `kind` property and solution-type `hostTypes`
* `awsCloudProfile` is no longer required by the service, matching the 2027-01-01 spec

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 27, 2026 22:08
@azure-client-tools-bot-prd

Copy link
Copy Markdown

Hi alexmahonic (@alexmahonic),
Please write the description of changes which can be perceived by customers into HISTORY.rst.
If you want to release a new extension version, please update the version in pyproject.toml (or setup.py, if the extension has not migrated yet) as well.

@azure-pipelines

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

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

This PR updates the multicloud-connector Azure CLI extension to target the 2027-01-01 GA Microsoft.HybridConnectivity API version and introduces GCP support alongside the existing AWS functionality.

Changes:

  • Bump all generated AAZ commands (and test recordings) from api-version=2024-12-01 to 2027-01-01.
  • Add GCP support to public-cloud-connector create/update and introduce a new arc-multicloud generate-gcp-template command (with an --output-directory customization similar to AWS).
  • Update extension versioning/docs and add a live-only scenario test for GCP.

Reviewed changes

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

Show a summary per file
File Description
src/multicloud-connector/setup.py Bumps extension version to 1.1.0.
src/multicloud-connector/README.md Adds GCP usage examples for create and template generation.
src/multicloud-connector/HISTORY.rst Adds 1.1.0 changelog entry describing API bump + GCP features.
src/multicloud-connector/azext_multicloud_connector/tests/latest/test_multicloud_connector.py Adds a live-only GCP scenario test exercising create/update/template/delete.
src/multicloud-connector/azext_multicloud_connector/tests/latest/recordings/test_solution_types.yaml Updates recorded URIs/defaultApiVersion to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/tests/latest/recordings/test_solution_configuration.yaml Updates recorded URIs/defaultApiVersion to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/tests/latest/recordings/test_public_cloud_connector.yaml Updates recorded URIs/asyncoperation URLs to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/custom.py Adds CustomizedGenerateGcpTemplate which writes the template output to disk.
src/multicloud-connector/azext_multicloud_connector/commands.py Registers the new arc-multicloud generate-gcp-template command.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/solution_type/_show.py Bumps API version; surfaces hostTypes on solution types.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/solution_type/_list.py Bumps API version; surfaces hostTypes on solution types.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/solution_configuration/_create.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/solution_configuration/_delete.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/solution_configuration/_list.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/solution_configuration/_show.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/solution_configuration/_sync_now.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/solution_configuration/_update.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/public_cloud_connector/_create.py Adds GCP args/schema + bumps API version; removes AWS profile requiredness.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/public_cloud_connector/_update.py Adds --gcp-cloud-profile (org exclusion lists) + bumps API version.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/public_cloud_connector/_show.py Bumps API version; surfaces read-only kind and gcpCloudProfile.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/public_cloud_connector/_list.py Bumps API version; surfaces read-only kind and gcpCloudProfile.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/public_cloud_connector/_wait.py Bumps API version; surfaces read-only kind and gcpCloudProfile.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/public_cloud_connector/_delete.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/public_cloud_connector/_test_permission.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/_generate_aws_template.py Bumps API version to 2027-01-01.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/_generate_gcp_template.py Adds new generated AAZ command for generate-gcp-template.
src/multicloud-connector/azext_multicloud_connector/aaz/latest/arc_multicloud/init.py Exports the new generated generate-gcp-template command module.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/multicloud-connector/azext_multicloud_connector/custom.py Outdated
@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

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

@yonzhan

Copy link
Copy Markdown
Collaborator

MulticloudConnector

- generate-gcp-template test: use a fully-qualified connector ID (leading '/').
  connectorId travels in the request body here, unlike the scope-style ID that
  solution-configuration interpolates into the request path.
- generate-aws/gcp-template: stop swallowing failures in _output(). Returning
  {"status": "error"} made the command exit 0 on failure; the helpers already
  raise ValidationError, so let it propagate.
- tests: pin the Microsoft.Resources api-version used by the RP-registration
  pre-check on replay. That version is owned by azure-cli-core, not this
  extension, and core moving to 2024-11-01 broke every recorded test here
  (reproduced on unmodified main).

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

alexmahonic (alexmahonic) commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

Pushed ebf9738 addressing both review comments (replied inline).

Heads-up on the red Integration Tests, Build Tests legs from the first /azp runthat failure is pre-existing on main, not introduced here.

Every command in this extension calls register_providers_if_needed(), which reaches Microsoft.Resources through ResourceType.MGMT_RESOURCE_RESOURCES. That api-version is pinned by azure-cli-core, not by this extension. The recordings captured 2022-09-01; azure-cli dev now pins 2024-11-01, so the RP-registration request no longer matches the cassette and every recorded test dies before it ever reaches a HybridConnectivity call.

I reproduced it on unmodified main (a2266a60c) with nothing changed but that api-version:

Tree MGMT_RESOURCE_RESOURCES Result
main, untouched 2022-09-01 (matches recordings) 3 passed
main, untouched shifted away from 2022-09-01 3 failed, identical error
this branch shifted away from 2022-09-01 3 passed, 1 skipped

The fix in this PR is a replay-only RecordingProcessor that normalises the api-version on just those RP-registration requests. No recordings are re-recorded, fabricated, or otherwise altered.

@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

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

public-cloud-connector create already showed both the nested brace form and the
flat key=value form for --aws-cloud-profile, but only the nested form for
--gcp-cloud-profile. Added the matching flat example, verified against the real
CLI (project-properties={...} and the dotted project-properties.project-id=...
form both parse to the expected request body).

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

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

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

Master's convention is to show each object argument twice: once in the
nested "{...}" brace form and once in the flat key=value form. The GCP
examples added for 2027-01-01 only followed this partially, and the
update command had no GCP example at all.

- public-cloud-connector create: the GCP "flat" example still nested
  braces one level down. Replace it with a fully dotted, brace-free form.
- public-cloud-connector update: add the missing AWS flat example and
  both GCP examples (nested and flat).
- generate-gcp-template: add the flat companion to the nested example.

Every example string was executed against the CLI and its serialized
request body compared against the nested form to confirm they produce
identical payloads.

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

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Commenter does not have sufficient privileges for PR 10267 in repo Azure/azure-cli-extensions

@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

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

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