template-monorepo/cmd/permission-seed/main.go

90 lines
2.7 KiB
Go

// Command permission-seed upserts the platform-wide permission catalog
// and (optionally) seeds default system roles for one or more tenants.
//
// Usage:
//
// permission-seed -f etc/gateway.dev.yaml # catalog only
// permission-seed -f etc/gateway.dev.yaml -tenant TEN-001 # catalog + tenant roles
// permission-seed -f etc/gateway.dev.yaml -tenant t1,t2 -skip-catalog
//
// The seeder is idempotent: re-running only updates fields that changed
// in the embedded catalog. Default system roles (tenant_owner, etc.)
// always have is_system=true; their permission set is rewritten on each
// run so renaming a catalog entry propagates automatically.
package main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"time"
"gateway/internal/config"
permrepo "gateway/internal/model/permission/repository"
permseed "gateway/internal/model/permission/seed"
"github.com/zeromicro/go-zero/core/conf"
)
var (
configFile = flag.String("f", "etc/gateway.dev.yaml", "config file")
tenantList = flag.String("tenant", "", "comma-separated tenant IDs to seed default system roles into")
skipCatalog = flag.Bool("skip-catalog", false, "skip platform-wide catalog upsert (only seed tenant roles)")
)
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run() error {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
if c.Mongo.Host == "" {
return fmt.Errorf("permission-seed: Mongo.Host is empty in config")
}
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
if err := permrepo.EnsureMongoIndexes(ctx, &c.Mongo); err != nil {
return fmt.Errorf("permission-seed: ensure indexes: %w", err)
}
perms := permrepo.NewPermissionRepository(permrepo.PermissionRepositoryParam{Conf: &c.Mongo})
roles := permrepo.NewRoleRepository(permrepo.RoleRepositoryParam{Conf: &c.Mongo})
rolePerms := permrepo.NewRolePermissionRepository(permrepo.RolePermissionRepositoryParam{Conf: &c.Mongo})
tenantIDs := splitTenantIDs(*tenantList)
report, err := permseed.Apply(ctx, perms, roles, rolePerms, permseed.ApplyOptions{
TenantIDs: tenantIDs,
SkipCatalog: *skipCatalog,
})
if err != nil {
return fmt.Errorf("permission-seed: apply: %w", err)
}
fmt.Printf("permission-seed: catalog upserted=%d roles upserted=%d role-permission rows=%d tenants=%v\n",
report.CatalogUpserted, report.RolesUpserted, report.RolePermissionSet, tenantIDs)
return nil
}
func splitTenantIDs(raw string) []string {
parts := strings.Split(raw, ",")
out := make([]string, 0, len(parts))
for _, p := range parts {
p = strings.TrimSpace(p)
if p != "" {
out = append(out, p)
}
}
return out
}