refactor: full-stack restructure with multi-tenancy, workspace management, and K8s diagnostics

- Add Workspace domain (entity, repository, service, handler, DTO)
- Add multi-tenant K8s client with tenant binding and quota management
- Add K8s diagnostics client (instance diagnostics)
- Add authorization middleware (authz package)
- Restructure frontend to feature-based architecture (features/)
- Add User Management page in configuration
- Add AccessDenied page and route guards
- Refactor shared components (form inputs, layout, UI)
- Update Tailwind config for new design system
- Add comprehensive documentation (docs/, tasks/, plans)
- Improve cluster service with better kubeconfig handling
- Add tests for crypto, config, helm client, tenant binding
This commit is contained in:
Ivan087
2026-05-12 16:15:14 +08:00
parent c5e51ed069
commit 7f238a3168
172 changed files with 15703 additions and 3162 deletions

View File

@ -84,6 +84,12 @@ func (s *Seeder) seedUsers(ctx context.Context) error {
// 创建用户
user := entity.NewUser(userSeed.Username, passwordHash, userSeed.Email)
user.ID = uuid.New().String()
if userSeed.Role != "" {
user.Role = userSeed.Role
}
if user.Role == "admin" {
user.WorkspaceID = entity.DefaultWorkspaceID
}
if err := s.repos.UserRepo.Create(ctx, user); err != nil {
log.Printf(" ✗ Failed to create user '%s': %v", userSeed.Username, err)
@ -105,6 +111,7 @@ func (s *Seeder) seedRegistries(ctx context.Context) error {
log.Printf(" ↳ Seeding %d registry(ies)...", len(s.config.Registries))
ownerID := s.bootstrapOwnerID(ctx)
for _, registrySeed := range s.config.Registries {
// 检查 Registry 是否已存在
existingRegistry, _ := s.repos.RegistryRepo.GetByName(ctx, registrySeed.Name)
@ -117,6 +124,9 @@ func (s *Seeder) seedRegistries(ctx context.Context) error {
registry := &entity.Registry{
ID: uuid.New().String(),
Name: registrySeed.Name,
WorkspaceID: entity.DefaultWorkspaceID,
OwnerID: ownerID,
Visibility: "global_shared",
URL: registrySeed.URL,
Description: registrySeed.Description,
Username: registrySeed.Username,
@ -146,6 +156,7 @@ func (s *Seeder) seedClusters(ctx context.Context) error {
log.Printf(" ↳ Seeding %d cluster(s)...", len(s.config.Clusters))
ownerID := s.bootstrapOwnerID(ctx)
for _, clusterSeed := range s.config.Clusters {
// 检查 Cluster 是否已存在
existingCluster, _ := s.repos.ClusterRepo.GetByName(ctx, clusterSeed.Name)
@ -158,6 +169,9 @@ func (s *Seeder) seedClusters(ctx context.Context) error {
cluster := &entity.Cluster{
ID: uuid.New().String(),
Name: clusterSeed.Name,
WorkspaceID: entity.DefaultWorkspaceID,
OwnerID: ownerID,
Visibility: "global_shared",
Host: clusterSeed.Host,
Description: clusterSeed.Description,
CAData: clusterSeed.CAData,
@ -179,3 +193,22 @@ func (s *Seeder) seedClusters(ctx context.Context) error {
return nil
}
func (s *Seeder) bootstrapOwnerID(ctx context.Context) string {
for _, userSeed := range s.config.Users {
if userSeed.Role == "admin" {
if user, err := s.repos.UserRepo.GetByUsername(ctx, userSeed.Username); err == nil && user != nil {
return user.ID
}
}
}
users, err := s.repos.UserRepo.List(ctx)
if err != nil {
return ""
}
for _, user := range users {
if user.Role == "admin" {
return user.ID
}
}
return ""
}