kubernetes-sigs/controller-tools

The order of the CRDs version are processed is not deterministic

Opened this issue · 4 comments

I'm trying to add the shortNames configuration to some CRDs. These CRDs have two versions: v1 and v1alpha2. I have changed the // +kubebuilder:resource:scope=Cluster,shortName=cap by adding the shortName field in the v1 CRDs. However, each time I run controller-gen, the resulting CRD definitions are different. On each run, the shortNames configuration is added to some CRDs but not to others.

After downloading the controller-tools repository, adding some debug messages, and building controller-gen locally, I found the issue. It turns out that every time controller-gen runs, the order in which it processes the CRD versions changes. Therefore, when the v1alpha2 CRD is the last one to be processed, the generated CRD definition misses the shortNames configuration. To fix this, I need to define the shortName field in the kubebuilder marker for both versions.

Is this behavior expected? Shouldn't controller-gen consider this marker only for the latest version?

Is this behavior expected? Shouldn't controller-gen consider this marker only for the latest version?

The latest is hard to define, since technically the version string can be anything and doesn't have to follow the v1alpha1, v1beta1, v1 pattern we typically see in Kube.

However, perhaps pinning this to the storage version would make sense, since that always has to be present and gives a singular answer to the version without having to write some complex logic internally to guess which is the latest

I wonder if we should simpy return an error if the // +kubebuilder:resource marker is defined multiple times for the same API type and otherwise only use the one occurence of the marker that we can find.

However, perhaps pinning this to the storage version would make sense, since that always has to be present and gives a singular answer to the version without having to write some complex logic internally to guess which is the latest

I like the idea of using the storage version to that.

I wonder if we should simpy return an error if the // +kubebuilder:resource marker is defined multiple times for the same API type and otherwise only use the one occurence of the marker that we can find.

If we do that, won't we miss the v1alpha2 definition in the final CRDs spec? I mean, if I want to keep both version in the CRD definition, which afaics is the current behavior, won't this change prevent users from doing that?

If we do that, won't we miss the v1alpha2 definition in the final CRDs spec?

No, if you define the resouce marker only on one of your Go types all versions are still included in the CRD.

The entire resource marker (

type Resource struct {
) consists of fields that only exist once on the CRD resource.

So I don't think it makes sense to allow it to be configured multiple times and then pick one of the markers that is then used for the CRD. Just like storage version it should be only defined once