# 将yaml字符串或json字符串转换为k8s内的结构体 ## Yml格式字符串转k8s对象 > 方式1 ``` func AddIngress(env,namespace string)(err error){ ingressJson :=` apiVersion: extensions/v1beta1 kind: Ingress metadata: name: chat-test namespace: sit annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: chat.chtwebapi.lingcb.net http: paths: - path: /chat backend: serviceName: chat-cloud-apis-chtweb-chat-server servicePort: 23503 - path: /report backend: serviceName: chat-cloud-apis-chtweb-report-server servicePort: 23506 ` //将yaml字符串转换为runtime.Object对象 s,_,err := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme). Decode([]byte(ingressJson),nil,&unstructured.Unstructured{}) //将runtime.Object对象转换为map[string]interface{}类型 ss,_ :=runtime.DefaultUnstructuredConverter.ToUnstructured(s) //定义需要转换的对象指针 var ingress = &v1beta1.Ingress{} //将map[string]interface通过runtime.DefaultUnstructuredConverter 类型转为ingress对象 err = runtime.DefaultUnstructuredConverter.FromUnstructured(ss,ingress) _ ,err = container.ItemCs[env].NetworkingV1beta1().Ingresses(namespace).Create(context.TODO(),ingress,v1.CreateOptions{}) //err = container.ItemCs[env].RESTClient().Post().Namespace(namespace).Resource("ingresses").Body(s).Do(context.TODO()).Error() fmt.Println(err) return err } ``` > 方式2 直接将yaml转换为json然后再转换,然后直接json.Unmarshal进行转换,建议使用 ``` 例如: func main() { var kubeconfig *string // home是家目录,如果能取到家目录的值,就可以用来做默认值 if home := homeDir();home != ""{ // 如果输入了kubeconfig参数,该参数的值就是kubeconfig文件的路径, // 如果没有输入kubeconfig参数,就用默认路径 ~/.kube/config kubeconfig = flag.String("kubeconfig",filepath.Join(home,".kube","config"),"(optional) path to the kubeconfig file") }else{ //如果取不到当前用户的家目录,就没有办法设置kubeconfig的默认目录了,只能从入参中取 kubeconfig = flag.String("kubeconfig","","(optional) path to the kubeconfig file") } flag.Parse() // 从本机加载kubeconfig配置文件,因此第一个参数为空字符串 config, err := clientcmd.BuildConfigFromFlags("",*kubeconfig) // kubeconfig 加载失败就直接退出 if err != nil{ fmt.Println("load kubeconfig failed!,err:",err) panic(err.Error()) } //实例化clientset对象 clientset,err := kubernetes.NewForConfig(config) if err != nil{ fmt.Println("init clientset failed!err:",err) panic(err.Error()) } //将yaml转换为json然后用json转换到deploy对象 js,err := yaml2.YAMLToJSON([]byte(yml)) var deploy *v1.Deployment err = json.Unmarshal(js,&deploy) clientset.AppsV1().Deployments("default").Create(context.TODO(),deploy,v12.CreateOptions{}) } ``` ## Json格式字符串转换为k8s对象 ``` func AddIngress(env,namespace string)(err error){ ingressJson :=` { "apiVersion": "extensions/v1beta1", "kind": "Ingress", "metadata": { "annotations": { "kubernetes.io/ingress.class": "nginx" }, "name": "chat-test", "namespace": "sit" }, "spec": { "rules": [ { "host": "chat.chtwebapi.lingcb.net", "http": { "paths": [ { "backend": { "serviceName": "chat-cloud-apis-chtweb-chat-server", "servicePort": 23503 }, "path": "/chat" }, { "backend": { "serviceName": "chat-cloud-apis-chtweb-report-server", "servicePort": 23506 }, "path": "/report" } ] } } ] } } ` var ingress = &v1beta1.Ingress{} json.Unmarshal([]byte(ingressJson),ingress) fmt.Printf("%T\n",ingress) _ ,err = container.ItemCs[env].NetworkingV1beta1().Ingresses(namespace).Create(context.TODO(),ingress,v1.CreateOptions{}) return err } ``` ## k8s对象转为yaml文本 ``` 需求,使用client-go创建对象后,保留一份可用的yaml文档放本地 例如: //container.ItemCs[dstEnv]为clientSet对象 result,err := container.ItemCs[dstEnv].AppsV1().Deployments(dstNs).Patch(context.TODO(),name,types.JSONPatchType,patchData,metav1.PatchOptions{}) //这里patch更新后返回一个更新后的对象和error //将更新后的对象先转json,然后再用json转yaml(注意如果直接将对象转换yaml,转换出来的不会是预期的格式,格式会如下图所示) resJson,_ := json.Marshal(result) yml,err = yaml.JSONToYAML(resJson) //创建写入文件 ymlName := fmt.Sprintf("%s.yml",srcObj.Name) f,_ := os.Create(filepath.Join(deployPath,ymlName)) defer f.Close() //由于返回对象中不会有gvk的信息,所以这里可以将jvk信息提前写入文件,然后再写入转换后的文件, f.WriteString("apiVersion: extensions/v1beta1\n") f.WriteString("kind: Deployment\n") _,_ = f.WriteString(string(yml)) ``` 直接把obj转换为yaml,转换结果如下: ![image-20210729114844551](https://xieys.club/images/posts/image-20210729114844551.png) 将obj转json后再转yaml,转换结果如下 ![image-20210729115138775](https://xieys.club/images/posts/image-20210729115138775.png)