参考: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
}