【k8s多集群管理平台开发实践】十、client-go实现读取pvc列表、pv列表、storageclass列表
本章节主要讲解通过client-go实现读取pvc的列表、pv的列表、storageclass的列表,并通过前端html页面进行展示,其中包含控制器这部分的代码,模型这部分代码,以及前端的html代码。
文章目录
简介
本章节主要讲解通过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 string
if len(labelsKV) == 2 {
labelsKey = labelsKV[0]
labelsValue = labelsKV[1]
}
//读取pvc列表
pvcList, err := m.PersistentVolumeClaimList(clusterId, nameSpace, pvcName, labelsKey, labelsValue)
msg := "success"
code := 0
count := 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.NamespaceDefault
namespace = corev1.NamespaceAll
}
//设置ListOptions
var 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 string
for kk, vv := range pvc.Labels {
labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
}
var annotationsStr string
for k2, v2 := range pvc.Annotations {
annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)
}
var accessModeStr string
for _, 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 := 0
count := 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)
//循环提取信息并赋值到结构体Items
for _, pv := range pvList.Items {
var labelsStr string
for kk, vv := range pv.Labels {
labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
}
var annotationsStr string
for k2, v2 := range pv.Annotations {
annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)
}
var accessModeStr string
for _, 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 := 0
count := 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 string
for kk, vv := range sc.Parameters {
parms += fmt.Sprintf("%s:%s,", kk, vv)
}
var labelsStr string
for kk, vv := range sc.Labels {
labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
}
var annotationsStr string
for 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中
//storageclass
beego.Router("/storage/v1/StorageclassList", &controllers.StorageController{}, "*:StorageclassList")
//pv
beego.Router("/storage/v1/PvList", &controllers.StorageController{}, "*:PvList")
//pvc
beego.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 controllers
import (
//"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 := 0
count := 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 := 0
count := 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"] = &datas
this.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 string
if len(labelsKV) == 2 {
labelsKey = labelsKV[0]
labelsValue = labelsKV[1]
}
pvcList, err := m.PersistentVolumeClaimList(clusterId, nameSpace, pvcName, labelsKey, labelsValue)
msg := "success"
code := 0
count := 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"] = &datas
this.ServeJSON()
}
6.2.模型storageModel.go的完整代码
6.2 storageModel.go,放到models下
// storageModel.go
package models
import (
"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 string
for kk, vv := range sc.Parameters {
parms += fmt.Sprintf("%s:%s,", kk, vv)
}
var labelsStr string
for kk, vv := range sc.Labels {
labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
}
var annotationsStr string
for 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 string
for kk, vv := range pv.Labels {
labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
}
var annotationsStr string
for k2, v2 := range pv.Annotations {
annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)
}
var accessModeStr string
for _, 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.NamespaceDefault
namespace = corev1.NamespaceAll
}
//设置ListOptions
var 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 string
for kk, vv := range pvc.Labels {
labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
}
var annotationsStr string
for k2, v2 := range pvc.Annotations {
annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)
}
var accessModeStr string
for _, 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
}
七.效果图
更多推荐
所有评论(0)