From 8c229f7a93004b60a27850437dddf02d1f9d962f Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Fri, 3 Jan 2025 13:25:53 +0100 Subject: [PATCH] added playground validator to validate the input more. --- cmd/policygen/config.go | 35 ++++++++++++++++++++++------------- cmd/policygen/main.go | 5 ++++- go.mod | 8 ++++++++ go.sum | 24 ++++++++++++++++++++---- 4 files changed, 54 insertions(+), 18 deletions(-) diff --git a/cmd/policygen/config.go b/cmd/policygen/config.go index 1820035..9e7c8ae 100644 --- a/cmd/policygen/config.go +++ b/cmd/policygen/config.go @@ -4,7 +4,9 @@ import ( "bytes" "errors" "fmt" + "github.com/go-playground/validator/v10" "github.com/goccy/go-yaml" + "log" "net" "os" "slices" @@ -41,42 +43,42 @@ func (c CIDR) MarshalYAML() ([]byte, error) { type Port struct { Port string `yaml:"port"` - Protocol string `yaml:"protocol"` + Protocol string `yaml:"protocol,omitempty" validate:"omitempty,oneof=TCP UDP"` } // Network represents each network entry in the YAML type Network struct { - Name string `yaml:"name"` + Name string `yaml:"name" validate:"required"` CIDR CIDR `yaml:"cidr"` - Except []CIDR `yaml:"except,omitempty"` - Ports []Port `yaml:"ports,omitempty"` + Except []CIDR `yaml:"except,omitempty" validate:"dive,required"` + Ports []Port `yaml:"ports,omitempty" validate:"dive,required"` } type Application struct { Name string `yaml:"name"` Ports []Port `yaml:"ports,omitempty"` MatchLabels map[string]string `yaml:"matchLabels"` - Namespace *Namespace `yaml:"-"` + Namespace *Namespace `yaml:"-" validate:"-"` } type Namespace struct { Name string `yaml:"name"` Open bool `yaml:"open"` Capabilities []string `yaml:"capabilities"` - Applications []*Application `yaml:"applications"` + Applications []*Application `yaml:"applications" validate:"dive,required"` } type Communication struct { - From []string `yaml:"from"` - To []string `yaml:"to"` - Ports []Port `yaml:"ports"` + From []string `yaml:"from" validate:"dive,required"` + To []string `yaml:"to" validate:"dive,required"` + Ports []Port `yaml:"ports" validate:"dive,required"` } // Config represents the top-level YAML structure type Config struct { - Networks []*Network `yaml:"networks,omitempty"` - Namespaces []*Namespace `yaml:"namespaces,omitempty"` - Communications []*Communication `yaml:"communications,omitempty"` + Networks []*Network `yaml:"networks,omitempty" validate:"dive,required"` + Namespaces []*Namespace `yaml:"namespaces,omitempty" validate:"dive,required"` + Communications []*Communication `yaml:"communications,omitempty" validate:"dive,required"` } func (c *Config) Update(config *Config) { @@ -85,6 +87,11 @@ func (c *Config) Update(config *Config) { c.Communications = append(c.Communications, config.Communications...) } +func (c Config) ValidateSchema() error { + validate := validator.New(validator.WithRequiredStructEnabled()) + return validate.Struct(c) +} + func (c Config) Validate() error { errs := make([]error, 0) @@ -100,7 +107,8 @@ func (c Config) Validate() error { // network names mus tbe unique networks := make(map[string]bool) - for _, network := range c.Networks { + for nn, network := range c.Networks { + log.Printf("Network %+v %v %v\n", network, nn, c.Networks) if networks[network.Name] { errs = append(errs, fmt.Errorf("Duplicate network name %s", network.Name)) } @@ -174,6 +182,7 @@ func LoadConfig(file string) (*Config, error) { yaml.UseJSONUnmarshaler(), yaml.DisallowUnknownField(), yaml.UseOrderedMap(), + yaml.Strict(), ) var config Config err = dec.Decode(&config) diff --git a/cmd/policygen/main.go b/cmd/policygen/main.go index 4aa8548..c85224d 100644 --- a/cmd/policygen/main.go +++ b/cmd/policygen/main.go @@ -22,7 +22,10 @@ func execute(files []string, options *Options) error { log.Printf("LOADING %s\n", file) configNew, err := LoadConfig(file) if err != nil { - return err + return fmt.Errorf("%s: %w", file, err) + } + if err = configNew.ValidateSchema(); err != nil { + return fmt.Errorf("%s: %w", file, err) } config.Update(configNew) } diff --git a/go.mod b/go.mod index 5ebe6eb..1bed828 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.23.4 require ( github.com/Masterminds/sprig/v3 v3.3.0 + github.com/go-playground/validator/v10 v10.23.0 github.com/goccy/go-yaml v1.15.13 github.com/spf13/cobra v1.8.1 ) @@ -12,13 +13,20 @@ require ( dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/crypto v0.26.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect ) diff --git a/go.sum b/go.sum index 1a0dd84..b6a85ea 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/goccy/go-yaml v1.15.13 h1:Xd87Yddmr2rC1SLLTm2MNDcTjeO/GYo0JGiww6gSTDg= github.com/goccy/go-yaml v1.15.13/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -25,6 +35,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -42,12 +54,16 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=