feat(frontend): add Helm chart browser, monitoring, chart-references and values templates pages
Add new frontend pages for the multi-tenant OCDP platform: - Charts page (/charts): Browse Harbor OCI registries to list Helm chart repositories and versions, with deploy modal to launch charts on selected clusters - Monitoring page (/monitoring): Display cluster metrics (CPU/Memory/GPU usage) and per-node details with resource utilization bars - Chart References page (/chart-references): CRUD for chart metadata references - Values Templates page (/templates): CRUD for Helm values templates with version history and rollback support - Sidebar: Add Charts navigation, update Storage and Templates links - api.ts: Add all API client functions (clusterApi, registryApi, instanceApi, monitoringApi, storageApi, chartReferenceApi, valuesTemplateApi, workspaceApi, userApi) with full TypeScript types Note: deploy flow and values template rollback not yet end-to-end tested.
This commit is contained in:
143
backend/internal/domain/service/values_template_service.go
Normal file
143
backend/internal/domain/service/values_template_service.go
Normal file
@ -0,0 +1,143 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/ocdp/cluster-service/internal/domain/entity"
|
||||
"github.com/ocdp/cluster-service/internal/domain/repository"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrTemplateNotFound = errors.New("template not found")
|
||||
ErrTemplateExists = errors.New("template already exists")
|
||||
)
|
||||
|
||||
// ValuesTemplateService Values 模板领域服务
|
||||
type ValuesTemplateService struct {
|
||||
valuesTemplateRepo repository.ValuesTemplateRepository
|
||||
chartRefRepo repository.ChartReferenceRepository
|
||||
}
|
||||
|
||||
// NewValuesTemplateService 创建 Values 模板服务
|
||||
func NewValuesTemplateService(
|
||||
valuesTemplateRepo repository.ValuesTemplateRepository,
|
||||
chartRefRepo repository.ChartReferenceRepository,
|
||||
) *ValuesTemplateService {
|
||||
return &ValuesTemplateService{
|
||||
valuesTemplateRepo: valuesTemplateRepo,
|
||||
chartRefRepo: chartRefRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// Create 创建 Values 模板
|
||||
func (s *ValuesTemplateService) Create(
|
||||
ctx context.Context,
|
||||
workspaceID, ownerID, chartRefID, name, description, valuesYAML string,
|
||||
isDefault bool,
|
||||
) (*entity.ValuesTemplate, error) {
|
||||
// 检查 Chart Reference 是否存在
|
||||
chartRef, err := s.chartRefRepo.GetByID(ctx, chartRefID)
|
||||
if err != nil {
|
||||
return nil, errors.New("chart reference not found")
|
||||
}
|
||||
|
||||
// 检查名称是否已存在
|
||||
existing, _ := s.valuesTemplateRepo.GetByName(ctx, workspaceID, chartRefID, name)
|
||||
if existing != nil {
|
||||
return nil, ErrTemplateExists
|
||||
}
|
||||
|
||||
template := entity.NewValuesTemplate(workspaceID, ownerID, chartRef.ID, name, valuesYAML)
|
||||
template.Description = description
|
||||
template.IsDefault = isDefault
|
||||
|
||||
if err := s.valuesTemplateRepo.Create(ctx, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return template, nil
|
||||
}
|
||||
|
||||
// GetByID 获取 Values 模板
|
||||
func (s *ValuesTemplateService) GetByID(ctx context.Context, id string) (*entity.ValuesTemplate, error) {
|
||||
template, err := s.valuesTemplateRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, ErrTemplateNotFound
|
||||
}
|
||||
return template, nil
|
||||
}
|
||||
|
||||
// GetByWorkspace 获取工作空间的所有 Values 模板
|
||||
func (s *ValuesTemplateService) GetByWorkspace(ctx context.Context, workspaceID string) ([]*entity.ValuesTemplate, error) {
|
||||
return s.valuesTemplateRepo.GetByWorkspace(ctx, workspaceID)
|
||||
}
|
||||
|
||||
// GetByChartReference 获取 Chart Reference 的所有 Values 模板
|
||||
func (s *ValuesTemplateService) GetByChartReference(ctx context.Context, chartRefID string) ([]*entity.ValuesTemplate, error) {
|
||||
return s.valuesTemplateRepo.GetByChartReference(ctx, chartRefID)
|
||||
}
|
||||
|
||||
// GetHistory 获取模板的版本历史
|
||||
func (s *ValuesTemplateService) GetHistory(ctx context.Context, chartRefID, name string) ([]*entity.ValuesTemplate, error) {
|
||||
return s.valuesTemplateRepo.GetHistory(ctx, chartRefID, name)
|
||||
}
|
||||
|
||||
// Update 更新 Values 模板(创建新版本)
|
||||
func (s *ValuesTemplateService) Update(
|
||||
ctx context.Context,
|
||||
id, description, valuesYAML string,
|
||||
isDefault bool,
|
||||
) (*entity.ValuesTemplate, error) {
|
||||
template, err := s.valuesTemplateRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, ErrTemplateNotFound
|
||||
}
|
||||
|
||||
template.Description = description
|
||||
template.ValuesYAML = valuesYAML
|
||||
template.IsDefault = isDefault
|
||||
|
||||
if err := s.valuesTemplateRepo.Update(ctx, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取最新版本
|
||||
return s.valuesTemplateRepo.GetByName(ctx, template.WorkspaceID, template.ChartReferenceID, template.Name)
|
||||
}
|
||||
|
||||
// Delete 删除 Values 模板
|
||||
func (s *ValuesTemplateService) Delete(ctx context.Context, id string) error {
|
||||
return s.valuesTemplateRepo.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// List 列出所有 Values 模板(管理员用)
|
||||
func (s *ValuesTemplateService) List(ctx context.Context) ([]*entity.ValuesTemplate, error) {
|
||||
return s.valuesTemplateRepo.List(ctx)
|
||||
}
|
||||
|
||||
// Rollback 回滚到指定版本
|
||||
func (s *ValuesTemplateService) Rollback(ctx context.Context, templateID string) (*entity.ValuesTemplate, error) {
|
||||
// 获取历史版本模板
|
||||
oldTemplate, err := s.valuesTemplateRepo.GetByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return nil, ErrTemplateNotFound
|
||||
}
|
||||
|
||||
// 重新创建该版本(创建新版本,内容与旧版本相同)
|
||||
newTemplate := &entity.ValuesTemplate{
|
||||
WorkspaceID: oldTemplate.WorkspaceID,
|
||||
OwnerID: oldTemplate.OwnerID,
|
||||
ChartReferenceID: oldTemplate.ChartReferenceID,
|
||||
Name: oldTemplate.Name,
|
||||
Description: oldTemplate.Description,
|
||||
ValuesYAML: oldTemplate.ValuesYAML,
|
||||
}
|
||||
|
||||
if err := s.valuesTemplateRepo.Update(ctx, newTemplate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取最新版本
|
||||
return s.valuesTemplateRepo.GetByName(ctx, newTemplate.WorkspaceID, newTemplate.ChartReferenceID, newTemplate.Name)
|
||||
}
|
||||
Reference in New Issue
Block a user