✨✨ 欢迎大家来到景天科技苑✨✨
🎈🎈 养成好习惯,先赞后看哦~🎈🎈
🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。所属的专栏:云原生开发
景天的主页:景天科技苑
文章目录
接口优化
观察前面我们开发的代码,我们发现,每种资源都有类似的增删改查逻辑,如果我们把这些类似的逻辑,做成统一的接口,就不用每种资源都需要写重复的代码了。
该怎么设计呢?
我们基于命名空间的struct,写增删改查方法,然后让各类资源去调用
我们使用一个接口工具来优化代码
接口工具地址:https://github.com/littlefun91/kubeutils
功能使用方法
1. 首先先安装下kubeutils
go get -u github.com/littlefun91/kubeutils
2. 使用接口改造controllers.go
创建各种资源,都可以使用这里面通用的增删改查方法
// Package controllers 控制器层,实现路由的逻辑处理package controllers
import("errors""github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/config""jingtian/krm-backend/utils/logs""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/clientcmd""net/http")// BasicInfo 定义全局的数据结构type BasicInfo struct{//使用form标签指定参数名,以便正确地绑定参数 get请求使用功能form标签
ClusterId string`json:"clusterId" form:"clusterId"`
Namespace string`json:"namespace" form:"namespace"`
Name string`json:"name" form:"name"`
Item interface{}`json:"item"`//用来接收前端传来的更新资源的json串
DeleteList []string`json:"deleteList"`//用来接收前端传来的删除资源的json串,可以删一个,也可以删多个}type Info struct{
BasicInfo
ReturnData config.ReturnData
LabelSelector string`json:"labelSelector" form:"labelSelector"`
FieldSelector string`json:"fieldSelector" form:"fieldSelector"`// 判断是否是强制删除
Force bool`json:"force" form:"force"`}// NewInfo 定义一个函数,用来返回kubeconfigfuncNewInfo(c *gin.Context, info *Info, returnDataMsg string)(kubeconfig string){// 首先获取请求的类型
requestMethod := c.Request.Method
var err error// var returnData config.ReturnData
info.ReturnData.Msg = returnDataMsg
info.ReturnData.Status =200if requestMethod =="GET"{
err = c.ShouldBindQuery(&info)}elseif requestMethod =="POST"{
err = c.ShouldBindJSON(&info)}else{
err = errors.New("不支持的请求类型")}
logs.Debug(map[string]interface{}{"info": info},"数据绑定结果")if err !=nil{
msg :="请求出错: "+ err.Error()
info.ReturnData.Msg = msg
info.ReturnData.Status =400
logs.Error(nil, msg)
c.JSON(http.StatusOK, info.ReturnData)return}// 获取kubeconfig
kubeconfig = config.ClusterKubeconfig[info.ClusterId]//我们的接口工具只需要接收个kubeconfig文件就可以实现增删改查了return kubeconfig
}// Create Info中的增删改查方法,重写kubeutils中的增删改查方法func(i *Info)Create(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){//Create里面传参是namespace
err := kubeUtilsInterface.Create(i.Namespace)if err !=nil{
msg :="创建失败: "+ err.Error()
i.ReturnData.Msg = msg
i.ReturnData.Status =400
logs.Error(nil, msg)}
c.JSON(200, i.ReturnData)}func(i *Info)Update(r *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){
err := kubeUtilsInterface.Update(i.Namespace)if err !=nil{
msg :="更新失败: "+ err.Error()
i.ReturnData.Msg = msg
i.ReturnData.Status =400
logs.Error(nil, msg)}
r.JSON(200, i.ReturnData)}func(i *Info)List(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){
items, err := kubeUtilsInterface.List(i.Namespace, i.LabelSelector, i.FieldSelector)if err !=nil{
msg :="查询失败: "+ err.Error()
i.ReturnData.Msg = msg
i.ReturnData.Status =400
logs.Error(nil, msg)}else{
i.ReturnData.Data =make(map[string]interface{})
i.ReturnData.Data["items"]= items
}
c.JSON(200, i.ReturnData)}func(i *Info)Get(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){
item, err := kubeUtilsInterface.Get(i.Namespace, i.Name)if err !=nil{
msg :="查询失败: "+ err.Error()
i.ReturnData.Msg = msg
i.ReturnData.Status =400
logs.Error(nil, msg)}else{
i.ReturnData.Data =make(map[string]interface{})
i.ReturnData.Data["item"]= item
}
c.JSON(200, i.ReturnData)}func(i *Info)Delete(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){var gracePeriodSeconds int64if i.Force {// 强制删除var s int64=0
gracePeriodSeconds = s
}
err := kubeUtilsInterface.Delete(i.Namespace, i.Name,&gracePeriodSeconds)if err !=nil{
msg :="删除失败: "+ err.Error()
i.ReturnData.Msg = msg
i.ReturnData.Status =400
logs.Error(nil, msg)}
c.JSON(200, i.ReturnData)}func(i *Info)DeleteList(c *gin.Context, kubeUtilsInterface kubeutils.KubeUtilser){var gracePeriodSeconds int64if i.Force {// 强制删除var s int64=0
gracePeriodSeconds = s
}
err := kubeUtilsInterface.DeleteList(i.Namespace, i.BasicInfo.DeleteList,&gracePeriodSeconds)if err !=nil{
msg :="删除失败: "+ err.Error()
i.ReturnData.Msg = msg
i.ReturnData.Status =400
logs.Error(nil, msg)}
c.JSON(200, i.ReturnData)}// BasicInit 这个函数用来返回通用的clientset,集群信息和errorfuncBasicInit(c *gin.Context, item interface{})(clientset *kubernetes.Clientset, basicInfo BasicInfo, err error){
basicInfo = BasicInfo{}//根据传参,来确定Item的类型,可以接收任意的资源
basicInfo.Item = item
// 首先获取请求的类型,根据不同的请求类型来使用不同的方式绑定数据
requestMethod := c.Request.Method
if requestMethod =="GET"{
err = c.ShouldBindQuery(&basicInfo)}elseif requestMethod =="POST"{
err = c.ShouldBindJSON(&basicInfo)}else{
err = errors.New("不支持的请求类型")}
logs.Debug(map[string]interface{}{"basicInfo": basicInfo},"数据绑定结果")if err !=nil{
msg :="请求出错: "+ err.Error()returnnil, basicInfo, errors.New(msg)}//如果前端不传namespace,就用默认的命名空间if basicInfo.Namespace ==""{
basicInfo.Namespace ="default"}// 获取kubeconfig
kubeconfig := config.ClusterKubeconfig[basicInfo.ClusterId]
restConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(kubeconfig))if err !=nil{
msg :="解析kubeconfig错误: "+ err.Error()returnnil, basicInfo, errors.New(msg)}//创建客户端
clientset, err = kubernetes.NewForConfig(restConfig)if err !=nil{
msg :="创建clientset失败: "+ err.Error()returnnil, basicInfo, errors.New(msg)}return clientset, basicInfo,nil}
3. 创建pod功能实现
pod/creaet.go
package pod
import("github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs"
corev1 "k8s.io/api/core/v1")// Create 创建namespace函数funcCreate(c *gin.Context){
logs.Debug(nil,"创建pod")var pod corev1.Pod
var info controllers.Info
info.Item =&pod
kubeconfig := controllers.NewInfo(c,&info,"pod创建成功")//改为接口形式的创建var kubeUtilser kubeutils.KubeUtilser
instance := kubeutils.NewPod(kubeconfig,&pod)// 把实例复制给kubeUtilser
kubeUtilser = instance
// 使用kubeUtilser创建资源
info.Create(c, kubeUtilser)}
执行创建请求
{
"clusterId":"cluster01",
"namespace":"jingtian","item":{"apiVersion":"v1","kind":"Pod","metadata":{"labels":{"app":"web6"},"name":"web6"},"spec":{"containers":[{"env":[{"name":"GIN_MODE","value":"release"},{"name":"LOG_LEVEL","value":"info"}],"image":"web:v4","imagePullPolicy":"IfNotPresent","name":"myweb","ports":[{"containerPort":8080,"protocol":"TCP"}]}]}}}
k8s集群查看,pod创建成功
4. 查询pod列表功能实现
package pod
import("github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs")funcList(c *gin.Context){
logs.Debug(nil,"列出pod列表")//声明结构体,用结构体的方法创建资源var info controllers.Info
//newInfo里面传默认的returndata.msg
kubeconfig := controllers.NewInfo(c,&info,"pod查询成功")var kubeUtilser kubeutils.KubeUtilser
instance := kubeutils.NewPod(kubeconfig,nil)// 把实例复制给kubeUtilser
kubeUtilser = instance
// 使用kubeUtilser查询资源
info.List(c, kubeUtilser)}
查询成功
5. 获取pod详情功能实现
package pod
import("github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs")funcGet(c *gin.Context){
logs.Debug(nil,"获取pod详情")//声明结构体,用结构体的方法创建资源var info controllers.Info
//newInfo里面传默认的returndata.msg
kubeconfig := controllers.NewInfo(c,&info,"pod查询详情成功")var kubeUtilser kubeutils.KubeUtilser
instance := kubeutils.NewPod(kubeconfig,nil)// 把实例复制给kubeUtilser
kubeUtilser = instance
// 使用kubeUtilser查询资源
info.Get(c, kubeUtilser)}
postman请求
6. 更新pod功能
一般,工作中我们也很少去更新pod。暂时不支持更新pod操作,响应给前端。
package pod
import("github.com/gin-gonic/gin""jingtian/krm-backend/config""jingtian/krm-backend/utils/logs")funcUpdate(c *gin.Context){
logs.Debug(nil,"更新pod")var returnData config.ReturnData
returnData.Msg ="Pod暂不支持更新操作"
returnData.Status =200
c.JSON(200, returnData)}
7. 删除单个pod和批量删除pod功能
package pod
import("github.com/gin-gonic/gin""github.com/littlefun91/kubeutils/kubeutils""jingtian/krm-backend/controllers""jingtian/krm-backend/utils/logs")// Delete 删除命名空间funcDelete(c *gin.Context){
logs.Debug(nil,"删除单个pod")//声明结构体,用结构体的方法创建资源var info controllers.Info
//newInfo里面传默认的returndata.msg
kubeconfig := controllers.NewInfo(c,&info,"pod删除成功")var kubeUtilser kubeutils.KubeUtilser
instance := kubeutils.NewPod(kubeconfig,nil)// 把实例复制给kubeUtilser
kubeUtilser = instance
// 使用kubeUtilser查询资源
info.Delete(c, kubeUtilser)}// DeleteList 批量删除funcDeleteList(c *gin.Context){
logs.Debug(nil,"批量删除pod")//声明结构体,用结构体的方法创建资源var info controllers.Info
//newInfo里面传默认的returndata.msg
kubeconfig := controllers.NewInfo(c,&info,"pod批量删除成功")var kubeUtilser kubeutils.KubeUtilser
instance := kubeutils.NewPod(kubeconfig,nil)// 把实例复制给kubeUtilser
kubeUtilser = instance
// 使用kubeUtilser查询资源
info.DeleteList(c, kubeUtilser)}
看下目前jingtian命名空间下的pod
postman执行删除单个pod
集群查看,删除单个pod成功
批量删除pod
集群查看,批量删除pod成功
版权归原作者 景天科技苑 所有, 如有侵权,请联系我们删除。