本文介绍了client-go:将 kubernetes json 文件解析为 k8s 结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想解析 kubernetes 清单文件 (json/yaml) 并能够将它们转换为 k8s 结构(以便稍后操作它们)

i would like to parse kubernetes manifest file (json/yaml) and be able to convert them to k8s structures (to later on manipulate them)

我知道有 NewYAMLOrJSONDecoder().Decode() 函数(https://github.com/kubernetes/apimachinery/blob/master/pkg/util/yaml/decoder.go) 读取 json/yaml 文件,但下一步是:如何将它们转换为 k8s 结构/类型?

I know there is the NewYAMLOrJSONDecoder().Decode() function (https://github.com/kubernetes/apimachinery/blob/master/pkg/util/yaml/decoder.go) to read a json/yaml file, but the next step is: how to convert them to k8s structure/type?

即如果我读取带有 Namespace 对象的 yaml 文件,例如如何将其转换为 core/v1/namespace 接口

i.e. if I read a yaml file with a Namespace object, how to convert it to a core/v1/namespace interface for example

问候,

推荐答案

谢谢 svenwltr,我不知道我们可以这样做.

Thanks svenwltr, I was not aware we can do like this.

与此同时,我设法找到的不是更好的方法,而是另一种方法:

In the same time, I manage to find not a better approach but a different one:

package main

import (
    "flag"
    "fmt"
    "os"
    "io"
    "path/filepath"
    "log"
    "encoding/json"
    //"time"

    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/discovery"
    "k8s.io/client-go/dynamic"
    "k8s.io/apimachinery/pkg/util/yaml"
    "k8s.io/apimachinery/pkg/runtime"
    "k8s.io/apimachinery/pkg/runtime/schema"
    "k8s.io/apimachinery/pkg/api/meta"
    "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

)

func main() {
    var kubeconfig *string
    if home := homeDir(); home != "" {
        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    } else {
        kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()

    // use the current context in kubeconfig
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
        panic(err.Error())
    }

    // create the clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }

    f,err := os.Open("namespace.yaml")
    if err!=nil {
        log.Fatal(err)
    }
    d := yaml.NewYAMLOrJSONDecoder(f,4096)
    dd := clientset.Discovery()
    apigroups,err := discovery.GetAPIGroupResources(dd)
    if err != nil {
        log.Fatal(err)
    }

    restmapper := discovery.NewRESTMapper(apigroups,meta.InterfacesForUnstructured)


    for {
        // https://github.com/kubernetes/apimachinery/blob/master/pkg/runtime/types.go
        ext := runtime.RawExtension{}
        if err := d.Decode(&ext); err!=nil {
            if err == io.EOF {
                break
            }
            log.Fatal(err)
        }
        fmt.Println("raw: ",string(ext.Raw))
        versions := &runtime.VersionedObjects{}
        //_, gvk, err := objectdecoder.Decode(ext.Raw,nil,versions)
        obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(ext.Raw,nil,versions)
        fmt.Println("obj: ",obj)

        // https://github.com/kubernetes/apimachinery/blob/master/pkg/api/meta/interfaces.go
        mapping, err := restmapper.RESTMapping(gvk.GroupKind(), gvk.Version)
        if err != nil {
            log.Fatal(err)
        }

        restconfig := config
        restconfig.GroupVersion = &schema.GroupVersion {
            Group: mapping.GroupVersionKind.Group,
            Version: mapping.GroupVersionKind.Version,
        }
        dclient,err := dynamic.NewClient(restconfig)
        if err != nil {
            log.Fatal(err)
        }

        // https://github.com/kubernetes/client-go/blob/master/discovery/discovery_client.go
        apiresourcelist, err := dd.ServerResources()
        if err != nil {
            log.Fatal(err)
        }
        var myapiresource metav1.APIResource
        for _,apiresourcegroup := range(apiresourcelist) {
            if apiresourcegroup.GroupVersion == mapping.GroupVersionKind.Version {
                for _,apiresource := range(apiresourcegroup.APIResources) {
                    //fmt.Println(apiresource)

                    if apiresource.Name == mapping.Resource && apiresource.Kind == mapping.GroupVersionKind.Kind {
                        myapiresource = apiresource
                    }
                }
            }
        }
        fmt.Println(myapiresource)
        // https://github.com/kubernetes/client-go/blob/master/dynamic/client.go

        var unstruct unstructured.Unstructured
        unstruct.Object = make(map[string]interface{})
        var blob interface{}
        if err := json.Unmarshal(ext.Raw,&blob); err != nil {
            log.Fatal(err)
        }
        unstruct.Object = blob.(map[string]interface{})
        fmt.Println("unstruct:",unstruct)
        ns := "default"
        if md,ok := unstruct.Object["metadata"]; ok {
            metadata := md.(map[string]interface{})
            if internalns,ok := metadata["namespace"]; ok {
                ns = internalns.(string)
            }
        }
        res := dclient.Resource(&myapiresource,ns)
        fmt.Println(res)
        us,err := res.Create(&unstruct)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println("unstruct response:",us)


    }
}

func homeDir() string {
    if h := os.Getenv("HOME"); h != "" {
        return h
    }
    return os.Getenv("USERPROFILE") // windows
}

这篇关于client-go:将 kubernetes json 文件解析为 k8s 结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-19 12:05