截止昨天,我们可以使用gin框架创建一个简单的web项目,实现通过访问根路径实现页面展示hello world消息。那么像昨天创建的简单项目肯定不能满足我们的调用k8s集群信息功能页面的设计需求,所以今天再接着来开发。
首先,也和vue框架一样,我们首先得设计好路由规则,其实就是你的接口功能以及地址是什么,这路由就是一个导航图,根据想要的功能带你到对应的界面,所以一般都是先设计路由规则,当然这是一般情况。如果你是不想当一般人的话,你也可以先设计功能,实现功能后再设计路由也不是不可以。在gin框架中,路由就是通过将收到的请求和处理函数关联起来,简单讲,就是用户发送请求,服务器可以寻找到能处理该请求的程序并执行。
Gin框架的路由主要有两部分,一个是请求的http方法、一个是对应的url地址,http方法就是常见的get、post、delete、update等等,url就是定义了处理函数对应的请求路径。
知道了以上知识,那么再来说说一般的go项目目录是什么样的,如下所示:
代码语言:javascript复制├── config # 配置文件夹
│ ├── config.yaml # 配置文件
├── controller # 控制器
│ ├── user.go # 用户控制器
├── middleware # 中间件
│ ├── auth.go # 认证中间件
├── model # 模型
│ ├── user.go # 用户模型
│ └── db.go # 数据库连接
├── router # 路由
│ ├── api_router.go # API路由
│ ├── web_router.go # Web路由
│ └── router.go # 路由入口
├── static # 静态资源
│ └── css # CSS文件夹
│ ├── style.css # 样式文件
├── templates # 模板文件夹
│ ├── index.tpl # 首页模板
│ ├── login.tpl # 登录页面模板
│ └── base.tpl # 基础模板
├── utils # 工具类
│ ├── jwt.go # JWT工具
│ └── response.go # 响应工具
├── main.go # 入口文件
├── go.mod # Go模块管理
└── README.md # 项目说明文件
再来解释一下:
config:就是主要放配置文件,不一定是yaml文件,可以根据需要,用不同格式来存储配置信息;
controller:这个主要是处理请求和返回响应,比如获取节点信息情况如何,成功或失败对应返回消息。
middleware:存放中间件代码,可以用于处理跨域请求、实现认证、权限控制、缓存等功能。
model:存放模型代码,定义了数据表结构和数据访问方法,这个这里咱们还暂时用不到。
router:存放路由代码,根据不同的HTTP请求方法和路径匹配对应的控制器方法。
static:存放静态资源文件,例如图片、样式表、JavaScript文件等。
templates:存放视图模板文件,使用模板引擎渲染生成HTML页面。
utils:存放一些常用的工具类,例如JWT工具、响应工具等。
main.go:应用程序的入口文件,初始化数据库连接、路由、中间件等。
go.mod:Go语言项目依赖管理文件。
README.md:项目说明文件,用于描述项目的背景、目的、功能、安装和运行方法等。
知道了以上这些,咱们就开始设计路由规则,可以单独拿出来初始化封装,以供包外调用。
好的,以下是一个可以被包外调用的路由规则示例:
代码语言:javascript复制package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.New()
// GET 请求示例
r.GET("/api/user/:id", getUserInfo)
// POST 请求示例
r.POST("/api/user", createUser)
// PUT 请求示例
r.PUT("/api/user/:id", updateUser)
// DELETE 请求示例
r.DELETE("/api/user/:id", deleteUser)
}
// GET 请求处理函数
func getUserInfo(c *gin.Context) {
id := c.Param("id")
// 根据 id 获取用户信息
user := getUserById(id)
c.JSON(200, gin.H{
"user": user,
})
}
// POST 请求处理函数
func createUser(c *gin.Context) {
// 获取用户信息
var user User
if err := c.BindJSON(&user); err != nil {
c.JSON(400, gin.H{"message": "请求参数有误"})
return
}
// 创建用户
createdUser := createUser(user)
c.JSON(200, gin.H{
"user": createdUser,
})
}
// PUT 请求处理函数
func updateUser(c *gin.Context) {
id := c.Param("id")
// 获取更新后的用户信息
var user User
if err := c.BindJSON(&user); err != nil {
c.JSON(400, gin.H{"message": "请求参数有误"})
return
}
// 根据 id 更新用户信息
updatedUser := updateUserById(id, user)
c.JSON(200, gin.H{
"user": updatedUser,
})
}
// DELETE 请求处理函数
func deleteUser(c *gin.Context) {
id := c.Param("id")
// 根据 id 删除用户信息
deleteUserById(id)
c.JSON(200, gin.H{
"message": "用户删除成功",
})
}
// 用户信息结构体
type User struct {
Id string `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
// 根据 id 获取用户信息
func getUserById(id string) User {
// TODO: 根据 id 从数据库或其他存储方式中获取用户信息
return User{
Id: id,
Name: "张三",
Age: 18,
}
}
// 创建用户
func createUser(user User) User {
// TODO: 将用户信息保存到数据库或其他存储方式中
return user
}
// 根据 id 更新用户信息
func updateUserById(id string, newUser User) User {
// TODO: 根据 id 更新用户信息,并返回更新后的用户信息
return newUser
}
// 根据 id 删除用户信息
func deleteUserById(id string) {
// TODO: 根据 id 删除用户信息
}
在上述代码中,我们定义了四个请求方法的路由规则,并分别用不同的请求处理函数来处理不同的业务逻辑。同时,我们还定义了用户信息结构体和相关的 CRUD 方法。这样,其他包中的代码就可以 import 这个包,并调用其中定义的路由规则来实现对用户信息的 CURD 操作。
而我们要设计的是一系列关于k8s信息的路由接口,所以可以单独提出来,然后在包外调用即可。
可以在main.go中全局注册router变量,也可以在路由的配置中实例化路由,设置成可以包外调用,然后在main.go中调用即可,这里介绍下具体步骤。
1、在main文件中创建一个全局route变量
代码语言:javascript复制package main
import "github.com/gin-gonic/gin"
var router *gin.Engine
func main() {
router = gin.Default()
//注册路由
router.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello World",
})
})
router.Run(":8888")
}
2、在其他包定义一个函数,接受*gin.Engine类型的参数,并注册路由
代码语言:javascript复制package utils
import "github.com/gin-gonic/gin"
func RegisterRoutes(r *gin.Engine) {
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
}
然后在mian文件中调用注册路由函数,传入全局router变量
代码语言:javascript复制package main
import (
"your-package/utils"
"github.com/gin-gonic/gin"
)
var router *gin.Engine
func main() {
router = gin.Default()
//注册路由
router.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello World",
})
})
//调用其他包中的函数,注册路由
utils.RegisterRoutes(router)
router.Run(":8888")
}
我们来看看,是否实现:
下面我们就可以设计调用k8s pods的接口:
例如:
代码语言:javascript复制//node操作
GET("/api/k8s/pods", GetPods).
设计好之后,就得想那么这个接口返回k8s集群的信息,那么k8s的信息从哪获取,这里就得介绍一下在这个k8s专为Go语言设计的调用api工具client-go客户端库,这个库可以让我们与k8s的api进行交互,并执行任何必要的操作。那么直接贴代码:
1、导入必要的包
代码语言:javascript复制在main.go文件的开头,导入k8s.io/client-go/kubernetes和k8s.io/client-go/rest包。
import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
2、建立与Kubernetes集群的连接
代码语言:javascript复制使用以下代码建立与Kubernetes集群的连接。
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
clientset, err :=
kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
这将建立一个clientset对象,它可以用于与Kubernetes API进行通信。
3、调用Kubernetes API
现在,您可以使用clientset对象调用Kubernetes API。例如,以下代码将获取所有的Pod。
代码语言:javascript复制pods, err :=
clientset.CoreV1().Pods("").List(context.Background(),
metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
c.JSON(http.StatusOK, gin.H{"pods信息": pods.Items})
for _, pod := range pods.Items {
fmt.Printf("Pod Name: %sn", pod.Name)
}
这将获取在集群上运行的所有Pod,并将它们的名称打印到控制台输出中。
运行代码。
最后,运行main.go文件以测试代码。您可以使用以下命令执行代码:
代码语言:javascript复制go run
控制台信息:
访问locahost:8080/pods路径,不出意外这就出现pod信息了
所以说,其他的k8s相关的信息调用和这个一个道理,那么今天就算完成了调用k8s接口的功能开发,也算是完成了后端开发的第一步,后面就能根据自己需求越来越完善。
感兴趣的朋友记得点赞关注呀!