Skip to content

Commit

Permalink
fix: move upsert resource config to schema service
Browse files Browse the repository at this point in the history
  • Loading branch information
FemiNoviaLina committed Oct 3, 2024
1 parent d87fd7a commit 25f16f8
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 138 deletions.
18 changes: 8 additions & 10 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func StartServer(logger *log.Zap, cfg *config.Shield) error {
}

var resourceBlobFS blob.Bucket
if parsedResourceStorageURL.Scheme != resource.RESOURCES_CONFIG_STORAGE_PG {
if parsedResourceStorageURL.Scheme != schema.RESOURCES_CONFIG_STORAGE_PG {
resourceBlobFS, err = blob.NewStore(ctx, cfg.App.ResourcesConfigPath, cfg.App.ResourcesConfigPathSecret)
if err != nil {
return err
Expand Down Expand Up @@ -140,18 +140,20 @@ func StartServer(logger *log.Zap, cfg *config.Shield) error {
resourcePGRepository := postgres.NewResourceRepository(dbClient)
var schemaConfigRepository schema.FileService
switch parsedResourceStorageURL.Scheme {
case resource.RESOURCES_CONFIG_STORAGE_PG:
case schema.RESOURCES_CONFIG_STORAGE_PG:
schemaConfigRepository = resourcePGRepository
case resource.RESOURCES_CONFIG_STORAGE_GS,
resource.RESOURCES_CONFIG_STORAGE_FILE,
resource.RESOURCES_CONFIG_STORAGE_MEM:
case schema.RESOURCES_CONFIG_STORAGE_GS,
schema.RESOURCES_CONFIG_STORAGE_FILE,
schema.RESOURCES_CONFIG_STORAGE_MEM:
schemaConfigRepository = blob.NewSchemaConfigRepository(resourceBlobFS)
default:
return errors.New("invalid resource config storage")
}

schemaMigrationService := schema.NewSchemaMigrationService(
schema.AppConfig{ConfigStorage: parsedResourceStorageURL.Scheme},
schemaConfigRepository,
resourcePGRepository,
namespaceService,
roleService,
actionService,
Expand Down Expand Up @@ -257,13 +259,9 @@ func BuildAPIDependencies(
policyPGRepository := postgres.NewPolicyRepository(dbc)
policyService := policy.NewService(logger, policyPGRepository, userService, activityService)

parsedResourceStorageURL, err := url.Parse(cfg.App.ResourcesConfigPath)
if err != nil {
return api.Deps{}, err
}
resourcePGRepository := postgres.NewResourceRepository(dbc)
resourceService := resource.NewService(
logger, resource.AppConfig{ConfigStorage: parsedResourceStorageURL.Scheme}, resourcePGRepository, resourcePGRepository, relationService,
logger, resourcePGRepository, resourcePGRepository, relationService,
userService, projectService, organizationService, groupService, policyService, namespaceService, schemaMigrationService, activityService)

serviceDataRepository := postgres.NewServiceDataRepository(dbc)
Expand Down
27 changes: 2 additions & 25 deletions core/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,12 @@ import (
)

const (
NON_RESOURCE_ID = "*"
RESOURCES_CONFIG_STORAGE_PG = "postgresql"
RESOURCES_CONFIG_STORAGE_GS = "gs"
RESOURCES_CONFIG_STORAGE_FILE = "file"
RESOURCES_CONFIG_STORAGE_MEM = "mem"
NON_RESOURCE_ID = "*"

AuditEntity = "resource"
)

type Repository interface {
Transactor
GetByID(ctx context.Context, id string) (Resource, error)
GetByURN(ctx context.Context, urn string) (Resource, error)
Upsert(ctx context.Context, resource Resource) (Resource, error)
Expand All @@ -30,14 +25,8 @@ type Repository interface {
GetByNamespace(ctx context.Context, name string, ns string) (Resource, error)
}

type Transactor interface {
WithTransaction(ctx context.Context) context.Context
Rollback(ctx context.Context, err error) error
Commit(ctx context.Context) error
}

type SchemaRepository interface {
UpsertConfig(ctx context.Context, name string, config schema.NamespaceConfigMapType) (Config, error)
UpsertConfig(ctx context.Context, name string, config schema.NamespaceConfigMapType) (schema.Config, error)
}

type Resource struct {
Expand Down Expand Up @@ -86,18 +75,6 @@ type PagedResources struct {

type ResourcePermissions = map[string][]string

type Config struct {
ID uint32
Name string
Config string
CreatedAt time.Time
UpdatedAt time.Time
}

type AppConfig struct {
ConfigStorage string
}

type LogData struct {
Entity string `mapstructure:"entity"`
URN string `mapstructure:"urn"`
Expand Down
57 changes: 4 additions & 53 deletions core/resource/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/goto/shield/core/policy"
"github.com/goto/shield/core/project"
"github.com/goto/shield/core/relation"
resourcecfg "github.com/goto/shield/core/resource/config"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/schema"
"github.com/goto/shield/pkg/uuid"
Expand Down Expand Up @@ -68,12 +67,11 @@ type NamespaceService interface {
}

type SchemaService interface {
RunMigrations(ctx context.Context) error
UpsertConfig(ctx context.Context, name string, config string) (schema.Config, error)
}

type Service struct {
logger log.Logger
appConfig AppConfig
repository Repository
schemaRepository SchemaRepository
relationService RelationService
Expand All @@ -87,10 +85,9 @@ type Service struct {
activityService ActivityService
}

func NewService(logger log.Logger, appConfig AppConfig, repository Repository, schemaRepository SchemaRepository, relationService RelationService, userService UserService, projectService ProjectService, organizationService OrganizationService, groupService GroupService, policyService PolicyService, namespaceService NamespaceService, schemaService SchemaService, activityService ActivityService) *Service {
func NewService(logger log.Logger, repository Repository, schemaRepository SchemaRepository, relationService RelationService, userService UserService, projectService ProjectService, organizationService OrganizationService, groupService GroupService, policyService PolicyService, namespaceService NamespaceService, schemaService SchemaService, activityService ActivityService) *Service {
return &Service{
logger: logger,
appConfig: appConfig,
repository: repository,
schemaRepository: schemaRepository,
relationService: relationService,
Expand Down Expand Up @@ -510,52 +507,6 @@ func (s Service) listUserResources(ctx context.Context, resourceType string, use
return resPermissionsMap, nil
}

func (s Service) UpsertConfig(ctx context.Context, name string, config string) (Config, error) {
if strings.TrimSpace(name) == "" {
return Config{}, ErrInvalidDetail
}

if strings.TrimSpace(config) == "" {
return Config{}, ErrInvalidDetail
}

resourceConfig, err := resourcecfg.ParseConfigYaml([]byte(config))
if err != nil {
return Config{}, ErrInvalidDetail
}

configMap := make(schema.NamespaceConfigMapType)
for k, v := range resourceConfig {
if v.Type == "resource_group" {
configMap = schema.MergeNamespaceConfigMap(configMap, resourcecfg.GetNamespacesForResourceGroup(k, v))
} else {
configMap = schema.MergeNamespaceConfigMap(resourcecfg.GetNamespaceFromConfig(k, v.Roles, v.Permissions), configMap)
}
}

ctx = s.repository.WithTransaction(ctx)

res, err := s.schemaRepository.UpsertConfig(ctx, name, configMap)
if err != nil {
if txErr := s.repository.Rollback(ctx, err); txErr != nil {
return Config{}, err
}
return Config{}, err
}

if s.appConfig.ConfigStorage == RESOURCES_CONFIG_STORAGE_PG {
if err := s.schemaService.RunMigrations(ctx); err != nil {
if txErr := s.repository.Rollback(ctx, err); txErr != nil {
return Config{}, err
}
return Config{}, err
}
}

err = s.repository.Commit(ctx)
if err != nil {
return Config{}, err
}

return res, nil
func (s Service) UpsertConfig(ctx context.Context, name string, config string) (schema.Config, error) {
return s.schemaService.UpsertConfig(ctx, name, config)
}
2 changes: 1 addition & 1 deletion core/rule/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

const (
RULES_CONFIG_STORAGE_PG = "postgresql"
RULES_CONFIG_STORAGE_PG = "postgres"
RULES_CONFIG_STORAGE_GS = "gs"
RULES_CONFIG_STORAGE_FILE = "file"
RULES_CONFIG_STORAGE_MEM = "mem"
Expand Down
16 changes: 9 additions & 7 deletions internal/api/v1beta1/mocks/resource_service.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/api/v1beta1/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type ResourceService interface {
BulkCheckAuthz(ctx context.Context, resources []resource.Resource, actions []action.Action) ([]relation.Permission, error)
ListUserResourcesByType(ctx context.Context, userID string, resourceType string, permissions []string) (resource.ResourcePermissions, error)
ListAllUserResources(ctx context.Context, userID string, resourceTypes []string, permissions []string) (map[string]resource.ResourcePermissions, error)
UpsertConfig(ctx context.Context, name string, config string) (resource.Config, error)
UpsertConfig(ctx context.Context, name string, config string) (schema.Config, error)
}

var grpcResourceNotFoundErr = status.Errorf(codes.NotFound, "resource doesn't exist")
Expand Down Expand Up @@ -322,7 +322,7 @@ func (h Handler) UpsertResourcesConfig(ctx context.Context, request *shieldv1bet
return resourceConfigToPB(rc), nil
}

func resourceConfigToPB(from resource.Config) *shieldv1beta1.UpsertResourcesConfigResponse {
func resourceConfigToPB(from schema.Config) *shieldv1beta1.UpsertResourcesConfigResponse {
return &shieldv1beta1.UpsertResourcesConfigResponse{
Id: from.ID,
Name: from.Name,
Expand Down
9 changes: 5 additions & 4 deletions internal/api/v1beta1/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/goto/shield/core/resource"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/api/v1beta1/mocks"
"github.com/goto/shield/internal/schema"
"github.com/goto/shield/pkg/uuid"
shieldv1beta1 "github.com/goto/shield/proto/v1beta1"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -970,7 +971,7 @@ func TestHandler_UpsertResourcesConfig(t *testing.T) {
setup: func(rs *mocks.ResourceService) {
rs.EXPECT().UpsertConfig(mock.AnythingOfType("context.todoCtx"),
"entropy", "entropy:\n type: resource_group\n resource_types:\n - name: firehose").
Return(resource.Config{
Return(schema.Config{
ID: 1,
Name: "entropy",
Config: "entropy:\n type: resource_group\n resource_types:\n - name: firehose",
Expand All @@ -996,7 +997,7 @@ func TestHandler_UpsertResourcesConfig(t *testing.T) {
setup: func(rs *mocks.ResourceService) {
rs.EXPECT().UpsertConfig(mock.AnythingOfType("context.todoCtx"),
"entropy", "entropy:\n type: resource_group\n resource_types:\n - name: firehose").
Return(resource.Config{}, resource.ErrInvalidDetail)
Return(schema.Config{}, resource.ErrInvalidDetail)
},
request: &shieldv1beta1.UpsertResourcesConfigRequest{
Name: "entropy",
Expand All @@ -1009,7 +1010,7 @@ func TestHandler_UpsertResourcesConfig(t *testing.T) {
setup: func(rs *mocks.ResourceService) {
rs.EXPECT().UpsertConfig(mock.AnythingOfType("context.todoCtx"),
"entropy", "entropy:\n type: resource_group\n resource_types:\n - name: firehose").
Return(resource.Config{}, resource.ErrUpsertConfigNotSupported)
Return(schema.Config{}, resource.ErrUpsertConfigNotSupported)
},
request: &shieldv1beta1.UpsertResourcesConfigRequest{
Name: "entropy",
Expand All @@ -1022,7 +1023,7 @@ func TestHandler_UpsertResourcesConfig(t *testing.T) {
setup: func(rs *mocks.ResourceService) {
rs.EXPECT().UpsertConfig(mock.AnythingOfType("context.todoCtx"),
"entropy", "entropy:\n type: resource_group\n resource_types:\n - name: firehose").
Return(resource.Config{}, resource.ErrMarshal)
Return(schema.Config{}, resource.ErrMarshal)
},
request: &shieldv1beta1.UpsertResourcesConfigRequest{
Name: "entropy",
Expand Down
27 changes: 13 additions & 14 deletions core/resource/config/config.go → internal/schema/config.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package config
package schema

import (
"fmt"
"maps"

"github.com/goto/shield/internal/schema"
"gopkg.in/yaml.v2"
)

Expand All @@ -24,7 +23,7 @@ type ResourceTypeConfig struct {
Permissions []PermissionsConfig `yaml:"permissions" json:"permissions"`
}

type Config struct {
type ResourceConfig struct {
Type string `yaml:"type" json:"type"`

ResourceTypes []ResourceTypeConfig `yaml:"resource_types" json:"resource_types,omitempty"`
Expand All @@ -33,18 +32,18 @@ type Config struct {
Permissions []PermissionsConfig `yaml:"permissions" json:"permissions,omitempty"`
}

type ConfigYAML []map[string]Config
type ConfigYAML []map[string]ResourceConfig

func ParseConfigYaml(fileBytes []byte) (map[string]Config, error) {
var config map[string]Config
func ParseConfigYaml(fileBytes []byte) (map[string]ResourceConfig, error) {
var config map[string]ResourceConfig
if err := yaml.Unmarshal(fileBytes, &config); err != nil {
return map[string]Config{}, err
return map[string]ResourceConfig{}, err
}
return config, nil
}

func GetNamespacesForResourceGroup(name string, c Config) schema.NamespaceConfigMapType {
namespaceConfig := schema.NamespaceConfigMapType{}
func GetNamespacesForResourceGroup(name string, c ResourceConfig) NamespaceConfigMapType {
namespaceConfig := NamespaceConfigMapType{}

for _, v := range c.ResourceTypes {
maps.Copy(namespaceConfig, GetNamespaceFromConfig(name, v.Roles, v.Permissions, v.Name))
Expand All @@ -53,8 +52,8 @@ func GetNamespacesForResourceGroup(name string, c Config) schema.NamespaceConfig
return namespaceConfig
}

func GetNamespaceFromConfig(name string, rolesConfigs []RoleConfig, permissionConfigs []PermissionsConfig, resourceType ...string) schema.NamespaceConfigMapType {
tnc := schema.NamespaceConfig{
func GetNamespaceFromConfig(name string, rolesConfigs []RoleConfig, permissionConfigs []PermissionsConfig, resourceType ...string) NamespaceConfigMapType {
tnc := NamespaceConfig{
Roles: make(map[string][]string),
Permissions: make(map[string][]string),
}
Expand All @@ -68,11 +67,11 @@ func GetNamespaceFromConfig(name string, rolesConfigs []RoleConfig, permissionCo
}

if len(resourceType) == 0 {
tnc.Type = schema.SystemNamespace
tnc.Type = SystemNamespace
} else {
tnc.Type = schema.ResourceGroupNamespace
tnc.Type = ResourceGroupNamespace
name = fmt.Sprintf("%s/%s", name, resourceType[0])
}

return schema.NamespaceConfigMapType{name: tnc}
return NamespaceConfigMapType{name: tnc}
}
Loading

0 comments on commit 25f16f8

Please sign in to comment.