Skip to content

Commit

Permalink
Give validation rules priority and severity
Browse files Browse the repository at this point in the history
- the higher the priority, the earlier a rule runs
- if a rule is "fatal" it stops further rule checking on that
  validation.
  • Loading branch information
jtigger committed Aug 30, 2022
1 parent a787f84 commit 35180a9
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#@assert/validate min=1, not_null=True
value: null

+++

ERR:
- "value" (stdin:2) requires "not null"; fail: value is null (by stdin:1)
27 changes: 27 additions & 0 deletions pkg/validations/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package validations
import (
"fmt"
"reflect"
"sort"

"github.com/k14s/starlark-go/starlark"
"github.com/vmware-tanzu/carvel-ytt/pkg/filepos"
Expand All @@ -26,6 +27,23 @@ type NodeValidation struct {
type rule struct {
msg string
assertion starlark.Callable
priority int // how early to run this rule. 0 = order it appears; more positive: earlier, more negative: later.
isFatal bool // whether not satisfying this rule prevents others rules from running.
}

// byPriority is a sort.Interface that orders rules based on priority
type byPriority []rule

func (r byPriority) Len() int {
return len(r)
}
func (r byPriority) Swap(idx, jdx int) {
r[idx], r[jdx] = r[jdx], r[idx]
}

// Less reports whether the rule at "idx" should run _later_ than the rule at "jdx".
func (r byPriority) Less(idx, jdx int) bool {
return r[idx].priority > r[jdx].priority
}

// validationKwargs represent the optional keyword arguments and their values in a validationRun annotation.
Expand Down Expand Up @@ -106,14 +124,21 @@ func (v NodeValidation) Validate(node yamlmeta.Node, thread *starlark.Thread) []
return nil
}

sort.Sort(byPriority(v.rules))
var failures []error
for _, r := range v.rules {
result, err := starlark.Call(thread, r.assertion, starlark.Tuple{nodeValue}, []starlark.Tuple{})
if err != nil {
failures = append(failures, fmt.Errorf("%s (%s) requires %q; %s (by %s)", key, node.GetPosition().AsCompactString(), r.msg, err.Error(), v.position.AsCompactString()))
if r.isFatal {
break
}
} else {
if !(result == starlark.True) {
failures = append(failures, fmt.Errorf("%s (%s) requires %q (by %s)", key, node.GetPosition().AsCompactString(), r.msg, v.position.AsCompactString()))
if r.isFatal {
break
}
}
}
}
Expand Down Expand Up @@ -187,6 +212,8 @@ func (v validationKwargs) asRules() []rule {
rules = append(rules, rule{
msg: fmt.Sprintf("not null"),
assertion: yttlibrary.NewAssertNotNull().CheckFunc(),
isFatal: true,
priority: 100,
})
}
if v.oneNotNull != nil {
Expand Down

0 comments on commit 35180a9

Please sign in to comment.