目录

将yaml字符串或json字符串转换为k8s内的结构体

Yml格式字符串转k8s对象

方式1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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进行转换,建议使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
例如:
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对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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文本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
需求,使用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,转换结果如下:

http://xieys.club/images/posts/image-20210729114844551.png

将obj转json后再转yaml,转换结果如下

http://xieys.club/images/posts/image-20210729115138775.png