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) }