Skip to content

OCPBUGS-82166: fix etcd snapshot restore for etcd 3.6 and enforce restoreSnapshotURL immutability#8186

Merged
openshift-merge-bot[bot] merged 4 commits intoopenshift:mainfrom
jparrill:OCPBUGS-82166
Apr 10, 2026
Merged

OCPBUGS-82166: fix etcd snapshot restore for etcd 3.6 and enforce restoreSnapshotURL immutability#8186
openshift-merge-bot[bot] merged 4 commits intoopenshift:mainfrom
jparrill:OCPBUGS-82166

Conversation

@jparrill
Copy link
Copy Markdown
Contributor

@jparrill jparrill commented Apr 8, 2026

Summary

  • Use etcdutl for snapshot restore/status on etcd 3.6+ (OCP 4.21+), falling back to etcdctl for older versions
  • Add CEL validation rule (self == oldSelf) to enforce restoreSnapshotURL immutability at admission time, aligning with the existing API contract ("only when the etcd PV is empty")
  • Add envtest CEL validation test suite for restoreSnapshotURL field constraints

Changes

  1. etcd-init.sh: etcdutl/etcdctl fallback with error when neither tool is available
  2. API: CEL immutability rule on restoreSnapshotURL + regenerated CRDs
  3. Test suite: envtest YAML-driven tests covering MaxItems enforcement, immutability on update (change/removal rejected), and allowed transitions (initial set, unchanged value, unrelated updates)

Test plan

  • Verify etcd snapshot restore works on OCP 4.21 (etcd 3.6) with a valid pre-signed S3 URL
  • Verify etcd snapshot restore works on OCP 4.18-4.20 (etcd 3.5.x)
  • Verify day-2 modification of restoreSnapshotURL is rejected by CEL validation
  • Verify OADP restore workflow (plugin patches HC before CREATE) is not affected by CEL
  • envtest suite passes for restoreSnapshotURL CEL validation (make test-envtest-kube)

Bug

https://redhat.atlassian.net/browse/OCPBUGS-82166

🤖 Generated with Claude Code

@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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

Important

Review skipped

Auto reviews are limited based on label configuration.

🚫 Review skipped — only excluded labels are configured. (1)
  • do-not-merge/work-in-progress

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 7c158ba8-8ca0-4306-82ce-3734fbb464f3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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 etcd init script now prefers /usr/bin/etcdutl for snapshot status/restore and prints an INFO when using it. If etcdutl is unavailable it falls back to ETCDCTL_API=3 etcdctl and prints an INFO about the fallback. If neither binary exists the script logs an ERROR and exits 1. The script still checks /var/lib/data (logging a warning and listing contents if non-empty), validates the downloaded snapshot by inspecting the first five bytes for an XML error header, restores into /var/lib/restore, and replaces /var/lib/data with the restored directory on success.

Sequence Diagram(s)

sequenceDiagram
  participant InitScript as Init Script
  participant ObjStorage as Object Storage (snapshot URL)
  participant FS as Filesystem
  participant Tool as Tool Selector
  participant EtcdUtl as /usr/bin/etcdutl
  participant EtcdCtl as etcdctl

  InitScript->>FS: check /var/lib/data
  alt data non-empty
    InitScript->>InitScript: log warning & list contents
  end
  InitScript->>ObjStorage: curl "snapshot-url" -> /tmp/snapshot
  ObjStorage-->>InitScript: snapshot bytes
  InitScript->>FS: read first 5 bytes of /tmp/snapshot
  alt header == "<?xml"
    InitScript->>InitScript: log error, output snapshot contents
    InitScript-->>InitScript: exit 1
  else header != "<?xml"
    InitScript->>FS: create /var/lib/restore
    InitScript->>Tool: test -x /usr/bin/etcdutl
    alt etcdutl exists
      Tool->>EtcdUtl: INFO + etcdutl snapshot status -w table /tmp/snapshot
      EtcdUtl-->>InitScript: status
      Tool->>EtcdUtl: etcdutl snapshot restore --data-dir=/var/lib/restore ...
      EtcdUtl-->>FS: write /var/lib/restore
    else
      Tool->>Tool: test for etcdctl
      alt etcdctl exists
        Tool->>EtcdCtl: INFO + ETCDCTL_API=3 etcdctl snapshot status /tmp/snapshot
        EtcdCtl-->>InitScript: status
        Tool->>EtcdCtl: ETCDCTL_API=3 etcdctl snapshot restore --data-dir=/var/lib/restore ...
        EtcdCtl-->>FS: write /var/lib/restore
      else neither exists
        Tool->>InitScript: ERROR "no etcdutl or etcdctl available"
        InitScript-->>InitScript: exit 1
      end
    end
    InitScript->>FS: remove /var/lib/data
    InitScript->>FS: move /var/lib/restore -> /var/lib/data
  end
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 openshift-ci bot requested review from bryan-cox and cblecker April 8, 2026 17:27
@openshift-ci openshift-ci bot added area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed do-not-merge/needs-area labels Apr 8, 2026
Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@control-plane-operator/controllers/hostedcontrolplane/v2/etcd/etcd-init.sh`:
- Line 12: The curl invocation in etcd-init.sh uses an unquoted variable
${RESTORE_URL}, which can be subject to word splitting or globbing; update the
curl command to quote the RESTORE_URL variable (use "${RESTORE_URL}") so the
pre-signed S3 URL is passed as a single argument to curl and special characters
are preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: e712833b-5890-4272-b160-6c2d74e1ff25

📥 Commits

Reviewing files that changed from the base of the PR and between c674483 and e1ff42a.

📒 Files selected for processing (1)
  • control-plane-operator/controllers/hostedcontrolplane/v2/etcd/etcd-init.sh

Comment thread control-plane-operator/controllers/hostedcontrolplane/v2/etcd/etcd-init.sh Outdated
@jparrill jparrill changed the title fix(OCPBUGS-82166): use etcdutl for snapshot restore on etcd 3.6+ OCPBUGS-82166: use etcdutl for snapshot restore on etcd 3.6+ Apr 8, 2026
@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Apr 8, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-82166, which is invalid:

  • expected the bug to target the "4.22.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • Use etcdutl for snapshot restore/status on etcd 3.6+ (OCP 4.21+), falling back to etcdctl for older versions
  • Fix S3 XML error detection: replace missing file binary with head -c 5 | grep '<?xml'

Root Cause

etcd 3.6 (shipped in OCP 4.21) removed etcdctl snapshot restore and etcdctl snapshot status subcommands, moving them to etcdutl. The etcd-init.sh script used by the etcd StatefulSet init container breaks on OCP 4.21+ because it calls the removed subcommands.

Additionally, the script used the file command to detect S3 XML error responses from expired pre-signed URLs, but the file binary has never been present in the etcd container image.

Changes

The init script now:

  1. Checks for /usr/bin/etcdutl and uses it when available (etcd 3.6+/OCP 4.21+)
  2. Falls back to etcdctl for older versions (etcd 3.5.x/OCP ≤4.20)
  3. Uses head -c 5 | grep '<?xml' instead of file to detect XML error responses

Test plan

  • Verify etcd snapshot restore works on OCP 4.21 (etcd 3.6) with a valid pre-signed S3 URL
  • Verify etcd snapshot restore still works on OCP 4.18-4.20 (etcd 3.5.x)
  • Verify expired/invalid pre-signed URL is properly detected and logged

Bug

https://redhat.atlassian.net/browse/OCPBUGS-82166

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
  • Improved snapshot error detection accuracy during validation
  • Enhanced snapshot restore operation reliability with broader tooling compatibility

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.

@jparrill
Copy link
Copy Markdown
Contributor Author

jparrill commented Apr 8, 2026

/jira refresh

@openshift-ci-robot openshift-ci-robot added jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. and removed jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Apr 8, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-82166, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state ASSIGNED, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

/jira refresh

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-robot
Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-82166, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

Summary

  • Use etcdutl for snapshot restore/status on etcd 3.6+ (OCP 4.21+), falling back to etcdctl for older versions
  • Fix S3 XML error detection: replace missing file binary with head -c 5 | grep '<?xml'

Root Cause

etcd 3.6 (shipped in OCP 4.21) removed etcdctl snapshot restore and etcdctl snapshot status subcommands, moving them to etcdutl. The etcd-init.sh script used by the etcd StatefulSet init container breaks on OCP 4.21+ because it calls the removed subcommands.

Additionally, the script used the file command to detect S3 XML error responses from expired pre-signed URLs, but the file binary has never been present in the etcd container image.

Changes

The init script now:

  1. Checks for /usr/bin/etcdutl and uses it when available (etcd 3.6+/OCP 4.21+)
  2. Falls back to etcdctl for older versions (etcd 3.5.x/OCP ≤4.20)
  3. Uses head -c 5 | grep '<?xml' instead of file to detect XML error responses

Test plan

  • Verify etcd snapshot restore works on OCP 4.21 (etcd 3.6) with a valid pre-signed S3 URL
  • Verify etcd snapshot restore still works on OCP 4.18-4.20 (etcd 3.5.x)
  • Verify expired/invalid pre-signed URL is properly detected and logged

Bug

https://redhat.atlassian.net/browse/OCPBUGS-82166

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
  • Improved snapshot validation accuracy to better detect error-page (XML) responses.
  • Logs a clear error when a downloaded snapshot contains an XML error before showing contents.
  • More reliable snapshot status and restore: prefers the newer snapshot tool when available, with a fallback to the previous tool for broader compatibility.

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.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 33.16%. Comparing base (c674483) to head (f2dab40).
⚠️ Report is 18 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8186      +/-   ##
==========================================
+ Coverage   33.11%   33.16%   +0.04%     
==========================================
  Files         768      768              
  Lines       93116    93163      +47     
==========================================
+ Hits        30840    30902      +62     
+ Misses      59665    59646      -19     
- Partials     2611     2615       +4     

see 5 files with indirect coverage changes

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

Copy link
Copy Markdown
Member

@bryan-cox bryan-cox left a comment

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 Apr 8, 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-azure-self-managed
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws

@cwbotbot
Copy link
Copy Markdown

cwbotbot commented Apr 8, 2026

Test Results

e2e-aws

e2e-aks

@jparrill
Copy link
Copy Markdown
Contributor Author

jparrill commented Apr 8, 2026

/retest-required

1 similar comment
@jparrill
Copy link
Copy Markdown
Contributor Author

jparrill commented Apr 9, 2026

/retest-required

@jparrill jparrill changed the title OCPBUGS-82166: use etcdutl for snapshot restore on etcd 3.6+ fix(OCPBUGS-82166): fix etcd snapshot restore race condition and etcd 3.6 compatibility Apr 9, 2026
@openshift-ci-robot openshift-ci-robot removed jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Apr 9, 2026
@enxebre enxebre linked an issue Apr 9, 2026 that may be closed by this pull request
@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Apr 9, 2026
route: {}
expectedError: "restoreSnapshotURL is immutable"

- name: When restoreSnapshotURL is added after creation it should pass
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 should not pass

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we also have a case for when unset after set it should fail

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

// storage specifies how etcd data is persisted.
// +required
// +kubebuilder:validation:XValidation:rule="(has(self.restoreSnapshotURL) == has(oldSelf.restoreSnapshotURL)) && (!has(self.restoreSnapshotURL) || self.restoreSnapshotURL == oldSelf.restoreSnapshotURL)",message="restoreSnapshotURL is immutable"
Storage ManagedEtcdStorageSpec `json:"storage"`
Copy link
Copy Markdown
Contributor

@muraee muraee Apr 10, 2026

Choose a reason for hiding this comment

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

This is difficult to read and reason about. Here I would just add:

// +kubebuilder:validation:XValidation:rule="has(self.restoreSnapshotURL) == has(oldSelf.restoreSnapshotURL)",message="restoreSnapshotURL cannot be added or removed after creation"
Storage ManagedEtcdStorageSpec `json:"storage"`

and add the equality check back ontop of restoreSnapshotUR field directly

// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="restoreSnapshotURL is immutable"
RestoreSnapshotURL []string `json:"restoreSnapshotURL,omitempty"`

@enxebre
Copy link
Copy Markdown
Member

enxebre commented Apr 10, 2026

/approve

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 10, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: bryan-cox, enxebre, jparrill

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

The pull request process is described 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 the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 10, 2026
jparrill and others added 3 commits April 10, 2026 12:42
Add two CEL rules to enforce restoreSnapshotURL immutability:
- Parent-level has() check on storage to prevent adding or removing
  the field after creation (covers absent-to-present transitions).
- Field-level self == oldSelf on restoreSnapshotURL to prevent
  changing the value once set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
…bility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
…alidation

Add CRD validation tests covering restoreSnapshotURL field constraints:
- MaxItems enforcement (at most 1 entry)
- Immutability on update (change and removal are rejected)
- Post-creation addition is rejected
- Allowed transitions (unchanged value, unrelated field updates)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
@muraee
Copy link
Copy Markdown
Contributor

muraee commented Apr 10, 2026

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Apr 10, 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-4-21
/test e2e-aws-4-21
/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

// +kubebuilder:validation:MaxItems=1
// +kubebuilder:validation:items:MaxLength=1024
// +kubebuilder:validation:XValidation:rule="self.size() <= 1", message="RestoreSnapshotURL shouldn't contain more than 1 entry"
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="restoreSnapshotURL is immutable"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we please update the gdoc to reflect clearly this is only settable on creation

@jparrill
Copy link
Copy Markdown
Contributor Author

/retest-required

@jparrill
Copy link
Copy Markdown
Contributor Author

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Apr 10, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@jparrill: The verified label has been added.

Details

In response to this:

/verified bypass

More info in here: https://redhat-internal.slack.com/archives/G01QS0P2F6W/p1775814810815969?thread_ts=1775808691.857879&cid=G01QS0P2F6W

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.

@jparrill
Copy link
Copy Markdown
Contributor Author

/retest-required

@enxebre
Copy link
Copy Markdown
Member

enxebre commented Apr 10, 2026

/test images
/test security

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 10, 2026

@jparrill: all tests passed!

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 openshift-merge-bot bot merged commit eb064c3 into openshift:main Apr 10, 2026
42 checks passed
@openshift-ci-robot
Copy link
Copy Markdown

@jparrill: Jira Issue Verification Checks: Jira Issue OCPBUGS-82166
✔️ This pull request was pre-merge verified.
✔️ All associated pull requests have merged.
✔️ All associated, merged pull requests were pre-merge verified.

Jira Issue OCPBUGS-82166 has been moved to the MODIFIED state and will move to the VERIFIED state when the change is available in an accepted nightly payload. 🕓

Details

In response to this:

Summary

  • Use etcdutl for snapshot restore/status on etcd 3.6+ (OCP 4.21+), falling back to etcdctl for older versions
  • Add CEL validation rule (self == oldSelf) to enforce restoreSnapshotURL immutability at admission time, aligning with the existing API contract ("only when the etcd PV is empty")
  • Add envtest CEL validation test suite for restoreSnapshotURL field constraints

Changes

  1. etcd-init.sh: etcdutl/etcdctl fallback with error when neither tool is available
  2. API: CEL immutability rule on restoreSnapshotURL + regenerated CRDs
  3. Test suite: envtest YAML-driven tests covering MaxItems enforcement, immutability on update (change/removal rejected), and allowed transitions (initial set, unchanged value, unrelated updates)

Test plan

  • Verify etcd snapshot restore works on OCP 4.21 (etcd 3.6) with a valid pre-signed S3 URL
  • Verify etcd snapshot restore works on OCP 4.18-4.20 (etcd 3.5.x)
  • Verify day-2 modification of restoreSnapshotURL is rejected by CEL validation
  • Verify OADP restore workflow (plugin patches HC before CREATE) is not affected by CEL
  • envtest suite passes for restoreSnapshotURL CEL validation (make test-envtest-kube)

Bug

https://redhat.atlassian.net/browse/OCPBUGS-82166

🤖 Generated with Claude Code

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.

mehabhalodiya pushed a commit to mehabhalodiya/hypershift that referenced this pull request Apr 13, 2026
…toreSnapshotURL immutability (openshift#8186)

* fix(OCPBUGS-82166): add etcd 3.6 compatibility for snapshot restore

etcd 3.6 (OCP 4.21+) removed `etcdctl snapshot restore/status` in
favor of `etcdutl`. Add fallback logic to use the available tool.

Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(CNTRLPLANE-2678): enforce restoreSnapshotURL immutability via CEL

Add two CEL rules to enforce restoreSnapshotURL immutability:
- Parent-level has() check on storage to prevent adding or removing
  the field after creation (covers absent-to-present transitions).
- Field-level self == oldSelf on restoreSnapshotURL to prevent
  changing the value once set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

* chore(CNTRLPLANE-2678): regenerate CRDs for restoreSnapshotURL immutability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

* test(CNTRLPLANE-2678): add envtest suite for restoreSnapshotURL CEL validation

Add CRD validation tests covering restoreSnapshotURL field constraints:
- MaxItems enforcement (at most 1 entry)
- Immutability on update (change and removal are rejected)
- Post-creation addition is rejected
- Allowed transitions (unchanged value, unrelated field updates)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

---------

Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
bryan-cox pushed a commit to bryan-cox/hypershift that referenced this pull request Apr 13, 2026
…toreSnapshotURL immutability (openshift#8186)

* fix(OCPBUGS-82166): add etcd 3.6 compatibility for snapshot restore

etcd 3.6 (OCP 4.21+) removed `etcdctl snapshot restore/status` in
favor of `etcdutl`. Add fallback logic to use the available tool.

Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(CNTRLPLANE-2678): enforce restoreSnapshotURL immutability via CEL

Add two CEL rules to enforce restoreSnapshotURL immutability:
- Parent-level has() check on storage to prevent adding or removing
  the field after creation (covers absent-to-present transitions).
- Field-level self == oldSelf on restoreSnapshotURL to prevent
  changing the value once set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

* chore(CNTRLPLANE-2678): regenerate CRDs for restoreSnapshotURL immutability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

* test(CNTRLPLANE-2678): add envtest suite for restoreSnapshotURL CEL validation

Add CRD validation tests covering restoreSnapshotURL field constraints:
- MaxItems enforcement (at most 1 entry)
- Immutability on update (change and removal are rejected)
- Post-creation addition is rejected
- Allowed transitions (unchanged value, unrelated field updates)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

---------

Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
bryan-cox pushed a commit to bryan-cox/hypershift that referenced this pull request Apr 14, 2026
…toreSnapshotURL immutability (openshift#8186)

* fix(OCPBUGS-82166): add etcd 3.6 compatibility for snapshot restore

etcd 3.6 (OCP 4.21+) removed `etcdctl snapshot restore/status` in
favor of `etcdutl`. Add fallback logic to use the available tool.

Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(CNTRLPLANE-2678): enforce restoreSnapshotURL immutability via CEL

Add two CEL rules to enforce restoreSnapshotURL immutability:
- Parent-level has() check on storage to prevent adding or removing
  the field after creation (covers absent-to-present transitions).
- Field-level self == oldSelf on restoreSnapshotURL to prevent
  changing the value once set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

* chore(CNTRLPLANE-2678): regenerate CRDs for restoreSnapshotURL immutability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

* test(CNTRLPLANE-2678): add envtest suite for restoreSnapshotURL CEL validation

Add CRD validation tests covering restoreSnapshotURL field constraints:
- MaxItems enforcement (at most 1 entry)
- Immutability on update (change and removal are rejected)
- Post-creation addition is rejected
- Allowed transitions (unchanged value, unrelated field updates)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

---------

Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.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 area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/testing Indicates the PR includes changes for e2e testing jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. 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. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Specifying ovnkube-master-external NodePorts in HostedCluster

7 participants