mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-09 13:12:20 +00:00
Factor out API defaulting from validation logic
Currently, the validation logic validates fields in an object and supply default values wherever applies. This change factors out defaulting to a set of defaulting callback functions for decoding (see #1502 for more discussion). * This change is based on pull request 2587. * Most defaulting has been migrated to defaults.go where the defaulting functions are added. * validation_test.go and converter_test.go have been adapted to not testing the default values. * Fixed all tests with that create invalid objects with the absence of defaulting logic.
This commit is contained in:
@@ -32,6 +32,14 @@ import (
|
||||
"speter.net/go/exp/math/dec/inf"
|
||||
)
|
||||
|
||||
func fuzzOneOf(c fuzz.Continue, objs ...interface{}) {
|
||||
// Use a new fuzzer which cannot populate nil to ensure one obj will be set.
|
||||
// FIXME: would be nicer to use FuzzOnePtr() and reflect.
|
||||
f := fuzz.New().NilChance(0).NumElements(1, 1)
|
||||
i := c.RandUint64() % uint64(len(objs))
|
||||
f.Fuzz(objs[i])
|
||||
}
|
||||
|
||||
// FuzzerFor can randomly populate api objects that are destined for version.
|
||||
func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
|
||||
f := fuzz.New().NilChance(.5).NumElements(1, 1)
|
||||
@@ -84,15 +92,18 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
|
||||
statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown}
|
||||
*j = statuses[c.Rand.Intn(len(statuses))]
|
||||
},
|
||||
func(j *api.PodTemplateSpec, c fuzz.Continue) {
|
||||
// TODO: v1beta1/2 can't round trip a nil template correctly, fix by having v1beta1/2
|
||||
// conversion compare converted object to nil via DeepEqual
|
||||
j.ObjectMeta = api.ObjectMeta{}
|
||||
c.Fuzz(&j.ObjectMeta)
|
||||
j.ObjectMeta = api.ObjectMeta{Labels: j.ObjectMeta.Labels}
|
||||
j.Spec = api.PodSpec{}
|
||||
c.Fuzz(&j.Spec)
|
||||
},
|
||||
func(j *api.ReplicationControllerSpec, c fuzz.Continue) {
|
||||
// TemplateRef must be nil for round trip
|
||||
// TemplateRef is set to nil by omission; this is required for round trip
|
||||
c.Fuzz(&j.Template)
|
||||
if j.Template == nil {
|
||||
// TODO: v1beta1/2 can't round trip a nil template correctly, fix by having v1beta1/2
|
||||
// conversion compare converted object to nil via DeepEqual
|
||||
j.Template = &api.PodTemplateSpec{}
|
||||
}
|
||||
j.Template.ObjectMeta = api.ObjectMeta{Labels: j.Template.ObjectMeta.Labels}
|
||||
c.Fuzz(&j.Selector)
|
||||
j.Replicas = int(c.RandUint64())
|
||||
},
|
||||
@@ -160,6 +171,46 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
|
||||
policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent}
|
||||
*p = policies[c.Rand.Intn(len(policies))]
|
||||
},
|
||||
func(rp *api.RestartPolicy, c fuzz.Continue) {
|
||||
// Exactly one of the fields should be set.
|
||||
fuzzOneOf(c, &rp.Always, &rp.OnFailure, &rp.Never)
|
||||
},
|
||||
func(vs *api.VolumeSource, c fuzz.Continue) {
|
||||
// Exactly one of the fields should be set.
|
||||
//FIXME: the fuzz can still end up nil. What if fuzz allowed me to say that?
|
||||
fuzzOneOf(c, &vs.HostPath, &vs.EmptyDir, &vs.GCEPersistentDisk, &vs.GitRepo)
|
||||
},
|
||||
func(d *api.DNSPolicy, c fuzz.Continue) {
|
||||
policies := []api.DNSPolicy{api.DNSClusterFirst, api.DNSDefault}
|
||||
*d = policies[c.Rand.Intn(len(policies))]
|
||||
},
|
||||
func(p *api.Protocol, c fuzz.Continue) {
|
||||
protocols := []api.Protocol{api.ProtocolTCP, api.ProtocolUDP}
|
||||
*p = protocols[c.Rand.Intn(len(protocols))]
|
||||
},
|
||||
func(p *api.AffinityType, c fuzz.Continue) {
|
||||
types := []api.AffinityType{api.AffinityTypeClientIP, api.AffinityTypeNone}
|
||||
*p = types[c.Rand.Intn(len(types))]
|
||||
},
|
||||
func(ct *api.Container, c fuzz.Continue) {
|
||||
// This function exists soley to set TerminationMessagePath to a
|
||||
// non-empty string. TODO: consider making TerminationMessagePath a
|
||||
// new type to simplify fuzzing.
|
||||
ct.TerminationMessagePath = api.TerminationMessagePathDefault
|
||||
// Let fuzzer handle the rest of the fileds.
|
||||
c.Fuzz(&ct.Name)
|
||||
c.Fuzz(&ct.Image)
|
||||
c.Fuzz(&ct.Command)
|
||||
c.Fuzz(&ct.Ports)
|
||||
c.Fuzz(&ct.WorkingDir)
|
||||
c.Fuzz(&ct.Env)
|
||||
c.Fuzz(&ct.VolumeMounts)
|
||||
c.Fuzz(&ct.LivenessProbe)
|
||||
c.Fuzz(&ct.Lifecycle)
|
||||
c.Fuzz(&ct.ImagePullPolicy)
|
||||
c.Fuzz(&ct.Privileged)
|
||||
c.Fuzz(&ct.Capabilities)
|
||||
},
|
||||
)
|
||||
return f
|
||||
}
|
||||
|
Reference in New Issue
Block a user