diff options
author | Dan Duvall <dduvall@wikimedia.org> | 2018-03-06 20:31:58 -0800 |
---|---|---|
committer | Dan Duvall <dduvall@wikimedia.org> | 2018-03-19 15:55:16 -0700 |
commit | eb9b69dd3d710cb7afa1dfb6e23a5987842b21cc (patch) | |
tree | 049b11cc885e4e9f54aac8981c91a1bf3620e7af /config/validation.go | |
parent | 6896e655eb5cc88b90e66979bc2d862eb92cbb9f (diff) | |
download | blubber-eb9b69dd3d710cb7afa1dfb6e23a5987842b21cc.tar.gz |
Allow for configuration policies
Summary:
Implements a rough interface for validating configuration against
arbitrary policy rules. Policies are provided as YAML and passed via the
command line as file paths or remote URIs.
The format of policies is:
enforcements:
- path: <path>
rule: <rule>
Where `<path>` is a YAML-ish path to a config field and `<rule>` is any
expression our config validator understands (expressions built in by the
validator library and custom tags defined in `config.validation.go`).
Example policy:
enforcements:
- path: variants.production.base
rule: oneof=debian:jessie debian:stretch
- path: variants.production.runs.as
rule: ne=foo
- path: variants.production.node.dependencies
rule: isfalse
Command flag parsing was implemented in `main.go` to support the new
`--policy=uri` flag and improve existing handling of `--version` and the
usage statement.
Test Plan: Run `go test ./...`.
Reviewers: thcipriani, demon, hashar, mmodell, #release-engineering-team
Reviewed By: thcipriani, #release-engineering-team
Tags: #release-engineering-team
Differential Revision: https://phabricator.wikimedia.org/D999
Diffstat (limited to 'config/validation.go')
-rw-r--r-- | config/validation.go | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/config/validation.go b/config/validation.go index 652a3c8..3359211 100644 --- a/config/validation.go +++ b/config/validation.go @@ -52,6 +52,8 @@ var ( "baseimage": isBaseImage, "debianpackage": isDebianPackage, "envvars": isEnvironmentVariables, + "isfalse": isFalse, + "istrue": isTrue, "variantref": isVariantReference, "variants": hasVariantNames, } @@ -61,11 +63,10 @@ type ctxKey uint8 const rootCfgCtx ctxKey = iota -// Validate runs all validations defined for config fields against the given -// Config value. If the returned error is not nil, it will contain a -// user-friendly message describing all invalid field values. +// NewValidator returns a validator instance for which our custom aliases and +// functions are registered. // -func Validate(config Config) error { +func NewValidator() *validator.Validate { validate := validator.New() validate.RegisterTagNameFunc(resolveYAMLTagName) @@ -78,6 +79,16 @@ func Validate(config Config) error { validate.RegisterValidationCtx(name, f) } + return validate +} + +// Validate runs all validations defined for config fields against the given +// Config value. If the returned error is not nil, it will contain a +// user-friendly message describing all invalid field values. +// +func Validate(config Config) error { + validate := NewValidator() + ctx := context.WithValue(context.Background(), rootCfgCtx, config) return validate.StructCtx(ctx, config) @@ -169,6 +180,18 @@ func isEnvironmentVariables(_ context.Context, fl validator.FieldLevel) bool { return true } +func isFalse(_ context.Context, fl validator.FieldLevel) bool { + val, ok := fl.Field().Interface().(bool) + + return ok && val == false +} + +func isTrue(_ context.Context, fl validator.FieldLevel) bool { + val, ok := fl.Field().Interface().(bool) + + return ok && val == true +} + func isVariantReference(ctx context.Context, fl validator.FieldLevel) bool { cfg := ctx.Value(rootCfgCtx).(Config) ref := fl.Field().String() |