Skip to content

HIVE-3132: admissionReviewVersions += v1#2880

Closed
2uasimojo wants to merge 2 commits intoopenshift:masterfrom
2uasimojo:HIVE-3132/admissionReview-v1
Closed

HIVE-3132: admissionReviewVersions += v1#2880
2uasimojo wants to merge 2 commits intoopenshift:masterfrom
2uasimojo:HIVE-3132/admissionReview-v1

Conversation

@2uasimojo
Copy link
Copy Markdown
Member

@2uasimojo 2uasimojo commented Mar 24, 2026

v1 has been out since k8s 1.16. Support it.

Leaving v1beta1 in place for the moment, just in case there are any ancient hubs out there.

Summary by CodeRabbit

  • New Features

    • Added validation support for ClusterPool resources.
  • Chores

    • Enabled the Kubernetes AdmissionReview v1 API for validating webhooks for broader compatibility.
    • Updated admission tests and test fixtures to use the v1 AdmissionReview format.

Turns out we've been running without this... forever, despite having
plenty of code for it in our admission server.
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Mar 24, 2026

@2uasimojo: This pull request references HIVE-3132 which is a valid jira issue.

Details

In response to this:

v1 has been out since k8s 1.16. Support it.

Leaving v1beta1 in place for the moment, just in case there are any ancient hubs out there.

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 openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Mar 24, 2026
@2uasimojo
Copy link
Copy Markdown
Member Author

/hold

This is currently stacked on #2879 so it can affect the clusterpool vwhc introduced there. Rebase and unhold after that merges.

@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 24, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

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

Multiple validating webhook configurations were updated to advertise AdmissionReview API version "v1" alongside "v1beta1". A new ValidatingWebhookConfiguration for clusterpools was added and embedded assets, operator registration, scheme registration, and tests/fixtures were updated accordingly.

Changes

Cohort / File(s) Summary
Webhook Version Upgrades
config/hiveadmission/clusterdeployment-webhook.yaml, config/hiveadmission/clusterimageset-webhook.yaml, config/hiveadmission/clusterprovision-webhook.yaml, config/hiveadmission/dnszones-webhook.yaml, config/hiveadmission/machinepool-webhook.yaml, config/hiveadmission/selectorsyncset-webhook.yaml, config/hiveadmission/syncset-webhook.yaml
Added v1 to webhooks[].admissionReviewVersions so each validating webhook advertises ["v1","v1beta1"]. No other fields changed.
New ClusterPool Webhook
config/hiveadmission/clusterpool-webhook.yaml
Added ValidatingWebhookConfiguration clusterpoolvalidators.admission.hive.openshift.io targeting hive.openshift.io clusterpools for CREATE/UPDATE/DELETE, admissionReviewVersions: ["v1","v1beta1"], failurePolicy: Fail, sideEffects: None, client service path /apis/admission.hive.openshift.io/v1/clusterpoolvalidators.
Generated Assets
pkg/operator/assets/bindata.go
Embedded the new clusterpool-webhook.yaml, added loader functions and registrations; updated existing embedded webhook manifests to include v1 in admissionReviewVersions.
Operator Webhook Registration
pkg/operator/hive/hiveadmission.go
Registered the new clusterpool webhook asset in webhookAssets so it will be reconciled and have CA injection applied alongside existing webhooks.
Admission Tests & Fixtures
test/e2e/postdeploy/admission/admission_test.go, test/e2e/postdeploy/admission/testdata/*
Switched test code to use k8s.io/api/admission/v1 AdmissionReview and updated JSON fixtures' apiVersion from admission.k8s.io/v1beta1 to admission.k8s.io/v1.
Scheme Registration & Binary
pkg/util/scheme/scheme.go, cmd/hiveadmission/main.go
Registered admission/v1 API types in the scheme and added a reference to the admission/v1 type so Admission v1 types are retained at runtime.

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant K8sAPI as "Kubernetes API"
  participant WebhookSvc as "Webhook Service"

  Operator->>Operator: Load embedded webhook assets (incl. clusterpool)
  Operator->>K8sAPI: Apply/Update ValidatingWebhookConfiguration (admissionReviewVersions: [v1,v1beta1])
  K8sAPI->>WebhookSvc: Route AdmissionReview (v1) to /apis/admission.hive.openshift.io/v1/clusterpoolvalidators
  WebhookSvc-->>K8sAPI: Return admission response (Allowed/Denied)
  K8sAPI-->>Operator: Observability / reconciliation feedback
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through YAML fields at night,

v1 joined v1beta1 — what a sight,
A Pool appears to keep things tight,
Assets baked in, tests now right,
I twitch my nose and dance with delight.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'HIVE-3132: admissionReviewVersions += v1' accurately and concisely describes the main change: adding v1 to the admissionReviewVersions list across Kubernetes webhook configurations.

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

✨ 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 dlom and suhanime March 24, 2026 19:02
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Mar 24, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: 2uasimojo

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 Mar 24, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Mar 24, 2026

@2uasimojo: This pull request references HIVE-3132 which is a valid jira issue.

Details

In response to this:

v1 has been out since k8s 1.16. Support it.

Leaving v1beta1 in place for the moment, just in case there are any ancient hubs out there.

Summary by CodeRabbit

  • New Features

  • Added validation support for cluster pool resources.

  • Chores

  • Enhanced compatibility with modern Kubernetes versions by enabling support for the latest admission API versions across validation webhooks.

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

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

🧹 Nitpick comments (1)
test/e2e/postdeploy/admission/admission_test.go (1)

55-75: Add explicit v1beta1 compatibility coverage.

Given the PR goal includes backward compatibility, consider adding one test case that validates v1beta1 AdmissionReview handling to prevent silent regressions on older hubs.

Also applies to: 93-100

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

In `@test/e2e/postdeploy/admission/admission_test.go` around lines 55 - 75, Add a
test case to the tests table in admission_test.go that covers v1beta1
AdmissionReview parsing/handling: update the tests []struct { name, file,
expectAllowed } slice (the same table used for "review success"/"review
failure") to include an entry like name: "review v1beta1 compatibility", file:
"hiveadmission-review-v1beta1.json", expectAllowed: <true|false> (match the
expected outcome for that fixture); ensure a corresponding v1beta1 fixture is
present and mirror the existing test flow that exercises the same handler (the
code paths referenced by the tests slice) so the test asserts v1beta1 behavior
the same way as the v1 AdmissionReview cases.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/e2e/postdeploy/admission/admission_test.go`:
- Around line 55-75: Add a test case to the tests table in admission_test.go
that covers v1beta1 AdmissionReview parsing/handling: update the tests []struct
{ name, file, expectAllowed } slice (the same table used for "review
success"/"review failure") to include an entry like name: "review v1beta1
compatibility", file: "hiveadmission-review-v1beta1.json", expectAllowed:
<true|false> (match the expected outcome for that fixture); ensure a
corresponding v1beta1 fixture is present and mirror the existing test flow that
exercises the same handler (the code paths referenced by the tests slice) so the
test asserts v1beta1 behavior the same way as the v1 AdmissionReview cases.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 81aac8a9-dc80-4910-8908-bca1da55b86d

📥 Commits

Reviewing files that changed from the base of the PR and between 14bd5ee and b8a4997.

📒 Files selected for processing (11)
  • config/hiveadmission/clusterdeployment-webhook.yaml
  • config/hiveadmission/clusterimageset-webhook.yaml
  • config/hiveadmission/clusterpool-webhook.yaml
  • config/hiveadmission/clusterprovision-webhook.yaml
  • config/hiveadmission/dnszones-webhook.yaml
  • config/hiveadmission/machinepool-webhook.yaml
  • config/hiveadmission/selectorsyncset-webhook.yaml
  • config/hiveadmission/syncset-webhook.yaml
  • pkg/operator/assets/bindata.go
  • pkg/operator/hive/hiveadmission.go
  • test/e2e/postdeploy/admission/admission_test.go

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 9.09091% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.29%. Comparing base (14bd5ee) to head (b5b5d32).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
pkg/operator/assets/bindata.go 0.00% 9 Missing ⚠️
cmd/hiveadmission/main.go 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2880      +/-   ##
==========================================
- Coverage   50.31%   50.29%   -0.02%     
==========================================
  Files         280      280              
  Lines       34314    34325      +11     
==========================================
+ Hits        17264    17265       +1     
- Misses      15689    15699      +10     
  Partials     1361     1361              
Files with missing lines Coverage Δ
pkg/operator/hive/hiveadmission.go 0.00% <ø> (ø)
pkg/util/scheme/scheme.go 100.00% <100.00%> (ø)
cmd/hiveadmission/main.go 0.00% <0.00%> (ø)
pkg/operator/assets/bindata.go 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@2uasimojo 2uasimojo force-pushed the HIVE-3132/admissionReview-v1 branch from b8a4997 to 0a55887 Compare March 24, 2026 20:01
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Mar 24, 2026

@2uasimojo: This pull request references HIVE-3132 which is a valid jira issue.

Details

In response to this:

v1 has been out since k8s 1.16. Support it.

Leaving v1beta1 in place for the moment, just in case there are any ancient hubs out there.

Summary by CodeRabbit

  • New Features

  • Added validation for cluster pool resources.

  • Chores

  • Enabled support for the v1 AdmissionReview API across validation webhooks for broader Kubernetes compatibility.

  • Updated admission-related tests and test fixtures to use the v1 AdmissionReview format.

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.

@2uasimojo 2uasimojo force-pushed the HIVE-3132/admissionReview-v1 branch from 0a55887 to cfbd5a6 Compare March 24, 2026 21:31
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Mar 24, 2026

@2uasimojo: This pull request references HIVE-3132 which is a valid jira issue.

Details

In response to this:

v1 has been out since k8s 1.16. Support it.

Leaving v1beta1 in place for the moment, just in case there are any ancient hubs out there.

Summary by CodeRabbit

  • New Features

  • Added validation for cluster pool resources.

  • Chores

  • Enabled support for the v1 AdmissionReview API across validation webhooks for broader Kubernetes compatibility.

  • Updated admission-related tests and fixtures to use the v1 AdmissionReview format.

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.

@2uasimojo 2uasimojo force-pushed the HIVE-3132/admissionReview-v1 branch from cfbd5a6 to 162bd2d Compare March 25, 2026 15:05
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Mar 25, 2026

@2uasimojo: This pull request references HIVE-3132 which is a valid jira issue.

Details

In response to this:

v1 has been out since k8s 1.16. Support it.

Leaving v1beta1 in place for the moment, just in case there are any ancient hubs out there.

Summary by CodeRabbit

  • New Features

  • Added validation support for cluster pool resources.

  • Chores

  • Enabled support for the v1 AdmissionReview API across validation webhooks for broader Kubernetes compatibility.

  • Updated admission-related tests and fixtures to use the v1 AdmissionReview format.

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.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I wasn't able to retrieve the specific log contents via web search. Let me try to fetch the build logs directly.


🏁 Script executed:

#!/bin/bash
# Try to fetch the build log content around the referenced lines from GCS
# e2e-pool log (around line 139)
curl -s "https://storage.googleapis.com/test-platform-results/pr-logs/pull/openshift_hive/2880/pull-ci-openshift-hive-master-e2e-pool/2036821995798138880/build-log.txt" 2>/dev/null | sed -n '120,160p' || echo "Failed to fetch e2e-pool log"

echo "---"

# e2e log (around line 153)
curl -s "https://storage.googleapis.com/test-platform-results/pr-logs/pull/openshift_hive/2880/pull-ci-openshift-hive-master-e2e/2036821993080229888/build-log.txt" 2>/dev/null | sed -n '135,175p' || echo "Failed to fetch e2e log"

Length of output: 7002


The error is clear from the logs:

AdmissionReview in version "v1" cannot be handled as a AdmissionReview: 
converting (v1.AdmissionReview) to (v1beta1.AdmissionReview): unknown conversion

The root cause: by listing v1 first in admissionReviewVersions, the Kubernetes API server now sends admission.k8s.io/v1 payloads to the webhook server. However, the actual hiveadmission handler code still internally decodes the incoming request as a v1beta1.AdmissionReview. When it tries to convert the received v1 object into v1beta1, the scheme has no registered conversion between those two types — hence the failure.

Adding admissionv1.AddToScheme in pkg/util/scheme/scheme.go registers the v1 types in the scheme, but it does not register a conversion function between admission/v1 and admission/v1beta1. The handler itself needs to be updated to natively speak v1.

Let me look at the handler code to give you a more concrete suggestion.


🏁 Script executed:

#!/bin/bash
# Find the hiveadmission webhook handler code
rg -rn "AdmissionReview\|AdmissionRequest\|admission/v1beta1\|admissionv1beta1\|admissionv1" --type go -l | grep -v "_test.go" | grep -v "bindata.go" | grep -v "vendor"

echo "---"

# Look at what package is imported for admission handling in the main webhook handler
rg -rn "v1beta1\|admissionv1" --type go -g "*.go" pkg/webhooks/ 2>/dev/null | head -80 || echo "No pkg/webhooks found"

echo "---"

# Try to find the admission handler files
fd -e go . --exclude vendor --exclude "bindata.go" | xargs grep -l "AdmissionReview" 2>/dev/null | grep -v "_test.go"

echo "---"

# Look at the core admission handler
rg -rn "func.*Admit\|AdmissionReview\|AdmissionRequest" --type go -g "*.go" --exclude-dir=vendor --exclude-dir=".git" | grep -v "bindata\|_test" | head -60

Unrecoverable error: Failed to clone repository


@2uasimojo: The logs make the root cause clear:

AdmissionReview in version "v1" cannot be handled as a AdmissionReview:
converting (v1.AdmissionReview) to (v1beta1.AdmissionReview): unknown conversion

What's happening: By listing v1 first in admissionReviewVersions, the Kubernetes API server now sends admission.k8s.io/v1 payloads to the hiveadmission server. The server receives the v1 object and attempts to convert it internally to v1beta1.AdmissionReview (which the handler code still uses), but Hive's custom scheme has no conversion registered between admission/v1 and admission/v1beta1. Adding admissionv1.AddToScheme registers the v1 types but does not register any conversion functions between the two versions.

Why v1 is being sent: In admissionReviewVersions: [v1, v1beta1], Kubernetes picks the first version that the webhook advertises — so it now always sends v1.

There are two paths to fix this:

  1. Preferred: Update the admission handler to natively use v1 types. The actual webhook handler code that decodes the incoming AdmissionReview and returns an AdmissionReview response needs to be changed from admissionv1beta1 types to admissionv1 types. This is the "real" fix.

  2. Quick workaround: Swap the order in admissionReviewVersions to [v1beta1, v1]. This restores v1beta1 as the preferred version (so the API server sends v1beta1 again), while still advertising v1 capability. However, this won't truly enable v1 support — it just avoids the conversion problem.

Given that the PR also updates test/e2e/postdeploy/admission/admission_test.go to use admissionv1 types and updates the test fixtures to admission.k8s.io/v1, the intent is clearly path 1. The missing piece is updating the actual hiveadmission server's handler code (likely in pkg/hiveadmission/ or similar) to decode and respond with v1 AdmissionReview objects natively, rather than relying on a scheme conversion from v1→v1beta1.

In short: the scheme registration and webhook YAML changes are necessary but not sufficient — the server-side handler that unmarshals the incoming HTTP body into an AdmissionReview struct still needs to be pointed at the v1 type.

v1 has been out since k8s 1.16. Support it.

Leaving v1beta1 in place for the moment, just in case there are any
ancient hubs out there.
@2uasimojo 2uasimojo force-pushed the HIVE-3132/admissionReview-v1 branch from 162bd2d to b5b5d32 Compare March 25, 2026 16:12
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Mar 25, 2026

@2uasimojo: This pull request references HIVE-3132 which is a valid jira issue.

Details

In response to this:

v1 has been out since k8s 1.16. Support it.

Leaving v1beta1 in place for the moment, just in case there are any ancient hubs out there.

Summary by CodeRabbit

  • New Features

  • Added validation support for ClusterPool resources.

  • Chores

  • Enabled the Kubernetes AdmissionReview v1 API for validating webhooks for broader compatibility.

  • Updated admission tests and test fixtures to use the v1 AdmissionReview format.

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.

@2uasimojo
Copy link
Copy Markdown
Member Author

@coderabbitai

  1. Preferred: Update the admission handler to natively use v1 types. The actual webhook handler code that decodes the incoming AdmissionReview and returns an AdmissionReview response needs to be changed from admissionv1beta1 types to admissionv1 types. This is the "real" fix.

The code that's processing AdmissionReview is upstream (vendored). Do I have any control over what version that code is using?

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Good question — let me look at the actual vendored handler code to see what levers are available.


🏁 Script executed:

#!/bin/bash
# Find the hiveadmission main/handler files
echo "=== hiveadmission main ==="
cat cmd/hiveadmission/main.go 2>/dev/null | head -80

echo ""
echo "=== Find files that register/handle webhook HTTP ==="
rg -rn "admission\|AdmissionReview\|webhook" --type go -l --glob '!vendor' --glob '!*bindata*' | grep -i "admission\|webhook" | head -20

echo ""
echo "=== Look at pkg/hiveadmission structure ==="
fd . pkg/hiveadmission --type f 2>/dev/null | head -20
ls pkg/hiveadmission/ 2>/dev/null

echo ""
echo "=== Look at the webhook server setup ==="
rg -rn "NewWebhookServer\|WebhookServer\|http.Handle\|admission.NewHandler\|webhook.NewServer\|admitter\|Admitter" --type go --glob '!vendor' --glob '!*bindata*' -A3 | head -80

Length of output: 1853


🏁 Script executed:

#!/bin/bash
echo "=== generic-admission-server vendored code - key files ==="
fd . vendor/github.com/openshift/generic-admission-server --type f | head -30

echo ""
echo "=== generic-admission-server apiserver/webhook handler ==="
rg -rn "AdmissionReview\|v1beta1\|admissionv1" vendor/github.com/openshift/generic-admission-server/ | head -60

echo ""
echo "=== Hook interface definition ==="
rg -rn "ValidatingAdmissionHook\|AdmissionHook\|interface" vendor/github.com/openshift/generic-admission-server/ | head -40

echo ""
echo "=== generic-admission-server go.mod or version ==="
cat vendor/github.com/openshift/generic-admission-server/go.mod 2>/dev/null || echo "no go.mod"
# Check for version info
find vendor/github.com/openshift/generic-admission-server -name "*.go" | xargs grep -l "package" | head -5
cat vendor/modules.txt 2>/dev/null | grep "generic-admission-server"

Length of output: 1664


🏁 Script executed:

#!/bin/bash
echo "=== admission_review_v1.go ==="
cat vendor/github.com/openshift/generic-admission-server/pkg/registry/admissionreview/admission_review_v1.go

echo ""
echo "=== admission_review.go ==="
cat vendor/github.com/openshift/generic-admission-server/pkg/registry/admissionreview/admission_review.go

echo ""
echo "=== apiserver.go ==="
cat vendor/github.com/openshift/generic-admission-server/pkg/apiserver/apiserver.go

echo ""
echo "=== start.go (hook interface) ==="
cat vendor/github.com/openshift/generic-admission-server/pkg/cmd/server/start.go | head -100

Length of output: 18491


🏁 Script executed:

#!/bin/bash
echo "=== validating-webhooks directory ==="
ls pkg/validating-webhooks/hive/v1/ 2>/dev/null | head -20

echo ""
echo "=== Sample hook - DNSZone (Validate method signature) ==="
rg -n "func.*Validate\|ValidatingResource\|admissionv1beta1\|admissionv1\b" pkg/validating-webhooks/hive/v1/ --type go | head -40

echo ""
echo "=== Check what admission types are imported in the hooks ==="
rg -n "admission/v1\|admission/v1beta1\|admissionv1" pkg/validating-webhooks/hive/v1/ --type go | grep "import\|admissionv1" | head -30

Length of output: 993


🏁 Script executed:

#!/bin/bash
echo "=== dnszone hook ==="
cat pkg/validating-webhooks/hive/v1/dnszone_validating_admission_hook.go | head -60

echo ""
echo "=== clusterpool hook ==="
cat pkg/validating-webhooks/hive/v1/clusterpool_validating_admission_hook.go | head -60

Length of output: 4682


@2uasimojo: Yes, you absolutely have control over this — and the fix is entirely in the Hive codebase, not the vendored library. In fact, the vendored generic-admission-server was already updated (that's why you're on that recent pseudo-version) to support exactly what you need.

Here's how the mechanism works in the vendored apiserver.go:

The library defines two separate interfaces your hooks can implement:

// For v1beta1 (current)
type ValidatingAdmissionHookV1Beta1 interface {
    ValidatingAdmissionHook
    Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
}

// For v1 (new)
type ValidatingAdmissionHookV1 interface {
    ValidatingAdmissionHook
    Validate(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse
}

admissionHooksByGroupThenVersion() uses separate type assertions for each — so a hook can implement both, or just one. If a hook implements ValidatingAdmissionHookV1, it gets routed to NewV1REST which natively speaks admissionv1 with no conversion needed. That's the entire fix.

What you need to do: Update the Validate() method signature on each hook in pkg/validating-webhooks/hive/v1/ from admissionv1beta1 types to admissionv1 types. For example, in dnszone_validating_admission_hook.go:

// Before
import admissionv1beta1 "k8s.io/api/admission/v1beta1"

func (a *DNSZoneValidatingAdmissionHook) Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse {
// After
import admissionv1 "k8s.io/api/admission/v1"

func (a *DNSZoneValidatingAdmissionHook) Validate(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse {

The internal logic of each Validate() body barely needs to change, because admissionv1.AdmissionRequest and admissionv1beta1.AdmissionRequest are structurally identical (v1 was a stable promotion of v1beta1 with no field changes). The admission.Decoder you use to decode .Object.Raw also works unchanged.

You'll need to apply this to all 8+ hooks (DNSZone, ClusterDeployment, ClusterPool, ClusterImageSet, ClusterProvision, MachinePool, SyncSet, SelectorSyncSet, ClusterDeploymentCustomization). The HACK comment already in main.go (var _ admissionv1.AdmissionReview = admissionv1.AdmissionReview{}) was an attempt in the right direction but doesn't actually wire up the interface — this is the real fix.

Copy link
Copy Markdown

@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 `@pkg/operator/assets/bindata.go`:
- Around line 280-281: The advertised admissionReviewVersions in the embedded
YAMLs are listing "v1" before "v1beta1", causing kube-apiserver to send v1
AdmissionReview objects while handlers like
clusterdeployment_validating_admission_hook.go (and other
*_validating_admission_hook.go files) still expect admissionv1beta1 types; fix
by updating the source YAMLs to list admissionReviewVersions with v1beta1 first
then v1 (admissionReviewVersions: - v1beta1 - v1) and then regenerate the
bindata (pkg/operator/assets/bindata.go), or alternatively migrate all webhook
handler signatures and logic to use admissionv1 types (and update
cmd/hiveadmission/main.go HACK handling accordingly) before keeping v1 first.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2f8fcbec-bf9e-4ae0-9a89-be4d97efc4fe

📥 Commits

Reviewing files that changed from the base of the PR and between 162bd2d and b5b5d32.

📒 Files selected for processing (15)
  • cmd/hiveadmission/main.go
  • config/hiveadmission/clusterdeployment-webhook.yaml
  • config/hiveadmission/clusterimageset-webhook.yaml
  • config/hiveadmission/clusterpool-webhook.yaml
  • config/hiveadmission/clusterprovision-webhook.yaml
  • config/hiveadmission/dnszones-webhook.yaml
  • config/hiveadmission/machinepool-webhook.yaml
  • config/hiveadmission/selectorsyncset-webhook.yaml
  • config/hiveadmission/syncset-webhook.yaml
  • pkg/operator/assets/bindata.go
  • pkg/util/scheme/scheme.go
  • test/e2e/postdeploy/admission/admission_test.go
  • test/e2e/postdeploy/admission/testdata/hiveadmission-review-failure.json
  • test/e2e/postdeploy/admission/testdata/hiveadmission-review-success.json
  • test/e2e/postdeploy/admission/testdata/hiveadmission-review-update-failure.json
✅ Files skipped from review due to trivial changes (8)
  • pkg/util/scheme/scheme.go
  • test/e2e/postdeploy/admission/testdata/hiveadmission-review-failure.json
  • config/hiveadmission/clusterimageset-webhook.yaml
  • config/hiveadmission/selectorsyncset-webhook.yaml
  • test/e2e/postdeploy/admission/testdata/hiveadmission-review-update-failure.json
  • config/hiveadmission/dnszones-webhook.yaml
  • config/hiveadmission/clusterprovision-webhook.yaml
  • config/hiveadmission/clusterpool-webhook.yaml
🚧 Files skipped from review as they are similar to previous changes (6)
  • config/hiveadmission/clusterdeployment-webhook.yaml
  • cmd/hiveadmission/main.go
  • test/e2e/postdeploy/admission/testdata/hiveadmission-review-success.json
  • config/hiveadmission/machinepool-webhook.yaml
  • config/hiveadmission/syncset-webhook.yaml
  • test/e2e/postdeploy/admission/admission_test.go

Comment on lines +280 to 281
- v1
- v1beta1
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Mar 25, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Webhook admissionReviewVersions ordering in source manifests"
rg -n --type=yaml 'admissionReviewVersions:|-\s*v1$|-\s*v1beta1$' config/hiveadmission/*-webhook.yaml -A2 -B1

echo
echo "2) Current admission type usage in server entrypoint/hooks"
rg -n --type=go 'admissionv1beta1|admissionv1\.' cmd/hiveadmission/main.go pkg/validating-webhooks -C2

echo
echo "3) Hook signatures/logic still bound to v1beta1 request/response types"
rg -n --type=go 'AdmissionReview|AdmissionRequest|AdmissionResponse' pkg/validating-webhooks -C2

Repository: openshift/hive

Length of output: 50371


admissionReviewVersions order causes v1/v1beta1 runtime mismatch.

Lines 280, 326, 370, 417, 547, 692, 762, and 862 advertise v1 first, causing kube-apiserver to prefer sending admission.k8s.io/v1 AdmissionReview objects. However, all webhook handlers (e.g., clusterdeployment_validating_admission_hook.go) are still hardcoded to v1beta1 types (*admissionv1beta1.AdmissionRequest, *admissionv1beta1.AdmissionResponse). This version mismatch will break admission requests at runtime until handlers are migrated to v1 types.

To restore compatibility, reorder admissionReviewVersions in source YAMLs (then regenerate bindata):

admissionReviewVersions:
  - v1beta1
  - v1

Alternatively, migrate all webhook handler signatures and logic to use admissionv1 types before keeping v1 first. The HACK comment in cmd/hiveadmission/main.go:40 ("Prevent pruning of admissionv1, resulting in conversion errors") indicates this conversion issue is already known.

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

In `@pkg/operator/assets/bindata.go` around lines 280 - 281, The advertised
admissionReviewVersions in the embedded YAMLs are listing "v1" before "v1beta1",
causing kube-apiserver to send v1 AdmissionReview objects while handlers like
clusterdeployment_validating_admission_hook.go (and other
*_validating_admission_hook.go files) still expect admissionv1beta1 types; fix
by updating the source YAMLs to list admissionReviewVersions with v1beta1 first
then v1 (admissionReviewVersions: - v1beta1 - v1) and then regenerate the
bindata (pkg/operator/assets/bindata.go), or alternatively migrate all webhook
handler signatures and logic to use admissionv1 types (and update
cmd/hiveadmission/main.go HACK handling accordingly) before keeping v1 first.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If I do this, will v1beta1 still be supported?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@2uasimojo Yes, v1beta1 will still be fully supported with the reordering to [v1beta1, v1].

Here's how the version selection works: API servers send the first AdmissionReview version in the admissionReviewVersions list that they support. Since every API server capable of running admission webhooks supports v1beta1, placing it first means v1beta1 will be the version actually used at runtime — the same behavior as before this PR changed the order.

The trade-off is that with [v1beta1, v1]:

  • Old hubs (pre-1.16): use v1beta1
  • Modern hubs (1.16+): also use v1beta1 (first in list), even though they support v1

So the reorder is a safe stop-gap to fix the CI failures without requiring handler code changes right now. The actual promotion to native v1 handling would require also migrating the webhook handler signatures from *admissionv1beta1.AdmissionRequest/*admissionv1beta1.AdmissionResponse to their admissionv1 equivalents — which is what the v1-first ordering + updated test fixtures were trying to accomplish, but the handler migration wasn't yet complete.

In short: [v1beta1, v1] keeps everything working today (v1beta1 is still the operative version), while [v1, v1beta1] requires the handler code to actually speak v1 to avoid the conversion error seen in CI.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Bah, sorry, I asked in the wrong spot. Disregard.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@2uasimojo No worries at all! Feel free to ping if you have questions in the right spot. 😄

(´• ω •`) ∫

@2uasimojo
Copy link
Copy Markdown
Member Author

2uasimojo commented Mar 25, 2026

@2uasimojo: Yes, you absolutely have control over this — and the fix is entirely in the Hive codebase, not the vendored library. In fact, the vendored generic-admission-server was already updated (that's why you're on that recent pseudo-version) to support exactly what you need.

Here's how the mechanism works in the vendored apiserver.go:

The library defines two separate interfaces your hooks can implement:

// For v1beta1 (current)
type ValidatingAdmissionHookV1Beta1 interface {
    ValidatingAdmissionHook
    Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
}

// For v1 (new)
type ValidatingAdmissionHookV1 interface {
    ValidatingAdmissionHook
    Validate(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse
}

admissionHooksByGroupThenVersion() uses separate type assertions for each — so a hook can implement both, or just one. If a hook implements ValidatingAdmissionHookV1, it gets routed to NewV1REST which natively speaks admissionv1 with no conversion needed. That's the entire fix.

What you need to do: Update the Validate() method signature on each hook in pkg/validating-webhooks/hive/v1/ from admissionv1beta1 types to admissionv1 types. For example, in dnszone_validating_admission_hook.go:

@coderabbitai Would v1beta1 still be supported if I did this, or would I need to have both implementations present? I thought this was the whole purpose of the conversion thing: if I implement support for v1beta1, the library converts incoming v1 AdmissionReview to v1beta1 for me.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Mar 25, 2026

@2uasimojo: 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-pool b5b5d32 link true /test e2e-pool
ci/prow/e2e b5b5d32 link true /test e2e

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.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Good question — let me look at the exact routing logic in the vendored library to give you an accurate answer.


🏁 Script executed:

#!/bin/bash
echo "=== Full apiserver.go ==="
cat vendor/github.com/openshift/generic-admission-server/pkg/apiserver/apiserver.go

echo ""
echo "=== admission_review.go ==="
cat vendor/github.com/openshift/generic-admission-server/pkg/registry/admissionreview/admission_review.go

echo ""
echo "=== admission_review_v1.go ==="
cat vendor/github.com/openshift/generic-admission-server/pkg/registry/admissionreview/admission_review_v1.go

echo ""
echo "=== List all files in generic-admission-server ==="
find vendor/github.com/openshift/generic-admission-server -name "*.go" | sort

echo ""
echo "=== start.go - full file ==="
cat vendor/github.com/openshift/generic-admission-server/pkg/cmd/server/start.go

Length of output: 21606


@2uasimojo: Good catch — but the answer is no, the library does not do that conversion for you. Let me explain exactly why, and what your real options are.

How the library actually works:

The library registers a completely separate REST endpoint for each version — there is no cross-version conversion bridge. NewREST handles v1beta1 natively; NewV1REST handles v1 natively. If a hook only implements ValidatingAdmissionHookV1Beta1, only a v1beta1 endpoint is registered. If the API server sends a v1 payload to that endpoint, the kube-apiserver's own conversion logic kicks in (since hiveadmission acts as an aggregated API server) — and that is the conversion that's failing, because neither the hive scheme nor the library scheme has a registered conversion between admission/v1 and admission/v1beta1.

Can you implement both interfaces on the same hook struct?

No. Both ValidatingAdmissionHookV1Beta1 and ValidatingAdmissionHookV1 define a method named Validate with different signatures:

// V1Beta1 interface
Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse

// V1 interface
Validate(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse

Go does not allow two methods with the same name but different signatures on the same type, so a single hook struct can only implement one of these two interfaces.

Your practical options:

  1. Switch all hooks to ValidatingAdmissionHookV1 — v1beta1 support is dropped. Since pre-1.16 hubs can only send v1beta1, they would fail. You could remove v1beta1 from admissionReviewVersions entirely to make this explicit and honest.

  2. Keep ValidatingAdmissionHookV1Beta1 but swap order to [v1beta1, v1] — Modern API servers (which support both) will always pick v1beta1 since it's listed first. You're advertising v1 capability but never actually using it in practice. Old hubs continue to work. This is the honest "backward-compat first" approach.

  3. Use a wrapper/adapter to register both — You could register each hook twice with separate wrapper structs: one implementing ValidatingAdmissionHookV1Beta1 and one implementing ValidatingAdmissionHookV1, where the v1 wrapper just converts the request fields (trivially, since admissionv1.AdmissionRequest and admissionv1beta1.AdmissionRequest are structurally identical) and calls the underlying v1beta1 logic. This achieves true dual support but is more code.

Given the PR's stated goal — "v1 has been out since k8s 1.16; leaving v1beta1 in place just in case" — option 2 (swap order to [v1beta1, v1]) is the lowest-risk path that still advertises v1 without breaking anything. Option 1 is the cleanest if you're comfortable dropping pre-1.16 hub support. Option 3 gives you true dual support at the cost of boilerplate.

@2uasimojo
Copy link
Copy Markdown
Member Author

@coderabbitai re option 2, if I swap the order but keep v1 in the list, I'm still lying about supporting v1, aren't I?

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

Tip

For best results, initiate chat on the files or code changes.

@2uasimojo: Yes, you're right — that would be lying about v1 support.

admissionReviewVersions is a contract: it tells the API server which versions your webhook handler actually understands, and the API server sends the first version from the list that it supports. If you list v1 but your handler can't truly process a v1 payload, you're advertising a capability that doesn't hold.

With [v1beta1, v1], modern API servers (which support both) will always pick v1beta1 since it's first — so you'd never get caught in practice today. But admission.k8s.io/v1beta1 was deprecated at Kubernetes 1.19, and if it were ever dropped from a future API server, that server would fall through to v1, send a v1 payload, and the handler would fail — even though it was advertising v1 support. So the lie has real consequences eventually.

The honest options as I see them:

  1. List only [v1beta1] — completely honest; works on all clusters until v1beta1 payloads are removed. No changes to handler code needed. The downside is you're not making forward progress on v1.

  2. Implement real v1 support (option 1 from before) — update the hook Validate() signatures to use admissionv1 types, list [v1, v1beta1] or just [v1]. This is the correct long-term fix.

  3. Implement a v1 wrapper adapter (option 3 from before) — register each hook twice with thin wrapper structs, one for each version. More boilerplate, but supports both simultaneously and honestly.

Given that v1beta1 payload support will go away eventually and your PR's stated goal is forward-looking, option 2 (switching the hooks to native v1) is the right path. It's less work than it sounds since admissionv1.AdmissionRequest and admissionv1beta1.AdmissionRequest are structurally identical field-for-field.

@2uasimojo
Copy link
Copy Markdown
Member Author

@coderabbitai I'm not worried about the work; I can see it's not hard mechanically to switch over to v1. My concern is that hive needs to be able to run "on any k8s", and I'm worried that there may exist ancient hub clusters out there that don't speak v1 yet. But it looks like it would have to be a pre-v1.16 k8s, which is so far out of support that nobody should be surprised to find stuff stops working there.

I'll do a full cutover to v1 via fresh PR #2881.

@2uasimojo 2uasimojo closed this Mar 25, 2026
@2uasimojo 2uasimojo deleted the HIVE-3132/admissionReview-v1 branch March 25, 2026 19:48
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

Tip

For best results, initiate chat on the files or code changes.

@2uasimojo: That reasoning is sound — admission.k8s.io/v1 has been stable since Kubernetes 1.16 (released September 2019), so any cluster that can't handle it is running software that has been end-of-life for years. Nobody on such a cluster should have a reasonable expectation that new versions of Hive will continue to work there.

Good luck with #2881 — the structural identity of admissionv1.AdmissionRequest and admissionv1beta1.AdmissionRequest should make the mechanical switch very smooth. 🐇✨

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. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants