From 682e5cc294fffb7884800b0915cba688237c13ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Cerqueira?= Date: Mon, 2 May 2022 09:05:29 +0100 Subject: [PATCH 1/3] feat: allow to load modules dynamically --- internal/policy/engine.go | 30 ++++++++++++++++++++++++++++++ pkg/sdk/sdk.go | 10 +++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/internal/policy/engine.go b/internal/policy/engine.go index 513b0e5..1b98eb7 100644 --- a/internal/policy/engine.go +++ b/internal/policy/engine.go @@ -19,6 +19,15 @@ type Engine struct { compiler *ast.Compiler } +func New() *Engine { + engine := Engine{ + modules: map[string]*ast.Module{}, + compiler: ast.NewCompiler().WithEnablePrintStatements(true), + } + + return &engine +} + func Load(ctx context.Context, policyPaths []string) (*Engine, error) { policies, err := loader.NewFileLoader(). WithProcessAnnotation(true). @@ -75,6 +84,27 @@ func (e *Engine) Modules() map[string]*ast.Module { return e.modules } +func (e *Engine) LoadPolicy(filename, policy string) error { + module, err := ast.ParseModuleWithOpts(filename, policy, ast.ParserOptions{ + ProcessAnnotation: true, + }) + if err != nil { + return err + } + + e.compiler.Compile(map[string]*ast.Module{ + filename: module, + }) + + if e.compiler.Failed() { + return fmt.Errorf("compiler: %w", e.compiler.Errors) + } + + e.modules[filename] = module + + return nil +} + func (e *Engine) Check(ctx context.Context, namespace string, input interface{}) (output.Report, error) { report, err := e.check(ctx, namespace, input) if err != nil { diff --git a/pkg/sdk/sdk.go b/pkg/sdk/sdk.go index d9a185c..a628a73 100644 --- a/pkg/sdk/sdk.go +++ b/pkg/sdk/sdk.go @@ -60,9 +60,13 @@ func New(ctx context.Context, policyPaths []string, opts ...Option) (*Reposaur, var err error - sdk.engine, err = policy.Load(ctx, policyPaths) - if err != nil { - return nil, err + if len(policyPaths) == 0 { + sdk.engine = policy.New() + } else { + sdk.engine, err = policy.Load(ctx, policyPaths) + if err != nil { + return nil, err + } } return sdk, nil From 31a119d99d81b4f4f7ddc454e54cb8ed6d5f7d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Cerqueira?= Date: Tue, 3 May 2022 08:15:35 +0100 Subject: [PATCH 2/3] fix: rename constructors --- internal/policy/engine.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/policy/engine.go b/internal/policy/engine.go index cc31f00..bf857e5 100644 --- a/internal/policy/engine.go +++ b/internal/policy/engine.go @@ -22,20 +22,20 @@ type Engine struct { enableTracing bool } -func New(opts ...Option) *Engine { +func NewEngine(opts ...Option) *Engine { engine := &Engine{ modules: map[string]*ast.Module{}, compiler: ast.NewCompiler().WithEnablePrintStatements(true), } - for _, opt := range opts { + for _, opt := range opts { opt(engine) } return engine } -func Load(ctx context.Context, policyPaths []string, opts ...Option) (*Engine, error) { +func NewEngineWithPolicies(ctx context.Context, policyPaths []string, opts ...Option) (*Engine, error) { policies, err := loader.NewFileLoader(). WithProcessAnnotation(true). Filtered(policyPaths, isRegoFile) From ae546feddb629fca644d9c5bb628f13a920fab6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Cerqueira?= Date: Tue, 3 May 2022 08:18:52 +0100 Subject: [PATCH 3/3] fix: rename constructors --- internal/policy/engine.go | 8 ++++---- pkg/sdk/sdk.go | 16 +++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/internal/policy/engine.go b/internal/policy/engine.go index bf857e5..dc7a373 100644 --- a/internal/policy/engine.go +++ b/internal/policy/engine.go @@ -14,7 +14,7 @@ import ( "github.com/reposaur/reposaur/pkg/output" ) -type Option func(*Engine) +type EngineOption func(*Engine) type Engine struct { modules map[string]*ast.Module @@ -22,7 +22,7 @@ type Engine struct { enableTracing bool } -func NewEngine(opts ...Option) *Engine { +func NewEngine(opts ...EngineOption) *Engine { engine := &Engine{ modules: map[string]*ast.Module{}, compiler: ast.NewCompiler().WithEnablePrintStatements(true), @@ -35,7 +35,7 @@ func NewEngine(opts ...Option) *Engine { return engine } -func NewEngineWithPolicies(ctx context.Context, policyPaths []string, opts ...Option) (*Engine, error) { +func NewEngineWithPolicies(ctx context.Context, policyPaths []string, opts ...EngineOption) (*Engine, error) { policies, err := loader.NewFileLoader(). WithProcessAnnotation(true). Filtered(policyPaths, isRegoFile) @@ -70,7 +70,7 @@ func NewEngineWithPolicies(ctx context.Context, policyPaths []string, opts ...Op // WithTracingEnabled enables or disables policy // execution tracing. -func WithTracingEnabled(enabled bool) Option { +func WithTracingEnabled(enabled bool) EngineOption { return func(e *Engine) { e.enableTracing = enabled } diff --git a/pkg/sdk/sdk.go b/pkg/sdk/sdk.go index d18cb1d..ef8000f 100644 --- a/pkg/sdk/sdk.go +++ b/pkg/sdk/sdk.go @@ -44,8 +44,8 @@ type Reposaur struct { // // The default HTTP client will use the default host `api.github.com`. Can // be customized using the `GITHUB_HOST` or `GH_HOST` environment variables. -func New(ctx context.Context, policyPaths []string, opts ...Option) (*Reposaur, error) { - sdk := &Reposaur{ +func New(ctx context.Context, policyPaths []string, opts ...Option) (sdk *Reposaur, err error) { + sdk = &Reposaur{ logger: zerolog.New(os.Stderr), } @@ -66,16 +66,18 @@ func New(ctx context.Context, policyPaths []string, opts ...Option) (*Reposaur, // to avoid unexpected side-effects by clients builtins.RegisterBuiltins(sdk.httpClient) - var err error + engineOpts := []policy.EngineOption{ + policy.WithTracingEnabled(sdk.enableTracing), + } if len(policyPaths) == 0 { - sdk.engine = policy.New() + sdk.engine = policy.NewEngine(engineOpts...) } else { - sdk.engine, err = policy.Load(ctx, policyPaths, policy.WithTracingEnabled(sdk.enableTracing)) + sdk.engine, err = policy.NewEngineWithPolicies(ctx, policyPaths, engineOpts...) if err != nil { return nil, err - } - } + } + } return sdk, nil }