From 8184c23a8f54c6fa707802833d88dce75ca73faa Mon Sep 17 00:00:00 2001 From: Abin Simon Date: Fri, 11 Mar 2022 14:54:17 +0530 Subject: [PATCH] Initialize script to create org, partner and roles We should probably have the role creation moved into adminsrv, but since we are only creating new orgs like this as of now let us continue with this. --- .../resourcepermissions/createresources.go | 2 +- scripts/resourceroles/createresourceroles.go | 125 ------------------ scripts/resourceroles/initialize.go | 101 ++++++++++++++ 3 files changed, 102 insertions(+), 126 deletions(-) delete mode 100644 scripts/resourceroles/createresourceroles.go create mode 100644 scripts/resourceroles/initialize.go diff --git a/scripts/resourcepermissions/createresources.go b/scripts/resourcepermissions/createresources.go index 6ec071f..dcff5c2 100644 --- a/scripts/resourcepermissions/createresources.go +++ b/scripts/resourcepermissions/createresources.go @@ -40,7 +40,7 @@ func addResourcePermissions(dao pg.EntityDAO, basePath string) error { } } - fmt.Println("Adding", len(items), "resouces permissions") + fmt.Println("Adding", len(items), "resource permissions") _, err = dao.Create(context.Background(), &items) return err } diff --git a/scripts/resourceroles/createresourceroles.go b/scripts/resourceroles/createresourceroles.go deleted file mode 100644 index fce438d..0000000 --- a/scripts/resourceroles/createresourceroles.go +++ /dev/null @@ -1,125 +0,0 @@ -package main - -import ( - "context" - "database/sql" - "encoding/json" - "fmt" - "io/ioutil" - "log" - "os" - "path" - - "github.com/RafaySystems/rcloud-base/internal/models" - "github.com/RafaySystems/rcloud-base/internal/persistence/provider/pg" - "github.com/google/uuid" - "github.com/uptrace/bun" - "github.com/uptrace/bun/dialect/pgdialect" - "github.com/uptrace/bun/driver/pgdriver" -) - -func addRole(dao pg.EntityDAO, name string, scope string, orgId uuid.UUID, partnerId uuid.UUID, permissions []string) error { - entity, err := dao.GetM(context.Background(), map[string]interface{}{"name": name, "scope": scope, "organization_id": orgId, "partner_id": partnerId}, &models.Role{}) - if err != nil && err.Error() != "sql: no rows in result set" { - return err - } - - role := models.Role{ - Name: name, - OrganizationId: orgId, - PartnerId: partnerId, - Scope: scope, - } - if r, ok := entity.(*models.Role); ok { - // I could technically do an update, but just to make it simpler - fmt.Printf("%v alrady exists, deleting and adding again\n", name) - err := dao.DeleteX(context.Background(), "resource_role_id", r.ID, &models.ResourceRolePermission{}) - if err != nil { - log.Fatalf("unable to delete permissions for '%v'", name) - } - - err = dao.Delete(context.Background(), r.ID, &models.Role{}) - if err != nil { - log.Fatalf("unable to delete '%v'", name) - } - } - - createdRole, err := dao.Create(context.Background(), &role) - if err != nil { - return err - } - - if r, ok := createdRole.(*models.Role); ok { - for _, p := range permissions { - entity, err := dao.GetByName(context.Background(), p, &models.ResourcePermission{}) - if err != nil { - log.Fatalf("unable to get rolepermission '%v'", p) - } - - if rlp, ok := entity.(*models.ResourcePermission); ok { - rolepermissionmapping := models.ResourceRolePermission{ - ResourceRoleId: r.ID, - ResourcePermissionId: rlp.ID, - } - _, err := dao.Create(context.Background(), &rolepermissionmapping) - if err != nil { - return err - } - } else { - log.Fatalf("unable to get rolepermission '%v'", p) - } - } - } else { - return fmt.Errorf("unable to create role") - } - - return nil -} - -func main() { - dsn := "postgres://admindbuser:admindbpassword@localhost:5432/admindb?sslmode=disable" - sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn))) - db := bun.NewDB(sqldb, pgdialect.New()) - - // db.AddQueryHook(bundebug.NewQueryHook( - // bundebug.WithVerbose(true), - // bundebug.FromEnv("BUNDEBUG"), - // )) - dao := pg.NewEntityDAO(db) - - if len(os.Args) != 3 { - // this step happens after org creation and so we will have org and partner id - log.Fatal("Usage: ", os.Args[0], " ", " ") - } - - content, err := ioutil.ReadFile(path.Join("scripts", "resourceroles", "data.json")) - if err != nil { - log.Fatal(err) - } - - orgId, err := uuid.Parse(os.Args[1]) - if err != nil { - log.Fatal(err) - } - partnerId, err := uuid.Parse(os.Args[2]) - if err != nil { - log.Fatal(err) - } - - var data map[string]map[string][]string - err = json.Unmarshal(content, &data) - if err != nil { - log.Fatal(err) - } - - for scope := range data { - for name := range data[scope] { - perms := data[scope][name] - fmt.Println(scope, name, len(perms)) - err := addRole(dao, name, scope, orgId, partnerId, perms) - if err != nil { - log.Fatal(err) - } - } - } -} diff --git a/scripts/resourceroles/initialize.go b/scripts/resourceroles/initialize.go new file mode 100644 index 0000000..d32fa8d --- /dev/null +++ b/scripts/resourceroles/initialize.go @@ -0,0 +1,101 @@ +package main + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + "io/ioutil" + "log" + "os" + "path" + + "github.com/RafaySystems/rcloud-base/pkg/enforcer" + "github.com/RafaySystems/rcloud-base/pkg/service" + commonv3 "github.com/RafaySystems/rcloud-base/proto/types/commonpb/v3" + rolev3 "github.com/RafaySystems/rcloud-base/proto/types/rolepb/v3" + systemv3 "github.com/RafaySystems/rcloud-base/proto/types/systempb/v3" + "github.com/uptrace/bun" + "github.com/uptrace/bun/dialect/pgdialect" + "github.com/uptrace/bun/driver/pgdriver" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +// This script will be run in an init container after we crate all the +// permissions. It will take care of the initialization, namely: +// - creating partner +// - creating org +// - creating roles in org +// +// We make use of service instead of just insserting to db as that way +// all the dependent items will be taken care of automatically. + +func main() { + if len(os.Args) != 3 { + // this step happens after org creation and so we will have org and partner id + log.Fatal("Usage: ", os.Args[0], " ", " ") + } + + org := os.Args[1] + partner := os.Args[2] + + content, err := ioutil.ReadFile(path.Join("scripts", "resourceroles", "data.json")) + if err != nil { + log.Fatal("unable to read file: ", err) + } + + var data map[string]map[string][]string + err = json.Unmarshal(content, &data) + if err != nil { + log.Fatal("unable to parse data file", err) + } + + dsn := "postgres://admindbuser:admindbpassword@localhost:5432/admindb?sslmode=disable" + sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn))) + db := bun.NewDB(sqldb, pgdialect.New()) + + // authz services + gormDb, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + log.Fatal("unable to create db connection", "error", err) + } + enforcer, err := enforcer.NewCasbinEnforcer(gormDb).Init() + if err != nil { + log.Fatal("unable to init enforcer", "error", err) + } + as := service.NewAuthzService(gormDb, enforcer) + + ps := service.NewPartnerService(db) + os := service.NewOrganizationService(db) + rs := service.NewRoleService(db, as) + + _, err = ps.Create(context.Background(), &systemv3.Partner{ + Metadata: &commonv3.Metadata{Name: partner, Description: "..."}, + Spec: &systemv3.PartnerSpec{Host: ""}, + }) + if err != nil { + log.Fatal("unable to create partner", err) + } + _, err = os.Create(context.Background(), &systemv3.Organization{ + Metadata: &commonv3.Metadata{Name: org, Partner: partner, Description: "..."}, + Spec: &systemv3.OrganizationSpec{Active: true}, + }) + if err != nil { + log.Fatal("unable to create organization", err) + } + + for scope := range data { + for name := range data[scope] { + perms := data[scope][name] + fmt.Println(scope, name, len(perms)) + _, err := rs.Create(context.Background(), &rolev3.Role{ + Metadata: &commonv3.Metadata{Name: name, Partner: partner, Organization: org, Description: "..."}, + Spec: &rolev3.RoleSpec{IsGlobal: true, Scope: "cluster", Rolepermissions: perms}, // TODO: look into scope + }) + if err != nil { + log.Fatal(err) + } + } + } +}