Skip to content

Commit

Permalink
chore: change from go-playground/validator to Manual Validation for…
Browse files Browse the repository at this point in the history
… settings (aws#4490)
  • Loading branch information
engedaam authored Aug 25, 2023
1 parent 742fa8b commit fe1d11f
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 69 deletions.
6 changes: 0 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ require (
github.com/avast/retry-go v3.0.0+incompatible
github.com/aws/aws-sdk-go v1.44.328
github.com/aws/karpenter-core v0.30.0-rc.0.0.20230824190041-a4c05cede32f
github.com/go-playground/validator/v10 v10.15.1
github.com/imdario/mergo v0.3.16
github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/onsi/ginkgo/v2 v2.11.0
Expand Down Expand Up @@ -46,16 +45,13 @@ require (
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/zapr v1.2.4 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.1 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gobuffalo/flect v0.2.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand All @@ -72,7 +68,6 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand All @@ -87,7 +82,6 @@ require (
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/automaxprocs v1.4.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
Expand Down
15 changes: 0 additions & 15 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJ
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
Expand All @@ -124,14 +122,6 @@ github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTr
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
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.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM=
github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
Expand Down Expand Up @@ -253,8 +243,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
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.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
Expand Down Expand Up @@ -338,7 +326,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down Expand Up @@ -379,8 +366,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down
52 changes: 4 additions & 48 deletions pkg/apis/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,10 @@ import (
"context"
"encoding/json"
"fmt"
"net/url"
"time"

"github.com/go-playground/validator/v10"
"go.uber.org/multierr"
v1 "k8s.io/api/core/v1"
"knative.dev/pkg/apis"
"knative.dev/pkg/configmap"

"github.com/aws/karpenter/pkg/apis/v1alpha1"
)

type settingsKeyType struct{}
Expand All @@ -53,18 +47,18 @@ var defaultSettings = &Settings{
// +k8s:deepcopy-gen=true
type Settings struct {
AssumeRoleARN string
AssumeRoleDuration time.Duration `validate:"min=15m"`
AssumeRoleDuration time.Duration
ClusterCABundle string
ClusterName string `validate:"required"`
ClusterName string
ClusterEndpoint string
DefaultInstanceProfile string
EnablePodENI bool
EnableENILimitedPodDensity bool
IsolatedVPC bool
VMMemoryOverheadPercent float64 `validate:"min=0"`
VMMemoryOverheadPercent float64
InterruptionQueueName string
Tags map[string]string
ReservedENIs int `validate:"min=0"`
ReservedENIs int
}

func (*Settings) ConfigMap() string {
Expand Down Expand Up @@ -98,44 +92,6 @@ func (*Settings) Inject(ctx context.Context, cm *v1.ConfigMap) (context.Context,
return ToContext(ctx, s), nil
}

// Validate leverages struct tags with go-playground/validator so you can define a struct with custom
// validation on fields i.e.
//
// type ExampleStruct struct {
// Example metav1.Duration `json:"example" validate:"required,min=10m"`
// }
func (s Settings) Validate() error {
return multierr.Combine(
s.validateEndpoint(),
s.validateTags(),
validator.New().Struct(s),
)
}

func (s Settings) validateEndpoint() error {
if s.ClusterEndpoint == "" {
return nil
}
endpoint, err := url.Parse(s.ClusterEndpoint)
// url.Parse() will accept a lot of input without error; make
// sure it's a real URL
if err != nil || !endpoint.IsAbs() || endpoint.Hostname() == "" {
return fmt.Errorf("\"%s\" not a valid clusterEndpoint URL", s.ClusterEndpoint)
}
return nil
}

func (s Settings) validateTags() (err error) {
for k := range s.Tags {
for _, pattern := range v1alpha1.RestrictedTagPatterns {
if pattern.MatchString(k) {
err = multierr.Append(err, apis.ErrInvalidKeyName(k, "tags", fmt.Sprintf("tag contains a restricted tag %q", pattern.String())))
}
}
}
return err
}

func ToContext(ctx context.Context, s *Settings) context.Context {
return context.WithValue(ctx, ContextKey, s)
}
Expand Down
88 changes: 88 additions & 0 deletions pkg/apis/settings/settings_validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package settings

import (
"fmt"
"net/url"
"time"

"knative.dev/pkg/apis"

"github.com/aws/karpenter/pkg/apis/v1alpha1"
)

func (s Settings) Validate() (errs *apis.FieldError) {
return errs.Also(
s.validateEndpoint(),
s.validateTags(),
s.validateClusterName(),
s.validateVMMemoryOverheadPercent(),
s.validateReservedENIs(),
s.validateAssumeRoleDuration(),
).ViaField("aws")
}

func (s Settings) validateAssumeRoleDuration() (errs *apis.FieldError) {
if s.AssumeRoleDuration < time.Minute*15 {
return errs.Also(apis.ErrInvalidValue("assumeRoleDuration cannot be less than 15 Minutes", "assumeRoleDuration"))
}
return nil
}

func (s Settings) validateClusterName() (errs *apis.FieldError) {
if s.ClusterName == "" {
return errs.Also(apis.ErrMissingField("clusterName is required", "clusterName"))
}
return nil
}

func (s Settings) validateEndpoint() (errs *apis.FieldError) {
if s.ClusterEndpoint == "" {
return nil
}
endpoint, err := url.Parse(s.ClusterEndpoint)
// url.Parse() will accept a lot of input without error; make
// sure it's a real URL
if err != nil || !endpoint.IsAbs() || endpoint.Hostname() == "" {
return errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%q not a valid clusterEndpoint URL", s.ClusterEndpoint), "clusterEndpoint"))
}
return nil
}

func (s Settings) validateTags() (errs *apis.FieldError) {
for k := range s.Tags {
for _, pattern := range v1alpha1.RestrictedTagPatterns {
if pattern.MatchString(k) {
errs = errs.Also(errs, apis.ErrInvalidKeyName(k, "tags", fmt.Sprintf("tag contains a restricted tag matching the pattern %q", pattern.String())))
}
}
}
return errs
}

func (s Settings) validateVMMemoryOverheadPercent() (errs *apis.FieldError) {
if s.VMMemoryOverheadPercent < 0 {
return errs.Also(apis.ErrInvalidValue("cannot be negative", "vmMemoryOverheadPercent"))
}
return nil
}

func (s Settings) validateReservedENIs() (errs *apis.FieldError) {
if s.ReservedENIs < 0 {
return errs.Also(apis.ErrInvalidValue("cannot be negative", "reservedENIs"))
}
return nil
}

0 comments on commit fe1d11f

Please sign in to comment.