dynamic创建snapshot


参考:https://www.cnblogs.com/bolingcavalry/archive/2021/09/09/15245354.html

package main

import (
	"context"
	"flag"
	"fmt"
	apiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	"path/filepath"
)

func main() {

	var kubeconfig *string

	// home是家目录,如果能取得家目录的值,就可以用来做默认值
	if home:=homedir.HomeDir(); home != "" {
		// 如果输入了kubeconfig参数,该参数的值就是kubeconfig文件的绝对路径,
		// 如果没有输入kubeconfig参数,就用默认路径~/.kube/config
		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
	} else {
		// 如果取不到当前用户的家目录,就没办法设置kubeconfig的默认目录了,只能从入参中取
		kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
	}

	flag.Parse()

	// 从本机加载kubeconfig配置文件,因此第一个参数为空字符串
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)

	// kubeconfig加载失败就直接退出了
	if err != nil {
		panic(err.Error())
	}

	dynamicClient, err := dynamic.NewForConfig(config)

	if err != nil {
		panic(err.Error())
	}

	// dynamicClient的唯一关联方法所需的入参
	gvr := schema.GroupVersionResource{Version: "v1", Resource: "pods"}

	// 使用dynamicClient的查询列表方法,查询指定namespace下的所有pod,
	// 注意此方法返回的数据结构类型是UnstructuredList
	unstructObj, err := dynamicClient.
		Resource(gvr).
		Namespace("kube-system").
		List(context.TODO(), metav1.ListOptions{Limit: 100})

	if err != nil {
		panic(err.Error())
	}

	// 实例化一个PodList数据结构,用于接收从unstructObj转换后的结果
	podList := &apiv1.PodList{}

	// 转换
	err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.UnstructuredContent(), podList)

	if err != nil {
		panic(err.Error())
	}

        // 
      	snapshot := snapV1.VolumeSnapshot{
		TypeMeta: metav1.TypeMeta{
			Kind:       "VolumeSnapshot",
			APIVersion: "snapshot.storage.k8s.io/v1beta1",
		},
		ObjectMeta: metav1.ObjectMeta{
			Namespace:   ns,
			Name:       name + "-" + timeFormat,
			Annotations: annotations,
		},
		Spec: snapV1.VolumeSnapshotSpec{
			Source:                  snapV1.VolumeSnapshotSource{
				PersistentVolumeClaimName: &name,
				//VolumeSnapshotContentName
			},
			VolumeSnapshotClassName: &snapClass,
		},
	}
        	log.Infof("%s/%s: creating snapshot for PVC %s", snapshot.ObjectMeta.Namespace, snapshot.ObjectMeta.Name, name)
	marshaled, err := json.Marshal(snapshot)
	if err != nil {
		return err
	}
	unst := unstructured.Unstructured{
		Object: map[string]interface{}{},
	}
	err = json.Unmarshal(marshaled, &unst.Object)
	if err != nil {
		return err
	}

	_, err = c.DynaClient.Resource(volumesnapshotRes).Namespace(ns).Create(context.TODO(), &unst, metav1.CreateOptions{})
	if err != nil {
		log.Errorf("req get err:%v", err)
		return fmt.Errorf("req get err:%v", err)
	}
}
}

func (c *K8sClientSet)ListVolSnap(ns string)(*snapV1.VolumeSnapshotList, error){
	volumesnapshotRes := schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1beta1",
		Resource: "volumesnapshots"}
	unst, err := c.DynaClient.Resource(volumesnapshotRes).Namespace(ns).List(context.TODO(), metav1.ListOptions{}) //Limit: 2000
	if err != nil {
		log.Errorf("list ns %s snap get err %v", ns, err)
		return nil, fmt.Errorf("list ns %s snap get err %v", ns, err)
	}
	snapList := &snapV1.VolumeSnapshotList{}
	err = runtime.DefaultUnstructuredConverter.FromUnstructured(unst.UnstructuredContent(), snapList)
	if err != nil {
		log.Errorf("revert snapList get err %v", err)
		return nil, fmt.Errorf("revert snapList get err %v", err)
	}
	return snapList, nil
}

posted @ 2022-03-01 20:15  nanaindi  阅读(36)  评论(0编辑  收藏  举报