Skip to content

GCP-391: Add ImageRegistry GSA field and IAM binding for Image Registry Operator#7828

Open
cblecker wants to merge 5 commits intoopenshift:mainfrom
cblecker:feat/gcp-391-image-registry-gsa
Open

GCP-391: Add ImageRegistry GSA field and IAM binding for Image Registry Operator#7828
cblecker wants to merge 5 commits intoopenshift:mainfrom
cblecker:feat/gcp-391-image-registry-gsa

Conversation

@cblecker
Copy link
Member

@cblecker cblecker commented Feb 28, 2026

What this PR does / why we need it:

Adds the ImageRegistry field to GCPServiceAccountsEmails and the corresponding IAM binding, enabling the Image Registry Operator on GCP Hosted Control Planes. This is the foundational API change (GCP-391) and IAM binding (GCP-408) that all downstream image registry stories depend on.

The GCPServiceAccountsEmails struct already has 4 GSA fields (NodePool, ControlPlane, CloudController, Storage). This PR adds a 5th: ImageRegistry. The IAM bindings JSON already has 4 entries — this adds a 5th. Both changes follow the exact established patterns.

Changes:

  • API Extension (api/hypershift/v1beta1/gcp.go): Add ImageRegistry field to GCPServiceAccountsEmails with validation, immutability CEL rule, and project-scoping CEL validation on GCPPlatformSpec
  • IAM Bindings (cmd/infra/gcp/iam-bindings.json): Add image-registry service account with roles/storage.admin for GCS bucket operations, targeting openshift-image-registry/cluster-image-registry-operator
  • Credential Reconciliation (hypershift-operator/.../gcp/gcp.go): Add ImageRegistryCredsSecret(), extend ReconcileCredentials() credential map and validateWorkloadIdentityConfiguration() validation
  • Tests: Update all test helpers and add missing image registry validation test case
  • Generated CRDs: Regenerated with the new imageRegistry field present in all CRD variants

Reference: /add-gcp-service-account skill — this PR covers Steps 1-2 (hypershift repo). Steps 3-5 are tracked by GCP-409.

Which issue(s) this PR fixes:

Fixes GCP-391, GCP-408

Special notes for your reviewer:

This follows the exact pattern used for the 4 existing GSA fields. No Go code changes needed for IAM bindings — the JSON is loaded via //go:embed and iterated generically by CreateServiceAccounts() and DeleteServiceAccounts().

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • New Features

    • Added support for configuring an Image Registry service account for GCP, including required validations and immutability; exposed as a required field and CLI option.
  • Documentation

    • Updated API and CRD docs to document imageRegistry format, length, immutability, and IAM guidance.
  • Bug Fixes / Validation

    • Adjusted minimum length validations for several GCP service account emails (38 → 37).
  • Tests

    • Extended unit, e2e fixtures, and validation tests to cover imageRegistry.
  • Chores

    • Added IAM binding and infra manifest entries for the Image Registry service account.

cblecker and others added 2 commits February 27, 2026 16:09
…stry Operator

Add the ImageRegistry field to GCPServiceAccountsEmails struct to support
the Image Registry Operator on GCP Hosted Control Planes. This is the 5th
GSA field, following the established pattern of NodePool, ControlPlane,
CloudController, and Storage.

Changes:
- Add ImageRegistry field to GCPServiceAccountsEmails with validation,
  immutability CEL rule, and project-scoping CEL validation on GCPPlatformSpec
- Add image-registry service account definition in iam-bindings.json with
  roles/storage.admin for GCS bucket operations
- Add ImageRegistryCredsSecret() and extend ReconcileCredentials() credential
  map and validateWorkloadIdentityConfiguration() validation
- Update tests for new field across gcp_test.go and create_iam_test.go

Signed-off-by: Christoph Blecker <cblecker@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Regenerated after rebuilding codegen tool for Go 1.26 compatibility.

Signed-off-by: Christoph Blecker <cblecker@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@openshift-ci-robot
Copy link

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Feb 28, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Feb 28, 2026

@cblecker: This pull request references GCP-391 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

What this PR does / why we need it:

Adds the ImageRegistry field to GCPServiceAccountsEmails and the corresponding IAM binding, enabling the Image Registry Operator on GCP Hosted Control Planes. This is the foundational API change (GCP-391) and IAM binding (GCP-408) that all downstream image registry stories depend on.

The GCPServiceAccountsEmails struct already has 4 GSA fields (NodePool, ControlPlane, CloudController, Storage). This PR adds a 5th: ImageRegistry. The IAM bindings JSON already has 4 entries — this adds a 5th. Both changes follow the exact established patterns.

Changes:

  • API Extension (api/hypershift/v1beta1/gcp.go): Add ImageRegistry field to GCPServiceAccountsEmails with validation, immutability CEL rule, and project-scoping CEL validation on GCPPlatformSpec
  • IAM Bindings (cmd/infra/gcp/iam-bindings.json): Add image-registry service account with roles/storage.admin for GCS bucket operations, targeting openshift-image-registry/cluster-image-registry-operator
  • Credential Reconciliation (hypershift-operator/.../gcp/gcp.go): Add ImageRegistryCredsSecret(), extend ReconcileCredentials() credential map and validateWorkloadIdentityConfiguration() validation
  • Tests: Update all test helpers and add missing image registry validation test case
  • Generated CRDs: Regenerated with the new imageRegistry field present in all CRD variants

Reference: /add-gcp-service-account skill — this PR covers Steps 1-2 (hypershift repo). Steps 3-5 are tracked by GCP-409.

Which issue(s) this PR fixes:

Fixes GCP-391, GCP-408

Special notes for your reviewer:

This follows the exact pattern used for the 4 existing GSA fields. No Go code changes needed for IAM bindings — the JSON is loaded via //go:embed and iterated generically by CreateServiceAccounts() and DeleteServiceAccounts().

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@cblecker cblecker marked this pull request as ready for review February 28, 2026 00:24
@openshift-ci openshift-ci bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. do-not-merge/needs-area labels Feb 28, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Feb 28, 2026

@cblecker: This pull request references GCP-391 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

What this PR does / why we need it:

Adds the ImageRegistry field to GCPServiceAccountsEmails and the corresponding IAM binding, enabling the Image Registry Operator on GCP Hosted Control Planes. This is the foundational API change (GCP-391) and IAM binding (GCP-408) that all downstream image registry stories depend on.

The GCPServiceAccountsEmails struct already has 4 GSA fields (NodePool, ControlPlane, CloudController, Storage). This PR adds a 5th: ImageRegistry. The IAM bindings JSON already has 4 entries — this adds a 5th. Both changes follow the exact established patterns.

Changes:

  • API Extension (api/hypershift/v1beta1/gcp.go): Add ImageRegistry field to GCPServiceAccountsEmails with validation, immutability CEL rule, and project-scoping CEL validation on GCPPlatformSpec
  • IAM Bindings (cmd/infra/gcp/iam-bindings.json): Add image-registry service account with roles/storage.admin for GCS bucket operations, targeting openshift-image-registry/cluster-image-registry-operator
  • Credential Reconciliation (hypershift-operator/.../gcp/gcp.go): Add ImageRegistryCredsSecret(), extend ReconcileCredentials() credential map and validateWorkloadIdentityConfiguration() validation
  • Tests: Update all test helpers and add missing image registry validation test case
  • Generated CRDs: Regenerated with the new imageRegistry field present in all CRD variants

Reference: /add-gcp-service-account skill — this PR covers Steps 1-2 (hypershift repo). Steps 3-5 are tracked by GCP-409.

Which issue(s) this PR fixes:

Fixes GCP-391, GCP-408

Special notes for your reviewer:

This follows the exact pattern used for the 4 existing GSA fields. No Go code changes needed for IAM bindings — the JSON is loaded via //go:embed and iterated generically by CreateServiceAccounts() and DeleteServiceAccounts().

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 28, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 446f451 and 85e6b04.

📒 Files selected for processing (4)
  • cmd/cluster/gcp/create.go
  • cmd/cluster/gcp/create_test.go
  • cmd/cluster/gcp/testdata/zz_fixture_TestCreateCluster_minimal_flags_necessary_to_render.yaml
  • test/e2e/v2/tests/api_ux_validation_test.go

Walkthrough

Adds an ImageRegistry GCP service account field across API, CRD manifests, client apply configs, docs, IAM bindings, tests, and controller logic; adjusts several GCP service-account minLength validations from 38→37 and enforces immutability and same-project validation.

Changes

Cohort / File(s) Summary
Core API Schema
api/hypershift/v1beta1/gcp.go
Added ImageRegistry string to GCPServiceAccountsEmails with pattern, minLength 37, maxLength 100, immutability marker; added XValidation on GCPPlatformSpec to require imageRegistry service account belong to the same project.
HostedCluster CRD Manifests
cmd/install/assets/.../hostedclusters-*.crd.yaml, api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
Added imageRegistry under spec.workloadIdentity.serviceAccountsEmails with pattern, minLength 37, maxLength 100, immutability, and made it required; adjusted other GSA minLength constraints 38→37; added same-project validation.
HostedControlPlane CRD Manifests
cmd/install/assets/.../hostedcontrolplanes-*.crd.yaml, api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
Added imageRegistry under spec.workloadIdentity.serviceAccountsEmails and spec.serviceAccountsEmails with same validations and immutability; added cross-field same-project validation; adjusted minLength 38→37 for other GSAs.
Client Apply Configuration
client/applyconfiguration/hypershift/v1beta1/gcpserviceaccountsemails.go
Added ImageRegistry *string to apply-configuration struct and WithImageRegistry() builder method.
GCP Infrastructure & Bindings
cmd/infra/gcp/iam-bindings.json, cmd/infra/gcp/create_iam_test.go
Added image-registry service account entry (roles/storage.admin) and updated test expected output to include image-registry email.
Controller Implementation & Tests
hypershift-operator/controllers/hostedcluster/internal/platform/gcp/gcp.go, hypershift-operator/controllers/hostedcluster/internal/platform/gcp/gcp_test.go
Added ImageRegistryCredsSecret(controlPlaneNamespace); wired into ReconcileCredentials secret map; extended workload identity validation to require ImageRegistry; updated tests/fixtures to include imageRegistry.
CLI create flow & tests
cmd/cluster/gcp/create.go, cmd/cluster/gcp/create_test.go, cmd/cluster/gcp/testdata/...yaml
Added CLI flag/option ImageRegistryServiceAccount, validation, and propagation into HostedCluster GCP workloadIdentity ImageRegistry; updated tests and fixtures.
End-to-end & API tests
test/e2e/create_cluster_test.go, test/e2e/v2/tests/api_ux_validation_test.go
Populated ImageRegistry in GCPServiceAccountsEmails fixtures; added validation tests for missing/invalid imageRegistry email.
Docs
docs/content/reference/api.md, docs/content/reference/aggregated-docs.md
Documented imageRegistry field and its purpose/format/IAM requirements in API reference and aggregated docs.

Sequence Diagram(s)

sequenceDiagram
    participant Controller as HostedCluster Controller
    participant GCP as GCP IAM
    participant K8s as Kubernetes API (Secret)
    participant ImageReg as Image Registry Operator

    Controller->>GCP: Validate imageRegistry GSA format & project (same-project rule)
    Controller->>K8s: Create/Update `image-registry-creds` Secret (ImageRegistryCredsSecret)
    K8s-->>Controller: Secret persisted
    ImageReg->>K8s: Mount/use `image-registry-creds` Secret to access GCS
    Note over Controller,GCP: Immutability and same-project validations enforced
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning Many unit tests use bare assertions without descriptive failure messages, making diagnoses difficult and violating meaningful assertion message requirements. Update assertions to include explanatory messages and consider splitting tests with multiple behaviors into separate functions for clarity.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding an ImageRegistry GSA field and IAM binding for the Image Registry Operator on GCP.
Stable And Deterministic Test Names ✅ Passed All test names in modified files use static, descriptive strings without dynamic information like timestamps, UUIDs, or generated suffixes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 28, 2026
@openshift-ci openshift-ci bot requested review from apahim and devguyio February 28, 2026 00:30
@openshift-ci openshift-ci bot added the area/api Indicates the PR includes changes for the API label Feb 28, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 28, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: cblecker
Once this PR has been reviewed and has the lgtm label, please assign jparrill for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added area/cli Indicates the PR includes changes for CLI area/documentation Indicates the PR includes changes for documentation area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/gcp PR/issue for GCP (GCPPlatform) platform and removed do-not-merge/needs-area labels Feb 28, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Feb 28, 2026

@cblecker: This pull request references GCP-391 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

What this PR does / why we need it:

Adds the ImageRegistry field to GCPServiceAccountsEmails and the corresponding IAM binding, enabling the Image Registry Operator on GCP Hosted Control Planes. This is the foundational API change (GCP-391) and IAM binding (GCP-408) that all downstream image registry stories depend on.

The GCPServiceAccountsEmails struct already has 4 GSA fields (NodePool, ControlPlane, CloudController, Storage). This PR adds a 5th: ImageRegistry. The IAM bindings JSON already has 4 entries — this adds a 5th. Both changes follow the exact established patterns.

Changes:

  • API Extension (api/hypershift/v1beta1/gcp.go): Add ImageRegistry field to GCPServiceAccountsEmails with validation, immutability CEL rule, and project-scoping CEL validation on GCPPlatformSpec
  • IAM Bindings (cmd/infra/gcp/iam-bindings.json): Add image-registry service account with roles/storage.admin for GCS bucket operations, targeting openshift-image-registry/cluster-image-registry-operator
  • Credential Reconciliation (hypershift-operator/.../gcp/gcp.go): Add ImageRegistryCredsSecret(), extend ReconcileCredentials() credential map and validateWorkloadIdentityConfiguration() validation
  • Tests: Update all test helpers and add missing image registry validation test case
  • Generated CRDs: Regenerated with the new imageRegistry field present in all CRD variants

Reference: /add-gcp-service-account skill — this PR covers Steps 1-2 (hypershift repo). Steps 3-5 are tracked by GCP-409.

Which issue(s) this PR fixes:

Fixes GCP-391, GCP-408

Special notes for your reviewer:

This follows the exact pattern used for the 4 existing GSA fields. No Go code changes needed for IAM bindings — the JSON is loaded via //go:embed and iterated generically by CreateServiceAccounts() and DeleteServiceAccounts().

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

Release Notes

  • New Features

  • Added support for specifying an Image Registry service account for GCP-based deployments. The new field enables configuration of a dedicated Google Service Account for the Image Registry Operator with required storage permissions.

  • Documentation

  • Updated API reference and configuration documentation to document the new Image Registry service account field, including format requirements and IAM role guidance.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
cmd/infra/gcp/iam-bindings.json (1)

61-65: Consider restricting Image Registry Operator GCS permissions to bucket scope.

Line 64 assigns roles/storage.admin, a project-level role with broad storage management permissions. The cluster-image-registry-operator requires only object-level operations (list, read, write, delete, update). If buckets are pre-created, use bucket-scoped roles instead: roles/storage.objectUser paired with roles/storage.legacyBucketReader (or roles/storage.objectAdmin alone) bound to the specific registry bucket to reduce blast radius. Verify the cluster provisioning workflow does not require project-level bucket management before narrowing scope.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/infra/gcp/iam-bindings.json` around lines 61 - 65, The current service
account entry "image-registry" assigns the project-level role
"roles/storage.admin"; replace this with bucket-scoped roles appropriate for
object operations (e.g., use "roles/storage.objectAdmin" on the specific
registry bucket, or combine "roles/storage.objectUser" +
"roles/storage.legacyBucketReader" on that bucket) and ensure the binding is
applied to the specific registry bucket rather than the project; update the
"roles" array for the "image-registry" entry and confirm the cluster
provisioning workflow does not require project-level bucket creation before
narrowing the scope.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml`:
- Around line 5077-5079: The new imageRegistry field is marked +required and
uses an immutability validation rule (self == oldSelf), which prevents adding it
to existing HostedControlPlane objects; either relax the schema or make the
validation transition-safe: remove the +required marker or change the validation
rule for imageRegistry (and the other four service account fields nodePool,
controlPlane, cloudController, storage) to allow initial setting on updates
(e.g., permit when oldSelf is null) or implement a backfill/reconciliation that
populates missing values before enforcing immutability; locate the field
definitions and their x-kubernetes-validations in the generated manifest and
update the required/validation logic accordingly.

In
`@cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml`:
- Around line 6190-6194: The CRD currently lists imageRegistry as required under
the HostedCluster spec which is incompatible with the immutable workloadIdentity
field; remove imageRegistry from the required array (the block that enumerates
cloudController, controlPlane, imageRegistry, nodePool) so imageRegistry remains
optional while workloadIdentity stays immutable, and ensure you also remove any
duplicate mentions of imageRegistry being required at the other occurrences
noted (the other required arrays around the workloadIdentity definition) so
existing HostedCluster objects can be updated without breaking status writes.

In
`@cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml`:
- Around line 6082-6087: The CRD currently makes the spec.imageRegistry field
required while spec.workloadIdentity is immutable, which prevents safe
backfilling of existing HostedControlPlane objects; to fix this, remove
"imageRegistry" from the required: list in the HostedControlPlane CRD (the
zz_generated.crd-manifests entry where required includes cloudController,
controlPlane, imageRegistry, nodePool, storage) so the field remains optional
for this release, or alternatively implement a migration/defaulting path (e.g.,
webhook/defaulting logic tied to the same CRD) before making spec.imageRegistry
required in a follow-up release; do not change the immutability of
spec.workloadIdentity in this change.
- Around line 6032-6034: The CRD field currently sets minLength: 38 for GSA
email validation which incorrectly rejects the shortest valid addresses; update
the schema entry that pairs minLength with the regex pattern
^[a-z][a-z0-9-]{4,28}[a-z0-9]@[a-z][a-z0-9-]{4,28}[a-z0-9]\.iam\.gserviceaccount\.com$
by changing minLength from 38 to 37 so the minimal valid service account email
is accepted.

---

Nitpick comments:
In `@cmd/infra/gcp/iam-bindings.json`:
- Around line 61-65: The current service account entry "image-registry" assigns
the project-level role "roles/storage.admin"; replace this with bucket-scoped
roles appropriate for object operations (e.g., use "roles/storage.objectAdmin"
on the specific registry bucket, or combine "roles/storage.objectUser" +
"roles/storage.legacyBucketReader" on that bucket) and ensure the binding is
applied to the specific registry bucket rather than the project; update the
"roles" array for the "image-registry" entry and confirm the cluster
provisioning workflow does not require project-level bucket creation before
narrowing the scope.

ℹ️ Review info

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 40d6470 and 5982742.

⛔ Files ignored due to path filters (1)
  • vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/gcp.go is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (14)
  • api/hypershift/v1beta1/gcp.go
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
  • client/applyconfiguration/hypershift/v1beta1/gcpserviceaccountsemails.go
  • cmd/infra/gcp/create_iam_test.go
  • cmd/infra/gcp/iam-bindings.json
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
  • docs/content/reference/aggregated-docs.md
  • docs/content/reference/api.md
  • hypershift-operator/controllers/hostedcluster/internal/platform/gcp/gcp.go
  • hypershift-operator/controllers/hostedcluster/internal/platform/gcp/gcp_test.go

@cblecker
Copy link
Member Author

/pipeline required

@openshift-ci-robot
Copy link

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-4-21
/test e2e-aws-4-21
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws

The minimum length for a GCP service account email
(a@b.iam.gserviceaccount.com) is 37 characters per GCP documentation,
not 38. Update all 5 GCPServiceAccountsEmails fields and regenerate
CRDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cblecker
Copy link
Member Author

/test e2e-aws-techpreview
/pipeline required

@openshift-ci-robot
Copy link

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-4-21
/test e2e-aws-4-21
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws

@openshift-ci-robot
Copy link

openshift-ci-robot commented Feb 28, 2026

@cblecker: This pull request references GCP-391 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

What this PR does / why we need it:

Adds the ImageRegistry field to GCPServiceAccountsEmails and the corresponding IAM binding, enabling the Image Registry Operator on GCP Hosted Control Planes. This is the foundational API change (GCP-391) and IAM binding (GCP-408) that all downstream image registry stories depend on.

The GCPServiceAccountsEmails struct already has 4 GSA fields (NodePool, ControlPlane, CloudController, Storage). This PR adds a 5th: ImageRegistry. The IAM bindings JSON already has 4 entries — this adds a 5th. Both changes follow the exact established patterns.

Changes:

  • API Extension (api/hypershift/v1beta1/gcp.go): Add ImageRegistry field to GCPServiceAccountsEmails with validation, immutability CEL rule, and project-scoping CEL validation on GCPPlatformSpec
  • IAM Bindings (cmd/infra/gcp/iam-bindings.json): Add image-registry service account with roles/storage.admin for GCS bucket operations, targeting openshift-image-registry/cluster-image-registry-operator
  • Credential Reconciliation (hypershift-operator/.../gcp/gcp.go): Add ImageRegistryCredsSecret(), extend ReconcileCredentials() credential map and validateWorkloadIdentityConfiguration() validation
  • Tests: Update all test helpers and add missing image registry validation test case
  • Generated CRDs: Regenerated with the new imageRegistry field present in all CRD variants

Reference: /add-gcp-service-account skill — this PR covers Steps 1-2 (hypershift repo). Steps 3-5 are tracked by GCP-409.

Which issue(s) this PR fixes:

Fixes GCP-391, GCP-408

Special notes for your reviewer:

This follows the exact pattern used for the 4 existing GSA fields. No Go code changes needed for IAM bindings — the JSON is loaded via //go:embed and iterated generically by CreateServiceAccounts() and DeleteServiceAccounts().

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • New Features

  • Added support for configuring an Image Registry service account for GCP deployments, including validation, immutability, and required-entry enforcement.

  • Documentation

  • Updated API reference and CRD docs to describe the imageRegistry field, format rules, length constraints, and IAM role guidance.

  • Tests

  • Extended unit tests and fixtures to cover the new imageRegistry service account and validation cases.

  • Chores

  • Added IAM binding and infra manifest entries to provision the Image Registry service account.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml (1)

6082-6087: ⚠️ Potential issue | 🟠 Major

Required imageRegistry + immutable workloadIdentity can block updates for pre-existing objects.

At Line 6085, imageRegistry is newly required, while Line 6096 keeps workloadIdentity immutable. Existing HostedControlPlanes created before this field may fail future updates because they cannot be backfilled.

Suggested mitigation
                             required:
                             - cloudController
                             - controlPlane
-                            - imageRegistry
                             - nodePool
                             - storage

Also applies to: 6096-6097

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml`
around lines 6082 - 6087, Newly making spec.imageRegistry required while
spec.workloadIdentity remains immutable will block updates for pre-existing
HostedControlPlane objects; change the CRD so imageRegistry is not added to the
required list (remove "imageRegistry" from the required array in the
HostedControlPlane schema) and/or remove the immutability constraint on
workloadIdentity (clear the immutable flag on spec.workloadIdentity) so existing
resources can be backfilled during upgrade; if you must keep imageRegistry
required, instead implement a migration/admission path to populate defaults
before enforcing the requirement. Ensure you update the schema entries named
imageRegistry and workloadIdentity in the HostedControlPlane CRD.
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml (1)

5077-5079: ⚠️ Potential issue | 🔴 Critical

Required + immutable imageRegistry remains migration-breaking for existing objects.

Line 5126 makes imageRegistry mandatory, while Line 5079 enforces strict immutability. Existing HostedControlPlanes that predate this field and lack it cannot be updated to add it later.

Suggested transition-safe direction
-                                - message: ImageRegistry is immutable
-                                  rule: self == oldSelf
+                                - message: ImageRegistry is immutable once set
+                                  rule: '!has(oldSelf) || self == oldSelf'
...
-                            - imageRegistry
+                            # keep optional unless backfilled before enforcement

Please apply this in the source API markers (not directly in generated YAML) and regenerate CRDs.

Also applies to: 5123-5127

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml`
around lines 5077 - 5079, The imageRegistry field is currently marked required
and immutable in the generated CRD which blocks upgrades for existing
HostedControlPlane objects that lack the field; update the source API markers on
the HostedControlPlane spec (the ImageRegistry field in the API Go type) to
remove the required validation and make the field optional (add/ensure the
kubebuilder Optional marker or remove the +kubebuilder:validation:Required
marker), and remove or relax the immutability x-kubernetes-validations marker
(the self == oldSelf rule) so that existing objects can be populated during
migration; after changing the ImageRegistry field markers in the API type,
regenerate the CRDs.
cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml (1)

6190-6195: ⚠️ Potential issue | 🟠 Major

Keep imageRegistry optional while workloadIdentity is immutable (compat risk).

At Line 6193, imageRegistry is required, but workloadIdentity is immutable at Line 6204-Line 6205. Existing HostedClusters created before this field existed can fail validation on update/status paths. Also, the Line 6231-Line 6235 CEL rule should be optional-aware if this field is transitional/optional.

Proposed transition-safe CRD diff
                             required:
                             - cloudController
                             - controlPlane
-                            - imageRegistry
                             - nodePool
                             - storage
                             type: object
@@
-                    - message: imageRegistry service account must belong to the same
-                        project
-                      rule: self.workloadIdentity.serviceAccountsEmails.imageRegistry.contains('@')
-                        && self.workloadIdentity.serviceAccountsEmails.imageRegistry.endsWith('@'
-                        + self.project + '.iam.gserviceaccount.com')
+                    - message: if set, imageRegistry service account must belong to the same
+                        project
+                      rule: '!has(self.workloadIdentity.serviceAccountsEmails.imageRegistry)
+                        || (self.workloadIdentity.serviceAccountsEmails.imageRegistry.contains(''@'')
+                        && self.workloadIdentity.serviceAccountsEmails.imageRegistry.endsWith(''@''
+                        + self.project + ''.iam.gserviceaccount.com''))'

Also applies to: 6204-6205, 6231-6235

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml`
around lines 6190 - 6195, The CRD currently lists imageRegistry as required
while workloadIdentity is immutable, which can break updates for existing
HostedClusters; remove imageRegistry from the required array (so imageRegistry
becomes optional) and update the CEL validation (the rule referenced around the
CEL block at lines ~6231-6235) to be presence-aware—i.e., guard the CEL
expression with a has(self.spec.imageRegistry) check (or equivalent) so the rule
only runs when imageRegistry is set; ensure no change makes workloadIdentity
(the immutable field) required or subject to this CEL check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml`:
- Around line 5939-5957: The new required + immutable imageRegistry field will
block updates for existing HostedClusters; make the transition
backward-compatible by (1) removing the required constraint for imageRegistry
(so pre-existing resources without the field aren’t rejected) and (2) relax the
x-kubernetes-validations rule on imageRegistry to allow one-time initialization
by changing the rule from "self == oldSelf" to "oldSelf == null || self ==
oldSelf" (refer to the imageRegistry field and its x-kubernetes-validations
entry in the CRD).

---

Duplicate comments:
In
`@api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml`:
- Around line 5077-5079: The imageRegistry field is currently marked required
and immutable in the generated CRD which blocks upgrades for existing
HostedControlPlane objects that lack the field; update the source API markers on
the HostedControlPlane spec (the ImageRegistry field in the API Go type) to
remove the required validation and make the field optional (add/ensure the
kubebuilder Optional marker or remove the +kubebuilder:validation:Required
marker), and remove or relax the immutability x-kubernetes-validations marker
(the self == oldSelf rule) so that existing objects can be populated during
migration; after changing the ImageRegistry field markers in the API type,
regenerate the CRDs.

In
`@cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml`:
- Around line 6190-6195: The CRD currently lists imageRegistry as required while
workloadIdentity is immutable, which can break updates for existing
HostedClusters; remove imageRegistry from the required array (so imageRegistry
becomes optional) and update the CEL validation (the rule referenced around the
CEL block at lines ~6231-6235) to be presence-aware—i.e., guard the CEL
expression with a has(self.spec.imageRegistry) check (or equivalent) so the rule
only runs when imageRegistry is set; ensure no change makes workloadIdentity
(the immutable field) required or subject to this CEL check.

In
`@cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml`:
- Around line 6082-6087: Newly making spec.imageRegistry required while
spec.workloadIdentity remains immutable will block updates for pre-existing
HostedControlPlane objects; change the CRD so imageRegistry is not added to the
required list (remove "imageRegistry" from the required array in the
HostedControlPlane schema) and/or remove the immutability constraint on
workloadIdentity (clear the immutable flag on spec.workloadIdentity) so existing
resources can be backfilled during upgrade; if you must keep imageRegistry
required, instead implement a migration/admission path to populate defaults
before enforcing the requirement. Ensure you update the schema entries named
imageRegistry and workloadIdentity in the HostedControlPlane CRD.

ℹ️ Review info

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 5982742 and 16b2bc9.

⛔ Files ignored due to path filters (1)
  • vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/gcp.go is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (7)
  • api/hypershift/v1beta1/gcp.go
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml

@cwbotbot
Copy link

cwbotbot commented Feb 28, 2026

Test Results

e2e-aks

e2e-aws

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 28, 2026

@cblecker: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-4-21 16b2bc9 link true /test e2e-aws-4-21
ci/prow/e2e-aws-techpreview 16b2bc9 link false /test e2e-aws-techpreview
ci/prow/e2e-aks-4-21 16b2bc9 link true /test e2e-aks-4-21

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@cristianoveiga
Copy link
Contributor

The TestOnCreateAPIUX e2e test is failing because the validGCPPlatformSpec() helper in test/e2e/create_cluster_test.go (line 55-60) is missing the new ImageRegistry field. Since it's +required, any GCP HostedCluster created without it fails CRD validation.

The fix is adding ImageRegistry to the ServiceAccountsEmails struct there:

  ServiceAccountsEmails: hyperv1.GCPServiceAccountsEmails{
      NodePool:        "nodepool@my-project-123.iam.gserviceaccount.com",
      ControlPlane:    "controlplane@my-project-123.iam.gserviceaccount.com",
      CloudController: "cloudcontroller@my-project-123.iam.gserviceaccount.com",
      Storage:         "storage@my-project-123.iam.gserviceaccount.com",
      ImageRegistry:   "imageregistry@my-project-123.iam.gserviceaccount.com",
  },

The TestOnCreateAPIUX e2e test was failing because the validGCPPlatformSpec
helper was missing the new required ImageRegistry field in
ServiceAccountsEmails, causing CRD validation failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cblecker
Copy link
Member Author

cblecker commented Mar 2, 2026

Fixed — added ImageRegistry to validGCPPlatformSpec() in the e2e test helper (446f451).

@openshift-ci openshift-ci bot added the area/testing Indicates the PR includes changes for e2e testing label Mar 2, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Mar 2, 2026

@cblecker: This pull request references GCP-391 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

What this PR does / why we need it:

Adds the ImageRegistry field to GCPServiceAccountsEmails and the corresponding IAM binding, enabling the Image Registry Operator on GCP Hosted Control Planes. This is the foundational API change (GCP-391) and IAM binding (GCP-408) that all downstream image registry stories depend on.

The GCPServiceAccountsEmails struct already has 4 GSA fields (NodePool, ControlPlane, CloudController, Storage). This PR adds a 5th: ImageRegistry. The IAM bindings JSON already has 4 entries — this adds a 5th. Both changes follow the exact established patterns.

Changes:

  • API Extension (api/hypershift/v1beta1/gcp.go): Add ImageRegistry field to GCPServiceAccountsEmails with validation, immutability CEL rule, and project-scoping CEL validation on GCPPlatformSpec
  • IAM Bindings (cmd/infra/gcp/iam-bindings.json): Add image-registry service account with roles/storage.admin for GCS bucket operations, targeting openshift-image-registry/cluster-image-registry-operator
  • Credential Reconciliation (hypershift-operator/.../gcp/gcp.go): Add ImageRegistryCredsSecret(), extend ReconcileCredentials() credential map and validateWorkloadIdentityConfiguration() validation
  • Tests: Update all test helpers and add missing image registry validation test case
  • Generated CRDs: Regenerated with the new imageRegistry field present in all CRD variants

Reference: /add-gcp-service-account skill — this PR covers Steps 1-2 (hypershift repo). Steps 3-5 are tracked by GCP-409.

Which issue(s) this PR fixes:

Fixes GCP-391, GCP-408

Special notes for your reviewer:

This follows the exact pattern used for the 4 existing GSA fields. No Go code changes needed for IAM bindings — the JSON is loaded via //go:embed and iterated generically by CreateServiceAccounts() and DeleteServiceAccounts().

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • New Features

  • Added support for configuring an Image Registry service account for GCP, with format, length, immutability, and cross-project validations; made it a required entry.

  • Documentation

  • Updated API and CRD docs to describe the imageRegistry field, pattern, length constraints, immutability, and IAM role guidance.

  • Tests

  • Extended unit and e2e fixtures and validation tests to cover the imageRegistry service account.

  • Chores

  • Added IAM binding and infra manifest entries to provision the Image Registry service account.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@cblecker
Copy link
Member Author

cblecker commented Mar 2, 2026

/test e2e-aws-techpreview

@cristianoveiga
Copy link
Contributor

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Mar 2, 2026
@openshift-ci-robot
Copy link

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-4-21
/test e2e-aws-4-21
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws

@cristianoveiga
Copy link
Contributor

File: cmd/cluster/gcp/create.go (not modified in this PR)

It looks like the --image-registry-service-account CLI flag is missing from cmd/cluster/gcp/create.go. Since imageRegistry is +required in the API, running hypershift create cluster gcp without a
way to pass this value would produce an invalid HostedCluster resource.

For reference, the existing --cloud-controller-service-account flag covers:

  • Flag constant and registration
  • RawCreateOptions / ValidatedCreateOptions fields
  • Required validation in ValidateCreateOptions()
  • Mapping to hostedCluster.Spec.Platform.GCP.WorkloadIdentity.ServiceAccountsEmails.CloudController
  • Test coverage in cmd/cluster/gcp/create_test.go

Should the equivalent be added here, or is it intentionally deferred to the next PR?

@cristianoveiga
Copy link
Contributor

/hold

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 2, 2026
@cristianoveiga
Copy link
Contributor

test/e2e/v2/tests/api_ux_validation_test.go has validation test entries for all existing GSA fields (NodePool, ControlPlane, CloudController, Storage) that verify invalid email formats are rejected. A corresponding entry for ImageRegistry appears to be missing:

Entry("it should reject invalid ImageRegistry service account email",
    func(spec *hyperv1.GCPPlatformSpec) {
        spec.WorkloadIdentity.ServiceAccountsEmails.ImageRegistry = "invalid-image-registry-email"
    },
    "imageRegistry in body"),

cristianoveiga added a commit to cristianoveiga/gcp-hcp that referenced this pull request Mar 2, 2026
…add-gcp-service-account skill

Review of PR openshift/hypershift#7828 (ImageRegistry GSA) revealed three
gaps not covered by the existing skill documentation:

- Step 1b: CLI flag in cmd/cluster/gcp/create.go (required for
  hypershift create cluster gcp to set +required API fields)
- Step 1c: Operator credential secret and WIF validation in
  hypershift-operator platform code
- Step 1d: E2E test fixtures and API UX validation test entries

Also updates the PR template to include the new files in staging
and test plan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dation test

Add the missing CLI flag for the Image Registry GSA to
`hypershift create cluster gcp`, following the established pattern
for the 4 existing GSA flags. Also add the ImageRegistry validation
test entry to the e2e v2 API UX tests.

Signed-off-by: Christoph Blecker <cblecker@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Mar 2, 2026
@cblecker
Copy link
Member Author

cblecker commented Mar 2, 2026

@cristianoveiga Both items addressed in 85e6b04:

  1. CLI flag: Added --image-registry-service-account to hypershift create cluster gcp — flag constant, RawCreateOptions field, binding, required validation, and spec mapping, following the exact pattern of the 4 existing GSA flags. Tests updated accordingly.

  2. e2e validation test: Added ImageRegistry to validGCPPlatformSpec() and added the rejection test entry in the api_ux_validation_test.go DescribeTable.

@cblecker
Copy link
Member Author

cblecker commented Mar 2, 2026

/test e2e-aws-techpreview

@openshift-ci-robot
Copy link

openshift-ci-robot commented Mar 2, 2026

@cblecker: This pull request references GCP-391 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

What this PR does / why we need it:

Adds the ImageRegistry field to GCPServiceAccountsEmails and the corresponding IAM binding, enabling the Image Registry Operator on GCP Hosted Control Planes. This is the foundational API change (GCP-391) and IAM binding (GCP-408) that all downstream image registry stories depend on.

The GCPServiceAccountsEmails struct already has 4 GSA fields (NodePool, ControlPlane, CloudController, Storage). This PR adds a 5th: ImageRegistry. The IAM bindings JSON already has 4 entries — this adds a 5th. Both changes follow the exact established patterns.

Changes:

  • API Extension (api/hypershift/v1beta1/gcp.go): Add ImageRegistry field to GCPServiceAccountsEmails with validation, immutability CEL rule, and project-scoping CEL validation on GCPPlatformSpec
  • IAM Bindings (cmd/infra/gcp/iam-bindings.json): Add image-registry service account with roles/storage.admin for GCS bucket operations, targeting openshift-image-registry/cluster-image-registry-operator
  • Credential Reconciliation (hypershift-operator/.../gcp/gcp.go): Add ImageRegistryCredsSecret(), extend ReconcileCredentials() credential map and validateWorkloadIdentityConfiguration() validation
  • Tests: Update all test helpers and add missing image registry validation test case
  • Generated CRDs: Regenerated with the new imageRegistry field present in all CRD variants

Reference: /add-gcp-service-account skill — this PR covers Steps 1-2 (hypershift repo). Steps 3-5 are tracked by GCP-409.

Which issue(s) this PR fixes:

Fixes GCP-391, GCP-408

Special notes for your reviewer:

This follows the exact pattern used for the 4 existing GSA fields. No Go code changes needed for IAM bindings — the JSON is loaded via //go:embed and iterated generically by CreateServiceAccounts() and DeleteServiceAccounts().

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • New Features

  • Added support for configuring an Image Registry service account for GCP, including required validations and immutability; exposed as a required field and CLI option.

  • Documentation

  • Updated API and CRD docs to document imageRegistry format, length, immutability, and IAM guidance.

  • Bug Fixes / Validation

  • Adjusted minimum length validations for several GCP service account emails (38 → 37).

  • Tests

  • Extended unit, e2e fixtures, and validation tests to cover imageRegistry.

  • Chores

  • Added IAM binding and infra manifest entries for the Image Registry service account.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@cristianoveiga
Copy link
Contributor

/hold cancel

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 2, 2026
@cristianoveiga
Copy link
Contributor

/retest ci/prow/docs-preview

@cristianoveiga
Copy link
Contributor

/test docs-preview

@cristianoveiga
Copy link
Contributor

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Mar 2, 2026
@openshift-ci-robot
Copy link

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-4-21
/test e2e-aws-4-21
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws

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

Labels

area/api Indicates the PR includes changes for the API area/cli Indicates the PR includes changes for CLI area/documentation Indicates the PR includes changes for documentation area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/gcp PR/issue for GCP (GCPPlatform) platform area/testing Indicates the PR includes changes for e2e testing jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants