Skip to content

Client-side validation is skipped if the cluster and resource support server-side validation #1625

@james-mchugh

Description

@james-mchugh

What happened:

This "bug" (perhaps not a bug, maybe more of a breaking change) is not with the kubectl CLI per-se. It is with the kubectl Go package. A breaking change appears to have been introduced with the added support of server-side validation in v0.30.0.

helm (which utilizes the kubectl Go package under the hood) now prints warnings when resources fail validation instead of throwing an error (see helm/helm#13053). This is because the schema returned by the new Validator factory no longer returns an error if the cluster supports server-side validation.

What you expected to happen:

helm throws a validation error if invalid fields are found in the manifest.

How to reproduce it (as minimally and precisely as possible):

In any version of Helm >= 3.9.0:

  1. Create a chart helm create foo.
  2. Modify the deployment.yaml to add an invalid field. Example:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "foo.fullname" . }}
  labels:
    {{- include "foo.labels" . | nindent 4 }}
spec:
  badField: false
  ...
  1. Run helm install foo ./foo
  2. Observe:
helm install foo foo
W0721 12:53:43.211370    4631 warnings.go:70] unknown field "spec.badField"
NAME: foo
LAST DEPLOYED: Sun Jul 21 12:53:43 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1

When instead, this previously caused Helm to fail.

Additionally, invalid fields (e.g., setting matchLabels to an array instead of object, cause helm install to install the chart and then fail, requiring it to then be uninstalled. Previously, the client-side validation would have prevented the chart from ever being installed in the first place.

Anything else we need to know?:

This appears to have been introduced in kubernetes/kubernetes@fe37728 when server-side validation support was added to Kubectl. This changed the schema returned by the Validator factory, which in turn changed the ValidateBytes function used to validate the resource. Specifically,

if resource.IsParamUnsupportedError(err) {
made it so that client side validation never runs if the cluster supports server-side validation of the resource. This was a breaking change, as previously, any errors that could have been detected client-side would have been detected here.

I experimented a bit with a potential solution for this. It is still very much a WIP/POC, but if you believe it will be valuable here, I can continue working on it. The potential solution (https://github.com/kubernetes/kubectl/compare/master...james-mchugh:kubectl:bugfix/client-side-validation?expand=1) adds a preferredStrategy field to the paramVerifyingSchema struct and Validator function, so callers of Validator can specify if they want server-side or client-side validation to be preferred. If client-side is picked, the ValidateBytes function will continue with validation regardless of whether the cluster supports server-side validation.

If you think this is something that should be fixed, I would be happy to contribute a fix for it.

Environment:

  • Kubernetes client and server versions (use kubectl version):
    Kubernetes server >= 1.25.0
    Kubectl Go package >= 0.30.0

  • Cloud provider or hardware configuration: NA

  • OS (e.g: cat /etc/os-release): NA

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.needs-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions