// 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 }