K8s 管理系统项目[API部分–Pv]
1. 接口实现
service/dataselector.go
type pvCell corev1.PersistentVolume
func(p pvCell) GetCreation() time.Time {
return p.CreationTimestamp.Time
}
func(p pvCell) GetName() string {
return p.Name
}
2. Pv功能
service/pv.go
2.1 获取Pv详情
// 获取pv详情
func (p *pv) GetPvDetail(pvName string) (pv *corev1.PersistentVolume, err error) {
pv, err = K8s.ClientSet.CoreV1().PersistentVolumes().Get(context.TODO(), pvName, metav1.GetOptions{})
if err != nil {
logger.Error(errors.New("获取Pv详情失败, " + err.Error()))
return nil, errors.New("获取Pv详情失败, " + err.Error())
}
return pv, nil
}
2.2 删除Pv
// 删除pv
func (p *pv) DeletePv(pvName string) (err error) {
err = K8s.ClientSet.CoreV1().PersistentVolumes().Delete(context.TODO(), pvName, metav1.DeleteOptions{})
if err != nil {
logger.Error(errors.New("删除Pv失败, " + err.Error()))
return errors.New("删除Pv失败, " + err.Error())
}
return nil
}
2.3 pv完整
package service
import (
"context"
"errors"
"github.com/wonderivan/logger"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var Pv pv
type pv struct{}
type PvsResp struct {
Items []corev1.PersistentVolume `json:"items"`
Total int `json:"total"`
}
// 获取pv列表,支持过滤、排序、分页
func (p *pv) GetPvs(filterName string, limit, page int) (pvsResp *PvsResp, err error) {
//获取pvList类型的pv列表
pvList, err := K8s.ClientSet.CoreV1().PersistentVolumes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
logger.Error(errors.New("获取Pv列表失败, " + err.Error()))
return nil, errors.New("获取Pv列表失败, " + err.Error())
}
//将pvList中的pv列表(Items),放进dataselector对象中,进行排序
selectableData := &dataSelector{
GenericDataList: p.toCells(pvList.Items),
DataSelect: &DataSelectQuery{
Filter: &FilterQuery{Name: filterName},
Paginate: &PaginateQuery{
Limit: limit,
Page: page,
},
},
}
filtered := selectableData.Filter()
total := len(filtered.GenericDataList)
data := filtered.Sort().Paginate()
//将[]DataCell类型的pv列表转为v1.pv列表
pvs := p.fromCells(data.GenericDataList)
return &PvsResp{
Items: pvs,
Total: total,
}, nil
}
// 获取pv详情
func (p *pv) GetPvDetail(pvName string) (pv *corev1.PersistentVolume, err error) {
pv, err = K8s.ClientSet.CoreV1().PersistentVolumes().Get(context.TODO(), pvName, metav1.GetOptions{})
if err != nil {
logger.Error(errors.New("获取Pv详情失败, " + err.Error()))
return nil, errors.New("获取Pv详情失败, " + err.Error())
}
return pv, nil
}
// 删除pv
func (p *pv) DeletePv(pvName string) (err error) {
err = K8s.ClientSet.CoreV1().PersistentVolumes().Delete(context.TODO(), pvName, metav1.DeleteOptions{})
if err != nil {
logger.Error(errors.New("删除Pv失败, " + err.Error()))
return errors.New("删除Pv失败, " + err.Error())
}
return nil
}
func (p *pv) toCells(std []corev1.PersistentVolume) []DataCell {
cells := make([]DataCell, len(std))
for i := range std {
cells[i] = pvCell(std[i])
}
return cells
}
func (p *pv) fromCells(cells []DataCell) []corev1.PersistentVolume {
pvs := make([]corev1.PersistentVolume, len(cells))
for i := range cells {
pvs[i] = corev1.PersistentVolume(cells[i].(pvCell))
}
return pvs
}
3. 获取Pv列表
controller/pv.go
package controller
import (
"github.com/gin-gonic/gin"
"github.com/wonderivan/logger"
"k8s-plantform/service"
"net/http"
)
var Pv pv
type pv struct {}
//获取pv列表,支持过滤、排序、分页
func(p *pv) GetPvs(ctx *gin.Context) {
params := new(struct {
FilterName string `form:"filter_name"`
Page int `form:"page"`
Limit int `form:"limit"`
})
if err := ctx.Bind(params); err != nil {
logger.Error("Bind请求参数失败, " + err.Error())
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
"data": nil,
})
return
}
data, err := service.Pv.GetPvs(params.FilterName, params.Limit, params.Page)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
"data": nil,
})
return
}
ctx.JSON(http.StatusOK, gin.H{
"msg": "获取Pv列表成功",
"data": data,
})
}
//获取pv详情
func(p *pv) GetPvDetail(ctx *gin.Context) {
params := new(struct {
PvName string `form:"pv_name"`
})
if err := ctx.Bind(params); err != nil {
logger.Error("Bind请求参数失败, " + err.Error())
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
"data": nil,
})
return
}
data, err := service.Pv.GetPvDetail(params.PvName)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
"data": nil,
})
return
}
ctx.JSON(http.StatusOK, gin.H{
"msg": "获取Pv详情成功",
"data": data,
})
}
//删除pv
func(p *pv) DeletePv(ctx *gin.Context) {
params := new(struct{
PvName string `json:"pv_name"`
})
//DELETE请求,绑定参数方法改为ctx.ShouldBindJSON
if err := ctx.ShouldBindJSON(params); err != nil {
logger.Error("Bind请求参数失败, " + err.Error())
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
"data": nil,
})
return
}
err := service.Pv.DeletePv(params.PvName)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
"data": nil,
})
return
}
ctx.JSON(http.StatusOK, gin.H{
"msg": "删除Pv成功",
"data": nil,
})
}
4. 定义路由
controller/router.go
//pv操作
GET("/api/k8s/pvs", Pv.GetPvs).
GET("/api/k8s/pv/detail", Pv.GetPvDetail)
5. 测试Pv方法
5.1 创建PV
先创建一个pv这样方便一会测试
- 先准备一个nfs
- 测试nfs可以正常被读取
root@master-01:~# showmount -e 192.168.31.109
Export list for 192.168.31.109:
/data/k8s/wework/images *
/data/ehelp *
/data/k8s *
yaml文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Mi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.31.109
path: /data/k8s
创建pv
root@master-01:~# kubectl apply -f pv.yaml
persistentvolume/nfs-pv created
root@master-01:~# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfs-pv 10Mi RWX Retain Available 4s
5.2 获取pv
/api/k8s/pvs
5.2 获取pv详细信息
/api/k8s/pv/detail