Skip to content

OCPBUGS-100316: Change failurePolicy to Ignore on MAPI-guarding VAPs … - #640

Open
miyadav wants to merge 1 commit into
openshift:mainfrom
miyadav:100316crbugcapinp
Open

OCPBUGS-100316: Change failurePolicy to Ignore on MAPI-guarding VAPs …#640
miyadav wants to merge 1 commit into
openshift:mainfrom
miyadav:100316crbugcapinp

Conversation

@miyadav

@miyadav miyadav commented Jul 31, 2026

Copy link
Copy Markdown
Member

…with CAPI paramKind.

looks good to me as immediate fix for unblocking tp installs on vsphere
When the CAPI CRDs (cluster.x-k8s.io/v1beta2) are not yet established during install, the apiserver cannot resolve the paramKind and the VAP is "misconfigured". With failurePolicy: Fail, this denies every MAPI machine update — including status patches from machine-api-controllers, which are normally exempted via matchConditions but never reach that
evaluation. Workers clone successfully in vCenter but the machinecontroller can never persist the provider task ID, leaving all workers stuck in Provisioning and failing the install.

Affected files:

  • authoritative-api-transition-requires-capi-infrastructure-ready.yaml
  • machine-api-machine-vap.yaml
  • machine-api-machine-set-vap.yaml
  • only-create-mapi-machine-if-authoritative-api-capi.yaml
  • prevent-authoritative-mapi-machineset-create-when-capi-exists.yaml

generated by claude

I understand there might be a reason we set them as Fail earlier , so we may have to dig more for a way to establish that CRDs are established and then we change it to fail ( that might need more in depth analysis )

Summary by CodeRabbit

  • Behavior Changes
    • Updated several admission policies to continue processing requests when policy evaluation cannot be completed.
    • Applies to machine and machine set validation, MAPI creation safeguards, and authoritative API transition checks.
    • These checks now fail open instead of blocking requests when an evaluation error occurs.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

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 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 Jul 31, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@miyadav: This pull request references Jira Issue OCPBUGS-100316, which is invalid:

  • expected the bug to target the "5.0.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:

…with CAPI paramKind.

looks good to me as immediate fix for unblocking tp installs on vsphere
When the CAPI CRDs (cluster.x-k8s.io/v1beta2) are not yet established during install, the apiserver cannot resolve the paramKind and the VAP is "misconfigured". With failurePolicy: Fail, this denies every MAPI machine update — including status patches from machine-api-controllers, which are normally exempted via matchConditions but never reach that
evaluation. Workers clone successfully in vCenter but the machinecontroller can never persist the provider task ID, leaving all workers stuck in Provisioning and failing the install.

Affected files:

  • authoritative-api-transition-requires-capi-infrastructure-ready.yaml
  • machine-api-machine-vap.yaml
  • machine-api-machine-set-vap.yaml
  • only-create-mapi-machine-if-authoritative-api-capi.yaml
  • prevent-authoritative-mapi-machineset-create-when-capi-exists.yaml

generated by claude

I understand there might be a reason we set them as Fail earlier , so we may have to dig more for a way to establish that CRDs are established and then we change it to fail ( that might need more in depth analysis )

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 nrb and theobarberbany July 31, 2026 10:16
@openshift-ci

openshift-ci Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

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

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

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Walkthrough

Five validating admission policies change failurePolicy from Fail to Ignore. The corresponding operator manifests apply the same setting.

Changes

Admission policy failure handling

Layer / File(s) Summary
Policy definition updates
admission-policies/default/*.yaml
Five default validating admission policies now ignore evaluation failures.
Operator manifest synchronization
capi-operator-manifests/default/manifests.yaml
The operator manifests use failurePolicy: Ignore for the same five policies.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: mdbooth

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the issue and the primary change to set MAPI-guarding VAP failure policies to Ignore.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed The PR changes only six YAML manifest files, replacing VAP failurePolicy values; no Ginkgo test files or test-title declarations changed.
Test Structure And Quality ✅ Passed The PR changes only six YAML manifests; no Ginkgo test files or test-framework constructs were changed, so the test-quality requirements do not apply.
Microshift Test Compatibility ✅ Passed The pull request changes only six YAML manifest files and adds no Ginkgo tests or test constructs, so MicroShift test compatibility is not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The patch changes only six YAML manifest files and adds no Ginkgo e2e tests, so SNO multi-node test compatibility does not apply.
Topology-Aware Scheduling Compatibility ✅ Passed The diff changes only five ValidatingAdmissionPolicy failurePolicy values from Fail to Ignore; it adds no topology, affinity, replica, selector, toleration, spread, or PDB constraints.
Ote Binary Stdout Contract ✅ Passed The PR changes only six YAML manifest files; no Go or OTE source changed, and OTE main has no direct stdout or logging writes.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The pull request changes only YAML ValidatingAdmissionPolicy failurePolicy fields; it adds no Ginkgo e2e tests or IPv4/external connectivity requirements.
No-Weak-Crypto ✅ Passed The PR changes only 10 YAML lines, all from failurePolicy: Fail to Ignore; no MD5, SHA1, DES, RC4, Blowfish, ECB, or crypto implementation appears.
Container-Privileges ✅ Passed The PR changes only five failurePolicy values in source policies and the generated manifest; no privileged, host namespace, SYS_ADMIN, root, or allowPrivilegeEscalation settings were added.
No-Sensitive-Data-In-Logs ✅ Passed The commit changes only six YAML failurePolicy values from Fail to Ignore; no logging statements, log fields, credentials, tokens, PII, or customer data were added.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@admission-policies/default/authoritative-api-transition-requires-capi-infrastructure-ready.yaml`:
- Line 28: Make all five migration VAPs fail closed by replacing their
failurePolicy: Ignore settings with Fail, and ensure their bindings do not allow
missing parameters via parameterNotFoundAction. Apply the corresponding binding
changes in capi-operator-manifests/default/manifests.yaml at lines 25, 152, 528,
579, and 904; update the five named policy files at their specified sites. Add
coverage for CEL/evaluation errors and monitoring for policy failures, or
explicitly gate activation during bootstrap and restore fail-closed enforcement
once CAPI readiness is established.
🪄 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), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: bf91382a-e254-4439-8479-6eb583719543

📥 Commits

Reviewing files that changed from the base of the PR and between b05f43c and 3135ae8.

📒 Files selected for processing (6)
  • admission-policies/default/authoritative-api-transition-requires-capi-infrastructure-ready.yaml
  • admission-policies/default/machine-api-machine-set-vap.yaml
  • admission-policies/default/machine-api-machine-vap.yaml
  • admission-policies/default/only-create-mapi-machine-if-authoritative-api-capi.yaml
  • admission-policies/default/prevent-authoritative-mapi-machineset-create-when-capi-exists.yaml
  • capi-operator-manifests/default/manifests.yaml

name: openshift-mapi-authoritative-api-transition-requires-capi-infrastructure-ready-and-not-deleting
spec:
failurePolicy: Fail
failurePolicy: Ignore

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

source_files=(
  admission-policies/default/authoritative-api-transition-requires-capi-infrastructure-ready.yaml
  admission-policies/default/machine-api-machine-set-vap.yaml
  admission-policies/default/machine-api-machine-vap.yaml
  admission-policies/default/only-create-mapi-machine-if-authoritative-api-capi.yaml
  admission-policies/default/prevent-authoritative-mapi-machineset-create-when-capi-exists.yaml
)

for file in "${source_files[@]}"; do
  grep -q '^  failurePolicy: Ignore$' "$file"
done

test "$(grep -c '^  failurePolicy: Ignore$' capi-operator-manifests/default/manifests.yaml)" -eq 5

rg -n --glob '*.go' --glob '*.yaml' --glob '*.yml' \
  'ValidatingAdmissionPolicy|failurePolicy|parameterNotFoundAction' . || true

Repository: openshift/cluster-capi-operator

Length of output: 169


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

for file in \
  admission-policies/default/authoritative-api-transition-requires-capi-infrastructure-ready.yaml \
  admission-policies/default/machine-api-machine-set-vap.yaml \
  admission-policies/default/machine-api-machine-vap.yaml \
  admission-policies/default/only-create-mapi-machine-if-authoritative-api-capi.yaml \
  admission-policies/default/prevent-authoritative-mapi-machineset-create-when-capi-exists.yaml \
  capi-operator-manifests/default/manifests.yaml
do
  if [ -f "$file" ]; then
    echo "===== $file ====="
    grep -n -E '^(apiVersion|kind|metadata:|  name:|  failurePolicy:|  validationActions:|  parameterNotFoundAction:|  matchConstraints:|  validations:|    - expression:)' "$file" || true
  else
    echo "MISSING $file"
  fi
done

echo "===== matching policy fields ====="
rg -n --glob '*.yaml' --glob '*.yml' \
  'failurePolicy:|validationActions:|parameterNotFoundAction:|kind: ValidatingAdmissionPolicy|kind: ValidatingAdmissionPolicyBinding' . || true

echo "===== repository status ====="
git status --short
git diff --stat

Repository: openshift/cluster-capi-operator

Length of output: 20276


🌐 Web query:

Kubernetes ValidatingAdmissionPolicy failurePolicy Ignore evaluation error parameterNotFoundAction Allow official documentation

💡 Result:

In Kubernetes ValidatingAdmissionPolicy, the behavior when parameters are missing is governed by the required parameterNotFoundAction field within the ValidatingAdmissionPolicyBinding's spec.paramRef [1]. This field determines how the system reacts when the referenced parameter resource cannot be found [1]. The parameterNotFoundAction field supports the following values [1]: - Allow: If the referenced parameters are not found, the binding treats the absence as a successful validation, effectively bypassing the policy's evaluation for that request [1]. - Deny: If the referenced parameters are not found, the binding treats the absence as a failure [1]. This failure is then subject to the ValidatingAdmissionPolicy's failurePolicy [1]. It is important to distinguish this from the failurePolicy field, which is defined at the policy level and controls how the system handles errors during the evaluation process (such as CEL expression runtime errors, type check errors, or misconfigurations) [2][1][3]. - If failurePolicy is set to Fail (the default), an error during policy evaluation causes the admission to fail [1][3]. - If failurePolicy is set to Ignore, an error during policy evaluation is ignored, and the API request is allowed to continue [1][3]. When using Deny for parameterNotFoundAction, if the parameter is missing, the resulting failure is enforced based on the configured failurePolicy [1]. If failurePolicy is set to Fail, the request is rejected; if it is set to Ignore, the error is ignored, and the request proceeds [1][3].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "===== candidate files ====="
git ls-files | grep -E '(^|/)(authoritative-api-transition-requires-capi-infrastructure-ready|machine-api-machine-set-vap|machine-api-machine-vap|only-create-mapi-machine-if-authoritative-api-capi|prevent-authoritative-mapi-machineset-create-when-capi-exists|manifests)\.yaml$' || true

echo "===== policy definitions and bindings ====="
rg -n -C 4 --glob '*.yaml' --glob '*.yml' \
  'ValidatingAdmissionPolicy|ValidatingAdmissionPolicyBinding|failurePolicy|validationActions|parameterNotFoundAction' . || true

Repository: openshift/cluster-capi-operator

Length of output: 50387


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

source_files = [
    Path("admission-policies/default/authoritative-api-transition-requires-capi-infrastructure-ready.yaml"),
    Path("admission-policies/default/machine-api-machine-set-vap.yaml"),
    Path("admission-policies/default/machine-api-machine-vap.yaml"),
    Path("admission-policies/default/only-create-mapi-machine-if-authoritative-api-capi.yaml"),
    Path("admission-policies/default/prevent-authoritative-mapi-machineset-create-when-capi-exists.yaml"),
]

def docs(text):
    return [x for x in re.split(r"(?m)^---\s*$", text) if x.strip()]

for path in source_files:
    print(f"===== {path} =====")
    parts = docs(path.read_text())
    policy = next(x for x in parts if re.search(r"(?m)^kind: ValidatingAdmissionPolicy\s*$", x))
    binding = next(x for x in parts if re.search(r"(?m)^kind: ValidatingAdmissionPolicyBinding\s*$", x))
    for label, text in (("policy", policy), ("binding", binding)):
        print(f"-- {label} --")
        for line in text.splitlines():
            if re.match(r"^\s*(name:|failurePolicy:|paramKind:|apiVersion:|kind:|parameterNotFoundAction:|validationActions:|matchConditions:|matchConstraints:|validations:|    - expression:|  - expression:|      - expression:|    message|      message)", line):
                print(line)
    print()

generated = Path("capi-operator-manifests/default/manifests.yaml").read_text()
print("===== generated targeted policies =====")
for name in [
    "machine-api-machine-vap",
    "machine-api-machine-set-vap",
    "openshift-only-create-mapi-machine-if-authoritative-api-capi",
    "openshift-prevent-authoritative-mapi-machineset-create-when-capi-exists",
    "openshift-mapi-authoritative-api-transition-requires-capi-infrastructure-ready-and-not-deleting",
]:
    policy = next(
        x for x in docs(generated)
        if re.search(rf"(?m)^  name: {re.escape(name)}\s*$", x)
        and re.search(r"(?m)^kind: ValidatingAdmissionPolicy\s*$", x)
    )
    print(name, re.search(r"(?m)^\s+failurePolicy:\s*(\S+)", policy).group(1))
PY

echo "===== relevant tests and documentation ====="
rg -n --glob '*.go' --glob '*_test.go' --glob '*.yaml' --glob '*.yml' --glob '*.md' \
  'authoritative-api-transition-requires-capi-infrastructure-ready|machine-api-machine-set-vap|machine-api-machine-vap|only-create-mapi-machine-if-authoritative-api-capi|prevent-authoritative-mapi-machineset-create-when-capi-exists|failurePolicy: Ignore|parameterNotFoundAction' \
  . | head -250 || true

Repository: openshift/cluster-capi-operator

Length of output: 21358


🌐 Web query:

site:kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy failurePolicy evaluation errors CEL runtime errors

💡 Result:

In Kubernetes, ValidatingAdmissionPolicy handles Common Expression Language (CEL) runtime errors and evaluation failures based on the configuration of the failurePolicy field [1]. The failurePolicy defines the response when an admission policy is misconfigured or when a CEL expression encounters an evaluation error [1]. The two possible values for failurePolicy are: 1. Fail: This is the default setting [1]. If a CEL expression results in an evaluation error or if the policy itself is misconfigured, the admission request is rejected, effectively failing closed [1]. 2. Ignore: If a CEL expression encounters a runtime error or the policy is misconfigured, the error is ignored, and the API request is allowed to continue, effectively failing open [1]. It is important to distinguish these behaviors from the result of a successful CEL evaluation that returns false. If a CEL expression evaluates to false, it is treated as a validation failure rather than a runtime error [1]. In such cases, the validation is always enforced regardless of the failurePolicy setting [1]. Additionally, specific rules apply to match conditions. If a match condition encounters a runtime error: - If failurePolicy is set to Fail, the API server rejects the request [1]. - If failurePolicy is set to Ignore, the API server proceeds with the request but skips the policy evaluation [1]. If any match condition evaluates to false, the policy is skipped entirely, regardless of other errors or the failurePolicy [1].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

for file_and_range in \
  "pkg/controllers/machinesetsync/machineset_vap_test.go:230,390" \
  "pkg/controllers/machinesetsync/machineset_vap_test.go:650,710" \
  "pkg/controllers/machinesync/machine_sync_controller_test.go:1835,1885" \
  "pkg/controllers/machinesync/machine_sync_controller_test.go:2180,2265" \
  "e2e/machine_migration_vap_test.go:1,150"
do
  file="${file_and_range%%:*}"
  range="${file_and_range#*:}"
  echo "===== $file:$range ====="
  sed -n "${range}p" "$file"
done

echo "===== failure/error observability references ====="
rg -n --glob '*.go' --glob '*.yaml' --glob '*.yml' --glob '*.md' \
  'ValidatingAdmissionPolicy|admission policy|evaluation error|CEL|failurePolicy|audit|metric|alert' \
  pkg controllers e2e admission-policies capi-operator-manifests 2>/dev/null | head -250 || true

Repository: openshift/cluster-capi-operator

Length of output: 50387


Keep these migration guards fail-closed, or cover the fail-open trade-off before merge.

All five VAPs use failurePolicy: Ignore, and their bindings use parameterNotFoundAction: Allow. A false CEL result is denied, but a parameter or CEL evaluation error allows the request. Missing CAPI v1beta2 parameters also bypass the guard. This can admit conflicting MAPI creates or updates.

Existing tests cover normal denials and missing parameters. Add tests for evaluation errors and monitoring for policy failures. If fail-open behavior is required only during bootstrap, gate policy activation or restore failurePolicy: Fail after CAPI readiness.

📍 Affects 6 files
  • admission-policies/default/authoritative-api-transition-requires-capi-infrastructure-ready.yaml#L28-L28 (this comment)
  • admission-policies/default/machine-api-machine-set-vap.yaml#L28-L28
  • admission-policies/default/machine-api-machine-vap.yaml#L28-L28
  • admission-policies/default/only-create-mapi-machine-if-authoritative-api-capi.yaml#L6-L6
  • admission-policies/default/prevent-authoritative-mapi-machineset-create-when-capi-exists.yaml#L6-L6
  • capi-operator-manifests/default/manifests.yaml#L25-L25
  • capi-operator-manifests/default/manifests.yaml#L152-L152
  • capi-operator-manifests/default/manifests.yaml#L528-L528
  • capi-operator-manifests/default/manifests.yaml#L579-L579
  • capi-operator-manifests/default/manifests.yaml#L904-L904
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@admission-policies/default/authoritative-api-transition-requires-capi-infrastructure-ready.yaml`
at line 28, Make all five migration VAPs fail closed by replacing their
failurePolicy: Ignore settings with Fail, and ensure their bindings do not allow
missing parameters via parameterNotFoundAction. Apply the corresponding binding
changes in capi-operator-manifests/default/manifests.yaml at lines 25, 152, 528,
579, and 904; update the five named policy files at their specified sites. Add
coverage for CEL/evaluation errors and monitoring for policy failures, or
explicitly gate activation during bootstrap and restore fail-closed enforcement
once CAPI readiness is established.

Source: MCP tools

@openshift-ci

openshift-ci Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

@miyadav: 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/unit 3135ae8 link true /test unit

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.

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

Labels

jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. 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