package service import ( "context" "github.com/google/uuid" "github.com/ocdp/cluster-service/internal/domain/entity" "github.com/ocdp/cluster-service/internal/domain/repository" "github.com/ocdp/cluster-service/internal/pkg/authz" ) // ClusterService 集群管理领域服务 type ClusterService struct { clusterRepo repository.ClusterRepository } // NewClusterService 创建集群服务 func NewClusterService(clusterRepo repository.ClusterRepository) *ClusterService { return &ClusterService{ clusterRepo: clusterRepo, } } // CreateCluster 创建新集群 func (s *ClusterService) CreateCluster(ctx context.Context, cluster *entity.Cluster) error { principal, err := authz.RequirePrincipal(ctx) if err != nil { return entity.ErrUnauthorized } // 生成 ID cluster.ID = uuid.New().String() cluster.OwnerID = principal.UserID cluster.WorkspaceID = principal.WorkspaceID if principal.IsAdmin() && cluster.WorkspaceID == "" { cluster.WorkspaceID = entity.DefaultWorkspaceID } if !principal.IsAdmin() && cluster.Visibility == authz.VisibilityGlobalShared { return entity.ErrForbidden } cluster.Visibility = authz.NormalizeVisibility(principal.Role, cluster.Visibility) // 验证 if err := cluster.Validate(); err != nil { return err } // 检查是否已存在 clusters, _ := s.clusterRepo.List(ctx) for _, existingCluster := range clusters { if existingCluster.Name == cluster.Name && existingCluster.WorkspaceID == cluster.WorkspaceID && existingCluster.OwnerID == cluster.OwnerID { return entity.ErrClusterExists } } return s.clusterRepo.Create(ctx, cluster) } // GetCluster 获取集群 func (s *ClusterService) GetCluster(ctx context.Context, id string) (*entity.Cluster, error) { principal, err := authz.RequirePrincipal(ctx) if err != nil { return nil, entity.ErrUnauthorized } cluster, err := s.clusterRepo.GetByID(ctx, id) if err != nil { return nil, err } if !authz.CanReadResource(principal, cluster.WorkspaceID, cluster.OwnerID, cluster.Visibility) { return nil, entity.ErrClusterNotFound } return cluster, nil } // UpdateCluster 更新集群 func (s *ClusterService) UpdateCluster(ctx context.Context, cluster *entity.Cluster) error { principal, err := authz.RequirePrincipal(ctx) if err != nil { return entity.ErrUnauthorized } // 检查是否存在 existing, err := s.clusterRepo.GetByID(ctx, cluster.ID) if err != nil { return entity.ErrClusterNotFound } if !authz.CanWriteResource(principal, existing.WorkspaceID, existing.OwnerID, existing.Visibility) { return entity.ErrForbidden } cluster.WorkspaceID = existing.WorkspaceID cluster.OwnerID = existing.OwnerID if principal.IsAdmin() { cluster.Visibility = authz.NormalizeVisibility(principal.Role, cluster.Visibility) } else { cluster.Visibility = existing.Visibility } // 验证 if err := cluster.Validate(); err != nil { return err } return s.clusterRepo.Update(ctx, cluster) } // DeleteCluster 删除集群 func (s *ClusterService) DeleteCluster(ctx context.Context, id string) error { principal, err := authz.RequirePrincipal(ctx) if err != nil { return entity.ErrUnauthorized } // 检查是否存在 cluster, err := s.clusterRepo.GetByID(ctx, id) if err != nil { return entity.ErrClusterNotFound } if !authz.CanWriteResource(principal, cluster.WorkspaceID, cluster.OwnerID, cluster.Visibility) { return entity.ErrForbidden } return s.clusterRepo.Delete(ctx, id) } // ListClusters 列出所有集群 func (s *ClusterService) ListClusters(ctx context.Context) ([]*entity.Cluster, error) { principal, err := authz.RequirePrincipal(ctx) if err != nil { return nil, entity.ErrUnauthorized } clusters, err := s.clusterRepo.List(ctx) if err != nil { return nil, err } visible := make([]*entity.Cluster, 0, len(clusters)) for _, cluster := range clusters { if authz.CanReadResource(principal, cluster.WorkspaceID, cluster.OwnerID, cluster.Visibility) { visible = append(visible, cluster) } } return visible, nil }