388 lines
9.8 KiB
Go
388 lines
9.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"ezops/internal/models"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// K8sHandler K8s处理器
|
|
type K8sHandler struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewK8sHandler 创建K8s处理器
|
|
func NewK8sHandler(db *gorm.DB) *K8sHandler {
|
|
return &K8sHandler{db: db}
|
|
}
|
|
|
|
// ListClusters 获取集群列表
|
|
// @Summary 获取集群列表
|
|
// @Description 获取所有K8s集群列表
|
|
// @Tags K8s集群
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param page query int false "页码"
|
|
// @Param page_size query int false "每页数量"
|
|
// @Success 200 {object} models.Response{data=models.ListResponse}
|
|
// @Router /k8s-clusters [get]
|
|
func (h *K8sHandler) ListClusters(c *gin.Context) {
|
|
var query models.PageQuery
|
|
c.ShouldBindQuery(&query)
|
|
|
|
var total int64
|
|
h.db.Model(&models.K8sCluster{}).Count(&total)
|
|
|
|
var clusters []models.K8sCluster
|
|
h.db.Offset(query.GetOffset()).Limit(query.GetLimit()).Find(&clusters)
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "success",
|
|
Data: models.ListResponse{
|
|
List: clusters,
|
|
Total: total,
|
|
},
|
|
})
|
|
}
|
|
|
|
// GetCluster 获取集群详情
|
|
// @Summary 获取集群详情
|
|
// @Description 获取指定K8s集群的详细信息
|
|
// @Tags K8s集群
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path int true "集群ID"
|
|
// @Success 200 {object} models.Response{data=models.K8sCluster}
|
|
// @Router /k8s-clusters/{id} [get]
|
|
func (h *K8sHandler) GetCluster(c *gin.Context) {
|
|
id, _ := strconv.Atoi(c.Param("id"))
|
|
|
|
var cluster models.K8sCluster
|
|
if err := h.db.First(&cluster, id).Error; err != nil {
|
|
c.JSON(http.StatusNotFound, models.Response{
|
|
Code: 404,
|
|
Message: "集群不存在",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "success",
|
|
Data: cluster,
|
|
})
|
|
}
|
|
|
|
// CreateCluster 创建集群
|
|
// @Summary 创建集群
|
|
// @Description 创建新K8s集群
|
|
// @Tags K8s集群
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param request body models.CreateK8sClusterRequest true "创建请求"
|
|
// @Success 200 {object} models.Response{data=models.K8sCluster}
|
|
// @Router /k8s-clusters [post]
|
|
func (h *K8sHandler) CreateCluster(c *gin.Context) {
|
|
var req models.CreateK8sClusterRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, models.Response{
|
|
Code: 400,
|
|
Message: "请求参数错误: " + err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
cluster := models.K8sCluster{
|
|
Name: req.Name,
|
|
Code: req.Code,
|
|
Version: req.Version,
|
|
ConfigType: req.ConfigType,
|
|
APIServer: req.APIServer,
|
|
APIEndpoint: req.APIServer, // auto-sync
|
|
Token: req.Token,
|
|
KubeConfig: req.KubeConfig,
|
|
Description: req.Description,
|
|
Status: "healthy",
|
|
}
|
|
|
|
if err := h.db.Create(&cluster).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, models.Response{
|
|
Code: 500,
|
|
Message: "创建失败",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "创建成功",
|
|
Data: cluster,
|
|
})
|
|
}
|
|
|
|
// UpdateCluster 更新集群
|
|
// @Summary 更新集群
|
|
// @Description 更新指定K8s集群信息
|
|
// @Tags K8s集群
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path int true "集群ID"
|
|
// @Param request body models.CreateK8sClusterRequest true "更新请求"
|
|
// @Success 200 {object} models.Response{data=models.K8sCluster}
|
|
// @Router /k8s-clusters/{id} [put]
|
|
func (h *K8sHandler) UpdateCluster(c *gin.Context) {
|
|
id, _ := strconv.Atoi(c.Param("id"))
|
|
|
|
var req models.CreateK8sClusterRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, models.Response{
|
|
Code: 400,
|
|
Message: "请求参数错误: " + err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
var cluster models.K8sCluster
|
|
if err := h.db.First(&cluster, id).Error; err != nil {
|
|
c.JSON(http.StatusNotFound, models.Response{
|
|
Code: 404,
|
|
Message: "集群不存在",
|
|
})
|
|
return
|
|
}
|
|
|
|
updates := map[string]interface{}{
|
|
"name": req.Name,
|
|
"version": req.Version,
|
|
"config_type": req.ConfigType,
|
|
"api_server": req.APIServer,
|
|
"api_endpoint": req.APIServer,
|
|
"token": req.Token,
|
|
"kube_config": req.KubeConfig,
|
|
"description": req.Description,
|
|
}
|
|
|
|
if err := h.db.Model(&cluster).Updates(updates).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, models.Response{
|
|
Code: 500,
|
|
Message: "更新失败",
|
|
})
|
|
return
|
|
}
|
|
|
|
h.db.First(&cluster, id)
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "更新成功",
|
|
Data: cluster,
|
|
})
|
|
}
|
|
|
|
// DeleteCluster 删除集群
|
|
// @Summary 删除集群
|
|
// @Description 删除指定K8s集群
|
|
// @Tags K8s集群
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path int true "集群ID"
|
|
// @Success 200 {object} models.Response
|
|
// @Router /k8s-clusters/{id} [delete]
|
|
func (h *K8sHandler) DeleteCluster(c *gin.Context) {
|
|
id, _ := strconv.Atoi(c.Param("id"))
|
|
|
|
if err := h.db.Delete(&models.K8sCluster{}, id).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, models.Response{
|
|
Code: 500,
|
|
Message: "删除失败",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "删除成功",
|
|
})
|
|
}
|
|
|
|
// ListNodes 获取节点列表
|
|
// @Summary 获取节点列表
|
|
// @Description 获取指定集群的节点列表
|
|
// @Tags K8s集群
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path int true "集群ID"
|
|
// @Success 200 {object} models.Response{data=[]models.K8sNode}
|
|
// @Router /k8s-clusters/{id}/nodes [get]
|
|
func (h *K8sHandler) ListNodes(c *gin.Context) {
|
|
clusterID, _ := strconv.Atoi(c.Param("id"))
|
|
|
|
var nodes []models.K8sNode
|
|
h.db.Where("cluster_id = ?", clusterID).Find(&nodes)
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "success",
|
|
Data: nodes,
|
|
})
|
|
}
|
|
|
|
// ListPods 获取Pod列表
|
|
// @Summary 获取Pod列表
|
|
// @Description 获取指定集群的Pod列表
|
|
// @Tags K8s集群
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path int true "集群ID"
|
|
// @Param namespace query string false "命名空间"
|
|
// @Success 200 {object} models.Response{data=[]models.K8sPod}
|
|
// @Router /k8s-clusters/{id}/pods [get]
|
|
func (h *K8sHandler) ListPods(c *gin.Context) {
|
|
clusterID, _ := strconv.Atoi(c.Param("id"))
|
|
namespace := c.Query("namespace")
|
|
|
|
db := h.db.Where("cluster_id = ?", clusterID)
|
|
if namespace != "" {
|
|
db = db.Where("namespace = ?", namespace)
|
|
}
|
|
|
|
var pods []models.K8sPod
|
|
db.Find(&pods)
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "success",
|
|
Data: pods,
|
|
})
|
|
}
|
|
|
|
// ListDeployments 获取Deployment列表
|
|
// @Summary 获取Deployment列表
|
|
// @Description 获取指定集群的Deployment列表
|
|
// @Tags K8s集群
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path int true "集群ID"
|
|
// @Param namespace query string false "命名空间"
|
|
// @Success 200 {object} models.Response{data=[]models.K8sDeployment}
|
|
// @Router /k8s-clusters/{id}/deployments [get]
|
|
func (h *K8sHandler) ListDeployments(c *gin.Context) {
|
|
clusterID, _ := strconv.Atoi(c.Param("id"))
|
|
namespace := c.Query("namespace")
|
|
|
|
db := h.db.Where("cluster_id = ?", clusterID)
|
|
if namespace != "" {
|
|
db = db.Where("namespace = ?", namespace)
|
|
}
|
|
|
|
var deployments []models.K8sDeployment
|
|
db.Find(&deployments)
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "success",
|
|
Data: deployments,
|
|
})
|
|
}
|
|
|
|
// ListServices 获取Service列表
|
|
// @Summary 获取Service列表
|
|
// @Description 获取指定集群的Service列表
|
|
// @Tags K8s集群
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path int true "集群ID"
|
|
// @Param namespace query string false "命名空间"
|
|
// @Success 200 {object} models.Response{data=[]models.K8sService}
|
|
// @Router /k8s-clusters/{id}/services [get]
|
|
func (h *K8sHandler) ListServices(c *gin.Context) {
|
|
clusterID, _ := strconv.Atoi(c.Param("id"))
|
|
namespace := c.Query("namespace")
|
|
|
|
db := h.db.Where("cluster_id = ?", clusterID)
|
|
if namespace != "" {
|
|
db = db.Where("namespace = ?", namespace)
|
|
}
|
|
|
|
var services []models.K8sService
|
|
db.Find(&services)
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "success",
|
|
Data: services,
|
|
})
|
|
}
|
|
|
|
// ListIngresses 获取Ingress列表
|
|
// @Summary 获取Ingress列表
|
|
// @Description 获取指定集群的Ingress列表
|
|
// @Tags K8s集群
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path int true "集群ID"
|
|
// @Param namespace query string false "命名空间"
|
|
// @Success 200 {object} models.Response{data=[]models.K8sIngress}
|
|
// @Router /k8s-clusters/{id}/ingresses [get]
|
|
func (h *K8sHandler) ListIngresses(c *gin.Context) {
|
|
clusterID, _ := strconv.Atoi(c.Param("id"))
|
|
namespace := c.Query("namespace")
|
|
|
|
db := h.db.Where("cluster_id = ?", clusterID)
|
|
if namespace != "" {
|
|
db = db.Where("namespace = ?", namespace)
|
|
}
|
|
|
|
var ingresses []models.K8sIngress
|
|
db.Find(&ingresses)
|
|
|
|
c.JSON(http.StatusOK, models.Response{
|
|
Code: 200,
|
|
Message: "success",
|
|
Data: ingresses,
|
|
})
|
|
}
|
|
|
|
// GetTopology 获取集群拓扑布局 // Logan.Li
|
|
func (h *K8sHandler) GetTopology(c *gin.Context) {
|
|
clusterID := c.Param("id")
|
|
var layout models.TopologyLayout
|
|
result := h.db.Where("cluster_id = ?", clusterID).First(&layout)
|
|
if result.Error != nil {
|
|
c.JSON(http.StatusOK, models.Response{Code: 200, Data: &models.TopologyLayout{}})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, models.Response{Code: 200, Data: layout})
|
|
}
|
|
|
|
// SaveTopology 保存集群拓扑布局 // Logan.Li
|
|
func (h *K8sHandler) SaveTopology(c *gin.Context) {
|
|
clusterID, _ := strconv.Atoi(c.Param("id"))
|
|
var req struct {
|
|
LayoutData string `json:"layout_data"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "参数错误"})
|
|
return
|
|
}
|
|
|
|
var layout models.TopologyLayout
|
|
h.db.Where("cluster_id = ?", clusterID).First(&layout)
|
|
layout.ClusterID = uint(clusterID)
|
|
layout.LayoutData = req.LayoutData
|
|
if layout.ID == 0 {
|
|
h.db.Create(&layout)
|
|
} else {
|
|
h.db.Save(&layout)
|
|
}
|
|
|
|
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "保存成功"})
|
|
}
|