Skip to content

Commit

Permalink
Validate rego when parsing rule types (#4906)
Browse files Browse the repository at this point in the history
This adds rego module parsing as part of the rule type validation. This
enables us to catch errors faster as opposed to needing to evaluate a
policy to figure out if the rule type was valid.

If we have a rule with invalid rego, we'd get errors as follows:

```
$ mindev ruletype lint -r rule-types/github/no_binaries_in_repo.yaml
error validating rule type from file rule-types/github/no_binaries_in_repo.yaml: invalid rule type
invalid rule type definition: rego definition is invalid: 1 error occurred: minder-ruletype-def.rego:16: rego_parse_error: unexpected eof token
	  msg := sprintf("Binary artifact found: %s", [current_file])
	                                                            ^
Error: failed linting rule type
Message: Error on execute
Details: failed linting rule type
```

Signed-off-by: Juan Antonio Osorio <[email protected]>
  • Loading branch information
JAORMX authored Nov 7, 2024
1 parent ebc9be8 commit 67bd38d
Showing 1 changed file with 36 additions and 6 deletions.
42 changes: 36 additions & 6 deletions pkg/api/protobuf/go/minder/v1/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"

"github.com/go-playground/validator/v10"
"github.com/open-policy-agent/opa/ast"
)

var (
Expand Down Expand Up @@ -148,10 +149,6 @@ func (rt *RuleType) Validate() error {
return fmt.Errorf("%w: %w", ErrInvalidRuleType, err)
}

if rt.Def == nil {
return fmt.Errorf("%w: rule type definition is nil", ErrInvalidRuleType)
}

if err := rt.Def.Validate(); err != nil {
return errors.Join(ErrInvalidRuleType, err)
}
Expand All @@ -161,6 +158,10 @@ func (rt *RuleType) Validate() error {

// Validate validates a rule type definition
func (def *RuleType_Definition) Validate() error {
if def == nil {
return fmt.Errorf("%w: rule type definition is nil", ErrInvalidRuleTypeDefinition)
}

if !EntityFromString(def.InEntity).IsValid() {
return fmt.Errorf("%w: invalid entity type: %s", ErrInvalidRuleTypeDefinition, def.InEntity)
}
Expand All @@ -175,8 +176,37 @@ func (def *RuleType_Definition) Validate() error {
return err
}

if def.Eval == nil {
return fmt.Errorf("%w: data eval is nil", ErrInvalidRuleTypeDefinition)
return def.Eval.Validate()
}

// Validate validates a rule type definition eval
func (ev *RuleType_Definition_Eval) Validate() error {
if ev == nil {
return fmt.Errorf("%w: eval is nil", ErrInvalidRuleTypeDefinition)
}

// Not using import to avoid circular dependency
if ev.Type == "rego" {
if err := ev.GetRego().Validate(); err != nil {
return err
}
}
return nil
}

// Validate validates a rule type definition eval rego
func (rego *RuleType_Definition_Eval_Rego) Validate() error {
if rego == nil {
return fmt.Errorf("%w: rego is nil", ErrInvalidRuleTypeDefinition)
}

if rego.Def == "" {
return fmt.Errorf("%w: rego definition is empty", ErrInvalidRuleTypeDefinition)
}

_, err := ast.ParseModule("minder-ruletype-def.rego", rego.Def)
if err != nil {
return fmt.Errorf("%w: rego definition is invalid: %s", ErrInvalidRuleTypeDefinition, err)
}

return nil
Expand Down

0 comments on commit 67bd38d

Please sign in to comment.