clieng-go 实现从 yaml 创建和删除资源

将 Clientset、dynamic.Interface 、ns和文件地址传入方法即可。如何创建 Clientset、dynamic.Interface ,可以参考我另一篇文章 《kubernetes 开发之 client-go 学习》

一、创建资源

方法

import (

	"errors"
	"fmt"
	"io"
	"strconv"
	"time"
	"os"
	
	"go/ast"
	"go/token"

	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/yaml"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/restmapper"
)

func installYaml(clientSet *kubernetes.Clientset, dynamicClient dynamic.Interface, ns string, filename string) error {
	f, err := os.Open(filename)
	logrus.Info("=====================>" + filename)

	if err != nil {
		logrus.Error(err)
		return err
	}
	d := yaml.NewYAMLOrJSONDecoder(f, 4096)
	dc := clientSet.Discovery()

	restMapperRes, err := restmapper.GetAPIGroupResources(dc)
	if err != nil {
		logrus.Error(err)
		return err
	}

	restMapper := restmapper.NewDiscoveryRESTMapper(restMapperRes)

	for {
		ext := runtime.RawExtension{}

		if err := d.Decode(&ext); err != nil {
			if err == io.EOF {
				break
			}
			logrus.Fatal(err)
		}

		// runtime.Object
		obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(ext.Raw, nil, nil)
		if err != nil {
			logrus.Error(err)
			return err
		}

		mapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version)
		fmt.Printf("mapping:%+v\n", mapping)
		if err != nil {
			logrus.Error(err)
			return err
		}

		// runtime.Object转换为unstructed
		unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
		if err != nil {
			logrus.Error(err)
			return err
		}
		// fmt.Printf("unstructuredObj: %+v", unstructuredObj)

		var unstruct unstructured.Unstructured

		unstruct.Object = unstructuredObj

		if ns == "" {
			res, err := dynamicClient.Resource(mapping.Resource).Create(&unstruct, metav1.CreateOptions{})
			if err != nil {
				logrus.Error(err)
				return err
			}

			GuessType(res)
		} else {
			res, err := dynamicClient.Resource(mapping.Resource).Namespace(ns).Create(&unstruct, metav1.CreateOptions{})
			if err != nil {
				logrus.Error(err)
				return err
			}
			GuessType(res)
		}

	}

	return nil
}

func GuessType(obj interface{}) {
	fset := token.NewFileSet()
	ast.Print(fset, obj)
}

使用

	pwd, _ := os.Getwd()
	if pwd != "" {
		pwd = pwd + "/"
	}
	
	err := installYaml(clientSet, dynamicClient, "", pwd+"abcdef.yaml")
	if err != nil {
		return err
	}

二、删除资源

与创建资源基本相同,不同的是我们传入 dynamic client 内的数据不是yaml信息,而是资源名,所以要从yaml文件中解析资源名。

方法

func uninstallYaml(clientSet *kubernetes.Clientset, dynamicClient dynamic.Interface, ns string, filename string) error {
	f, err := os.Open(filename)

	if err != nil {
		logrus.Error(err)
		return err
	}
	d := yaml.NewYAMLOrJSONDecoder(f, 4096)
	dc := clientSet.Discovery()

	restMapperRes, err := restmapper.GetAPIGroupResources(dc)
	if err != nil {
		logrus.Error(err)
		return err
	}

	restMapper := restmapper.NewDiscoveryRESTMapper(restMapperRes)

	for {
		ext := runtime.RawExtension{}

		if err := d.Decode(&ext); err != nil {
			if err == io.EOF {
				break
			}
			logrus.Fatal(err)
		}

		// runtime.Object
		obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(ext.Raw, nil, nil)
		if err != nil {
			logrus.Error(err)
			return err
		}

		mapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version)
		// fmt.Printf("mapping:%+v\n", mapping)
		if err != nil {
			logrus.Error(err)
			return err
		}

		// runtime.Object转换为unstructed
		unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
		if err != nil {
			logrus.Error(err)
			return err
		}
		// fmt.Printf("unstructuredObj: %+v", unstructuredObj)

		var unstruct unstructured.Unstructured

		unstruct.Object = unstructuredObj

		tmpMetadata := unstructuredObj["metadata"].(map[string]interface{})
		tmpName := tmpMetadata["name"].(string)
		tmpKind := unstructuredObj["kind"].(string)
		logrus.Info("deleting resource name: " + tmpName + ", kind: " + tmpKind + ", ns: " + ns)

		if ns == "" {
			err := dynamicClient.Resource(mapping.Resource).Delete(tmpName, &metav1.DeleteOptions{})
			if err != nil {
				logrus.Error(err)
				return err
			}
		} else {
			err := dynamicClient.Resource(mapping.Resource).Namespace(ns).Delete(tmpName, &metav1.DeleteOptions{})
			if err != nil {
				logrus.Error(err)
				return err
			}
		}

	}

	return nil
}

使用

	uninstallYaml(clientSet, dynamicClient, "", "abcdef.yaml")

参考资料


linux 查找最近修改的文件 论十大关系