Client-go: CRD Bug in v4.0.0

Created on 22 Aug 2017  Â·  9Comments  Â·  Source: kubernetes/client-go

There are 2 bugs that I thought would get fixed in release 4.0.0 but still persist.

I was getting the following error:

Failed to list *spec.APIProxy: no kind "ApiProxyList" is registered for version "kanali.io/v1"

The fix was to change my type name from APIProxyList to ApiProxyList. Of course this will break golint. It seems as though it expects the type name to match the kind name. However, since we are giving it a runtime.Object telling it what the type should be, why should it matter what the type name is?

In addition, client-go does not seem to be respecting the json tags for a type. For example, client-go will not understand my type unless I have an Items field in my list type. I would think I could name it whatever I want as long as I have json:"items"

It is really unfortunate that in order for client-go to work, I would have to turn off linting...

Is there a fix or a workaround?

Most helpful comment

Thanks to @liggitt for discussing this with me in the Kubernetes Slack. Here is the summary of our conversation that will result in the closing of this issue:

  • It is highly recommended that the name of the CRD kind match exactly (case sensitive) the name of the golang struct used with it. For example, if your kind is ApiFoo, then your struct should be type ApiFoo struct
  • Users of golint will notice that in this particular edge case (ApiFoo), having a struct with this name would break one of the rules. However, as I learned the hard way, _golint is not, and will never be, trustworthy enough for its suggestions to be enforced automatically, for example as part of a build process_. However, there is a workaround if you still have a compelling reason not to change your kind or spec names: scheme.AddKnownTypeWithName(schemeGroupVersion.WithKind("ApiFoo"), &APIFoo{})

All 9 comments

Would someone be able to comment on this issue?

@deads2k suggested that this might be fixed with CRDs and that this problem might just be localized to TPRs.

@deads2k suggested that this might be fixed with CRDs and that this problem might just be localized to TPRs.

In particular, the serialization of list kinds from the API server using TPRs used a guess at what the valid ListKind may be. CRDs have a field for the user to specify the actual value.

@deads2k

This issue persists with CRDs. I have created a complete reproducible program along with instructions. Find it here. Here is a recap of the README for that project:

Start Minikube

$ minikube start

Build Program

$ git clone [email protected]:frankgreco/client-go-crd-bug.git
$ cd client-go-crd-bug
$ glide install
$ go build

Create CRD Manually

$ kubectl apply -f crd.yml
$ kubect apply -f example.yml

Start Program

$ ./client-go-crd-bug --kubeconfig=~/.kube/config
adding crd named example

Reproduce Bug

$ sed -i -e 's/ApiFoo/APIFoo/g' main.go
$ go build
$ ./client-go-crd-bug --kubeconfig=~/.kube/config
E0927 20:37:00.072532   26614 reflector.go:201] github.com/frankgreco/client-go-crd-bug/main.go:96: Failed to list *main.APIFoo: no kind "ApiFooList" is registered for version "bar.io/v1"

Thanks to @liggitt for discussing this with me in the Kubernetes Slack. Here is the summary of our conversation that will result in the closing of this issue:

  • It is highly recommended that the name of the CRD kind match exactly (case sensitive) the name of the golang struct used with it. For example, if your kind is ApiFoo, then your struct should be type ApiFoo struct
  • Users of golint will notice that in this particular edge case (ApiFoo), having a struct with this name would break one of the rules. However, as I learned the hard way, _golint is not, and will never be, trustworthy enough for its suggestions to be enforced automatically, for example as part of a build process_. However, there is a workaround if you still have a compelling reason not to change your kind or spec names: scheme.AddKnownTypeWithName(schemeGroupVersion.WithKind("ApiFoo"), &APIFoo{})

It is highly recommended that the name of the CRD kind match exactly (case sensitive) the name of the golang struct used with it. For example, if your kind is ApiFoo, then your struct should be type ApiFoo struct.

I think this is not just recommended and this may be a must when defining the golang struct of the CRD.
If not so, the CRDList could not be registered and it couldn't use client-go to create instances of a CRD resource which is difficult to find what's wrong until knowing the implicit rule 😢

@flyer103

I agree but what about:

‘’’
scheme.AddKnownTypeWithName(schemeGroupVersion.WithKind("ApiFoo"), &APIFoo{})
‘’’

I have tested it on k8s-v1.7.3 using client-go-v4.0.

If the SchemeBuilder is built from the following, it could use client-go to create instances of a CRD resource but the controller which watches the events of the CRD resource couldn't list the CRDList:

func AddKnownTypes(scheme *runtime.Scheme) error {
    scheme.AddKnownTypeWithName(schema.GroupVersionKind{
            Group: XXX,  // CRD Group
            Version: XXX,  // CRD Version
            Kind: XXX,  // CRD Kind
        },
        &CRD_STRUCT{},  // a pointer to an instance of the CRD struct
    )

    return nil
}

Do I have missed something to register the CRDList?

If the SchemeBuilder is built from the following and the name of the golang struct of the CRD resource is the same as the CRDKind, then it's ok to use client-go to create instances of the CRD resource and watch events of the CRD resource for a controller:

func AddKnownTypes(scheme *runtime.Scheme) error {
    scheme.AddKnownTypes(
        schema.GroupVersion{
            Group:   XXX,  // CRD Group
            Version: XXX,  // CRD Version
        },
        &CRD_STRUCT{},  // a pointer to an instance of the CRD struct
        &CRD_LIST_STRUCT{},  // a pointer to an instance of the CRD LIST struct
    )
    metav1.AddToGroupVersion(scheme, schema.GroupVersion{
        Group:   XXX,  // CRD Group
        Version: XXX,  // CRD Version
    })

    return nil
}

@flyer103 How to solve this issue?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aaron276h picture aaron276h  Â·  4Comments

peterwillcn picture peterwillcn  Â·  5Comments

alexec picture alexec  Â·  5Comments

mheese picture mheese  Â·  5Comments

AdheipSingh picture AdheipSingh  Â·  5Comments