List kubernetes resources by clinet-go, How can I get the kind and apiversion?

3/23/2021

When I get the kubernetes resources from api with client-go, but I can't found the apiversion and kind in the response, the apiversion and kind is empty. How can I get the apiversion and kind of the resource?

below is my code:

package main

import (
    "flag"
    "k8s.io/client-go/tools/clientcmd"
    "log"
    "k8s.io/client-go/kubernetes"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "fmt"
)

var clientset *kubernetes.Clientset

func main()  {
    k8sconfig := flag.String("k8sconfig","./k8sconfig","kubernetes config file path")
    flag.Parse()
    config , err := clientcmd.BuildConfigFromFlags("",*k8sconfig)
    if err != nil {
        log.Println(err)
    }
    clientset , err = kubernetes.NewForConfig(config)
    if err != nil {
        log.Fatalln(err)
    } else {
        fmt.Println("connect k8s success")
    }
    pods,err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
    if err != nil {
        log.Println(err.Error())
    }
    for _, pod := range pods.Items{
    	fmt.Println("apiversion: ", pod.APIVersion, "kind: ", pod.Kind)
	}   
}

The output:
apiversion:   kind:  
apiversion:   kind:  
apiversion:   kind:  
apiversion:   kind:  
apiversion:   kind:  
apiversion:   kind:  
apiversion:   kind:  
apiversion:   kind:
......
......
-- yzhengwei
client-go
go
kubernetes
kubernetes-pod

2 Answers

3/23/2021

You are not getting the APIVersion and Kind because it was ignored from the code.

If you take a look at the API server JSON response, it will be something like below:

{
   "kind":"PodList",
   "apiVersion":"v1",
   "metadata":{
      "resourceVersion":"2397"
   },
   "items":[
      {
... ... ...

So the response does contain the APIVersion and Kind. But when the response is decoded to k8s object, here

out, _, err := r.decoder.Decode(r.body, nil, obj)

Here you can see that the second output parameter is ignored, which is schema.GroupVersionKind.

func (c *Something) Decode([]byte, *schema.GroupVersionKind, runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
	
}

N.B.: When you are making an API call using the client-go (unless dynamic client), you already know the APIVersion (ie. CoreV1() ) and the Kind ( ie. List()).

-- Kamol Hasan
Source: StackOverflow

3/23/2021

I think the issue is that you are getting the list of pods using the List() API so it is not a pod as you expect and doesn't have a Kind field.

You need to iterate over the list of pods to access individual pods:

for _, pod := range pods.Items {
	fmt.Printf("%s %s\n", pod.GetName(), pod.GetCreationTimestamp())
}

The Kind field is present as part of Pod's Metadata and can be accessed using pod.ObjectMeta.Kind.

-- Krishna Chaurasia
Source: StackOverflow