Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make sure crd-* manifests are YAML before passing to controller-gen #3996

Conversation

maelvls
Copy link
Member

@maelvls maelvls commented May 12, 2021

As described in #3989, controller-gen's schemapatch option silently skips CRDs files that are not valid YAML. We often forget that, and end up merging a CRD file that we silently won't be able to update using ./hack/update-crds.sh like what happened in #3932.

This patch uses the excellent cue to parse the YAML files. I could have picked something like yq (Python) or its Go port, mikefarah/yq, but we don't want Python dependencies, and the Go port mikefarah/yq isn't great (e.g., does not show the file name when a parsing error happens...).

Here is what you can expect when one of the CRDs isn't a proper YAML file:

  % ./hack/update-crds.sh
  /home/mvalais/code/cert-manager/deploy/crds/crd-orders.yaml:14: did not find expected key

Note to the reviewer:

I don't know whether using CUE is really a good idea... I don't know how to tell Bazel to download CUE either, so I just defaulted to using Go 1.16's go install @version syntax.

/kind cleanup
/release-note-none

@jetstack-bot
Copy link
Collaborator

@maelvls: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

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/test-infra repository.

@jetstack-bot jetstack-bot added dco-signoff: yes Indicates that all commits in the pull request have the valid DCO sign-off message. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. needs-kind Indicates a PR lacks a `kind/foo` label and requires one. labels May 12, 2021
@jetstack-bot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: maelvls

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

The pull request process is described here

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

@jetstack-bot jetstack-bot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels May 12, 2021
Copy link
Member

@wallrj wallrj left a comment

Choose a reason for hiding this comment

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

Looks like some tests failed, and I think you will need to figure out how to get Bazel to install the cue tool. See https://github.com/jetstack/cert-manager/blob/3bb830c2abb40742466452b301ab9f1b64f47eda/hack/BUILD.bazel#L235-L262

Also might be worth considering kubeval: https://kubeval.instrumenta.dev/

$ kubeval deploy/crds/*.yaml
ERR  - Failed to decode YAML from deploy/crds/crd-certificaterequests.yaml: error converting YAML to JSON: yaml: line 32: did not find expected node content
ERR  - Failed to decode YAML from deploy/crds/crd-certificates.yaml: error converting YAML to JSON: yaml: line 32: did not find expected node content
ERR  - Failed to decode YAML from deploy/crds/crd-challenges.yaml: error converting YAML to JSON: yaml: line 30: did not find expected node content
ERR  - Failed to decode YAML from deploy/crds/crd-clusterissuers.yaml: error converting YAML to JSON: yaml: line 29: did not find expected node content
ERR  - Failed to decode YAML from deploy/crds/crd-issuers.yaml: error converting YAML to JSON: yaml: line 29: did not find expected node content
ERR  - Failed to decode YAML from deploy/crds/crd-orders.yaml: error converting YAML to JSON: yaml: line 30: did not find expected node content

@wallrj
Copy link
Member

wallrj commented May 12, 2021

I went looking to see if there's a kubectl validation command but it seems not: kubernetes/kubernetes#64830

I tried dry-run=client, but it still requires a connection to an API server:

$ kubectl apply --dry-run=client -f deploy/crds/crd-*
The connection to the server localhost:8080 was refused - did you specify the right host or port?

@munnerz
Copy link
Member

munnerz commented May 17, 2021

I don't know whether using CUE is really a good idea... I don't know how to tell Bazel to download CUE either, so I just defaulted to using Go 1.16's go install @Version syntax.

Happy to help with running through how to wire up Bazel for this! You should be able to take a look at controller-gen as an example of depending on a binary dependency of another project too 😄

@maelvls
Copy link
Member Author

maelvls commented May 17, 2021

I'm not quite familiar with Bazel 😅 I'll look into it

@jetstack-bot jetstack-bot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels May 18, 2021
@maelvls
Copy link
Member Author

maelvls commented May 18, 2021

Phew... After a lot of struggling, I went back to just go install 😞

I just can't be bothered struggling with Bazel when we can just go install with Go 1.16. We still keep the sandboxing by setting GOPATH to Bazel's $PWD:

# Tools installed with "go install" below are sandboxed by Bazel.
export GOPATH=$PWD
export PATH=$(dirname "$go"):$GOPATH/bin:$PATH

# Only installs the first time you run ./hack/update-crds.sh.
go install cuelang.org/go/cmd/cue@v0.4.0-beta.1
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.9

cue vet hack/valid-crd.cue deploy/crds/*.yaml
controller-gen schemapatch:manifests=./deploy/crds output:dir=./deploy/crds paths=./pkg/apis/...

The only downside with this approach is that go install does a quick network call every time we run ./hack/update-crds.sh, but the installation only happens once. This overhead seems negligible compared to the cost of running this script inside Bazel.

I know I should be doing it "properly" by using sh_binary and go_binary but this go install solution seems so much more elegant... 😅

cc @wallrj @irbekrm

@irbekrm
Copy link
Collaborator

irbekrm commented May 18, 2021

Do we run this script in CI? I think the images might not have go as we use Bazel to download go.

I'd also be happy to look at the Bazel bits.

@maelvls maelvls force-pushed the prevent-future-controller-gen-issue branch from e3c2ae7 to 35bb0f8 Compare July 5, 2021 13:01
@maelvls
Copy link
Member Author

maelvls commented Jul 5, 2021

@irbekrm I removed the go install lines and added bazel rules.

@maelvls maelvls force-pushed the prevent-future-controller-gen-issue branch from 35bb0f8 to 0c99be6 Compare July 5, 2021 13:48
The controller-gen tool's schemapatch option silently skips CRDs files that
are not valid YAML. We often forget that, and end up merging a CRD file
that we silently won't be able to update using ./hack/update-crds.sh.

This patch uses CUE to parse the YAML files. We could have picked
something like yq (Python) or the Go version of yq, but we don't want
Python dependencies, and the Go version of yq has a poor UX.

Here is what you can expect when one of the CRDs isn't a proper YAML
file:

  % ./hack/update-crds.sh
  /home/mvalais/code/cert-manager/deploy/crds/crd-orders.yaml:14: did not find expected key

Signed-off-by: Maël Valais <mael@vls.dev>
@maelvls maelvls force-pushed the prevent-future-controller-gen-issue branch from 0c99be6 to ac327d1 Compare July 5, 2021 14:22
@maelvls
Copy link
Member Author

maelvls commented Jul 5, 2021

apiserver.go:64: failed to start control plane: unable to start control plane itself:
failed to start the controlplane. retried 5 times: timeout waiting for process etcd
to start successfully (it may have failed to start, or stopped unexpectedly before
becoming ready)

/test pull-cert-manager-bazel

Copy link
Collaborator

@irbekrm irbekrm left a comment

Choose a reason for hiding this comment

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

Looks great to me, glad we'll have this check.

I've only added a nit, happy to lgtm otherwise.

Note- I did briefly look at whether we can use any of the existing tools for this, but looks like we cannot. I guess it would be nice if we could use a single yaml validation/interpolation tool for all yaml templating/validation etc, but that doesn't seem possible.

@@ -0,0 +1,2 @@
// We just validate that our CRDs are valid YAML files, we don't care about
// validating the data itself.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: whitespace

@jetstack-bot jetstack-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 7, 2021
@jetstack-bot
Copy link
Collaborator

@maelvls: PR needs rebase.

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/test-infra repository.

@jetstack-bot
Copy link
Collaborator

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.
If this issue is safe to close now please do so with /close.
Send feedback to jetstack.
/lifecycle stale

@jetstack-bot jetstack-bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Dec 6, 2021
@jetstack-bot
Copy link
Collaborator

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.
If this issue is safe to close now please do so with /close.
Send feedback to jetstack.
/lifecycle rotten
/remove-lifecycle stale

@jetstack-bot jetstack-bot added lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Jan 5, 2022
@jetstack-bot
Copy link
Collaborator

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.
Send feedback to jetstack.
/close

@jetstack-bot
Copy link
Collaborator

@jetstack-bot: Closed this PR.

In response to this:

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.
Send feedback to jetstack.
/close

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/test-infra repository.

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. dco-signoff: yes Indicates that all commits in the pull request have the valid DCO sign-off message. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. needs-kind Indicates a PR lacks a `kind/foo` label and requires one. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants