ocdp v1
This commit is contained in:
221
backend/internal/adapter/input/http/rest/cluster_handler.go
Normal file
221
backend/internal/adapter/input/http/rest/cluster_handler.go
Normal file
@ -0,0 +1,221 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/ocdp/cluster-service/internal/adapter/input/http/dto"
|
||||
"github.com/ocdp/cluster-service/internal/domain/entity"
|
||||
"github.com/ocdp/cluster-service/internal/domain/service"
|
||||
)
|
||||
|
||||
// ClusterHandler 集群 Handler
|
||||
type ClusterHandler struct {
|
||||
clusterService *service.ClusterService
|
||||
}
|
||||
|
||||
// NewClusterHandler 创建集群 Handler
|
||||
func NewClusterHandler(clusterService *service.ClusterService) *ClusterHandler {
|
||||
return &ClusterHandler{
|
||||
clusterService: clusterService,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateCluster 创建集群
|
||||
// @Summary 创建集群
|
||||
// @Description 创建一个新的 Kubernetes 集群配置
|
||||
// @Tags Clusters
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param request body dto.CreateClusterRequest true "集群信息"
|
||||
// @Success 201 {object} dto.ClusterResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Router /clusters [post]
|
||||
func (h *ClusterHandler) CreateCluster(w http.ResponseWriter, r *http.Request) {
|
||||
var req dto.CreateClusterRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
respondError(w, http.StatusBadRequest, "Invalid request body", err.Error())
|
||||
return
|
||||
}
|
||||
req.Normalize()
|
||||
|
||||
// 创建实体
|
||||
cluster := entity.NewCluster(req.Name, req.Host)
|
||||
cluster.Description = req.Description
|
||||
|
||||
if req.CertData != "" && req.KeyData != "" {
|
||||
cluster.SetCertAuth(req.CAData, req.CertData, req.KeyData)
|
||||
} else if req.Token != "" {
|
||||
cluster.SetTokenAuth(req.Token)
|
||||
} else if os.Getenv("ADAPTER_MODE") == "mock" {
|
||||
// Mock 模式:如果没有提供认证信息,使用默认的 Mock 证书
|
||||
cluster.SetCertAuth(
|
||||
"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1vY2sgQ0EgQ2VydGlmaWNhdGUKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==",
|
||||
"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1vY2sgQ2xpZW50IENlcnRpZmljYXRlCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=",
|
||||
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNb2NrIFByaXZhdGUgS2V5Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t",
|
||||
)
|
||||
}
|
||||
|
||||
// 调用领域服务
|
||||
if err := h.clusterService.CreateCluster(r.Context(), cluster); err != nil {
|
||||
respondError(w, http.StatusBadRequest, "Failed to create cluster", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 返回响应
|
||||
response := h.toClusterResponse(cluster)
|
||||
respondJSON(w, http.StatusCreated, response)
|
||||
}
|
||||
|
||||
// GetCluster 获取集群详情
|
||||
// @Summary 获取集群详情
|
||||
// @Tags Clusters
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param cluster_id path string true "集群 ID"
|
||||
// @Success 200 {object} dto.ClusterResponse
|
||||
// @Failure 404 {object} dto.ErrorResponse
|
||||
// @Router /clusters/{cluster_id} [get]
|
||||
func (h *ClusterHandler) GetCluster(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
clusterID := vars["cluster_id"]
|
||||
|
||||
cluster, err := h.clusterService.GetCluster(r.Context(), clusterID)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusNotFound, "Cluster not found", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response := h.toClusterResponse(cluster)
|
||||
respondJSON(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GetAllClusters 获取所有集群
|
||||
// @Summary 列出所有集群
|
||||
// @Tags Clusters
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {array} dto.ClusterResponse
|
||||
// @Failure 500 {object} dto.ErrorResponse
|
||||
// @Router /clusters [get]
|
||||
func (h *ClusterHandler) GetAllClusters(w http.ResponseWriter, r *http.Request) {
|
||||
clusters, err := h.clusterService.ListClusters(r.Context())
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "Failed to list clusters", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
responses := make([]*dto.ClusterResponse, 0, len(clusters))
|
||||
for _, cluster := range clusters {
|
||||
responses = append(responses, h.toClusterResponse(cluster))
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, responses)
|
||||
}
|
||||
|
||||
// UpdateCluster 更新集群
|
||||
// @Summary 更新集群
|
||||
// @Tags Clusters
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param cluster_id path string true "集群 ID"
|
||||
// @Param request body dto.UpdateClusterRequest true "更新内容"
|
||||
// @Success 200 {object} dto.ClusterResponse
|
||||
// @Failure 404 {object} dto.ErrorResponse
|
||||
// @Router /clusters/{cluster_id} [put]
|
||||
func (h *ClusterHandler) UpdateCluster(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
clusterID := vars["cluster_id"]
|
||||
|
||||
var req dto.UpdateClusterRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
respondError(w, http.StatusBadRequest, "Invalid request body", err.Error())
|
||||
return
|
||||
}
|
||||
req.Normalize()
|
||||
|
||||
// 获取现有集群
|
||||
cluster, err := h.clusterService.GetCluster(r.Context(), clusterID)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusNotFound, "Cluster not found", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
cluster.Update(req.Name, req.Host, req.Description)
|
||||
|
||||
if req.CertData != "" && req.KeyData != "" {
|
||||
cluster.SetCertAuth(req.CAData, req.CertData, req.KeyData)
|
||||
} else if req.Token != "" {
|
||||
cluster.SetTokenAuth(req.Token)
|
||||
}
|
||||
|
||||
// 调用领域服务
|
||||
if err := h.clusterService.UpdateCluster(r.Context(), cluster); err != nil {
|
||||
respondError(w, http.StatusBadRequest, "Failed to update cluster", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response := h.toClusterResponse(cluster)
|
||||
respondJSON(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
// DeleteCluster 删除集群
|
||||
// @Summary 删除集群
|
||||
// @Tags Clusters
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param cluster_id path string true "集群 ID"
|
||||
// @Success 204 {string} string "No Content"
|
||||
// @Failure 404 {object} dto.ErrorResponse
|
||||
// @Router /clusters/{cluster_id} [delete]
|
||||
func (h *ClusterHandler) DeleteCluster(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
clusterID := vars["cluster_id"]
|
||||
|
||||
if err := h.clusterService.DeleteCluster(r.Context(), clusterID); err != nil {
|
||||
respondError(w, http.StatusNotFound, "Failed to delete cluster", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// GetClusterHealth 获取集群健康状态
|
||||
// @Summary 获取集群健康状态
|
||||
// @Tags Clusters
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param cluster_id path string true "集群 ID"
|
||||
// @Success 200 {object} dto.ClusterHealthResponse
|
||||
// @Failure 404 {object} dto.ErrorResponse
|
||||
// @Router /clusters/{cluster_id}/health [get]
|
||||
func (h *ClusterHandler) GetClusterHealth(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
clusterID := vars["cluster_id"]
|
||||
|
||||
// 检查集群是否存在
|
||||
_, err := h.clusterService.GetCluster(r.Context(), clusterID)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusNotFound, "Cluster not found", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 实现真实的健康检查
|
||||
response := &dto.ClusterHealthResponse{
|
||||
Healthy: true,
|
||||
Message: "Cluster is healthy",
|
||||
Version: "v1.28.0",
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
// toClusterResponse 将 Cluster 实体转换为响应 DTO(脱敏)
|
||||
func (h *ClusterHandler) toClusterResponse(cluster *entity.Cluster) *dto.ClusterResponse {
|
||||
return dto.ToClusterResponse(cluster)
|
||||
}
|
||||
Reference in New Issue
Block a user