Skip to content

CNTRLPLANE-2939: Coordinate CRD lifecycle with Cluster CAPI Operator#7996

Merged
openshift-merge-bot[bot] merged 2 commits into
openshift:mainfrom
muraee:capi-compatibility
May 5, 2026
Merged

CNTRLPLANE-2939: Coordinate CRD lifecycle with Cluster CAPI Operator#7996
openshift-merge-bot[bot] merged 2 commits into
openshift:mainfrom
muraee:capi-compatibility

Conversation

@muraee

@muraee muraee commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

When a management cluster has the Cluster CAPI Operator (CCAPIO) installed, HyperShift's hypershift install command installs CAPI CRDs that may conflict with CRDs already managed by CCAPIO. This PR adds coordination logic to the install flow:

Dry-run validation: All CRDs are validated via server-side dry-run before applying, catching webhook rejections and schema conflicts early — regardless of CCAPIO presence
CCAPIO detection: Uses the discovery API to check if the ClusterAPI kind is served under operator.openshift.io/v1alpha1
CRD ownership signaling: Gets-or-creates the ClusterAPI config singleton and populates spec.unmanagedCustomResourceDefinitions with HyperShift's CAPI CRD names (groups ending in .cluster.x-k8s.io), telling CCAPIO to skip these CRDs
The coordination only mutates the ClusterAPI config after dry-run passes, so there are no side effects if CRDs cannot be applied.

Install flow (after this PR):

generate manifests
  → dry-run validate all CRDs
  → if ClusterAPI API available: ensure unmanaged CRDs in config
  → apply CRDs
  → wait for CRDs to be established (if requested)
  → apply remaining objects

Vendor bump

Bumps github.com/openshift/api from v0.0.0-20260120150926-4c643a652d54 to v0.0.0-20260227165130-5a7add616a90 to vendor the ClusterAPI config type (operator.openshift.io/v1alpha1). The selected commit remains compatible with k8s.io v0.34.x.

Which issue(s) this PR fixes:

Fixes https://issues.redhat.com/browse/CNTRLPLANE-2939

Special notes for your reviewer:

The unmanagedCustomResourceDefinitions field is append-only (CEL enforced) — once a CRD name is added, it cannot be removed
In the pre-upgrade scenario (4.N-1), CCAPIO webhooks are not running so dry-run passes trivially — this is expected and correct
Helm chart rendering (hyperShiftOperatorManifests with nil client) is unaffected — CCAPIO coordination only runs in InstallHyperShiftOperator

Summary by CodeRabbit

  • New Features

    • Installation performs CRD dry-run validation and coordinates with ClusterAPI to mark certain CRDs as unmanaged when applicable.
  • Chores

    • Updated OpenShift API dependency version.
    • Removed NetworkDiagnosticsConfig from feature gates in generated CRD manifests.
  • Tests

    • Added tests for ClusterAPI detection and unmanaged-CRD coordination.

@openshift-ci-robot

Copy link
Copy Markdown

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 Mar 18, 2026
@openshift-ci-robot

openshift-ci-robot commented Mar 18, 2026

Copy link
Copy Markdown

@muraee: This pull request references CNTRLPLANE-2939 which is a valid jira issue.

Details

In response to this:

What this PR does / why we need it:

When a management cluster has the Cluster CAPI Operator (CCAPIO) installed, HyperShift's hypershift install command installs CAPI CRDs that may conflict with CRDs already managed by CCAPIO. This PR adds coordination logic to the install flow:

Dry-run validation: All CRDs are validated via server-side dry-run before applying, catching webhook rejections and schema conflicts early — regardless of CCAPIO presence
CCAPIO detection: Uses the discovery API to check if the ClusterAPI kind is served under operator.openshift.io/v1alpha1
CRD ownership signaling: Gets-or-creates the ClusterAPI config singleton and populates spec.unmanagedCustomResourceDefinitions with HyperShift's CAPI CRD names (groups ending in .cluster.x-k8s.io), telling CCAPIO to skip these CRDs
The coordination only mutates the ClusterAPI config after dry-run passes, so there are no side effects if CRDs cannot be applied.

Install flow (after this PR):

generate manifests
 → dry-run validate all CRDs
 → if ClusterAPI API available: ensure unmanaged CRDs in config
 → apply CRDs
 → wait for CRDs to be established (if requested)
 → apply remaining objects

Vendor bump

Bumps github.com/openshift/api from v0.0.0-20260120150926-4c643a652d54 to v0.0.0-20260227165130-5a7add616a90 to vendor the ClusterAPI config type (operator.openshift.io/v1alpha1). The selected commit remains compatible with k8s.io v0.34.x.

Which issue(s) this PR fixes:

Fixes https://issues.redhat.com/browse/CNTRLPLANE-2939

Special notes for your reviewer:

The unmanagedCustomResourceDefinitions field is append-only (CEL enforced) — once a CRD name is added, it cannot be removed
In the pre-upgrade scenario (4.N-1), CCAPIO webhooks are not running so dry-run passes trivially — this is expected and correct
Helm chart rendering (hyperShiftOperatorManifests with nil client) is unaffected — CCAPIO coordination only runs in InstallHyperShiftOperator

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.

@muraee

muraee commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-minimal

@coderabbitai

coderabbitai Bot commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The installer now performs server-side dry-run validation of CRDs before applying manifests. It uses discovery to detect whether the ClusterAPI (cluster.x-k8s.io) API is served on the management cluster. If ClusterAPI is present, the installer creates or updates the ClusterAPI configuration object to mark HyperShift CRDs as unmanaged. New unexported helpers implement discovery queries, CRD dry-run validation, and ensuring the singleton ClusterAPI config. The change also updates an OpenShift API dependency and removes NetworkDiagnosticsConfig from two generated CRD FeatureGates entries.

Sequence Diagram

sequenceDiagram
    participant Installer
    participant APIServer as Management Cluster API
    participant Discovery
    participant CAPIConfig as ClusterAPI Config

    Installer->>APIServer: Dry-run validate CRDs (server-side patch)
    APIServer-->>Installer: Validation results

    Installer->>Discovery: Query API resources for cluster.x-k8s.io
    Discovery->>APIServer: GET /apis/cluster.x-k8s.io
    APIServer-->>Discovery: APIResourceList or NotFound
    Discovery-->>Installer: ClusterAPI present? (yes/no)

    alt ClusterAPI registered
        Installer->>CAPIConfig: Get existing ClusterAPI config
        CAPIConfig-->>Installer: Config (or not found)
        Installer->>Installer: Merge HyperShift CRDs into unmanaged list
        Installer->>CAPIConfig: Create/Update config with unmanaged CRDs
        CAPIConfig-->>Installer: Config updated
    end

    Installer->>APIServer: Apply CRDs and manifests
    APIServer-->>Installer: Apply result
Loading
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci-robot

openshift-ci-robot commented Mar 18, 2026

Copy link
Copy Markdown

@muraee: This pull request references CNTRLPLANE-2939 which is a valid jira issue.

Details

In response to this:

What this PR does / why we need it:

When a management cluster has the Cluster CAPI Operator (CCAPIO) installed, HyperShift's hypershift install command installs CAPI CRDs that may conflict with CRDs already managed by CCAPIO. This PR adds coordination logic to the install flow:

Dry-run validation: All CRDs are validated via server-side dry-run before applying, catching webhook rejections and schema conflicts early — regardless of CCAPIO presence
CCAPIO detection: Uses the discovery API to check if the ClusterAPI kind is served under operator.openshift.io/v1alpha1
CRD ownership signaling: Gets-or-creates the ClusterAPI config singleton and populates spec.unmanagedCustomResourceDefinitions with HyperShift's CAPI CRD names (groups ending in .cluster.x-k8s.io), telling CCAPIO to skip these CRDs
The coordination only mutates the ClusterAPI config after dry-run passes, so there are no side effects if CRDs cannot be applied.

Install flow (after this PR):

generate manifests
 → dry-run validate all CRDs
 → if ClusterAPI API available: ensure unmanaged CRDs in config
 → apply CRDs
 → wait for CRDs to be established (if requested)
 → apply remaining objects

Vendor bump

Bumps github.com/openshift/api from v0.0.0-20260120150926-4c643a652d54 to v0.0.0-20260227165130-5a7add616a90 to vendor the ClusterAPI config type (operator.openshift.io/v1alpha1). The selected commit remains compatible with k8s.io v0.34.x.

Which issue(s) this PR fixes:

Fixes https://issues.redhat.com/browse/CNTRLPLANE-2939

Special notes for your reviewer:

The unmanagedCustomResourceDefinitions field is append-only (CEL enforced) — once a CRD name is added, it cannot be removed
In the pre-upgrade scenario (4.N-1), CCAPIO webhooks are not running so dry-run passes trivially — this is expected and correct
Helm chart rendering (hyperShiftOperatorManifests with nil client) is unaffected — CCAPIO coordination only runs in InstallHyperShiftOperator

Summary by CodeRabbit

  • New Features

  • Enhanced installation process with server-side CRD validation to ensure cluster compatibility.

  • Added automatic detection and coordination with ClusterAPI when present on the management cluster.

  • Chores

  • Updated OpenShift API dependency version.

  • Removed NetworkDiagnosticsConfig from feature gates.

  • Tests

  • Added tests for ClusterAPI registration detection and unmanaged CRD handling.

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 openshift-ci Bot requested review from enxebre and sjenning March 18, 2026 12:14
@openshift-ci openshift-ci Bot added area/api Indicates the PR includes changes for the API area/cli Indicates the PR includes changes for CLI approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed do-not-merge/needs-area labels Mar 18, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 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/install.go`:
- Around line 961-999: The Get/Create/Update sequence in ensureUnmanagedCRDs can
race with concurrent installers; wrap the whole read-modify-write block in a
retry.RetryOnConflict loop so it will re-fetch and retry on resource version
conflicts. Inside the loop, call client.Get to load ClusterAPI, on
apierrors.IsNotFound create the singleton and if client.Create returns
apierrors.IsAlreadyExists convert that to a conflict error (so RetryOnConflict
will re-get and continue); otherwise on success return. For the update path,
recompute merged UnmanagedCustomResourceDefinitions, set clusterAPI.Spec if nil,
and call client.Update; let RetryOnConflict retry on conflicts until the update
succeeds or a non-retryable error is returned.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: ec2b7873-5c3e-4bd5-b920-00ebf03314e0

📥 Commits

Reviewing files that changed from the base of the PR and between c720fb7 and b0e0214.

⛔ Files ignored due to path filters (100)
  • api/go.sum is excluded by !**/*.sum
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/config/v1/types_ingress.go is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/config/v1/types_insights.go is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/config/v1/types_network.go is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !**/zz_generated*.go, !**/zz_generated.swagger_doc_generated.go
  • api/vendor/github.com/openshift/api/operator/v1/types_network.go is excluded by !**/vendor/**
  • api/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**
  • api/vendor/modules.txt is excluded by !**/vendor/**
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/.coderabbit.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/.golangci.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/Makefile is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/types_compatibilityrequirement.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated.swagger_doc_generated.go
  • vendor/github.com/openshift/api/apps/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/apps/v1/zz_prerelease_lifecycle_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_ingress.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_insights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_network.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated.swagger_doc_generated.go
  • vendor/github.com/openshift/api/config/v1alpha1/register.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_backup.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_crio_credential_provider_config.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_insights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated.swagger_doc_generated.go
  • vendor/github.com/openshift/api/config/v1alpha2/types_insights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha2/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_sample.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/etcd/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/etcd/install.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/Makefile is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/register.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/types_pacemakercluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go
  • vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated.swagger_doc_generated.go
  • vendor/github.com/openshift/api/features.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/install.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machine/v1/types_controlplanemachineset.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machine/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated.swagger_doc_generated.go
  • vendor/github.com/openshift/api/machineconfiguration/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/operator/v1/types_network.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/register.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated.swagger_doc_generated.go
  • vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (5)
  • api/go.mod
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests.yaml
  • cmd/install/install.go
  • cmd/install/install_test.go
  • go.mod
💤 Files with no reviewable changes (1)
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests.yaml

Comment thread cmd/install/install.go Outdated
@muraee

muraee commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

/test verify

@muraee muraee force-pushed the capi-compatibility branch from b0e0214 to d3c739c Compare March 18, 2026 15:10
@openshift-ci-robot

openshift-ci-robot commented Mar 18, 2026

Copy link
Copy Markdown

@muraee: This pull request references CNTRLPLANE-2939 which is a valid jira issue.

Details

In response to this:

What this PR does / why we need it:

When a management cluster has the Cluster CAPI Operator (CCAPIO) installed, HyperShift's hypershift install command installs CAPI CRDs that may conflict with CRDs already managed by CCAPIO. This PR adds coordination logic to the install flow:

Dry-run validation: All CRDs are validated via server-side dry-run before applying, catching webhook rejections and schema conflicts early — regardless of CCAPIO presence
CCAPIO detection: Uses the discovery API to check if the ClusterAPI kind is served under operator.openshift.io/v1alpha1
CRD ownership signaling: Gets-or-creates the ClusterAPI config singleton and populates spec.unmanagedCustomResourceDefinitions with HyperShift's CAPI CRD names (groups ending in .cluster.x-k8s.io), telling CCAPIO to skip these CRDs
The coordination only mutates the ClusterAPI config after dry-run passes, so there are no side effects if CRDs cannot be applied.

Install flow (after this PR):

generate manifests
 → dry-run validate all CRDs
 → if ClusterAPI API available: ensure unmanaged CRDs in config
 → apply CRDs
 → wait for CRDs to be established (if requested)
 → apply remaining objects

Vendor bump

Bumps github.com/openshift/api from v0.0.0-20260120150926-4c643a652d54 to v0.0.0-20260227165130-5a7add616a90 to vendor the ClusterAPI config type (operator.openshift.io/v1alpha1). The selected commit remains compatible with k8s.io v0.34.x.

Which issue(s) this PR fixes:

Fixes https://issues.redhat.com/browse/CNTRLPLANE-2939

Special notes for your reviewer:

The unmanagedCustomResourceDefinitions field is append-only (CEL enforced) — once a CRD name is added, it cannot be removed
In the pre-upgrade scenario (4.N-1), CCAPIO webhooks are not running so dry-run passes trivially — this is expected and correct
Helm chart rendering (hyperShiftOperatorManifests with nil client) is unaffected — CCAPIO coordination only runs in InstallHyperShiftOperator

Summary by CodeRabbit

  • New Features

  • Enhanced installation flow with server-side CRD dry-run validation before applying manifests.

  • Automatic detection and coordination with ClusterAPI on the management cluster to mark certain CRDs as unmanaged when appropriate.

  • Chores

  • Updated OpenShift API dependency version.

  • Removed NetworkDiagnosticsConfig from feature gates.

  • Tests

  • Added tests covering ClusterAPI detection and unmanaged-CRD coordination behavior.

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.

@enxebre

enxebre commented Mar 20, 2026

Copy link
Copy Markdown
Member

we'll want to test this via #8016 as well
/lgtm
/hold
pending #7996 (comment) resolution

@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 20, 2026
@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Mar 20, 2026
@openshift-ci-robot

Copy link
Copy Markdown

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

@cwbotbot

cwbotbot commented Mar 20, 2026

Copy link
Copy Markdown

Test Results

e2e-aws

e2e-aks

@JoelSpeed

Copy link
Copy Markdown
Contributor

In the pre-upgrade scenario (4.N-1), CCAPIO webhooks are not running so dry-run passes trivially — this is expected and correct

I think eventually we will have upgrade checks in place so that the webhooks will warn about the future version being incompatible, but otherwise, PR description is accurate

@JoelSpeed

Copy link
Copy Markdown
Contributor

/lgtm

In the pre-upgrade scenario (4.N-1), CCAPIO webhooks are not running so dry-run passes trivially — this is expected and correct

I think this has made us realise we need to adjust the way we are setting up CompatibilityRequirements, but that's fine, I'll make a note and we can make this concept work and be safe so that your initial dry runs are effective

@muraee

muraee commented Mar 23, 2026

Copy link
Copy Markdown
Contributor Author

/retest-required

@enxebre

enxebre commented Mar 25, 2026

Copy link
Copy Markdown
Member

@muraee can we rebase?
/hold cancel

@codecov

codecov Bot commented Mar 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.86207% with 57 lines in your changes missing coverage. Please review.
✅ Project coverage is 37.24%. Comparing base (29053b7) to head (a410597).
⚠️ Report is 30 commits behind head on main.

Files with missing lines Patch % Lines
cmd/install/install.go 50.86% 54 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7996      +/-   ##
==========================================
+ Coverage   37.22%   37.24%   +0.01%     
==========================================
  Files         750      750              
  Lines       91789    91905     +116     
==========================================
+ Hits        34168    34227      +59     
- Misses      54981    55035      +54     
- Partials     2640     2643       +3     
Files with missing lines Coverage Δ
cmd/install/install.go 51.34% <50.86%> (-0.06%) ⬇️
Flag Coverage Δ
cmd-support 32.14% <50.86%> (+0.07%) ⬆️
cpo-hostedcontrolplane 36.45% <ø> (ø)
cpo-other 37.73% <ø> (ø)
hypershift-operator 47.84% <ø> (ø)
other 27.77% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gaol

gaol commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

I did a round of tests and attached the test report to the Jira comments.

basically what I did were:

  • test on 4.21 nightly cluster on AWS which does not have ClusterAPI CRD yet, so the coordinate does not happen, all works as before, HO installed without problems.

  • test on 4.22 nightly cluster on AWS, enable the clusterapi featuregate and it will create a ClusterAPI CR, then hypershift install will do the coordinations.

  • The hypershift operator pods are in running status after installation, the UnmanagedCustomResourceDefinitions contains all *.cluster.x-k8s.io CRD names, and the CRDs have hypershift as the field owner.

I did not test the hosted cluster creation yet after the hypershift operator installation succeeded (mgmt cluster expired ...).

If the pr needs the verified tag today, I can tag :) , or I can do the hosted cluster creation next Tuesday. (PTO tomorrow and holidays)

@muraee

@mdbooth mdbooth 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.

This is mostly there, thanks. Once you're also waiting for the config change to have been actioned it'll be there.

From our side, in addition to the missing status field I mentioned, note that we also haven't actually integrated CRD Compatibility into the installer yet. We're hopefully very close, but it won't current do anything. Until we do, even after you've marked the CRDs unmanaged we're still going to be trying to manage them. This is going to result in a controller fight.

Comment thread cmd/install/install.go Outdated
Comment thread cmd/install/install.go Outdated
Comment thread cmd/install/install.go
@muraee muraee force-pushed the capi-compatibility branch from aee5318 to cb85728 Compare April 7, 2026 16:37
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Apr 7, 2026
@muraee muraee force-pushed the capi-compatibility branch 2 times, most recently from 45e4666 to 8e7f844 Compare April 30, 2026 09:05
Comment thread cmd/install/install.go
capiCRDNames := set.New[string]()
for _, crd := range capiCRDs {
name := crd.GetName()
if strings.HasSuffix(name, ".cluster.x-k8s.io") {

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.

I suspect this suffix selection will be insufficient. I'm thinking specifically of ASO on Azure (not currently deployed by CAPIO, but probably will be eventually) and ORC on OpenStack (currently deployed by CAPIO), but there could be others.

Something which can be addressed when it comes up, doesn't have to be a blocker today.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, this will likely need expanding for ASO/ORC and others. I've left it as-is for now since those aren't deployed by CAPIO yet — we can extend the filter when the need arises.

Comment thread cmd/install/install.go Outdated
Comment on lines +1018 to +1021
if err := hyperapi.YamlSerializer.Encode(clusterAPI, &buf); err != nil {
return fmt.Errorf("failed to encode ClusterAPI config: %w", err)
}
if err := client.Patch(ctx, clusterAPI, crclient.RawPatch(types.ApplyPatchType, buf.Bytes()),

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.

FYI this is not safe in general due to the vagiaries of serialisation in Go. Suggest you use an ApplyConfiguration instead which is specifically designed for this. You'll find them in openshift/client-go.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call. ApplyConfiguration types for operator/v1alpha1 don't exist in openshift/client-go yet, so I've switched to constructing the SSA patch payload as a map[string]any with encoding/json.Marshal. This ensures only the fields we intend to own are included in the patch, avoiding zero-value serialization issues.

Comment thread cmd/install/install.go Outdated
Comment on lines +1045 to +1047
if clusterAPI.Status.ObservedRevisionGeneration < clusterAPI.Generation {
return false, nil
}

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.

This is not correct, yet: you're asserting that the ClusterAPI object you've read here was up to date with itself, but you're not asserting that it's up to date with the one you just wrote. i.e. The first time this executes you could (and if you're using an informer almost definitely will, if you're not using an informer still might) read an old version of ClusterAPI before you updated it. This old ClusterAPI will almost certainly pass both of these checks, but it's still out of date.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. ensureUnmanagedCRDs now returns the metadata.generation from the SSA patch response, and waitForCAPIOperatorSync compares status.observedRevisionGeneration against that known generation rather than against the polled object's own generation. Added a test case for the stale-read scenario.

Comment thread cmd/install/install.go
crclient.ForceOwnership, crclient.FieldOwner("hypershift"),
); err != nil {
return fmt.Errorf("failed to apply ClusterAPI config: %w", err)
}

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.

At this point your clusterAPI object has been updated to be current with whatever was written in the PATCH. The metadata.generation from this object is the one you need to compare against in waitForCAPIOperatorSync.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — ensureUnmanagedCRDs now returns clusterAPI.Generation from the patch response object and the caller passes it through to waitForCAPIOperatorSync.

@hypershift-jira-solve-ci

hypershift-jira-solve-ci Bot commented Apr 30, 2026

Copy link
Copy Markdown

I have all the evidence needed. Here is the complete analysis:

Test Failure Analysis Complete

Job Information

Test Failure Analysis

Error

OUTDATED: .github/workflows/envtest-kube.yaml has been updated on main since this branch diverged.
OUTDATED: .github/workflows/envtest-ocp.yaml has been updated on main since this branch diverged.

Rebase your branch on main: git fetch upstream main && git rebase upstream/main

Summary

The verify-workflows CI check ensures that GitHub Actions workflow files in a PR branch are not stale relative to main. PR #7996 branched from main at commit 5eaee74 (merged 2026-04-30 05:31 UTC). After the branch diverged, PR #8166 (CNTRLPLANE-3160) was merged at 15:08 UTC, which updated .github/workflows/envtest-kube.yaml and .github/workflows/envtest-ocp.yaml to add karpenter test paths to the envtest workflow triggers. Since PR #7996 does not include those updates (its copies of those files match the pre-#8166 versions), the verify-workflows check correctly flagged them as outdated and failed. This is not a product bug — it is a branch staleness issue requiring a rebase.

Root Cause

The verify-workflows CI step compares the SHA of every file under .github/workflows/ between three refs:

  1. MAIN (9bb7d76) — current tip of main
  2. PR_HEAD (2a959d57) — the actual PR branch head (second parent of ci-operator's merge commit)
  3. BASE (5eaee74) — the merge-base of the PR branch and main

For each workflow file, if the file's content on PR_HEAD matches BASE but differs from MAIN, the file is flagged as OUTDATED — meaning main updated it after the branch diverged, and the PR branch never picked up those changes.

Timeline:

PR #7996 only modifies cmd/install/install.go and cmd/install/install_test.go — it does not touch any workflow files. The workflow files on the PR branch are identical to the merge-base but differ from current main, triggering the staleness check.

Recommendations
  1. Rebase the PR branch on main to pick up the workflow file updates:

    git fetch upstream main && git rebase upstream/main

    This will incorporate the envtest-kube.yaml and envtest-ocp.yaml changes from PR CNTRLPLANE-3160: Drop AutoNodeKarpenter feature gate and promote EC2NodeClass to v1 #8166 and resolve the verify-workflows failure.

  2. Re-trigger the CI job after the rebase — no code changes to the PR itself are needed.

  3. This is not a flake and will not resolve on retry without rebasing — the check is deterministic and will continue to fail as long as the branch is behind main on these workflow files.

Evidence
Evidence Detail
Failing check verify-workflows (container test in ci-operator)
Outdated file 1 .github/workflows/envtest-kube.yaml
Outdated file 2 .github/workflows/envtest-ocp.yaml
PR branch base (merge-base) 5eaee747 (2026-04-30 05:31 UTC — dependabot consolidation merge)
Commit that updated workflows on main 366f2553 (2026-04-30 08:18 UTC — PR #8166, CNTRLPLANE-3160)
PR #8166 merged at 2026-04-30 15:08 UTC
verify-workflows ran at 2026-04-30 16:45 UTC (after main had diverged)
PR #7996 files changed cmd/install/install.go, cmd/install/install_test.go (no workflow files)
CI check script location openshift/release repo: ci-operator/config/openshift/hypershift/openshift-hypershift-main.yaml (inline commands block under as: verify-workflows)
Check logic Compares git rev-parse "${MAIN_REF}:${file}" vs "${PR_HEAD}:${file}" vs "${BASE}:${file}" for all files under .github/workflows/

muraee and others added 2 commits May 4, 2026 11:47
When the ClusterAPI CRD (clusterapis.operator.openshift.io) is
registered on the management cluster, the install command now:

1. Detects CCAPIO presence by checking for the ClusterAPI CRD
2. Gets-or-creates the ClusterAPI config singleton and populates
   unmanagedCustomResourceDefinitions with HyperShift's CAPI CRD
   names (those with groups ending in .cluster.x-k8s.io)
3. Validates all CRDs via server-side dry-run before applying,
   regardless of CCAPIO presence, to catch webhook rejections
   and schema conflicts early

This prevents conflicts between HyperShift and CCAPIO when both
attempt to manage the same CAPI CRDs on the management cluster.

Ref: CNTRLPLANE-2939

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use JSON map for SSA patch payload instead of YamlSerializer to avoid
  zero-value serialization issues (ApplyConfiguration types for
  operator/v1alpha1 are not yet available in openshift/client-go)
- Return metadata.generation from ensureUnmanagedCRDs and pass it to
  waitForCAPIOperatorSync to prevent false positives from stale reads
- Add test case for stale object scenario

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@muraee muraee force-pushed the capi-compatibility branch from 2a959d5 to a410597 Compare May 4, 2026 09:47

@mdbooth mdbooth 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.

/lgtm

👍

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label May 5, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

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

@hypershift-jira-solve-ci

Copy link
Copy Markdown

AI Test Failure Analysis

Job: pull-ci-openshift-hypershift-main-e2e-aws | Build: 2051570519186083840 | Cost: $2.861941500000001 | Failed step: hypershift-aws-run-e2e-nested

View full analysis report


Generated by hypershift-analyze-e2e-failure post-step using Claude claude-opus-4-6

@muraee

muraee commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

/retest-required

@muraee

muraee commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

/verified bypass

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label May 5, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@muraee: The verified label has been added.

Details

In response to this:

/verified bypass

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-merge-bot

Copy link
Copy Markdown
Contributor

/retest-required

Remaining retests: 0 against base HEAD e09cc2d and 2 for PR HEAD a410597 in total

@openshift-ci

openshift-ci Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

@muraee: The following test 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/verify-workflows 2a959d5 link true /test verify-workflows

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.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

/retest-required

Remaining retests: 0 against base HEAD 3c3ccfc and 1 for PR HEAD a410597 in total

@openshift-merge-bot openshift-merge-bot Bot merged commit effd754 into openshift:main May 5, 2026
38 checks passed
chdeshpa-hue added a commit to chdeshpa-hue/hypershift-addon-operator that referenced this pull request Jun 9, 2026
Fixes: https://redhat.atlassian.net/browse/OCPBUGS-86791

The HyperShift install code (openshift/hypershift#7996) added CAPI
coordination logic that patches clusterapis.operator.openshift.io/cluster
to register unmanaged CRDs with the Cluster CAPI Operator. The addon
agent ClusterRole template was never updated to grant these permissions,
causing the install job to fail with a forbidden error when the
ClusterAPIInstall FeatureGate is enabled.

Add get/list/watch/patch on operator.openshift.io/clusterapis to the
addon agent ClusterRole template, and add a unit test to prevent
regression.

Signed-off-by: Chirag Deshpande <chdeshpa@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
openshift-merge-bot Bot pushed a commit to stolostron/hypershift-addon-operator that referenced this pull request Jun 9, 2026
…#711)

Fixes: https://redhat.atlassian.net/browse/OCPBUGS-86791

The HyperShift install code (openshift/hypershift#7996) added CAPI
coordination logic that patches clusterapis.operator.openshift.io/cluster
to register unmanaged CRDs with the Cluster CAPI Operator. The addon
agent ClusterRole template was never updated to grant these permissions,
causing the install job to fail with a forbidden error when the
ClusterAPIInstall FeatureGate is enabled.

Add get/list/watch/patch on operator.openshift.io/clusterapis to the
addon agent ClusterRole template, and add a unit test to prevent
regression.

Signed-off-by: Chirag Deshpande <chdeshpa@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/api Indicates the PR includes changes for the API area/cli Indicates the PR includes changes for CLI 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. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants