Files
aiops/backend/internal/api/handlers/k8s.go
T

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: "保存成功"})
}