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" ) // RegistryService Registry 管理领域服务 type RegistryService struct { registryRepo repository.RegistryRepository ociClient repository.OCIClient } // NewRegistryService 创建 Registry 服务 func NewRegistryService( registryRepo repository.RegistryRepository, ociClient repository.OCIClient, ) *RegistryService { return &RegistryService{ registryRepo: registryRepo, ociClient: ociClient, } } // CreateRegistry 创建新 Registry func (s *RegistryService) CreateRegistry(ctx context.Context, registry *entity.Registry) error { principal, err := authz.RequirePrincipal(ctx) if err != nil { return entity.ErrUnauthorized } // 生成 ID registry.ID = uuid.New().String() registry.OwnerID = principal.UserID registry.WorkspaceID = principal.WorkspaceID if principal.IsAdmin() && registry.WorkspaceID == "" { registry.WorkspaceID = entity.DefaultWorkspaceID } if !principal.IsAdmin() && registry.Visibility == authz.VisibilityGlobalShared { return entity.ErrForbidden } registry.Visibility = authz.NormalizeVisibility(principal.Role, registry.Visibility) // 验证 if err := registry.Validate(); err != nil { return err } // 检查是否已存在 registries, _ := s.registryRepo.List(ctx) for _, existingRegistry := range registries { if existingRegistry.Name == registry.Name && existingRegistry.WorkspaceID == registry.WorkspaceID && existingRegistry.OwnerID == registry.OwnerID { return entity.ErrRegistryExists } } return s.registryRepo.Create(ctx, registry) } // GetRegistry 获取 Registry func (s *RegistryService) GetRegistry(ctx context.Context, id string) (*entity.Registry, error) { principal, err := authz.RequirePrincipal(ctx) if err != nil { return nil, entity.ErrUnauthorized } registry, err := s.registryRepo.GetByID(ctx, id) if err != nil { return nil, err } if !authz.CanReadResource(principal, registry.WorkspaceID, registry.OwnerID, registry.Visibility) { return nil, entity.ErrRegistryNotFound } return registry, nil } // UpdateRegistry 更新 Registry func (s *RegistryService) UpdateRegistry(ctx context.Context, registry *entity.Registry) error { principal, err := authz.RequirePrincipal(ctx) if err != nil { return entity.ErrUnauthorized } // 检查是否存在 existing, err := s.registryRepo.GetByID(ctx, registry.ID) if err != nil { return entity.ErrRegistryNotFound } if !authz.CanWriteResource(principal, existing.WorkspaceID, existing.OwnerID, existing.Visibility) { return entity.ErrForbidden } registry.WorkspaceID = existing.WorkspaceID registry.OwnerID = existing.OwnerID if principal.IsAdmin() { registry.Visibility = authz.NormalizeVisibility(principal.Role, registry.Visibility) } else { registry.Visibility = existing.Visibility } // 验证 if err := registry.Validate(); err != nil { return err } return s.registryRepo.Update(ctx, registry) } // DeleteRegistry 删除 Registry func (s *RegistryService) DeleteRegistry(ctx context.Context, id string) error { principal, err := authz.RequirePrincipal(ctx) if err != nil { return entity.ErrUnauthorized } // 检查是否存在 registry, err := s.registryRepo.GetByID(ctx, id) if err != nil { return entity.ErrRegistryNotFound } if !authz.CanWriteResource(principal, registry.WorkspaceID, registry.OwnerID, registry.Visibility) { return entity.ErrForbidden } return s.registryRepo.Delete(ctx, id) } // ListRegistries 列出所有 Registries func (s *RegistryService) ListRegistries(ctx context.Context) ([]*entity.Registry, error) { principal, err := authz.RequirePrincipal(ctx) if err != nil { return nil, entity.ErrUnauthorized } registries, err := s.registryRepo.List(ctx) if err != nil { return nil, err } visible := make([]*entity.Registry, 0, len(registries)) for _, registry := range registries { if authz.CanReadResource(principal, registry.WorkspaceID, registry.OwnerID, registry.Visibility) { visible = append(visible, registry) } } return visible, nil } // CheckHealth 检查 Registry 健康状态 func (s *RegistryService) CheckHealth(ctx context.Context, id string) error { registry, err := s.GetRegistry(ctx, id) if err != nil { return entity.ErrRegistryNotFound } return s.ociClient.CheckHealth(ctx, registry) }