From c2ff8bae6b1233eec29b3dc45397a6ce212fa1fc Mon Sep 17 00:00:00 2001 From: Varsha Munishwar Date: Thu, 21 Apr 2022 14:42:58 -0700 Subject: [PATCH 1/3] store assert/vaildate rules in Node's metas Signed-off-by: Garrett Cheadle --- pkg/workspace/assert.go | 112 +++++++++++++++++---------------------- pkg/yamlmeta/convert.go | 6 +++ pkg/yamlmeta/validate.go | 55 +++++++++++++++++++ 3 files changed, 109 insertions(+), 64 deletions(-) create mode 100644 pkg/yamlmeta/validate.go diff --git a/pkg/workspace/assert.go b/pkg/workspace/assert.go index 03fc2ff2..2830be98 100644 --- a/pkg/workspace/assert.go +++ b/pkg/workspace/assert.go @@ -5,11 +5,10 @@ package workspace import ( "fmt" + "github.com/k14s/starlark-go/starlark" - "github.com/vmware-tanzu/carvel-ytt/pkg/filepos" "github.com/vmware-tanzu/carvel-ytt/pkg/template" "github.com/vmware-tanzu/carvel-ytt/pkg/yamlmeta" - "github.com/vmware-tanzu/carvel-ytt/pkg/yamltemplate" ) // Declare @assert/... annotation names @@ -17,6 +16,7 @@ const ( AnnotationAssertValidate template.AnnotationName = "assert/validate" ) +// TODO: update go docs // ProcessAndRunValidations takes a root Node, and threadName, and traverses the tree checking for assert annotations. // Validations are processed and executed using the value of the annotated node as the parameter to the assertions. // @@ -26,14 +26,18 @@ func ProcessAndRunValidations(n yamlmeta.Node, threadName string) (AssertCheck, if n == nil { return AssertCheck{}, nil } + err := yamlmeta.Walk(n, &assertGetter{}) + if err != nil { + return AssertCheck{}, err + } - assertionChecker := newAssertChecker(threadName) - err := yamlmeta.Walk(n, assertionChecker) + assertionRunner := newAssertRunner(threadName) + err = yamlmeta.Walk(n, assertionRunner) if err != nil { return AssertCheck{}, err } - return assertionChecker.chk, nil + return assertionRunner.chk, nil } // AssertCheck holds the resulting violations from executing Validations on a node. @@ -59,21 +63,10 @@ func (ac *AssertCheck) HasViolations() bool { return len(ac.Violations) > 0 } -type assertChecker struct { - thread *starlark.Thread - chk AssertCheck -} +type assertGetter struct {} -func newAssertChecker(threadName string) *assertChecker { - return &assertChecker{thread: &starlark.Thread{Name: threadName}, chk: AssertCheck{[]error{}}} -} - -// Visit if `node` is annotated with `@assert/validate` (AnnotationAssertValidate). -// Checks, validates, and runs the validation Rules, any violations from running the assertions are collected. -// -// This visitor returns and error if any assertion is not well-formed, -// otherwise, returns nil. -func (a *assertChecker) Visit(node yamlmeta.Node) error { +// TODO: update go docs +func (a *assertGetter) Visit(node yamlmeta.Node) error { nodeAnnotations := template.NewAnnotations(node) if !nodeAnnotations.Has(AnnotationAssertValidate) { return nil @@ -86,19 +79,16 @@ func (a *assertChecker) Visit(node yamlmeta.Node) error { if syntaxErr != nil { return syntaxErr } - for _, rule := range rules { - err := rule.Validate(node, a.thread) - if err != nil { - a.chk.Violations = append(a.chk.Violations, err) - } - } + //store rules in node's meta + // TODO: not overriding any metas previously set + node.SetMeta("validations", rules) } return nil } -func newRulesFromAssertValidateAnnotation(annotation template.NodeAnnotation) ([]Rule, error) { - var rules []Rule +func newRulesFromAssertValidateAnnotation(annotation template.NodeAnnotation) ([]yamlmeta.Rule, error) { + var rules []yamlmeta.Rule if len(annotation.Kwargs) != 0 { return nil, fmt.Errorf("Invalid @%s annotation - expected @%s to have 2-tuple as argument(s), but found keyword argument (by %s)", AnnotationAssertValidate, AnnotationAssertValidate, annotation.Position.AsCompactString()) @@ -122,58 +112,52 @@ func newRulesFromAssertValidateAnnotation(annotation template.NodeAnnotation) ([ if !ok { return nil, fmt.Errorf("Invalid @%s annotation - expected second item in the 2-tuple to be an assertion function, but was %s (at %s)", AnnotationAssertValidate, ruleTuple[1].Type(), annotation.Position.AsCompactString()) } - rules = append(rules, Rule{ - msg: message.GoString(), - assertion: lambda, - position: annotation.Position, + rules = append(rules, yamlmeta.Rule{ + Msg: message.GoString(), + Assertion: lambda, + Position: annotation.Position, }) } return rules, nil } -// A Rule represents an argument to an @assert/validate annotation; -// it contains a string description of what constitutes a valid value, -// and a function that asserts the rule against an actual value. -// One @assert/validate annotation can have multiple Rules. -type Rule struct { - msg string - assertion starlark.Callable - position *filepos.Position + +type assertRunner struct { + thread *starlark.Thread + chk AssertCheck +} + +func newAssertRunner(threadName string) *assertRunner { + return &assertRunner{thread: &starlark.Thread{Name: threadName}, chk: AssertCheck{[]error{}}} } -// Validate runs the assertion from the Rule with the node's value as arguments. +// TODO: update go docs +// Visit if `node` is annotated with `@assert/validate` (AnnotationAssertValidate). +// Checks, validates, and runs the validation Rules, any violations from running the assertions are collected. // -// Returns an error if the assertion returns False (not-None), or assert.fail()s. -// Otherwise, returns nil. -func (r Rule) Validate(node yamlmeta.Node, thread *starlark.Thread) error { - var key string - var nodeValue starlark.Value - switch typedNode := node.(type) { - case *yamlmeta.DocumentSet, *yamlmeta.Array, *yamlmeta.Map: - panic(fmt.Sprintf("@%s annotation at %s - not supported on %s at %s", AnnotationAssertValidate, r.position.AsCompactString(), yamlmeta.TypeName(node), node.GetPosition().AsCompactString())) - case *yamlmeta.MapItem: - key = fmt.Sprintf("%q", typedNode.Key) - nodeValue = yamltemplate.NewGoValueWithYAML(typedNode.Value).AsStarlarkValue() - case *yamlmeta.ArrayItem: - key = yamlmeta.TypeName(typedNode) - nodeValue = yamltemplate.NewGoValueWithYAML(typedNode.Value).AsStarlarkValue() - case *yamlmeta.Document: - key = yamlmeta.TypeName(typedNode) - nodeValue = yamltemplate.NewGoValueWithYAML(typedNode.Value).AsStarlarkValue() +// This visitor returns and error if any assertion is not well-formed, +// otherwise, returns nil. +func (a *assertRunner) Visit(node yamlmeta.Node) error { + + //get rules in node's meta + metas := node.GetMeta("validations") + if metas == nil { + return nil } - result, err := starlark.Call(thread, r.assertion, starlark.Tuple{nodeValue}, []starlark.Tuple{}) - if err != nil { - return fmt.Errorf("%s (%s) requires %q; %s (by %s)", key, node.GetPosition().AsCompactString(), r.msg, err.Error(), r.position.AsCompactString()) + rules, ok := metas.([]yamlmeta.Rule) + if !ok { + return nil } - // in order to pass, the assertion must return True or None - if _, ok := result.(starlark.NoneType); !ok { - if !result.Truth() { - return fmt.Errorf("%s (%s) requires %q (by %s)", key, node.GetPosition().AsCompactString(), r.msg, r.position.AsCompactString()) + for _, rule := range rules { + err := rule.Validate(node, a.thread) + if err != nil { + a.chk.Violations = append(a.chk.Violations, err) } } return nil } + diff --git a/pkg/yamlmeta/convert.go b/pkg/yamlmeta/convert.go index 73399b59..df341c79 100644 --- a/pkg/yamlmeta/convert.go +++ b/pkg/yamlmeta/convert.go @@ -8,6 +8,7 @@ import ( "github.com/vmware-tanzu/carvel-ytt/pkg/filepos" "github.com/vmware-tanzu/carvel-ytt/pkg/orderedmap" + tplcore "github.com/vmware-tanzu/carvel-ytt/pkg/template/core" "github.com/vmware-tanzu/carvel-ytt/pkg/yamlmeta/internal/yaml.v2" ) @@ -27,6 +28,11 @@ func NewGoFromAST(val interface{}) interface{} { return convertToGo(val) } +//TODO: how else can we provide the RIGHT type of value +func NewGoValueFromAST(val interface{}) tplcore.GoValue { + return tplcore.NewGoValue(convertToGo(val)) +} + func convertToLowYAML(val interface{}) interface{} { switch typedVal := val.(type) { case map[interface{}]interface{}: diff --git a/pkg/yamlmeta/validate.go b/pkg/yamlmeta/validate.go new file mode 100644 index 00000000..483a2d2d --- /dev/null +++ b/pkg/yamlmeta/validate.go @@ -0,0 +1,55 @@ +package yamlmeta + +import ( + "fmt" + + "github.com/k14s/starlark-go/starlark" + "github.com/vmware-tanzu/carvel-ytt/pkg/filepos" +) + +// A Rule represents an argument to an @assert/validate annotation; +// it contains a string description of what constitutes a valid value, +// and a function that asserts the rule against an actual value. +// One @assert/validate annotation can have multiple Rules. +type Rule struct { + Msg string + Assertion starlark.Callable + Position *filepos.Position +} + +// Validate runs the assertion from the Rule with the node's value as arguments. +// +// Returns an error if the assertion returns False (not-None), or assert.fail()s. +// Otherwise, returns nil. +func (r Rule) Validate(node Node, thread *starlark.Thread) error { + var key string + var nodeValue starlark.Value + switch typedNode := node.(type) { + case *DocumentSet, *Array, *Map: + // TODO: is this the correct place for as specific of an error + panic(fmt.Sprintf("@%s annotation at %s - not supported on %s at %s", "assert/validate", r.Position.AsCompactString(), TypeName(node), node.GetPosition().AsCompactString())) + case *MapItem: + key = fmt.Sprintf("%q", typedNode.Key) + nodeValue = NewGoValueFromAST(typedNode.Value).AsStarlarkValue() + case *ArrayItem: + key = TypeName(typedNode) + nodeValue = NewGoValueFromAST(typedNode.Value).AsStarlarkValue() + case *Document: + key = TypeName(typedNode) + nodeValue = NewGoValueFromAST(typedNode.Value).AsStarlarkValue() + } + + result, err := starlark.Call(thread, r.Assertion, starlark.Tuple{nodeValue}, []starlark.Tuple{}) + if err != nil { + return fmt.Errorf("%s (%s) requires %q; %s (by %s)", key, node.GetPosition().AsCompactString(), r.Msg, err.Error(), r.Position.AsCompactString()) + } + + // in order to pass, the assertion must return True or None + if _, ok := result.(starlark.NoneType); !ok { + if !result.Truth() { + return fmt.Errorf("%s (%s) requires %q (by %s)", key, node.GetPosition().AsCompactString(), r.Msg, r.Position.AsCompactString()) + } + } + + return nil +} From 62d5f3026818a3cb8f29db945d504753e01bb1a5 Mon Sep 17 00:00:00 2001 From: Garrett Cheadle Date: Mon, 25 Apr 2022 15:27:07 -0700 Subject: [PATCH 2/3] create assertion top level package --- pkg/{workspace => assertions}/assert.go | 73 +++++++++++------------- pkg/{yamlmeta => assertions}/validate.go | 30 +++++----- pkg/assertions/yamlmeta.go | 23 ++++++++ pkg/workspace/library_execution.go | 3 +- pkg/yamlmeta/convert.go | 6 -- 5 files changed, 72 insertions(+), 63 deletions(-) rename pkg/{workspace => assertions}/assert.go (71%) rename pkg/{yamlmeta => assertions}/validate.go (57%) create mode 100644 pkg/assertions/yamlmeta.go diff --git a/pkg/workspace/assert.go b/pkg/assertions/assert.go similarity index 71% rename from pkg/workspace/assert.go rename to pkg/assertions/assert.go index 2830be98..213eb729 100644 --- a/pkg/workspace/assert.go +++ b/pkg/assertions/assert.go @@ -1,11 +1,10 @@ // Copyright 2022 VMware, Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package assertions import ( "fmt" - "github.com/k14s/starlark-go/starlark" "github.com/vmware-tanzu/carvel-ytt/pkg/template" "github.com/vmware-tanzu/carvel-ytt/pkg/yamlmeta" @@ -16,28 +15,28 @@ const ( AnnotationAssertValidate template.AnnotationName = "assert/validate" ) -// TODO: update go docs -// ProcessAndRunValidations takes a root Node, and threadName, and traverses the tree checking for assert annotations. -// Validations are processed and executed using the value of the annotated node as the parameter to the assertions. +// ProcessAndRunValidations takes a root Node, and threadName, and validates each Node in the tree. +// Assert annotations are stored on the Node as Validations, which are then executed using the +// value of the annotated node as the parameter to the assertions. // -// When the assertions have violations, the errors are collected and returned in an AssertCheck. -// Otherwise, returns empty AssertCheck and nil. +// When a Node's value is invalid, the errors are collected and returned in an AssertCheck. +// Otherwise, returns empty AssertCheck and nil error. func ProcessAndRunValidations(n yamlmeta.Node, threadName string) (AssertCheck, error) { if n == nil { return AssertCheck{}, nil } - err := yamlmeta.Walk(n, &assertGetter{}) + err := yamlmeta.Walk(n, &convertAssertAnnsToValidations{}) if err != nil { return AssertCheck{}, err } - assertionRunner := newAssertRunner(threadName) - err = yamlmeta.Walk(n, assertionRunner) + validationRunner := newValidationRunner(threadName) + err = yamlmeta.Walk(n, validationRunner) if err != nil { return AssertCheck{}, err } - return assertionRunner.chk, nil + return validationRunner.chk, nil } // AssertCheck holds the resulting violations from executing Validations on a node. @@ -63,10 +62,14 @@ func (ac *AssertCheck) HasViolations() bool { return len(ac.Violations) > 0 } -type assertGetter struct {} +type convertAssertAnnsToValidations struct{} -// TODO: update go docs -func (a *assertGetter) Visit(node yamlmeta.Node) error { +// Visit if `node` is annotated with `@assert/validate` (AnnotationAssertValidate). +// Checks annotation, and stores validation Rules on Node's validations meta. +// +// This visitor returns and error if any assert annotation is not well-formed, +// otherwise, returns nil. +func (a *convertAssertAnnsToValidations) Visit(node yamlmeta.Node) error { nodeAnnotations := template.NewAnnotations(node) if !nodeAnnotations.Has(AnnotationAssertValidate) { return nil @@ -79,16 +82,15 @@ func (a *assertGetter) Visit(node yamlmeta.Node) error { if syntaxErr != nil { return syntaxErr } - //store rules in node's meta - // TODO: not overriding any metas previously set - node.SetMeta("validations", rules) + // store rules in node's validations meta without overriding any existing rules + AddValidations(node, rules) } return nil } -func newRulesFromAssertValidateAnnotation(annotation template.NodeAnnotation) ([]yamlmeta.Rule, error) { - var rules []yamlmeta.Rule +func newRulesFromAssertValidateAnnotation(annotation template.NodeAnnotation) ([]Rule, error) { + var rules []Rule if len(annotation.Kwargs) != 0 { return nil, fmt.Errorf("Invalid @%s annotation - expected @%s to have 2-tuple as argument(s), but found keyword argument (by %s)", AnnotationAssertValidate, AnnotationAssertValidate, annotation.Position.AsCompactString()) @@ -112,7 +114,7 @@ func newRulesFromAssertValidateAnnotation(annotation template.NodeAnnotation) ([ if !ok { return nil, fmt.Errorf("Invalid @%s annotation - expected second item in the 2-tuple to be an assertion function, but was %s (at %s)", AnnotationAssertValidate, ruleTuple[1].Type(), annotation.Position.AsCompactString()) } - rules = append(rules, yamlmeta.Rule{ + rules = append(rules, Rule{ Msg: message.GoString(), Assertion: lambda, Position: annotation.Position, @@ -122,35 +124,25 @@ func newRulesFromAssertValidateAnnotation(annotation template.NodeAnnotation) ([ return rules, nil } - -type assertRunner struct { +type validationRunner struct { thread *starlark.Thread chk AssertCheck } -func newAssertRunner(threadName string) *assertRunner { - return &assertRunner{thread: &starlark.Thread{Name: threadName}, chk: AssertCheck{[]error{}}} +func newValidationRunner(threadName string) *validationRunner { + return &validationRunner{thread: &starlark.Thread{Name: threadName}, chk: AssertCheck{[]error{}}} } -// TODO: update go docs -// Visit if `node` is annotated with `@assert/validate` (AnnotationAssertValidate). -// Checks, validates, and runs the validation Rules, any violations from running the assertions are collected. +// Visit if `node` is has validations in its meta. +// Runs the validation Rules, any violations from running the assertions are collected. // -// This visitor returns and error if any assertion is not well-formed, -// otherwise, returns nil. -func (a *assertRunner) Visit(node yamlmeta.Node) error { - - //get rules in node's meta - metas := node.GetMeta("validations") - if metas == nil { - return nil - } - - rules, ok := metas.([]yamlmeta.Rule) - if !ok { +// This visitor stores error(violations) in the validationRunner and returns nil. +func (a *validationRunner) Visit(node yamlmeta.Node) error { + // get rules in node's meta + rules := GetValidations(node) + if rules == nil { return nil } - for _, rule := range rules { err := rule.Validate(node, a.thread) if err != nil { @@ -160,4 +152,3 @@ func (a *assertRunner) Visit(node yamlmeta.Node) error { return nil } - diff --git a/pkg/yamlmeta/validate.go b/pkg/assertions/validate.go similarity index 57% rename from pkg/yamlmeta/validate.go rename to pkg/assertions/validate.go index 483a2d2d..fa707896 100644 --- a/pkg/yamlmeta/validate.go +++ b/pkg/assertions/validate.go @@ -1,16 +1,17 @@ -package yamlmeta +package assertions import ( "fmt" "github.com/k14s/starlark-go/starlark" "github.com/vmware-tanzu/carvel-ytt/pkg/filepos" + "github.com/vmware-tanzu/carvel-ytt/pkg/yamlmeta" + "github.com/vmware-tanzu/carvel-ytt/pkg/yamltemplate" ) -// A Rule represents an argument to an @assert/validate annotation; +// A Rule represents a validation attached to a Node via an annotation; // it contains a string description of what constitutes a valid value, // and a function that asserts the rule against an actual value. -// One @assert/validate annotation can have multiple Rules. type Rule struct { Msg string Assertion starlark.Callable @@ -21,22 +22,21 @@ type Rule struct { // // Returns an error if the assertion returns False (not-None), or assert.fail()s. // Otherwise, returns nil. -func (r Rule) Validate(node Node, thread *starlark.Thread) error { +func (r Rule) Validate(node yamlmeta.Node, thread *starlark.Thread) error { var key string var nodeValue starlark.Value switch typedNode := node.(type) { - case *DocumentSet, *Array, *Map: - // TODO: is this the correct place for as specific of an error - panic(fmt.Sprintf("@%s annotation at %s - not supported on %s at %s", "assert/validate", r.Position.AsCompactString(), TypeName(node), node.GetPosition().AsCompactString())) - case *MapItem: + case *yamlmeta.DocumentSet, *yamlmeta.Array, *yamlmeta.Map: + panic(fmt.Sprintf("validation at %s - not supported on %s at %s", r.Position.AsCompactString(), yamlmeta.TypeName(node), node.GetPosition().AsCompactString())) + case *yamlmeta.MapItem: key = fmt.Sprintf("%q", typedNode.Key) - nodeValue = NewGoValueFromAST(typedNode.Value).AsStarlarkValue() - case *ArrayItem: - key = TypeName(typedNode) - nodeValue = NewGoValueFromAST(typedNode.Value).AsStarlarkValue() - case *Document: - key = TypeName(typedNode) - nodeValue = NewGoValueFromAST(typedNode.Value).AsStarlarkValue() + nodeValue = yamltemplate.NewGoValueWithYAML(typedNode.Value).AsStarlarkValue() + case *yamlmeta.ArrayItem: + key = yamlmeta.TypeName(typedNode) + nodeValue = yamltemplate.NewGoValueWithYAML(typedNode.Value).AsStarlarkValue() + case *yamlmeta.Document: + key = yamlmeta.TypeName(typedNode) + nodeValue = yamltemplate.NewGoValueWithYAML(typedNode.Value).AsStarlarkValue() } result, err := starlark.Call(thread, r.Assertion, starlark.Tuple{nodeValue}, []starlark.Tuple{}) diff --git a/pkg/assertions/yamlmeta.go b/pkg/assertions/yamlmeta.go new file mode 100644 index 00000000..542f88ab --- /dev/null +++ b/pkg/assertions/yamlmeta.go @@ -0,0 +1,23 @@ +package assertions + +import "github.com/vmware-tanzu/carvel-ytt/pkg/yamlmeta" + +func AddValidations(node yamlmeta.Node, rules []Rule) { + metas := node.GetMeta("validations") + if currRules, ok := metas.([]Rule); ok { + rules = append(currRules, rules...) + } + SetValidations(node, rules) +} + +func SetValidations(node yamlmeta.Node, rules []Rule) { + node.SetMeta("validations", rules) +} + +func GetValidations(node yamlmeta.Node) []Rule { + metas := node.GetMeta("validations") + if rules, ok := metas.([]Rule); ok { + return rules + } + return nil +} diff --git a/pkg/workspace/library_execution.go b/pkg/workspace/library_execution.go index 32c04590..052e1f65 100644 --- a/pkg/workspace/library_execution.go +++ b/pkg/workspace/library_execution.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/k14s/starlark-go/starlark" + "github.com/vmware-tanzu/carvel-ytt/pkg/assertions" "github.com/vmware-tanzu/carvel-ytt/pkg/cmd/ui" "github.com/vmware-tanzu/carvel-ytt/pkg/files" "github.com/vmware-tanzu/carvel-ytt/pkg/template" @@ -100,7 +101,7 @@ func (ll *LibraryExecution) Values(valuesOverlays []*datavalues.Envelope, schema // Returns an error if the arguments to an @assert/validate are invalid, // otherwise, checks the AssertCheck for violations, and returns nil if there are no violations. func (ll *LibraryExecution) validateValues(values *datavalues.Envelope) error { - assertCheck, err := ProcessAndRunValidations(values.Doc, "assert-data-values") + assertCheck, err := assertions.ProcessAndRunValidations(values.Doc, "assert-data-values") if err != nil { return err } diff --git a/pkg/yamlmeta/convert.go b/pkg/yamlmeta/convert.go index df341c79..73399b59 100644 --- a/pkg/yamlmeta/convert.go +++ b/pkg/yamlmeta/convert.go @@ -8,7 +8,6 @@ import ( "github.com/vmware-tanzu/carvel-ytt/pkg/filepos" "github.com/vmware-tanzu/carvel-ytt/pkg/orderedmap" - tplcore "github.com/vmware-tanzu/carvel-ytt/pkg/template/core" "github.com/vmware-tanzu/carvel-ytt/pkg/yamlmeta/internal/yaml.v2" ) @@ -28,11 +27,6 @@ func NewGoFromAST(val interface{}) interface{} { return convertToGo(val) } -//TODO: how else can we provide the RIGHT type of value -func NewGoValueFromAST(val interface{}) tplcore.GoValue { - return tplcore.NewGoValue(convertToGo(val)) -} - func convertToLowYAML(val interface{}) interface{} { switch typedVal := val.(type) { case map[interface{}]interface{}: From 67456b782307a593c385f85e3951c2f4e9c64b4c Mon Sep 17 00:00:00 2001 From: Garrett Cheadle Date: Mon, 25 Apr 2022 15:31:32 -0700 Subject: [PATCH 3/3] update godocs --- pkg/assertions/assert.go | 1 + pkg/assertions/validate.go | 3 +++ pkg/assertions/yamlmeta.go | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/pkg/assertions/assert.go b/pkg/assertions/assert.go index 213eb729..8147eb30 100644 --- a/pkg/assertions/assert.go +++ b/pkg/assertions/assert.go @@ -5,6 +5,7 @@ package assertions import ( "fmt" + "github.com/k14s/starlark-go/starlark" "github.com/vmware-tanzu/carvel-ytt/pkg/template" "github.com/vmware-tanzu/carvel-ytt/pkg/yamlmeta" diff --git a/pkg/assertions/validate.go b/pkg/assertions/validate.go index fa707896..5b6f730a 100644 --- a/pkg/assertions/validate.go +++ b/pkg/assertions/validate.go @@ -1,3 +1,6 @@ +// Copyright 2022 VMware, Inc. +// SPDX-License-Identifier: Apache-2.0 + package assertions import ( diff --git a/pkg/assertions/yamlmeta.go b/pkg/assertions/yamlmeta.go index 542f88ab..41d248da 100644 --- a/pkg/assertions/yamlmeta.go +++ b/pkg/assertions/yamlmeta.go @@ -1,7 +1,11 @@ +// Copyright 2022 VMware, Inc. +// SPDX-License-Identifier: Apache-2.0 + package assertions import "github.com/vmware-tanzu/carvel-ytt/pkg/yamlmeta" +// AddValidations appends validation Rules to node's validations metadata, later retrieved via GetValidations(). func AddValidations(node yamlmeta.Node, rules []Rule) { metas := node.GetMeta("validations") if currRules, ok := metas.([]Rule); ok { @@ -10,10 +14,12 @@ func AddValidations(node yamlmeta.Node, rules []Rule) { SetValidations(node, rules) } +// SetValidations attaches validation Rules to node's metadata, later retrieved via GetValidations(). func SetValidations(node yamlmeta.Node, rules []Rule) { node.SetMeta("validations", rules) } +// GetValidations retrieves validation Rules from node metadata, set previously via SetValidations(). func GetValidations(node yamlmeta.Node) []Rule { metas := node.GetMeta("validations") if rules, ok := metas.([]Rule); ok {