文章目录
- 简介
- 一.k8s读取pvc列表
- 1.1.controllers控制器代码
- 1.2.models模型代码
- 二.k8s读取pv列表
- 2.1.controllers控制器代码
- 2.2.models模分代码
- 三.k8s读取storageclass列表
- 3.1.controllers控制器代码
- 3.2.models模型代码
- 四.路由设置
- 4.1.路由设置
- 五.前端代码
- 5.1.pvc列表的html代码
- 5.2.pv列表的html代码
- 5.3.storageclass列表的html代码
- 六.完整代码
- 6.1.控制器storage.go的完整代码
- 6.2.模型storageModel.go的完整代码
- 七.效果图
简介
本章节主要讲解通过client-go实现读取pvc的列表、pv的列表、storageclass的列表,并通过前端html页面进行展示,其中包含控制器这部分的代码,模型这部分代码,以及前端的html代码。
一.k8s读取pvc列表
1.1.controllers控制器代码
通过传递集群id、命名空间、pvc名称、标签来进行过滤,并调用模型代码中PersistentVolumeClaimList函数来读取列表
func (this *StorageController) PvcList() {clusterId := this.GetString("clusterId")nameSpace := this.GetString("nameSpace")pvcName := this.GetString("pvcName") //pvc名称labels := this.GetString("labels")labelsKV := strings.Split(labels, ":")var labelsKey, labelsValue stringif len(labelsKV) == 2 {labelsKey = labelsKV[0]labelsValue = labelsKV[1]}//读取pvc列表pvcList, err := m.PersistentVolumeClaimList(clusterId, nameSpace, pvcName, labelsKey, labelsValue)msg := "success"code := 0count := len(pvcList)if err != nil {log.Println(err)msg = err.Error()code = -1}this.Data["json"] = &map[string]interface{}{"code": code, "msg": msg, "count": count, "data": &pvcList}this.ServeJSON()
}
1.2.models模型代码
先定义一个结构体PersistentVolumeClaim,然后定义一个结构体数组
var bbb = make([]PersistentVolumeClaim, 0)
,并循环读取Items中的数据并赋值到结构体,然后再追加到数组中bbb
中。
type PersistentVolumeClaim struct {PvcName string `json:"pvcName"`NameSpace string `json:"nameSpace"`Capacity string `json:"capacity"` //容量AccessMode string `json:"accessMode"` //访问模式StorageClass string `json:"storageClass"` //存储类型Status string `json:"status"` //状态VolumeName string `json:"volumeName"` //关联存储卷Labels string `json:"labels"`Annotations string `json:"annotations"` //注解CreateTime string `json:"createTime"`
}func PersistentVolumeClaimList(kubeconfig, namespace, pvcName, labelsKey, labelsValue string) ([]PersistentVolumeClaim, error) {clientset := common.ClientSet(kubeconfig)if namespace == "" {//namespace = corev1.NamespaceDefaultnamespace = corev1.NamespaceAll}//设置ListOptionsvar listOptions = metav1.ListOptions{}if labelsKey != "" && labelsValue != "" {listOptions = metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", labelsKey, labelsValue),}}//通过api读取pvc列表pvcList, err := clientset.CoreV1().PersistentVolumeClaims(namespace).List(context.TODO(), listOptions)if err != nil {log.Printf("list deployment error, err:%v\n", err)}var bbb = make([]PersistentVolumeClaim, 0)for _, pvc := range pvcList.Items {//根据pvc名称过滤if pvcName != "" {if !strings.Contains(pvc.Name, pvcName) {continue}}var labelsStr stringfor kk, vv := range pvc.Labels {labelsStr += fmt.Sprintf("%s:%s,", kk, vv)}var annotationsStr stringfor k2, v2 := range pvc.Annotations {annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)}var accessModeStr stringfor _, v3 := range pvc.Spec.AccessModes {accessModeStr += fmt.Sprintf("%s", v3)}//赋值到结构体Items := &PersistentVolumeClaim{PvcName: pvc.Name,NameSpace: pvc.Namespace,Capacity: pvc.Status.Capacity.Storage().String(),AccessMode: accessModeStr,StorageClass: *pvc.Spec.StorageClassName,Status: fmt.Sprintf("%s", pvc.Status.Phase),VolumeName: pvc.Spec.VolumeName,Labels: labelsStr,Annotations: annotationsStr,CreateTime: pvc.CreationTimestamp.Format("2006-01-02 15:04:05"),}//追加到数组bbb = append(bbb, *Items)}return bbb, err
}
二.k8s读取pv列表
2.1.controllers控制器代码
通过传递集群id,并调用模型代码中PvList函数来读取列表
func (this *StorageController) PvList() {clusterId := this.GetString("clusterId")List, err := m.PersistentVolumeList(clusterId)msg := "success"code := 0count := len(List)if err != nil {log.Println(err)msg = err.Error()code = -1}this.Data["json"] = &map[string]interface{}{"code": code, "msg": msg, "count": count, "data": &List}this.ServeJSON()
}
2.2.models模分代码
定义结构体PersistentVolume,在PersistentVolumeList函数中,通过
clientset.CoreV1().PersistentVolumes().List
读取pv列表,并循环赋值到结构体Items := &PersistentVolume
,并追加到结构体数组中var bbb = make([]PersistentVolume, 0)
type PersistentVolume struct {PvName string `json:"pvName"` //pv名称Capacity string `json:"capacity"` //容量AccessMode string `json:"accessMode"` //访问模式PvReclaimPolicy string `json:"pvReclaimPolicy"` //回收策略StorageClass string `json:"storageClass"` //存储类型Status string `json:"status"` //状态ClaimRef string `json:"claimRef"` //绑定存储申明Labels string `json:"labels"`Annotations string `json:"annotations"` //注解CreateTime string `json:"createTime"`
}func PersistentVolumeList(kubeconfig string) ([]PersistentVolume, error) {clientset := common.ClientSet(kubeconfig)//api读取pv列表pvList, err := clientset.CoreV1().PersistentVolumes().List(context.TODO(), metav1.ListOptions{})if err != nil {log.Printf("list deployment error, err:%v\n", err)}var bbb = make([]PersistentVolume, 0)//循环提取信息并赋值到结构体Itemsfor _, pv := range pvList.Items {var labelsStr stringfor kk, vv := range pv.Labels {labelsStr += fmt.Sprintf("%s:%s,", kk, vv)}var annotationsStr stringfor k2, v2 := range pv.Annotations {annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)}var accessModeStr stringfor _, v3 := range pv.Spec.AccessModes {accessModeStr += fmt.Sprintf("%s", v3)}Items := &PersistentVolume{PvName: pv.Name,Capacity: pv.Spec.Capacity.Storage().String(),AccessMode: accessModeStr,PvReclaimPolicy: fmt.Sprintf("%s", pv.Spec.PersistentVolumeReclaimPolicy),StorageClass: pv.Spec.StorageClassName,Status: fmt.Sprintf("%s", pv.Status.Phase),ClaimRef: fmt.Sprintf("命名空间:%s<br>名称:%s", pv.Spec.ClaimRef.Namespace, pv.Spec.ClaimRef.Name),Labels: labelsStr,Annotations: annotationsStr,CreateTime: pv.CreationTimestamp.Format("2006-01-02 15:04:05"),}//追加到数组中bbb = append(bbb, *Items)}return bbb, err
}
三.k8s读取storageclass列表
3.1.controllers控制器代码
通过传递集群id,调用StorageclassList函数来读取存储类storageclass的列表
func (this *StorageController) StorageclassList() {clusterId := this.GetString("clusterId")List, err := m.StorageclassList(clusterId)msg := "success"code := 0count := len(List)if err != nil {log.Println(err)msg = err.Error()code = -1}this.Data["json"] = &map[string]interface{}{"code": code, "msg": msg, "count": count, "data": &List}this.ServeJSON()
}
3.2.models模型代码
先定义结构体Storageclass,将控制器传递过来的集群id读取对应集群存储类数据,然后赋值到结构体,并追加到结构体数组
var bbb = make([]Storageclass, 0)
.
type Storageclass struct {StorageclassName string `json:"storageclassName"`Provisioner string `json:"provisioner"` //提供者Parameters string `json:"parameters"` //参数ReclaimPolicy string `json:"reclaimPolicy"` //回收策略Labels string `json:"labels"` //标签Annotations string `json:"annotations"` //注解CreateTime string `json:"createTime"`
}func StorageclassList(kubeconfig string) ([]Storageclass, error) {clientset := common.ClientSet(kubeconfig)storageclassList, err := clientset.StorageV1().StorageClasses().List(context.TODO(), metav1.ListOptions{})if err != nil {log.Printf("list deployment error, err:%v\n", err)}var bbb = make([]Storageclass, 0)for _, sc := range storageclassList.Items {var parms stringfor kk, vv := range sc.Parameters {parms += fmt.Sprintf("%s:%s,", kk, vv)}var labelsStr stringfor kk, vv := range sc.Labels {labelsStr += fmt.Sprintf("%s:%s,", kk, vv)}var annotationsStr stringfor k2, v2 := range sc.Annotations {annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)}Items := &Storageclass{StorageclassName: sc.Name,Provisioner: sc.Provisioner,Parameters: parms,ReclaimPolicy: fmt.Sprintf("%s", *sc.ReclaimPolicy),Labels: labelsStr,Annotations: annotationsStr,CreateTime: sc.CreationTimestamp.Format("2006-01-02 15:04:05"),}bbb = append(bbb, *Items)}return bbb, err
}
四.路由设置
4.1.路由设置
将以下代码放到routers/route.go中
//storageclassbeego.Router("/storage/v1/StorageclassList", &controllers.StorageController{}, "*:StorageclassList")//pvbeego.Router("/storage/v1/PvList", &controllers.StorageController{}, "*:PvList")//pvcbeego.Router("/storage/v1/PvcList", &controllers.StorageController{}, "*:PvcList")
五.前端代码
5.1.pvc列表的html代码
5.1 pvcList.html,放到views/front/page/xkube下
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>pvc列表</title><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><link rel="stylesheet" href="/lib/layui-v2.6.3/css/layui.css" media="all"><link rel="stylesheet" href="/css/public.css" media="all"><script type="text/javascript" src="/lib/jquery-3.4.1/jquery-3.4.1.min.js"></script><script src="/lib/layui-v2.6.3/layui.js" charset="utf-8"></script><script src="/js/xkube.js?v=1" charset="utf-8"></script><script src="/js/lay-config.js?v=1.0.4" charset="utf-8"></script><style type="text/css">.layui-table-cell {height: auto;line-height: 22px !important;text-overflow: inherit;overflow: visible;white-space: normal;}.layui-table-cell .layui-table-tool-panel li {word-break: break-word;}
</style>
</head>
<body>
<div class="layuimini-container"><div class="layuimini-main"><table class="layui-table" id="currentTableId" lay-filter="currentTableFilter"></table><script type="text/html" id="currentTableBar"><a class="layui-btn layui-btn-normal layui-btn-sm" lay-event="viewYaml">查看yaml</a></script></div>
</div>
</body>
<script type="text/html" id="tagTpl">{{# if (d.labels != "") { }}{{# layui.each(d.labels.split(','), function(index, item){ }}{{# if(index == 0) { }}<span>{{ item }}</span>{{# }else{ }}<br><span>{{ item }}</span>{{# } }} {{# }); }}{{# }else{ }}<span></span>{{# } }}
</script>
<script type="text/html" id="annotationsTpl">{{# if (d.annotations != "") { }}{{# layui.each(d.annotations.split(','), function(index, item){ }}{{# if(index == 0) { }}<span>{{ item }}</span>{{# }else{ }}<br><span>{{ item }}</span>{{# } }} {{# }); }}{{# }else{ }}<span></span>{{# } }}
</script>
<script>var clusterId = getQueryString("clusterId");
if (clusterId == null) {clusterId = getCookie("clusterId")
}layui.use(['form', 'table','miniTab'], function () {var $ = layui.jquery,form = layui.form,table = layui.table;miniTab = layui.miniTab,miniTab.listen();table.render({elem: '#currentTableId',url: '/storage/v1/PvcList?clusterId='+clusterId,toolbar: '#toolbarDemo',defaultToolbar: ['filter', 'exports', 'print', {title: '提示',layEvent: 'LAYTABLE_TIPS',icon: 'layui-icon-tips'}],parseData: function(res) { //实现加载全部数据后再分页if(this.page.curr) {result=res.data.slice(this.limit*(this.page.curr-1),this.limit*this.page.curr);}else{result=res.data.slice(0,this.limit);}return {"code": res.code,"msg":'',"count":res.count,"data":result};},cols: [[{field: 'pvcName',title: '名称', sort: true},{field: 'nameSpace',title: '命名空间', sort: true},{field: 'capacity',title: '容量', sort: true},{field: 'accessMode',title: '访问模式', sort: true},{field: 'storageClass',title: '存储类型', sort: true},{field: 'status', title: '状态', sort: true},{field: 'volumeName', title: '关联存储卷', sort: true},{field: 'annotations', title: '注解', sort: true,templet: '#annotationsTpl',hide:true},{field: 'labels', title: '标签', sort: true,templet: '#tagTpl',hide:true},{field: 'createTime',title: '创建时间'},{title: '操作', minWidth:250, toolbar: '#currentTableBar', align: "center"}]],//size:'lg',limits: [25, 50, 100],limit: 25,page: true});table.on('tool(currentTableFilter)', function (obj) {var data = obj.data;if (obj.event === 'viewYaml') {var index = layer.open({title: 'yaml',type: 2,shade: 0.2,maxmin:true,shadeClose: true,area: ['50%', '92%'],content: '/page/xkube/pvcYaml.html?clusterId='+clusterId+'&nameSpace='+data.nameSpace+'&pvcName='+data.pvcName,});$(window).on("resize", function () {layer.full(index);});return false;}});});
</script>
</html>
5.2.pv列表的html代码
5.2 pvList.html,放到views/front/page/xkube下
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>pv列表</title><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><link rel="stylesheet" href="/lib/layui-v2.6.3/css/layui.css" media="all"><link rel="stylesheet" href="/css/public.css" media="all"><script type="text/javascript" src="/lib/jquery-3.4.1/jquery-3.4.1.min.js"></script><script src="/lib/layui-v2.6.3/layui.js" charset="utf-8"></script><script src="/js/xkube.js?v=1" charset="utf-8"></script><script src="/js/lay-config.js?v=1.0.4" charset="utf-8"></script>
<style type="text/css">.layui-table-cell {height: auto;line-height: 22px !important;text-overflow: inherit;overflow: visible;white-space: normal;}.layui-table-cell .layui-table-tool-panel li {word-break: break-word;}
</style>
</head>
<body>
<div class="layuimini-container"><div class="layuimini-main"><table class="layui-table" id="currentTableId" lay-filter="currentTableFilter"></table><script type="text/html" id="currentTableBar"><a class="layui-btn layui-btn-normal layui-btn-sm" lay-event="viewYaml">查看yaml</a></script></div>
</div>
</body><script type="text/html" id="tagTpl">{{# if (d.labels != "") { }}{{# layui.each(d.labels.split(','), function(index, item){ }}{{# if(index == 0) { }}<span>{{ item }}</span>{{# }else{ }}<br><span>{{ item }}</span>{{# } }} {{# }); }}{{# }else{ }}<span></span>{{# } }}
</script>
<script type="text/html" id="annotationsTpl">{{# if (d.annotations != "") { }}{{# layui.each(d.annotations.split(','), function(index, item){ }}{{# if(index == 0) { }}<span>{{ item }}</span>{{# }else{ }}<br><span>{{ item }}</span>{{# } }} {{# }); }}{{# }else{ }}<span></span>{{# } }}
</script>
<script>var clusterId = getQueryString("clusterId");
if (clusterId == null) {clusterId = getCookie("clusterId")
}layui.use(['form', 'table','miniTab'], function () {var $ = layui.jquery,form = layui.form,table = layui.table;miniTab = layui.miniTab,miniTab.listen();table.render({elem: '#currentTableId',url: '/storage/v1/PvList?clusterId='+clusterId,toolbar: '#toolbarDemo',defaultToolbar: ['filter', 'exports', 'print', {title: '提示',layEvent: 'LAYTABLE_TIPS',icon: 'layui-icon-tips'}],parseData: function(res) { //实现加载全部数据后再分页if(this.page.curr) {result=res.data.slice(this.limit*(this.page.curr-1),this.limit*this.page.curr);}else{result=res.data.slice(0,this.limit);}return {"code": res.code,"msg":'',"count":res.count,"data":result};},cols: [[//{type: "checkbox", width: 50},{field: 'pvName',title: '名称', sort: true},{field: 'capacity',title: '容量', sort: true},{field: 'accessMode', title: '访问模式', sort: true},{field: 'pvReclaimPolicy',title: '回收策略', sort: true},{field: 'storageClass', title: '存储类型', sort: true},{field: 'status',title: '状态', sort: true},{field: 'claimRef', title: '存储申明', sort: true},{field: 'annotations', title: '注解', sort: true,templet: '#annotationsTpl',hide:true},{field: 'labels', title: '标签', sort: true,templet: '#tagTpl',hide:true},{field: 'createTime', title: '创建时间'},{title: '操作', minWidth:250, toolbar: '#currentTableBar', align: "center"}]],//size:'lg',limits: [25, 50, 100],limit: 25,page: true});table.on('tool(currentTableFilter)', function (obj) {var data = obj.data;if (obj.event === 'viewYaml') {var index = layer.open({title: 'yaml',type: 2,shade: 0.2,maxmin:true,shadeClose: true,area: ['50%', '92%'],content: '/page/xkube/pvYaml.html?clusterId='+clusterId+'&pvName='+data.pvName,});$(window).on("resize", function () {layer.full(index);});return false;}});});
</script>
</html>
5.3.storageclass列表的html代码
5.3 storageclassList.html,放到views/front/page/xkube下
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>storageclass列表</title><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><link rel="stylesheet" href="/lib/layui-v2.6.3/css/layui.css" media="all"><link rel="stylesheet" href="/css/public.css" media="all"><script type="text/javascript" src="/lib/jquery-3.4.1/jquery-3.4.1.min.js"></script><script src="/lib/layui-v2.6.3/layui.js" charset="utf-8"></script><script src="/js/xkube.js?v=1" charset="utf-8"></script><script src="/js/lay-config.js?v=1.0.4" charset="utf-8"></script><style type="text/css">.layui-table-cell {height: auto;line-height: 22px !important;text-overflow: inherit;overflow: visible;white-space: normal;}.layui-table-cell .layui-table-tool-panel li {word-break: break-word;}
</style>
</head>
<body>
<div class="layuimini-container"><div class="layuimini-main"><table class="layui-table" id="currentTableId" lay-filter="currentTableFilter"></table><script type="text/html" id="currentTableBar"><a class="layui-btn layui-btn-normal layui-btn-sm" lay-event="viewYaml">查看yaml</a></script></div>
</div>
</body><script type="text/html" id="parmsTpl">{{# if (d.parameters != "") { }}{{# layui.each(d.parameters.split(','), function(index, item){ }}{{# if(index == 0) { }}<span>{{ item }}</span>{{# }else{ }}<br><span>{{ item }}</span>{{# } }} {{# }); }}{{# }else{ }}<span></span>{{# } }}
</script>
<script>var clusterId = getQueryString("clusterId");
if (clusterId == null) {clusterId = getCookie("clusterId")
}layui.use(['form', 'table','miniTab'], function () {var $ = layui.jquery,form = layui.form,table = layui.table;miniTab = layui.miniTab,miniTab.listen();table.render({elem: '#currentTableId',url: '/storage/v1/StorageclassList?clusterId='+clusterId,toolbar: '#toolbarDemo',defaultToolbar: ['filter', 'exports', 'print', {title: '提示',layEvent: 'LAYTABLE_TIPS',icon: 'layui-icon-tips'}],parseData: function(res) { //实现加载全部数据后再分页if(this.page.curr) {result=res.data.slice(this.limit*(this.page.curr-1),this.limit*this.page.curr);}else{result=res.data.slice(0,this.limit);}return {"code": res.code,"msg":'',"count":res.count,"data":result};},cols: [[//{type: "checkbox", width: 50},{field: 'storageclassName',title: '名称', sort: true},{field: 'provisioner', title: '提供者', sort: true},{field: 'parameters',title: '参数', sort: true,templet: '#parmsTpl'},{field: 'reclaimPolicy', title: '回收策略', sort: true},{field: 'createTime', title: '创建时间'},{title: '操作', minWidth:250, toolbar: '#currentTableBar', align: "center"}]],//size:'lg',limits: [25, 50, 100],limit: 25,page: true});table.on('tool(currentTableFilter)', function (obj) {var data = obj.data;if (obj.event === 'viewYaml') {var index = layer.open({title: 'yaml',type: 2,shade: 0.2,maxmin:true,shadeClose: true,area: ['50%', '92%'],content: '/page/xkube/storageclassYaml.html?clusterId='+clusterId+'&storageclassName='+data.storageclassName,});$(window).on("resize", function () {layer.full(index);});return false;}});});
</script>
</html>
六.完整代码
6.1.控制器storage.go的完整代码
6.1 storage.go,放到contrillers下
// storage.go
package controllersimport (//"encoding/json""log"//"myk8s/common"m "myk8s/models""strings"beego "github.com/beego/beego/v2/server/web""github.com/tidwall/gjson"
)type StorageController struct {beego.Controller
}func (this *StorageController) StorageclassList() {clusterId := this.GetString("clusterId")List, err := m.StorageclassList(clusterId)msg := "success"code := 0count := len(List)if err != nil {log.Println(err)msg = err.Error()code = -1}this.Data["json"] = &map[string]interface{}{"code": code, "msg": msg, "count": count, "data": &List}this.ServeJSON()
}func (this *StorageController) PvList() {clusterId := this.GetString("clusterId")List, err := m.PersistentVolumeList(clusterId)msg := "success"code := 0count := len(List)if err != nil {log.Println(err)msg = err.Error()code = -1}this.Data["json"] = &map[string]interface{}{"code": code, "msg": msg, "count": count, "data": &List}//this.Data["json"] = &datasthis.ServeJSON()
}func (this *StorageController) PvcList() {clusterId := this.GetString("clusterId")nameSpace := this.GetString("nameSpace")pvcName := this.GetString("pvcName")labels := this.GetString("labels")if this.Ctx.Input.Method() == "POST" {gp := gjson.ParseBytes(this.Ctx.Input.RequestBody)pvcName = gp.Get("pvcName").String()nameSpace = gp.Get("nameSpace").String()}labelsKV := strings.Split(labels, ":")var labelsKey, labelsValue stringif len(labelsKV) == 2 {labelsKey = labelsKV[0]labelsValue = labelsKV[1]}pvcList, err := m.PersistentVolumeClaimList(clusterId, nameSpace, pvcName, labelsKey, labelsValue)msg := "success"code := 0count := len(pvcList)if err != nil {log.Println(err)msg = err.Error()code = -1}this.Data["json"] = &map[string]interface{}{"code": code, "msg": msg, "count": count, "data": &pvcList}//this.Data["json"] = &datasthis.ServeJSON()
}
6.2.模型storageModel.go的完整代码
6.2 storageModel.go,放到models下
// storageModel.go
package modelsimport ("context""fmt""log""myk8s/common""strings"corev1 "k8s.io/api/core/v1"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"//"k8s.io/apimachinery/pkg/runtime"//"sigs.k8s.io/yaml"
)type Storageclass struct {StorageclassName string `json:"storageclassName"`Provisioner string `json:"provisioner"` //提供者Parameters string `json:"parameters"` //参数ReclaimPolicy string `json:"reclaimPolicy"` //回收策略Labels string `json:"labels"`Annotations string `json:"annotations"` //注解CreateTime string `json:"createTime"`
}type PersistentVolume struct {PvName string `json:"pvName"`Capacity string `json:"capacity"` //容量AccessMode string `json:"accessMode"` //访问模式PvReclaimPolicy string `json:"pvReclaimPolicy"` //回收策略StorageClass string `json:"storageClass"` //存储类型Status string `json:"status"` //状态ClaimRef string `json:"claimRef"` //绑定存储申明Labels string `json:"labels"`Annotations string `json:"annotations"` //注解CreateTime string `json:"createTime"`
}type PersistentVolumeClaim struct {PvcName string `json:"pvcName"`NameSpace string `json:"nameSpace"`Capacity string `json:"capacity"` //容量AccessMode string `json:"accessMode"` //访问模式StorageClass string `json:"storageClass"` //存储类型Status string `json:"status"` //状态VolumeName string `json:"volumeName"` //关联存储卷Labels string `json:"labels"`Annotations string `json:"annotations"` //注解CreateTime string `json:"createTime"`
}func StorageclassList(kubeconfig string) ([]Storageclass, error) {clientset := common.ClientSet(kubeconfig)storageclassList, err := clientset.StorageV1().StorageClasses().List(context.TODO(), metav1.ListOptions{})if err != nil {log.Printf("list deployment error, err:%v\n", err)}var bbb = make([]Storageclass, 0)for _, sc := range storageclassList.Items {var parms stringfor kk, vv := range sc.Parameters {parms += fmt.Sprintf("%s:%s,", kk, vv)}var labelsStr stringfor kk, vv := range sc.Labels {labelsStr += fmt.Sprintf("%s:%s,", kk, vv)}var annotationsStr stringfor k2, v2 := range sc.Annotations {annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)}Items := &Storageclass{StorageclassName: sc.Name,Provisioner: sc.Provisioner,Parameters: parms,ReclaimPolicy: fmt.Sprintf("%s", *sc.ReclaimPolicy),Labels: labelsStr,Annotations: annotationsStr,CreateTime: sc.CreationTimestamp.Format("2006-01-02 15:04:05"),}bbb = append(bbb, *Items)}return bbb, err
}func PersistentVolumeList(kubeconfig string) ([]PersistentVolume, error) {clientset := common.ClientSet(kubeconfig)pvList, err := clientset.CoreV1().PersistentVolumes().List(context.TODO(), metav1.ListOptions{})if err != nil {log.Printf("list deployment error, err:%v\n", err)}var bbb = make([]PersistentVolume, 0)for _, pv := range pvList.Items {var labelsStr stringfor kk, vv := range pv.Labels {labelsStr += fmt.Sprintf("%s:%s,", kk, vv)}var annotationsStr stringfor k2, v2 := range pv.Annotations {annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)}var accessModeStr stringfor _, v3 := range pv.Spec.AccessModes {accessModeStr += fmt.Sprintf("%s", v3)}Items := &PersistentVolume{PvName: pv.Name,Capacity: pv.Spec.Capacity.Storage().String(),AccessMode: accessModeStr,PvReclaimPolicy: fmt.Sprintf("%s", pv.Spec.PersistentVolumeReclaimPolicy),StorageClass: pv.Spec.StorageClassName,Status: fmt.Sprintf("%s", pv.Status.Phase),ClaimRef: fmt.Sprintf("命名空间:%s<br>名称:%s", pv.Spec.ClaimRef.Namespace, pv.Spec.ClaimRef.Name),Labels: labelsStr,Annotations: annotationsStr,CreateTime: pv.CreationTimestamp.Format("2006-01-02 15:04:05"),}bbb = append(bbb, *Items)}return bbb, err
}func PersistentVolumeClaimList(kubeconfig, namespace, pvcName, labelsKey, labelsValue string) ([]PersistentVolumeClaim, error) {clientset := common.ClientSet(kubeconfig)if namespace == "" {//namespace = corev1.NamespaceDefaultnamespace = corev1.NamespaceAll}//设置ListOptionsvar listOptions = metav1.ListOptions{}if labelsKey != "" && labelsValue != "" {listOptions = metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", labelsKey, labelsValue),}}pvcList, err := clientset.CoreV1().PersistentVolumeClaims(namespace).List(context.TODO(), listOptions)if err != nil {log.Printf("list deployment error, err:%v\n", err)}var bbb = make([]PersistentVolumeClaim, 0)for _, pvc := range pvcList.Items {//搜索if pvcName != "" {if !strings.Contains(pvc.Name, pvcName) {continue}}var labelsStr stringfor kk, vv := range pvc.Labels {labelsStr += fmt.Sprintf("%s:%s,", kk, vv)}var annotationsStr stringfor k2, v2 := range pvc.Annotations {annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)}var accessModeStr stringfor _, v3 := range pvc.Spec.AccessModes {accessModeStr += fmt.Sprintf("%s", v3)}Items := &PersistentVolumeClaim{PvcName: pvc.Name,NameSpace: pvc.Namespace,Capacity: pvc.Status.Capacity.Storage().String(),AccessMode: accessModeStr,StorageClass: *pvc.Spec.StorageClassName,Status: fmt.Sprintf("%s", pvc.Status.Phase),VolumeName: pvc.Spec.VolumeName,Labels: labelsStr,Annotations: annotationsStr,CreateTime: pvc.CreationTimestamp.Format("2006-01-02 15:04:05"),}bbb = append(bbb, *Items)}return bbb, err
}
七.效果图