Skip to content

processNodeAgainstAllRules can write an empty NodeEvaluation that fails CRD validation and drops FailedNodes updates #217

@sahitya-chandra

Description

@sahitya-chandra

What happens

On a failed evaluation (evaluateRuleForNode returns an error, e.g. a non-retryable taint patch failure), processNodeAgainstAllRules still appends a zero-value NodeEvaluation{} to the rule-status patch:

https://github.com/kubernetes-sigs/node-readiness-controller/blob/main/internal/controller/node_controller.go#L159-L206

Every required field on NodeEvaluation (nodeName, conditionResults, taintStatus, lastEvaluationTime) is omitempty, so the empty entry serializes to {} and the apiserver rejects the entire Status().Patch with a 422:

status.nodeEvaluations[0].conditionResults: Required value,
status.nodeEvaluations[0].lastEvaluationTime: Required value,
status.nodeEvaluations[0].nodeName: Required value,
status.nodeEvaluations[0].taintStatus: Required value

The patch is atomic, and the FailedNodes update (recorded via recordNodeFailure) is bundled into the same patch, so it is rejected too. Net effect: on a failed evaluation nothing is persisted to rule.status, and the only signal is a controller log line. Confirmed via envtest.

Expected

Skip the empty NodeEvaluation on the failure path and still persist the FailedNodes entry, so the failure is visible via kubectl get nodereadinessrule -o yaml.

Reproduce

Make a node's taint patch fail persistently with a non-conflict error (e.g. RBAC-deny the nodes patch) so evaluateRuleForNode returns an error: the controller logs the 422 above and failedNodes never appears for that node.

/kind bug

Metadata

Metadata

Labels

kind/bugCategorizes issue or PR as related to a bug.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions