diff --git a/federation/registry/cluster/BUILD b/federation/registry/cluster/BUILD index e9461311a18..cee61740c2e 100644 --- a/federation/registry/cluster/BUILD +++ b/federation/registry/cluster/BUILD @@ -42,6 +42,7 @@ go_test( deps = [ "//federation/apis/federation:go_default_library", "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", diff --git a/federation/registry/cluster/strategy_test.go b/federation/registry/cluster/strategy_test.go index f01a82976d4..8a53ad3f292 100644 --- a/federation/registry/cluster/strategy_test.go +++ b/federation/registry/cluster/strategy_test.go @@ -28,6 +28,9 @@ import ( "k8s.io/kubernetes/federation/apis/federation" "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func validNewCluster() *federation.Cluster { diff --git a/pkg/api/BUILD b/pkg/api/BUILD index a19431bbb15..4c15747dd47 100644 --- a/pkg/api/BUILD +++ b/pkg/api/BUILD @@ -108,6 +108,7 @@ filegroup( "//pkg/api/endpoints:all-srcs", "//pkg/api/errors:all-srcs", "//pkg/api/events:all-srcs", + "//pkg/api/fuzzer:all-srcs", "//pkg/api/helper:all-srcs", "//pkg/api/install:all-srcs", "//pkg/api/meta:all-srcs", diff --git a/pkg/api/fuzzer/BUILD b/pkg/api/fuzzer/BUILD new file mode 100644 index 00000000000..7b5ef881c23 --- /dev/null +++ b/pkg/api/fuzzer/BUILD @@ -0,0 +1,38 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/api:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/api/fuzzer/fuzzer.go b/pkg/api/fuzzer/fuzzer.go new file mode 100644 index 00000000000..9d0f94a2678 --- /dev/null +++ b/pkg/api/fuzzer/fuzzer.go @@ -0,0 +1,443 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + "reflect" + "strconv" + + fuzz "github.com/google/gofuzz" + + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/kubernetes/pkg/api" +) + +// Funcs returns the fuzzer functions for the core api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(q *resource.Quantity, c fuzz.Continue) { + *q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent) + }, + func(j *api.ObjectReference, c fuzz.Continue) { + // We have to customize the randomization of TypeMetas because their + // APIVersion and Kind must remain blank in memory. + j.APIVersion = c.RandString() + j.Kind = c.RandString() + j.Namespace = c.RandString() + j.Name = c.RandString() + j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) + j.FieldPath = c.RandString() + }, + func(j *api.ListOptions, c fuzz.Continue) { + label, _ := labels.Parse("a=b") + j.LabelSelector = label + field, _ := fields.ParseSelector("a=b") + j.FieldSelector = field + }, + func(j *api.PodExecOptions, c fuzz.Continue) { + j.Stdout = true + j.Stderr = true + }, + func(j *api.PodAttachOptions, c fuzz.Continue) { + j.Stdout = true + j.Stderr = true + }, + func(j *api.PodPortForwardOptions, c fuzz.Continue) { + if c.RandBool() { + j.Ports = make([]int32, c.Intn(10)) + for i := range j.Ports { + j.Ports[i] = c.Int31n(65535) + } + } + }, + func(s *api.PodSpec, c fuzz.Continue) { + c.FuzzNoCustom(s) + // has a default value + ttl := int64(30) + if c.RandBool() { + ttl = int64(c.Uint32()) + } + s.TerminationGracePeriodSeconds = &ttl + + c.Fuzz(s.SecurityContext) + + if s.SecurityContext == nil { + s.SecurityContext = new(api.PodSecurityContext) + } + if s.Affinity == nil { + s.Affinity = new(api.Affinity) + } + if s.SchedulerName == "" { + s.SchedulerName = api.DefaultSchedulerName + } + }, + func(j *api.PodPhase, c fuzz.Continue) { + statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} + *j = statuses[c.Rand.Intn(len(statuses))] + }, + func(j *api.Binding, c fuzz.Continue) { + c.Fuzz(&j.ObjectMeta) + j.Target.Name = c.RandString() + }, + func(j *api.ReplicationControllerSpec, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + //j.TemplateRef = nil // this is required for round trip + }, + func(j *api.List, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + // TODO: uncomment when round trip starts from a versioned object + if false { //j.Items == nil { + j.Items = []runtime.Object{} + } + }, + func(q *api.ResourceRequirements, c fuzz.Continue) { + randomQuantity := func() resource.Quantity { + var q resource.Quantity + c.Fuzz(&q) + // precalc the string for benchmarking purposes + _ = q.String() + return q + } + q.Limits = make(api.ResourceList) + q.Requests = make(api.ResourceList) + cpuLimit := randomQuantity() + q.Limits[api.ResourceCPU] = *cpuLimit.Copy() + q.Requests[api.ResourceCPU] = *cpuLimit.Copy() + memoryLimit := randomQuantity() + q.Limits[api.ResourceMemory] = *memoryLimit.Copy() + q.Requests[api.ResourceMemory] = *memoryLimit.Copy() + storageLimit := randomQuantity() + q.Limits[api.ResourceStorage] = *storageLimit.Copy() + q.Requests[api.ResourceStorage] = *storageLimit.Copy() + }, + func(q *api.LimitRangeItem, c fuzz.Continue) { + var cpuLimit resource.Quantity + c.Fuzz(&cpuLimit) + + q.Type = api.LimitTypeContainer + q.Default = make(api.ResourceList) + q.Default[api.ResourceCPU] = *(cpuLimit.Copy()) + + q.DefaultRequest = make(api.ResourceList) + q.DefaultRequest[api.ResourceCPU] = *(cpuLimit.Copy()) + + q.Max = make(api.ResourceList) + q.Max[api.ResourceCPU] = *(cpuLimit.Copy()) + + q.Min = make(api.ResourceList) + q.Min[api.ResourceCPU] = *(cpuLimit.Copy()) + + q.MaxLimitRequestRatio = make(api.ResourceList) + q.MaxLimitRequestRatio[api.ResourceCPU] = resource.MustParse("10") + }, + func(p *api.PullPolicy, c fuzz.Continue) { + policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent} + *p = policies[c.Rand.Intn(len(policies))] + }, + func(rp *api.RestartPolicy, c fuzz.Continue) { + policies := []api.RestartPolicy{api.RestartPolicyAlways, api.RestartPolicyNever, api.RestartPolicyOnFailure} + *rp = policies[c.Rand.Intn(len(policies))] + }, + // api.DownwardAPIVolumeFile needs to have a specific func since FieldRef has to be + // defaulted to a version otherwise roundtrip will fail + func(m *api.DownwardAPIVolumeFile, c fuzz.Continue) { + m.Path = c.RandString() + versions := []string{"v1"} + m.FieldRef = &api.ObjectFieldSelector{} + m.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))] + m.FieldRef.FieldPath = c.RandString() + c.Fuzz(m.Mode) + if m.Mode != nil { + *m.Mode &= 0777 + } + }, + func(s *api.SecretVolumeSource, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + + if c.RandBool() { + opt := c.RandBool() + s.Optional = &opt + } + // DefaultMode should always be set, it has a default + // value and it is expected to be between 0 and 0777 + var mode int32 + c.Fuzz(&mode) + mode &= 0777 + s.DefaultMode = &mode + }, + func(cm *api.ConfigMapVolumeSource, c fuzz.Continue) { + c.FuzzNoCustom(cm) // fuzz self without calling this function again + + if c.RandBool() { + opt := c.RandBool() + cm.Optional = &opt + } + // DefaultMode should always be set, it has a default + // value and it is expected to be between 0 and 0777 + var mode int32 + c.Fuzz(&mode) + mode &= 0777 + cm.DefaultMode = &mode + }, + func(d *api.DownwardAPIVolumeSource, c fuzz.Continue) { + c.FuzzNoCustom(d) // fuzz self without calling this function again + + // DefaultMode should always be set, it has a default + // value and it is expected to be between 0 and 0777 + var mode int32 + c.Fuzz(&mode) + mode &= 0777 + d.DefaultMode = &mode + }, + func(s *api.ProjectedVolumeSource, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + + // DefaultMode should always be set, it has a default + // value and it is expected to be between 0 and 0777 + var mode int32 + c.Fuzz(&mode) + mode &= 0777 + s.DefaultMode = &mode + }, + func(k *api.KeyToPath, c fuzz.Continue) { + c.FuzzNoCustom(k) // fuzz self without calling this function again + k.Key = c.RandString() + k.Path = c.RandString() + + // Mode is not mandatory, but if it is set, it should be + // a value between 0 and 0777 + if k.Mode != nil { + *k.Mode &= 0777 + } + }, + func(vs *api.VolumeSource, c fuzz.Continue) { + // Exactly one of the fields must be set. + v := reflect.ValueOf(vs).Elem() + i := int(c.RandUint64() % uint64(v.NumField())) + t := v.Field(i).Addr() + for v.Field(i).IsNil() { + c.Fuzz(t.Interface()) + } + }, + func(i *api.ISCSIVolumeSource, c fuzz.Continue) { + i.ISCSIInterface = c.RandString() + if i.ISCSIInterface == "" { + i.ISCSIInterface = "default" + } + }, + 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.ServiceAffinity, c fuzz.Continue) { + types := []api.ServiceAffinity{api.ServiceAffinityClientIP, api.ServiceAffinityNone} + *p = types[c.Rand.Intn(len(types))] + }, + func(p *api.ServiceType, c fuzz.Continue) { + types := []api.ServiceType{api.ServiceTypeClusterIP, api.ServiceTypeNodePort, api.ServiceTypeLoadBalancer} + *p = types[c.Rand.Intn(len(types))] + }, + func(p *api.ServiceExternalTrafficPolicyType, c fuzz.Continue) { + types := []api.ServiceExternalTrafficPolicyType{api.ServiceExternalTrafficPolicyTypeCluster, api.ServiceExternalTrafficPolicyTypeLocal} + *p = types[c.Rand.Intn(len(types))] + }, + func(ct *api.Container, c fuzz.Continue) { + c.FuzzNoCustom(ct) // fuzz self without calling this function again + ct.TerminationMessagePath = "/" + ct.TerminationMessagePath // Must be non-empty + ct.TerminationMessagePolicy = "File" + }, + func(p *api.Probe, c fuzz.Continue) { + c.FuzzNoCustom(p) + // These fields have default values. + intFieldsWithDefaults := [...]string{"TimeoutSeconds", "PeriodSeconds", "SuccessThreshold", "FailureThreshold"} + v := reflect.ValueOf(p).Elem() + for _, field := range intFieldsWithDefaults { + f := v.FieldByName(field) + if f.Int() == 0 { + f.SetInt(1) + } + } + }, + func(ev *api.EnvVar, c fuzz.Continue) { + ev.Name = c.RandString() + if c.RandBool() { + ev.Value = c.RandString() + } else { + ev.ValueFrom = &api.EnvVarSource{} + ev.ValueFrom.FieldRef = &api.ObjectFieldSelector{} + + versions := []schema.GroupVersion{ + {Group: "admission.k8s.io", Version: "v1alpha1"}, + {Group: "apps", Version: "v1beta1"}, + {Group: "apps", Version: "v1beta2"}, + {Group: "foo", Version: "v42"}, + } + + ev.ValueFrom.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))].String() + ev.ValueFrom.FieldRef.FieldPath = c.RandString() + } + }, + func(ev *api.EnvFromSource, c fuzz.Continue) { + if c.RandBool() { + ev.Prefix = "p_" + } + if c.RandBool() { + c.Fuzz(&ev.ConfigMapRef) + } else { + c.Fuzz(&ev.SecretRef) + } + }, + func(cm *api.ConfigMapEnvSource, c fuzz.Continue) { + c.FuzzNoCustom(cm) // fuzz self without calling this function again + if c.RandBool() { + opt := c.RandBool() + cm.Optional = &opt + } + }, + func(s *api.SecretEnvSource, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + }, + func(sc *api.SecurityContext, c fuzz.Continue) { + c.FuzzNoCustom(sc) // fuzz self without calling this function again + if c.RandBool() { + priv := c.RandBool() + sc.Privileged = &priv + } + + if c.RandBool() { + sc.Capabilities = &api.Capabilities{ + Add: make([]api.Capability, 0), + Drop: make([]api.Capability, 0), + } + c.Fuzz(&sc.Capabilities.Add) + c.Fuzz(&sc.Capabilities.Drop) + } + }, + func(s *api.Secret, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + s.Type = api.SecretTypeOpaque + }, + func(r *api.RBDVolumeSource, c fuzz.Continue) { + r.RBDPool = c.RandString() + if r.RBDPool == "" { + r.RBDPool = "rbd" + } + r.RadosUser = c.RandString() + if r.RadosUser == "" { + r.RadosUser = "admin" + } + r.Keyring = c.RandString() + if r.Keyring == "" { + r.Keyring = "/etc/ceph/keyring" + } + }, + func(pv *api.PersistentVolume, c fuzz.Continue) { + c.FuzzNoCustom(pv) // fuzz self without calling this function again + types := []api.PersistentVolumePhase{api.VolumeAvailable, api.VolumePending, api.VolumeBound, api.VolumeReleased, api.VolumeFailed} + pv.Status.Phase = types[c.Rand.Intn(len(types))] + pv.Status.Message = c.RandString() + reclamationPolicies := []api.PersistentVolumeReclaimPolicy{api.PersistentVolumeReclaimRecycle, api.PersistentVolumeReclaimRetain} + pv.Spec.PersistentVolumeReclaimPolicy = reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))] + }, + func(pvc *api.PersistentVolumeClaim, c fuzz.Continue) { + c.FuzzNoCustom(pvc) // fuzz self without calling this function again + types := []api.PersistentVolumeClaimPhase{api.ClaimBound, api.ClaimPending, api.ClaimLost} + pvc.Status.Phase = types[c.Rand.Intn(len(types))] + }, + func(obj *api.AzureDiskVolumeSource, c fuzz.Continue) { + if obj.CachingMode == nil { + obj.CachingMode = new(api.AzureDataDiskCachingMode) + *obj.CachingMode = api.AzureDataDiskCachingReadWrite + } + if obj.Kind == nil { + obj.Kind = new(api.AzureDataDiskKind) + *obj.Kind = api.AzureSharedBlobDisk + } + if obj.FSType == nil { + obj.FSType = new(string) + *obj.FSType = "ext4" + } + if obj.ReadOnly == nil { + obj.ReadOnly = new(bool) + *obj.ReadOnly = false + } + }, + func(sio *api.ScaleIOVolumeSource, c fuzz.Continue) { + sio.ProtectionDomain = c.RandString() + if sio.ProtectionDomain == "" { + sio.ProtectionDomain = "default" + } + sio.StoragePool = c.RandString() + if sio.StoragePool == "" { + sio.StoragePool = "default" + } + sio.StorageMode = c.RandString() + if sio.StorageMode == "" { + sio.StorageMode = "ThinProvisioned" + } + sio.FSType = c.RandString() + if sio.FSType == "" { + sio.FSType = "xfs" + } + }, + func(s *api.NamespaceSpec, c fuzz.Continue) { + s.Finalizers = []api.FinalizerName{api.FinalizerKubernetes} + }, + func(s *api.NamespaceStatus, c fuzz.Continue) { + s.Phase = api.NamespaceActive + }, + func(http *api.HTTPGetAction, c fuzz.Continue) { + c.FuzzNoCustom(http) // fuzz self without calling this function again + http.Path = "/" + http.Path // can't be blank + http.Scheme = "x" + http.Scheme // can't be blank + }, + func(ss *api.ServiceSpec, c fuzz.Continue) { + c.FuzzNoCustom(ss) // fuzz self without calling this function again + if len(ss.Ports) == 0 { + // There must be at least 1 port. + ss.Ports = append(ss.Ports, api.ServicePort{}) + c.Fuzz(&ss.Ports[0]) + } + for i := range ss.Ports { + switch ss.Ports[i].TargetPort.Type { + case intstr.Int: + ss.Ports[i].TargetPort.IntVal = 1 + ss.Ports[i].TargetPort.IntVal%65535 // non-zero + case intstr.String: + ss.Ports[i].TargetPort.StrVal = "x" + ss.Ports[i].TargetPort.StrVal // non-empty + } + } + }, + func(n *api.Node, c fuzz.Continue) { + c.FuzzNoCustom(n) + n.Spec.ExternalID = "external" + }, + func(s *api.NodeStatus, c fuzz.Continue) { + c.FuzzNoCustom(s) + s.Allocatable = s.Capacity + }, + } +} diff --git a/pkg/api/testing/BUILD b/pkg/api/testing/BUILD index a0858217a65..e1fdcbb0e47 100644 --- a/pkg/api/testing/BUILD +++ b/pkg/api/testing/BUILD @@ -18,29 +18,25 @@ go_library( deps = [ "//cmd/kubeadm/app/apis/kubeadm/fuzzer:go_default_library", "//pkg/api:go_default_library", - "//pkg/api/testapi:go_default_library", - "//pkg/apis/admissionregistration:go_default_library", - "//pkg/apis/apps:go_default_library", - "//pkg/apis/autoscaling:go_default_library", - "//pkg/apis/batch:go_default_library", - "//pkg/apis/certificates:go_default_library", + "//pkg/api/fuzzer:go_default_library", + "//pkg/apis/admissionregistration/fuzzer:go_default_library", + "//pkg/apis/apps/fuzzer:go_default_library", + "//pkg/apis/autoscaling/fuzzer:go_default_library", + "//pkg/apis/batch/fuzzer:go_default_library", + "//pkg/apis/certificates/fuzzer:go_default_library", "//pkg/apis/extensions:go_default_library", + "//pkg/apis/extensions/fuzzer:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", - "//pkg/apis/policy:go_default_library", - "//pkg/apis/rbac:go_default_library", + "//pkg/apis/policy/fuzzer:go_default_library", + "//pkg/apis/rbac/fuzzer:go_default_library", "//vendor/github.com/google/gofuzz:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library", ], ) diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index 56492941243..cb1d85ecb8a 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -18,35 +18,28 @@ package testing import ( "fmt" - "reflect" - "strconv" "github.com/google/gofuzz" "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" apitesting "k8s.io/apimachinery/pkg/api/testing" "k8s.io/apimachinery/pkg/api/testing/fuzzer" genericfuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/util/intstr" kubeadmfuzzer "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/apis/admissionregistration" - "k8s.io/kubernetes/pkg/apis/apps" - "k8s.io/kubernetes/pkg/apis/autoscaling" - "k8s.io/kubernetes/pkg/apis/batch" - "k8s.io/kubernetes/pkg/apis/certificates" + corefuzzer "k8s.io/kubernetes/pkg/api/fuzzer" + admissionregistrationfuzzer "k8s.io/kubernetes/pkg/apis/admissionregistration/fuzzer" + appsfuzzer "k8s.io/kubernetes/pkg/apis/apps/fuzzer" + autoscalingfuzzer "k8s.io/kubernetes/pkg/apis/autoscaling/fuzzer" + batchfuzzer "k8s.io/kubernetes/pkg/apis/batch/fuzzer" + certificatesfuzzer "k8s.io/kubernetes/pkg/apis/certificates/fuzzer" "k8s.io/kubernetes/pkg/apis/extensions" + extensionsfuzzer "k8s.io/kubernetes/pkg/apis/extensions/fuzzer" extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" - "k8s.io/kubernetes/pkg/apis/policy" - "k8s.io/kubernetes/pkg/apis/rbac" + policyfuzzer "k8s.io/kubernetes/pkg/apis/policy/fuzzer" + rbacfuzzer "k8s.io/kubernetes/pkg/apis/rbac/fuzzer" ) // overrideGenericFuncs override some generic fuzzer funcs from k8s.io/apiserver in order to have more realistic @@ -94,702 +87,17 @@ func overrideGenericFuncs(codecs runtimeserializer.CodecFactory) []interface{} { } } -func coreFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(q *resource.Quantity, c fuzz.Continue) { - *q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent) - }, - func(j *api.ObjectReference, c fuzz.Continue) { - // We have to customize the randomization of TypeMetas because their - // APIVersion and Kind must remain blank in memory. - j.APIVersion = c.RandString() - j.Kind = c.RandString() - j.Namespace = c.RandString() - j.Name = c.RandString() - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.FieldPath = c.RandString() - }, - func(j *api.ListOptions, c fuzz.Continue) { - label, _ := labels.Parse("a=b") - j.LabelSelector = label - field, _ := fields.ParseSelector("a=b") - j.FieldSelector = field - }, - func(j *api.PodExecOptions, c fuzz.Continue) { - j.Stdout = true - j.Stderr = true - }, - func(j *api.PodAttachOptions, c fuzz.Continue) { - j.Stdout = true - j.Stderr = true - }, - func(j *api.PodPortForwardOptions, c fuzz.Continue) { - if c.RandBool() { - j.Ports = make([]int32, c.Intn(10)) - for i := range j.Ports { - j.Ports[i] = c.Int31n(65535) - } - } - }, - func(s *api.PodSpec, c fuzz.Continue) { - c.FuzzNoCustom(s) - // has a default value - ttl := int64(30) - if c.RandBool() { - ttl = int64(c.Uint32()) - } - s.TerminationGracePeriodSeconds = &ttl - - c.Fuzz(s.SecurityContext) - - if s.SecurityContext == nil { - s.SecurityContext = new(api.PodSecurityContext) - } - if s.Affinity == nil { - s.Affinity = new(api.Affinity) - } - if s.SchedulerName == "" { - s.SchedulerName = api.DefaultSchedulerName - } - }, - func(j *api.PodPhase, c fuzz.Continue) { - statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} - *j = statuses[c.Rand.Intn(len(statuses))] - }, - func(j *api.Binding, c fuzz.Continue) { - c.Fuzz(&j.ObjectMeta) - j.Target.Name = c.RandString() - }, - func(j *api.ReplicationControllerSpec, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - //j.TemplateRef = nil // this is required for round trip - }, - func(j *api.List, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - // TODO: uncomment when round trip starts from a versioned object - if false { //j.Items == nil { - j.Items = []runtime.Object{} - } - }, - func(q *api.ResourceRequirements, c fuzz.Continue) { - randomQuantity := func() resource.Quantity { - var q resource.Quantity - c.Fuzz(&q) - // precalc the string for benchmarking purposes - _ = q.String() - return q - } - q.Limits = make(api.ResourceList) - q.Requests = make(api.ResourceList) - cpuLimit := randomQuantity() - q.Limits[api.ResourceCPU] = *cpuLimit.Copy() - q.Requests[api.ResourceCPU] = *cpuLimit.Copy() - memoryLimit := randomQuantity() - q.Limits[api.ResourceMemory] = *memoryLimit.Copy() - q.Requests[api.ResourceMemory] = *memoryLimit.Copy() - storageLimit := randomQuantity() - q.Limits[api.ResourceStorage] = *storageLimit.Copy() - q.Requests[api.ResourceStorage] = *storageLimit.Copy() - }, - func(q *api.LimitRangeItem, c fuzz.Continue) { - var cpuLimit resource.Quantity - c.Fuzz(&cpuLimit) - - q.Type = api.LimitTypeContainer - q.Default = make(api.ResourceList) - q.Default[api.ResourceCPU] = *(cpuLimit.Copy()) - - q.DefaultRequest = make(api.ResourceList) - q.DefaultRequest[api.ResourceCPU] = *(cpuLimit.Copy()) - - q.Max = make(api.ResourceList) - q.Max[api.ResourceCPU] = *(cpuLimit.Copy()) - - q.Min = make(api.ResourceList) - q.Min[api.ResourceCPU] = *(cpuLimit.Copy()) - - q.MaxLimitRequestRatio = make(api.ResourceList) - q.MaxLimitRequestRatio[api.ResourceCPU] = resource.MustParse("10") - }, - func(p *api.PullPolicy, c fuzz.Continue) { - policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent} - *p = policies[c.Rand.Intn(len(policies))] - }, - func(rp *api.RestartPolicy, c fuzz.Continue) { - policies := []api.RestartPolicy{api.RestartPolicyAlways, api.RestartPolicyNever, api.RestartPolicyOnFailure} - *rp = policies[c.Rand.Intn(len(policies))] - }, - // api.DownwardAPIVolumeFile needs to have a specific func since FieldRef has to be - // defaulted to a version otherwise roundtrip will fail - func(m *api.DownwardAPIVolumeFile, c fuzz.Continue) { - m.Path = c.RandString() - versions := []string{"v1"} - m.FieldRef = &api.ObjectFieldSelector{} - m.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))] - m.FieldRef.FieldPath = c.RandString() - c.Fuzz(m.Mode) - if m.Mode != nil { - *m.Mode &= 0777 - } - }, - func(s *api.SecretVolumeSource, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - - if c.RandBool() { - opt := c.RandBool() - s.Optional = &opt - } - // DefaultMode should always be set, it has a default - // value and it is expected to be between 0 and 0777 - var mode int32 - c.Fuzz(&mode) - mode &= 0777 - s.DefaultMode = &mode - }, - func(cm *api.ConfigMapVolumeSource, c fuzz.Continue) { - c.FuzzNoCustom(cm) // fuzz self without calling this function again - - if c.RandBool() { - opt := c.RandBool() - cm.Optional = &opt - } - // DefaultMode should always be set, it has a default - // value and it is expected to be between 0 and 0777 - var mode int32 - c.Fuzz(&mode) - mode &= 0777 - cm.DefaultMode = &mode - }, - func(d *api.DownwardAPIVolumeSource, c fuzz.Continue) { - c.FuzzNoCustom(d) // fuzz self without calling this function again - - // DefaultMode should always be set, it has a default - // value and it is expected to be between 0 and 0777 - var mode int32 - c.Fuzz(&mode) - mode &= 0777 - d.DefaultMode = &mode - }, - func(s *api.ProjectedVolumeSource, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - - // DefaultMode should always be set, it has a default - // value and it is expected to be between 0 and 0777 - var mode int32 - c.Fuzz(&mode) - mode &= 0777 - s.DefaultMode = &mode - }, - func(k *api.KeyToPath, c fuzz.Continue) { - c.FuzzNoCustom(k) // fuzz self without calling this function again - k.Key = c.RandString() - k.Path = c.RandString() - - // Mode is not mandatory, but if it is set, it should be - // a value between 0 and 0777 - if k.Mode != nil { - *k.Mode &= 0777 - } - }, - func(vs *api.VolumeSource, c fuzz.Continue) { - // Exactly one of the fields must be set. - v := reflect.ValueOf(vs).Elem() - i := int(c.RandUint64() % uint64(v.NumField())) - t := v.Field(i).Addr() - for v.Field(i).IsNil() { - c.Fuzz(t.Interface()) - } - }, - func(i *api.ISCSIVolumeSource, c fuzz.Continue) { - i.ISCSIInterface = c.RandString() - if i.ISCSIInterface == "" { - i.ISCSIInterface = "default" - } - }, - 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.ServiceAffinity, c fuzz.Continue) { - types := []api.ServiceAffinity{api.ServiceAffinityClientIP, api.ServiceAffinityNone} - *p = types[c.Rand.Intn(len(types))] - }, - func(p *api.ServiceType, c fuzz.Continue) { - types := []api.ServiceType{api.ServiceTypeClusterIP, api.ServiceTypeNodePort, api.ServiceTypeLoadBalancer} - *p = types[c.Rand.Intn(len(types))] - }, - func(p *api.ServiceExternalTrafficPolicyType, c fuzz.Continue) { - types := []api.ServiceExternalTrafficPolicyType{api.ServiceExternalTrafficPolicyTypeCluster, api.ServiceExternalTrafficPolicyTypeLocal} - *p = types[c.Rand.Intn(len(types))] - }, - func(ct *api.Container, c fuzz.Continue) { - c.FuzzNoCustom(ct) // fuzz self without calling this function again - ct.TerminationMessagePath = "/" + ct.TerminationMessagePath // Must be non-empty - ct.TerminationMessagePolicy = "File" - }, - func(p *api.Probe, c fuzz.Continue) { - c.FuzzNoCustom(p) - // These fields have default values. - intFieldsWithDefaults := [...]string{"TimeoutSeconds", "PeriodSeconds", "SuccessThreshold", "FailureThreshold"} - v := reflect.ValueOf(p).Elem() - for _, field := range intFieldsWithDefaults { - f := v.FieldByName(field) - if f.Int() == 0 { - f.SetInt(1) - } - } - }, - func(ev *api.EnvVar, c fuzz.Continue) { - ev.Name = c.RandString() - if c.RandBool() { - ev.Value = c.RandString() - } else { - ev.ValueFrom = &api.EnvVarSource{} - ev.ValueFrom.FieldRef = &api.ObjectFieldSelector{} - - var versions []schema.GroupVersion - for _, testGroup := range testapi.Groups { - versions = append(versions, *testGroup.GroupVersion()) - } - - ev.ValueFrom.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))].String() - ev.ValueFrom.FieldRef.FieldPath = c.RandString() - } - }, - func(ev *api.EnvFromSource, c fuzz.Continue) { - if c.RandBool() { - ev.Prefix = "p_" - } - if c.RandBool() { - c.Fuzz(&ev.ConfigMapRef) - } else { - c.Fuzz(&ev.SecretRef) - } - }, - func(cm *api.ConfigMapEnvSource, c fuzz.Continue) { - c.FuzzNoCustom(cm) // fuzz self without calling this function again - if c.RandBool() { - opt := c.RandBool() - cm.Optional = &opt - } - }, - func(s *api.SecretEnvSource, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - }, - func(sc *api.SecurityContext, c fuzz.Continue) { - c.FuzzNoCustom(sc) // fuzz self without calling this function again - if c.RandBool() { - priv := c.RandBool() - sc.Privileged = &priv - } - - if c.RandBool() { - sc.Capabilities = &api.Capabilities{ - Add: make([]api.Capability, 0), - Drop: make([]api.Capability, 0), - } - c.Fuzz(&sc.Capabilities.Add) - c.Fuzz(&sc.Capabilities.Drop) - } - }, - func(s *api.Secret, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - s.Type = api.SecretTypeOpaque - }, - func(r *api.RBDVolumeSource, c fuzz.Continue) { - r.RBDPool = c.RandString() - if r.RBDPool == "" { - r.RBDPool = "rbd" - } - r.RadosUser = c.RandString() - if r.RadosUser == "" { - r.RadosUser = "admin" - } - r.Keyring = c.RandString() - if r.Keyring == "" { - r.Keyring = "/etc/ceph/keyring" - } - }, - func(pv *api.PersistentVolume, c fuzz.Continue) { - c.FuzzNoCustom(pv) // fuzz self without calling this function again - types := []api.PersistentVolumePhase{api.VolumeAvailable, api.VolumePending, api.VolumeBound, api.VolumeReleased, api.VolumeFailed} - pv.Status.Phase = types[c.Rand.Intn(len(types))] - pv.Status.Message = c.RandString() - reclamationPolicies := []api.PersistentVolumeReclaimPolicy{api.PersistentVolumeReclaimRecycle, api.PersistentVolumeReclaimRetain} - pv.Spec.PersistentVolumeReclaimPolicy = reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))] - }, - func(pvc *api.PersistentVolumeClaim, c fuzz.Continue) { - c.FuzzNoCustom(pvc) // fuzz self without calling this function again - types := []api.PersistentVolumeClaimPhase{api.ClaimBound, api.ClaimPending, api.ClaimLost} - pvc.Status.Phase = types[c.Rand.Intn(len(types))] - }, - func(obj *api.AzureDiskVolumeSource, c fuzz.Continue) { - if obj.CachingMode == nil { - obj.CachingMode = new(api.AzureDataDiskCachingMode) - *obj.CachingMode = api.AzureDataDiskCachingReadWrite - } - if obj.Kind == nil { - obj.Kind = new(api.AzureDataDiskKind) - *obj.Kind = api.AzureSharedBlobDisk - } - if obj.FSType == nil { - obj.FSType = new(string) - *obj.FSType = "ext4" - } - if obj.ReadOnly == nil { - obj.ReadOnly = new(bool) - *obj.ReadOnly = false - } - }, - func(sio *api.ScaleIOVolumeSource, c fuzz.Continue) { - sio.ProtectionDomain = c.RandString() - if sio.ProtectionDomain == "" { - sio.ProtectionDomain = "default" - } - sio.StoragePool = c.RandString() - if sio.StoragePool == "" { - sio.StoragePool = "default" - } - sio.StorageMode = c.RandString() - if sio.StorageMode == "" { - sio.StorageMode = "ThinProvisioned" - } - sio.FSType = c.RandString() - if sio.FSType == "" { - sio.FSType = "xfs" - } - }, - func(s *api.NamespaceSpec, c fuzz.Continue) { - s.Finalizers = []api.FinalizerName{api.FinalizerKubernetes} - }, - func(s *api.NamespaceStatus, c fuzz.Continue) { - s.Phase = api.NamespaceActive - }, - func(http *api.HTTPGetAction, c fuzz.Continue) { - c.FuzzNoCustom(http) // fuzz self without calling this function again - http.Path = "/" + http.Path // can't be blank - http.Scheme = "x" + http.Scheme // can't be blank - }, - func(ss *api.ServiceSpec, c fuzz.Continue) { - c.FuzzNoCustom(ss) // fuzz self without calling this function again - if len(ss.Ports) == 0 { - // There must be at least 1 port. - ss.Ports = append(ss.Ports, api.ServicePort{}) - c.Fuzz(&ss.Ports[0]) - } - for i := range ss.Ports { - switch ss.Ports[i].TargetPort.Type { - case intstr.Int: - ss.Ports[i].TargetPort.IntVal = 1 + ss.Ports[i].TargetPort.IntVal%65535 // non-zero - case intstr.String: - ss.Ports[i].TargetPort.StrVal = "x" + ss.Ports[i].TargetPort.StrVal // non-empty - } - } - }, - func(n *api.Node, c fuzz.Continue) { - c.FuzzNoCustom(n) - n.Spec.ExternalID = "external" - }, - func(s *api.NodeStatus, c fuzz.Continue) { - c.FuzzNoCustom(s) - s.Allocatable = s.Capacity - }, - } -} - -func extensionFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(j *extensions.DeploymentSpec, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - rhl := int32(c.Rand.Int31()) - pds := int32(c.Rand.Int31()) - j.RevisionHistoryLimit = &rhl - j.ProgressDeadlineSeconds = &pds - }, - func(j *extensions.DeploymentStrategy, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - // Ensure that strategyType is one of valid values. - strategyTypes := []extensions.DeploymentStrategyType{extensions.RecreateDeploymentStrategyType, extensions.RollingUpdateDeploymentStrategyType} - j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] - if j.Type != extensions.RollingUpdateDeploymentStrategyType { - j.RollingUpdate = nil - } else { - rollingUpdate := extensions.RollingUpdateDeployment{} - if c.RandBool() { - rollingUpdate.MaxUnavailable = intstr.FromInt(int(c.Rand.Int31())) - rollingUpdate.MaxSurge = intstr.FromInt(int(c.Rand.Int31())) - } else { - rollingUpdate.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.Rand.Int31())) - } - j.RollingUpdate = &rollingUpdate - } - }, - func(psp *extensions.PodSecurityPolicySpec, c fuzz.Continue) { - c.FuzzNoCustom(psp) // fuzz self without calling this function again - runAsUserRules := []extensions.RunAsUserStrategy{extensions.RunAsUserStrategyMustRunAsNonRoot, extensions.RunAsUserStrategyMustRunAs, extensions.RunAsUserStrategyRunAsAny} - psp.RunAsUser.Rule = runAsUserRules[c.Rand.Intn(len(runAsUserRules))] - seLinuxRules := []extensions.SELinuxStrategy{extensions.SELinuxStrategyRunAsAny, extensions.SELinuxStrategyMustRunAs} - psp.SELinux.Rule = seLinuxRules[c.Rand.Intn(len(seLinuxRules))] - }, - func(s *extensions.Scale, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - // TODO: Implement a fuzzer to generate valid keys, values and operators for - // selector requirements. - if s.Status.Selector != nil { - s.Status.Selector = &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "testlabelkey": "testlabelval", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "testkey", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"val1", "val2", "val3"}, - }, - }, - } - } - }, - func(j *extensions.DaemonSetSpec, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - rhl := int32(c.Rand.Int31()) - j.RevisionHistoryLimit = &rhl - }, - func(j *extensions.DaemonSetUpdateStrategy, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - // Ensure that strategyType is one of valid values. - strategyTypes := []extensions.DaemonSetUpdateStrategyType{extensions.RollingUpdateDaemonSetStrategyType, extensions.OnDeleteDaemonSetStrategyType} - j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] - if j.Type != extensions.RollingUpdateDaemonSetStrategyType { - j.RollingUpdate = nil - } else { - rollingUpdate := extensions.RollingUpdateDaemonSet{} - if c.RandBool() { - if c.RandBool() { - rollingUpdate.MaxUnavailable = intstr.FromInt(1 + int(c.Rand.Int31())) - } else { - rollingUpdate.MaxUnavailable = intstr.FromString(fmt.Sprintf("%d%%", 1+c.Rand.Int31())) - } - } - j.RollingUpdate = &rollingUpdate - } - }, - } -} - -func batchFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(j *batch.JobSpec, c fuzz.Continue) { - c.FuzzNoCustom(j) // fuzz self without calling this function again - completions := int32(c.Rand.Int31()) - parallelism := int32(c.Rand.Int31()) - j.Completions = &completions - j.Parallelism = ¶llelism - if c.Rand.Int31()%2 == 0 { - j.ManualSelector = newBool(true) - } else { - j.ManualSelector = nil - } - }, - func(sj *batch.CronJobSpec, c fuzz.Continue) { - c.FuzzNoCustom(sj) - suspend := c.RandBool() - sj.Suspend = &suspend - sds := int64(c.RandUint64()) - sj.StartingDeadlineSeconds = &sds - sj.Schedule = c.RandString() - if hasSuccessLimit := c.RandBool(); hasSuccessLimit { - successfulJobsHistoryLimit := int32(c.Rand.Int31()) - sj.SuccessfulJobsHistoryLimit = &successfulJobsHistoryLimit - } - if hasFailedLimit := c.RandBool(); hasFailedLimit { - failedJobsHistoryLimit := int32(c.Rand.Int31()) - sj.FailedJobsHistoryLimit = &failedJobsHistoryLimit - } - }, - func(cp *batch.ConcurrencyPolicy, c fuzz.Continue) { - policies := []batch.ConcurrencyPolicy{batch.AllowConcurrent, batch.ForbidConcurrent, batch.ReplaceConcurrent} - *cp = policies[c.Rand.Intn(len(policies))] - }, - } -} - -func autoscalingFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(s *autoscaling.HorizontalPodAutoscalerSpec, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - minReplicas := int32(c.Rand.Int31()) - s.MinReplicas = &minReplicas - - randomQuantity := func() resource.Quantity { - var q resource.Quantity - c.Fuzz(&q) - // precalc the string for benchmarking purposes - _ = q.String() - return q - } - - targetUtilization := int32(c.RandUint64()) - s.Metrics = []autoscaling.MetricSpec{ - { - Type: autoscaling.PodsMetricSourceType, - Pods: &autoscaling.PodsMetricSource{ - MetricName: c.RandString(), - TargetAverageValue: randomQuantity(), - }, - }, - { - Type: autoscaling.ResourceMetricSourceType, - Resource: &autoscaling.ResourceMetricSource{ - Name: api.ResourceCPU, - TargetAverageUtilization: &targetUtilization, - }, - }, - } - }, - func(s *autoscaling.HorizontalPodAutoscalerStatus, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - randomQuantity := func() resource.Quantity { - var q resource.Quantity - c.Fuzz(&q) - // precalc the string for benchmarking purposes - _ = q.String() - return q - } - currentUtilization := int32(c.RandUint64()) - s.CurrentMetrics = []autoscaling.MetricStatus{ - { - Type: autoscaling.PodsMetricSourceType, - Pods: &autoscaling.PodsMetricStatus{ - MetricName: c.RandString(), - CurrentAverageValue: randomQuantity(), - }, - }, - { - Type: autoscaling.ResourceMetricSourceType, - Resource: &autoscaling.ResourceMetricStatus{ - Name: api.ResourceCPU, - CurrentAverageUtilization: ¤tUtilization, - }, - }, - } - }, - } -} - -func rbacFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(r *rbac.RoleRef, c fuzz.Continue) { - c.FuzzNoCustom(r) // fuzz self without calling this function again - - // match defaulter - if len(r.APIGroup) == 0 { - r.APIGroup = rbac.GroupName - } - }, - func(r *rbac.Subject, c fuzz.Continue) { - switch c.Int31n(3) { - case 0: - r.Kind = rbac.ServiceAccountKind - r.APIGroup = "" - c.FuzzNoCustom(&r.Name) - c.FuzzNoCustom(&r.Namespace) - case 1: - r.Kind = rbac.UserKind - r.APIGroup = rbac.GroupName - c.FuzzNoCustom(&r.Name) - // user "*" won't round trip because we convert it to the system:authenticated group. try again. - for r.Name == "*" { - c.FuzzNoCustom(&r.Name) - } - case 2: - r.Kind = rbac.GroupKind - r.APIGroup = rbac.GroupName - c.FuzzNoCustom(&r.Name) - } - }, - } -} - -func appsFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(s *apps.StatefulSet, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - - // match defaulter - if len(s.Spec.PodManagementPolicy) == 0 { - s.Spec.PodManagementPolicy = apps.OrderedReadyPodManagement - } - if len(s.Spec.UpdateStrategy.Type) == 0 { - s.Spec.UpdateStrategy.Type = apps.RollingUpdateStatefulSetStrategyType - } - if s.Spec.RevisionHistoryLimit == nil { - s.Spec.RevisionHistoryLimit = new(int32) - *s.Spec.RevisionHistoryLimit = 10 - } - if s.Status.ObservedGeneration == nil { - s.Status.ObservedGeneration = new(int64) - } - if s.Status.CollisionCount == nil { - s.Status.CollisionCount = new(int64) - } - }, - } -} -func policyFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(s *policy.PodDisruptionBudgetStatus, c fuzz.Continue) { - c.FuzzNoCustom(s) // fuzz self without calling this function again - s.PodDisruptionsAllowed = int32(c.Rand.Intn(2)) - }, - } -} - -func certificateFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(obj *certificates.CertificateSigningRequestSpec, c fuzz.Continue) { - c.FuzzNoCustom(obj) // fuzz self without calling this function again - obj.Usages = []certificates.KeyUsage{certificates.UsageKeyEncipherment} - }, - } -} - -func admissionregistrationFuncs(codecs runtimeserializer.CodecFactory) []interface{} { - return []interface{}{ - func(obj *admissionregistration.ExternalAdmissionHook, c fuzz.Continue) { - c.FuzzNoCustom(obj) // fuzz self without calling this function again - p := admissionregistration.FailurePolicyType("Fail") - obj.FailurePolicy = &p - }, - func(obj *admissionregistration.Initializer, c fuzz.Continue) { - c.FuzzNoCustom(obj) // fuzz self without calling this function again - p := admissionregistration.FailurePolicyType("Fail") - obj.FailurePolicy = &p - }, - } -} - var FuzzerFuncs = fuzzer.MergeFuzzerFuncs( genericfuzzer.Funcs, overrideGenericFuncs, - coreFuncs, - extensionFuncs, - appsFuncs, - batchFuncs, - autoscalingFuncs, - rbacFuncs, + corefuzzer.Funcs, + extensionsfuzzer.Funcs, + appsfuzzer.Funcs, + batchfuzzer.Funcs, + autoscalingfuzzer.Funcs, + rbacfuzzer.Funcs, kubeadmfuzzer.Funcs, - policyFuncs, - certificateFuncs, - admissionregistrationFuncs, + policyfuzzer.Funcs, + certificatesfuzzer.Funcs, + admissionregistrationfuzzer.Funcs, ) - -func newBool(val bool) *bool { - p := new(bool) - *p = val - return p -} diff --git a/pkg/apis/abac/BUILD b/pkg/apis/abac/BUILD index 92e6ea9683c..e0915a84f2b 100644 --- a/pkg/apis/abac/BUILD +++ b/pkg/apis/abac/BUILD @@ -36,6 +36,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/abac/fuzzer:all-srcs", "//pkg/apis/abac/latest:all-srcs", "//pkg/apis/abac/v0:all-srcs", "//pkg/apis/abac/v1beta1:all-srcs", diff --git a/pkg/apis/abac/fuzzer/BUILD b/pkg/apis/abac/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/abac/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/abac/fuzzer/fuzzer.go b/pkg/apis/abac/fuzzer/fuzzer.go new file mode 100644 index 00000000000..9f6e432bc6e --- /dev/null +++ b/pkg/apis/abac/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the abac api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/admission/BUILD b/pkg/apis/admission/BUILD index cc3632025b2..3d57e510d10 100644 --- a/pkg/apis/admission/BUILD +++ b/pkg/apis/admission/BUILD @@ -37,6 +37,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/admission/fuzzer:all-srcs", "//pkg/apis/admission/install:all-srcs", "//pkg/apis/admission/v1alpha1:all-srcs", ], diff --git a/pkg/apis/admission/fuzzer/BUILD b/pkg/apis/admission/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/admission/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/admission/fuzzer/fuzzer.go b/pkg/apis/admission/fuzzer/fuzzer.go new file mode 100644 index 00000000000..6b4aea2de13 --- /dev/null +++ b/pkg/apis/admission/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the admission api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/admissionregistration/BUILD b/pkg/apis/admissionregistration/BUILD index 72f4fd29b83..e8136f1b40a 100644 --- a/pkg/apis/admissionregistration/BUILD +++ b/pkg/apis/admissionregistration/BUILD @@ -35,6 +35,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/admissionregistration/fuzzer:all-srcs", "//pkg/apis/admissionregistration/install:all-srcs", "//pkg/apis/admissionregistration/v1alpha1:all-srcs", "//pkg/apis/admissionregistration/validation:all-srcs", diff --git a/pkg/apis/admissionregistration/fuzzer/BUILD b/pkg/apis/admissionregistration/fuzzer/BUILD new file mode 100644 index 00000000000..aa940764d65 --- /dev/null +++ b/pkg/apis/admissionregistration/fuzzer/BUILD @@ -0,0 +1,32 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/apis/admissionregistration:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/admissionregistration/fuzzer/fuzzer.go b/pkg/apis/admissionregistration/fuzzer/fuzzer.go new file mode 100644 index 00000000000..4029e02298c --- /dev/null +++ b/pkg/apis/admissionregistration/fuzzer/fuzzer.go @@ -0,0 +1,40 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + fuzz "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubernetes/pkg/apis/admissionregistration" +) + +// Funcs returns the fuzzer functions for the admissionregistration api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(obj *admissionregistration.ExternalAdmissionHook, c fuzz.Continue) { + c.FuzzNoCustom(obj) // fuzz self without calling this function again + p := admissionregistration.FailurePolicyType("Fail") + obj.FailurePolicy = &p + }, + func(obj *admissionregistration.Initializer, c fuzz.Continue) { + c.FuzzNoCustom(obj) // fuzz self without calling this function again + p := admissionregistration.FailurePolicyType("Fail") + obj.FailurePolicy = &p + }, + } +} diff --git a/pkg/apis/apps/BUILD b/pkg/apis/apps/BUILD index 890b1ecc1c3..baff881d1a6 100644 --- a/pkg/apis/apps/BUILD +++ b/pkg/apis/apps/BUILD @@ -37,6 +37,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/apps/fuzzer:all-srcs", "//pkg/apis/apps/install:all-srcs", "//pkg/apis/apps/v1beta1:all-srcs", "//pkg/apis/apps/v1beta2:all-srcs", diff --git a/pkg/apis/apps/fuzzer/BUILD b/pkg/apis/apps/fuzzer/BUILD new file mode 100644 index 00000000000..e759932eecf --- /dev/null +++ b/pkg/apis/apps/fuzzer/BUILD @@ -0,0 +1,32 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/apis/apps:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/apps/fuzzer/fuzzer.go b/pkg/apis/apps/fuzzer/fuzzer.go new file mode 100644 index 00000000000..beb97dc1684 --- /dev/null +++ b/pkg/apis/apps/fuzzer/fuzzer.go @@ -0,0 +1,51 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + fuzz "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubernetes/pkg/apis/apps" +) + +// Funcs returns the fuzzer functions for the apps api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(s *apps.StatefulSet, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + + // match defaulter + if len(s.Spec.PodManagementPolicy) == 0 { + s.Spec.PodManagementPolicy = apps.OrderedReadyPodManagement + } + if len(s.Spec.UpdateStrategy.Type) == 0 { + s.Spec.UpdateStrategy.Type = apps.RollingUpdateStatefulSetStrategyType + } + if s.Spec.RevisionHistoryLimit == nil { + s.Spec.RevisionHistoryLimit = new(int32) + *s.Spec.RevisionHistoryLimit = 10 + } + if s.Status.ObservedGeneration == nil { + s.Status.ObservedGeneration = new(int64) + } + if s.Status.CollisionCount == nil { + s.Status.CollisionCount = new(int64) + } + }, + } +} diff --git a/pkg/apis/authentication/BUILD b/pkg/apis/authentication/BUILD index 996c1eff8fd..51b6d55acd4 100644 --- a/pkg/apis/authentication/BUILD +++ b/pkg/apis/authentication/BUILD @@ -35,6 +35,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/authentication/fuzzer:all-srcs", "//pkg/apis/authentication/install:all-srcs", "//pkg/apis/authentication/v1:all-srcs", "//pkg/apis/authentication/v1beta1:all-srcs", diff --git a/pkg/apis/authentication/fuzzer/BUILD b/pkg/apis/authentication/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/authentication/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/authentication/fuzzer/fuzzer.go b/pkg/apis/authentication/fuzzer/fuzzer.go new file mode 100644 index 00000000000..7bb5204e92c --- /dev/null +++ b/pkg/apis/authentication/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the authentication api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/authorization/BUILD b/pkg/apis/authorization/BUILD index 4cdc7b8deed..c7c67fadd1c 100644 --- a/pkg/apis/authorization/BUILD +++ b/pkg/apis/authorization/BUILD @@ -35,6 +35,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/authorization/fuzzer:all-srcs", "//pkg/apis/authorization/install:all-srcs", "//pkg/apis/authorization/v1:all-srcs", "//pkg/apis/authorization/v1beta1:all-srcs", diff --git a/pkg/apis/authorization/fuzzer/BUILD b/pkg/apis/authorization/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/authorization/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/authorization/fuzzer/fuzzer.go b/pkg/apis/authorization/fuzzer/fuzzer.go new file mode 100644 index 00000000000..fb154c0d751 --- /dev/null +++ b/pkg/apis/authorization/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the authorization api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/autoscaling/BUILD b/pkg/apis/autoscaling/BUILD index 7543110a8da..f57abeee54e 100644 --- a/pkg/apis/autoscaling/BUILD +++ b/pkg/apis/autoscaling/BUILD @@ -38,6 +38,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/autoscaling/fuzzer:all-srcs", "//pkg/apis/autoscaling/install:all-srcs", "//pkg/apis/autoscaling/v1:all-srcs", "//pkg/apis/autoscaling/v2alpha1:all-srcs", diff --git a/pkg/apis/autoscaling/fuzzer/BUILD b/pkg/apis/autoscaling/fuzzer/BUILD new file mode 100644 index 00000000000..879ad183809 --- /dev/null +++ b/pkg/apis/autoscaling/fuzzer/BUILD @@ -0,0 +1,34 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/api:go_default_library", + "//pkg/apis/autoscaling:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/autoscaling/fuzzer/fuzzer.go b/pkg/apis/autoscaling/fuzzer/fuzzer.go new file mode 100644 index 00000000000..7133c162735 --- /dev/null +++ b/pkg/apis/autoscaling/fuzzer/fuzzer.go @@ -0,0 +1,89 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + fuzz "github.com/google/gofuzz" + "k8s.io/apimachinery/pkg/api/resource" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/autoscaling" +) + +// Funcs returns the fuzzer functions for the autoscaling api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(s *autoscaling.HorizontalPodAutoscalerSpec, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + minReplicas := int32(c.Rand.Int31()) + s.MinReplicas = &minReplicas + + randomQuantity := func() resource.Quantity { + var q resource.Quantity + c.Fuzz(&q) + // precalc the string for benchmarking purposes + _ = q.String() + return q + } + + targetUtilization := int32(c.RandUint64()) + s.Metrics = []autoscaling.MetricSpec{ + { + Type: autoscaling.PodsMetricSourceType, + Pods: &autoscaling.PodsMetricSource{ + MetricName: c.RandString(), + TargetAverageValue: randomQuantity(), + }, + }, + { + Type: autoscaling.ResourceMetricSourceType, + Resource: &autoscaling.ResourceMetricSource{ + Name: api.ResourceCPU, + TargetAverageUtilization: &targetUtilization, + }, + }, + } + }, + func(s *autoscaling.HorizontalPodAutoscalerStatus, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + randomQuantity := func() resource.Quantity { + var q resource.Quantity + c.Fuzz(&q) + // precalc the string for benchmarking purposes + _ = q.String() + return q + } + currentUtilization := int32(c.RandUint64()) + s.CurrentMetrics = []autoscaling.MetricStatus{ + { + Type: autoscaling.PodsMetricSourceType, + Pods: &autoscaling.PodsMetricStatus{ + MetricName: c.RandString(), + CurrentAverageValue: randomQuantity(), + }, + }, + { + Type: autoscaling.ResourceMetricSourceType, + Resource: &autoscaling.ResourceMetricStatus{ + Name: api.ResourceCPU, + CurrentAverageUtilization: ¤tUtilization, + }, + }, + } + }, + } +} diff --git a/pkg/apis/batch/BUILD b/pkg/apis/batch/BUILD index 4ee030ca40c..effedcb0d18 100644 --- a/pkg/apis/batch/BUILD +++ b/pkg/apis/batch/BUILD @@ -36,6 +36,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/batch/fuzzer:all-srcs", "//pkg/apis/batch/install:all-srcs", "//pkg/apis/batch/v1:all-srcs", "//pkg/apis/batch/v2alpha1:all-srcs", diff --git a/pkg/apis/batch/fuzzer/BUILD b/pkg/apis/batch/fuzzer/BUILD new file mode 100644 index 00000000000..7d85a093893 --- /dev/null +++ b/pkg/apis/batch/fuzzer/BUILD @@ -0,0 +1,32 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/apis/batch:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/batch/fuzzer/fuzzer.go b/pkg/apis/batch/fuzzer/fuzzer.go new file mode 100644 index 00000000000..cb4b751f6d1 --- /dev/null +++ b/pkg/apis/batch/fuzzer/fuzzer.go @@ -0,0 +1,68 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + fuzz "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubernetes/pkg/apis/batch" +) + +func newBool(val bool) *bool { + p := new(bool) + *p = val + return p +} + +// Funcs returns the fuzzer functions for the batch api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(j *batch.JobSpec, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + completions := int32(c.Rand.Int31()) + parallelism := int32(c.Rand.Int31()) + j.Completions = &completions + j.Parallelism = ¶llelism + if c.Rand.Int31()%2 == 0 { + j.ManualSelector = newBool(true) + } else { + j.ManualSelector = nil + } + }, + func(sj *batch.CronJobSpec, c fuzz.Continue) { + c.FuzzNoCustom(sj) + suspend := c.RandBool() + sj.Suspend = &suspend + sds := int64(c.RandUint64()) + sj.StartingDeadlineSeconds = &sds + sj.Schedule = c.RandString() + if hasSuccessLimit := c.RandBool(); hasSuccessLimit { + successfulJobsHistoryLimit := int32(c.Rand.Int31()) + sj.SuccessfulJobsHistoryLimit = &successfulJobsHistoryLimit + } + if hasFailedLimit := c.RandBool(); hasFailedLimit { + failedJobsHistoryLimit := int32(c.Rand.Int31()) + sj.FailedJobsHistoryLimit = &failedJobsHistoryLimit + } + }, + func(cp *batch.ConcurrencyPolicy, c fuzz.Continue) { + policies := []batch.ConcurrencyPolicy{batch.AllowConcurrent, batch.ForbidConcurrent, batch.ReplaceConcurrent} + *cp = policies[c.Rand.Intn(len(policies))] + }, + } +} diff --git a/pkg/apis/certificates/BUILD b/pkg/apis/certificates/BUILD index 44cb3863035..2d3922c582a 100644 --- a/pkg/apis/certificates/BUILD +++ b/pkg/apis/certificates/BUILD @@ -36,6 +36,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/certificates/fuzzer:all-srcs", "//pkg/apis/certificates/install:all-srcs", "//pkg/apis/certificates/v1beta1:all-srcs", "//pkg/apis/certificates/validation:all-srcs", diff --git a/pkg/apis/certificates/fuzzer/BUILD b/pkg/apis/certificates/fuzzer/BUILD new file mode 100644 index 00000000000..2f4db68d723 --- /dev/null +++ b/pkg/apis/certificates/fuzzer/BUILD @@ -0,0 +1,32 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/apis/certificates:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/certificates/fuzzer/fuzzer.go b/pkg/apis/certificates/fuzzer/fuzzer.go new file mode 100644 index 00000000000..ccfca013bed --- /dev/null +++ b/pkg/apis/certificates/fuzzer/fuzzer.go @@ -0,0 +1,34 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + fuzz "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubernetes/pkg/apis/certificates" +) + +// Funcs returns the fuzzer functions for the certificates api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(obj *certificates.CertificateSigningRequestSpec, c fuzz.Continue) { + c.FuzzNoCustom(obj) // fuzz self without calling this function again + obj.Usages = []certificates.KeyUsage{certificates.UsageKeyEncipherment} + }, + } +} diff --git a/pkg/apis/componentconfig/BUILD b/pkg/apis/componentconfig/BUILD index f6d6ab2b2e3..89f76295813 100644 --- a/pkg/apis/componentconfig/BUILD +++ b/pkg/apis/componentconfig/BUILD @@ -48,6 +48,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/componentconfig/fuzzer:all-srcs", "//pkg/apis/componentconfig/install:all-srcs", "//pkg/apis/componentconfig/v1alpha1:all-srcs", "//pkg/apis/componentconfig/validation:all-srcs", diff --git a/pkg/apis/componentconfig/fuzzer/BUILD b/pkg/apis/componentconfig/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/componentconfig/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/componentconfig/fuzzer/fuzzer.go b/pkg/apis/componentconfig/fuzzer/fuzzer.go new file mode 100644 index 00000000000..cfde7535a30 --- /dev/null +++ b/pkg/apis/componentconfig/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the componentconfig api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/extensions/BUILD b/pkg/apis/extensions/BUILD index a9de8e682ee..8289b25bb5b 100644 --- a/pkg/apis/extensions/BUILD +++ b/pkg/apis/extensions/BUILD @@ -47,6 +47,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/extensions/fuzzer:all-srcs", "//pkg/apis/extensions/install:all-srcs", "//pkg/apis/extensions/v1beta1:all-srcs", "//pkg/apis/extensions/validation:all-srcs", diff --git a/pkg/apis/extensions/fuzzer/BUILD b/pkg/apis/extensions/fuzzer/BUILD new file mode 100644 index 00000000000..8271f15c826 --- /dev/null +++ b/pkg/apis/extensions/fuzzer/BUILD @@ -0,0 +1,34 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/apis/extensions:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/extensions/fuzzer/fuzzer.go b/pkg/apis/extensions/fuzzer/fuzzer.go new file mode 100644 index 00000000000..a36148b79d7 --- /dev/null +++ b/pkg/apis/extensions/fuzzer/fuzzer.go @@ -0,0 +1,109 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + "fmt" + + fuzz "github.com/google/gofuzz" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/kubernetes/pkg/apis/extensions" +) + +// Funcs returns the fuzzer functions for the extensions api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(j *extensions.DeploymentSpec, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + rhl := int32(c.Rand.Int31()) + pds := int32(c.Rand.Int31()) + j.RevisionHistoryLimit = &rhl + j.ProgressDeadlineSeconds = &pds + }, + func(j *extensions.DeploymentStrategy, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + // Ensure that strategyType is one of valid values. + strategyTypes := []extensions.DeploymentStrategyType{extensions.RecreateDeploymentStrategyType, extensions.RollingUpdateDeploymentStrategyType} + j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] + if j.Type != extensions.RollingUpdateDeploymentStrategyType { + j.RollingUpdate = nil + } else { + rollingUpdate := extensions.RollingUpdateDeployment{} + if c.RandBool() { + rollingUpdate.MaxUnavailable = intstr.FromInt(int(c.Rand.Int31())) + rollingUpdate.MaxSurge = intstr.FromInt(int(c.Rand.Int31())) + } else { + rollingUpdate.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.Rand.Int31())) + } + j.RollingUpdate = &rollingUpdate + } + }, + func(psp *extensions.PodSecurityPolicySpec, c fuzz.Continue) { + c.FuzzNoCustom(psp) // fuzz self without calling this function again + runAsUserRules := []extensions.RunAsUserStrategy{extensions.RunAsUserStrategyMustRunAsNonRoot, extensions.RunAsUserStrategyMustRunAs, extensions.RunAsUserStrategyRunAsAny} + psp.RunAsUser.Rule = runAsUserRules[c.Rand.Intn(len(runAsUserRules))] + seLinuxRules := []extensions.SELinuxStrategy{extensions.SELinuxStrategyRunAsAny, extensions.SELinuxStrategyMustRunAs} + psp.SELinux.Rule = seLinuxRules[c.Rand.Intn(len(seLinuxRules))] + }, + func(s *extensions.Scale, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + // TODO: Implement a fuzzer to generate valid keys, values and operators for + // selector requirements. + if s.Status.Selector != nil { + s.Status.Selector = &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "testlabelkey": "testlabelval", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "testkey", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"val1", "val2", "val3"}, + }, + }, + } + } + }, + func(j *extensions.DaemonSetSpec, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + rhl := int32(c.Rand.Int31()) + j.RevisionHistoryLimit = &rhl + }, + func(j *extensions.DaemonSetUpdateStrategy, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + // Ensure that strategyType is one of valid values. + strategyTypes := []extensions.DaemonSetUpdateStrategyType{extensions.RollingUpdateDaemonSetStrategyType, extensions.OnDeleteDaemonSetStrategyType} + j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] + if j.Type != extensions.RollingUpdateDaemonSetStrategyType { + j.RollingUpdate = nil + } else { + rollingUpdate := extensions.RollingUpdateDaemonSet{} + if c.RandBool() { + if c.RandBool() { + rollingUpdate.MaxUnavailable = intstr.FromInt(1 + int(c.Rand.Int31())) + } else { + rollingUpdate.MaxUnavailable = intstr.FromString(fmt.Sprintf("%d%%", 1+c.Rand.Int31())) + } + } + j.RollingUpdate = &rollingUpdate + } + }, + } +} diff --git a/pkg/apis/imagepolicy/BUILD b/pkg/apis/imagepolicy/BUILD index b63c74769c9..eb1c95a4d7c 100644 --- a/pkg/apis/imagepolicy/BUILD +++ b/pkg/apis/imagepolicy/BUILD @@ -35,6 +35,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/imagepolicy/fuzzer:all-srcs", "//pkg/apis/imagepolicy/install:all-srcs", "//pkg/apis/imagepolicy/v1alpha1:all-srcs", ], diff --git a/pkg/apis/imagepolicy/fuzzer/BUILD b/pkg/apis/imagepolicy/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/imagepolicy/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/imagepolicy/fuzzer/fuzzer.go b/pkg/apis/imagepolicy/fuzzer/fuzzer.go new file mode 100644 index 00000000000..fedada09f0b --- /dev/null +++ b/pkg/apis/imagepolicy/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the imagepolicy api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/networking/BUILD b/pkg/apis/networking/BUILD index 385b9ef7195..f72f8058253 100644 --- a/pkg/apis/networking/BUILD +++ b/pkg/apis/networking/BUILD @@ -37,6 +37,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/networking/fuzzer:all-srcs", "//pkg/apis/networking/install:all-srcs", "//pkg/apis/networking/v1:all-srcs", "//pkg/apis/networking/validation:all-srcs", diff --git a/pkg/apis/networking/fuzzer/BUILD b/pkg/apis/networking/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/networking/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/networking/fuzzer/fuzzer.go b/pkg/apis/networking/fuzzer/fuzzer.go new file mode 100644 index 00000000000..6e142826d3b --- /dev/null +++ b/pkg/apis/networking/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the networking api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/policy/BUILD b/pkg/apis/policy/BUILD index e971f0bd3c9..0bd08a80d2e 100644 --- a/pkg/apis/policy/BUILD +++ b/pkg/apis/policy/BUILD @@ -36,6 +36,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/policy/fuzzer:all-srcs", "//pkg/apis/policy/install:all-srcs", "//pkg/apis/policy/v1alpha1:all-srcs", "//pkg/apis/policy/v1beta1:all-srcs", diff --git a/pkg/apis/policy/fuzzer/BUILD b/pkg/apis/policy/fuzzer/BUILD new file mode 100644 index 00000000000..70477501902 --- /dev/null +++ b/pkg/apis/policy/fuzzer/BUILD @@ -0,0 +1,32 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/apis/policy:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/policy/fuzzer/fuzzer.go b/pkg/apis/policy/fuzzer/fuzzer.go new file mode 100644 index 00000000000..e6b5a6b9798 --- /dev/null +++ b/pkg/apis/policy/fuzzer/fuzzer.go @@ -0,0 +1,34 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + fuzz "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubernetes/pkg/apis/policy" +) + +// Funcs returns the fuzzer functions for the policy api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(s *policy.PodDisruptionBudgetStatus, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + s.PodDisruptionsAllowed = int32(c.Rand.Intn(2)) + }, + } +} diff --git a/pkg/apis/rbac/BUILD b/pkg/apis/rbac/BUILD index 06ac7a23f48..0b519637f58 100644 --- a/pkg/apis/rbac/BUILD +++ b/pkg/apis/rbac/BUILD @@ -37,6 +37,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/rbac/fuzzer:all-srcs", "//pkg/apis/rbac/install:all-srcs", "//pkg/apis/rbac/v1:all-srcs", "//pkg/apis/rbac/v1alpha1:all-srcs", diff --git a/pkg/apis/rbac/fuzzer/BUILD b/pkg/apis/rbac/fuzzer/BUILD new file mode 100644 index 00000000000..c558047bf2b --- /dev/null +++ b/pkg/apis/rbac/fuzzer/BUILD @@ -0,0 +1,32 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = [ + "//pkg/apis/rbac:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/rbac/fuzzer/fuzzer.go b/pkg/apis/rbac/fuzzer/fuzzer.go new file mode 100644 index 00000000000..ca8f462ec54 --- /dev/null +++ b/pkg/apis/rbac/fuzzer/fuzzer.go @@ -0,0 +1,59 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + fuzz "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubernetes/pkg/apis/rbac" +) + +// Funcs returns the fuzzer functions for the rbac api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(r *rbac.RoleRef, c fuzz.Continue) { + c.FuzzNoCustom(r) // fuzz self without calling this function again + + // match defaulter + if len(r.APIGroup) == 0 { + r.APIGroup = rbac.GroupName + } + }, + func(r *rbac.Subject, c fuzz.Continue) { + switch c.Int31n(3) { + case 0: + r.Kind = rbac.ServiceAccountKind + r.APIGroup = "" + c.FuzzNoCustom(&r.Name) + c.FuzzNoCustom(&r.Namespace) + case 1: + r.Kind = rbac.UserKind + r.APIGroup = rbac.GroupName + c.FuzzNoCustom(&r.Name) + // user "*" won't round trip because we convert it to the system:authenticated group. try again. + for r.Name == "*" { + c.FuzzNoCustom(&r.Name) + } + case 2: + r.Kind = rbac.GroupKind + r.APIGroup = rbac.GroupName + c.FuzzNoCustom(&r.Name) + } + }, + } +} diff --git a/pkg/apis/scheduling/BUILD b/pkg/apis/scheduling/BUILD index f8e055121a1..34899cbae4c 100644 --- a/pkg/apis/scheduling/BUILD +++ b/pkg/apis/scheduling/BUILD @@ -35,6 +35,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/scheduling/fuzzer:all-srcs", "//pkg/apis/scheduling/install:all-srcs", "//pkg/apis/scheduling/v1alpha1:all-srcs", "//pkg/apis/scheduling/validation:all-srcs", diff --git a/pkg/apis/scheduling/fuzzer/BUILD b/pkg/apis/scheduling/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/scheduling/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/scheduling/fuzzer/fuzzer.go b/pkg/apis/scheduling/fuzzer/fuzzer.go new file mode 100644 index 00000000000..ee9286de2cb --- /dev/null +++ b/pkg/apis/scheduling/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the scheduling api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/settings/BUILD b/pkg/apis/settings/BUILD index 96a9ee6421f..17b22780f7b 100644 --- a/pkg/apis/settings/BUILD +++ b/pkg/apis/settings/BUILD @@ -36,6 +36,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/settings/fuzzer:all-srcs", "//pkg/apis/settings/install:all-srcs", "//pkg/apis/settings/v1alpha1:all-srcs", "//pkg/apis/settings/validation:all-srcs", diff --git a/pkg/apis/settings/fuzzer/BUILD b/pkg/apis/settings/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/settings/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/settings/fuzzer/fuzzer.go b/pkg/apis/settings/fuzzer/fuzzer.go new file mode 100644 index 00000000000..be5a228f5a1 --- /dev/null +++ b/pkg/apis/settings/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the settings api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/apis/storage/BUILD b/pkg/apis/storage/BUILD index 24f25759fa5..4aa001b3a64 100644 --- a/pkg/apis/storage/BUILD +++ b/pkg/apis/storage/BUILD @@ -35,6 +35,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//pkg/apis/storage/fuzzer:all-srcs", "//pkg/apis/storage/install:all-srcs", "//pkg/apis/storage/util:all-srcs", "//pkg/apis/storage/v1:all-srcs", diff --git a/pkg/apis/storage/fuzzer/BUILD b/pkg/apis/storage/fuzzer/BUILD new file mode 100644 index 00000000000..2aa37c3b8f5 --- /dev/null +++ b/pkg/apis/storage/fuzzer/BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["fuzzer.go"], + tags = ["automanaged"], + deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/storage/fuzzer/fuzzer.go b/pkg/apis/storage/fuzzer/fuzzer.go new file mode 100644 index 00000000000..a0a68bdf9ff --- /dev/null +++ b/pkg/apis/storage/fuzzer/fuzzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 fuzzer + +import ( + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Funcs returns the fuzzer functions for the storage api group. +var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{} +} diff --git a/pkg/registry/core/event/BUILD b/pkg/registry/core/event/BUILD index 4a9fd1b4daa..4fa7714d20c 100644 --- a/pkg/registry/core/event/BUILD +++ b/pkg/registry/core/event/BUILD @@ -37,6 +37,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", diff --git a/pkg/registry/core/event/strategy_test.go b/pkg/registry/core/event/strategy_test.go index 9b5e5959abd..be78b5aa0f8 100644 --- a/pkg/registry/core/event/strategy_test.go +++ b/pkg/registry/core/event/strategy_test.go @@ -25,6 +25,9 @@ import ( "k8s.io/apimachinery/pkg/util/diff" "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func testEvent(name string) *api.Event { diff --git a/pkg/registry/core/namespace/BUILD b/pkg/registry/core/namespace/BUILD index 95123b7ccbd..40b3985c608 100644 --- a/pkg/registry/core/namespace/BUILD +++ b/pkg/registry/core/namespace/BUILD @@ -41,6 +41,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/core/namespace/strategy_test.go b/pkg/registry/core/namespace/strategy_test.go index 37691ac7201..8e3dbc3e800 100644 --- a/pkg/registry/core/namespace/strategy_test.go +++ b/pkg/registry/core/namespace/strategy_test.go @@ -23,6 +23,9 @@ import ( genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func TestNamespaceStrategy(t *testing.T) { diff --git a/pkg/registry/core/node/BUILD b/pkg/registry/core/node/BUILD index b8791bcac12..3509b9be2ac 100644 --- a/pkg/registry/core/node/BUILD +++ b/pkg/registry/core/node/BUILD @@ -45,6 +45,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", diff --git a/pkg/registry/core/node/strategy_test.go b/pkg/registry/core/node/strategy_test.go index 2fd33f6ac73..ec740efdc2f 100644 --- a/pkg/registry/core/node/strategy_test.go +++ b/pkg/registry/core/node/strategy_test.go @@ -23,6 +23,9 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func TestMatchNode(t *testing.T) { diff --git a/pkg/registry/core/persistentvolume/BUILD b/pkg/registry/core/persistentvolume/BUILD index 2d2df364970..6ab27cd0daa 100644 --- a/pkg/registry/core/persistentvolume/BUILD +++ b/pkg/registry/core/persistentvolume/BUILD @@ -37,6 +37,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", ], ) diff --git a/pkg/registry/core/persistentvolume/strategy_test.go b/pkg/registry/core/persistentvolume/strategy_test.go index 65b975e8b9b..1bec01dac3c 100644 --- a/pkg/registry/core/persistentvolume/strategy_test.go +++ b/pkg/registry/core/persistentvolume/strategy_test.go @@ -21,6 +21,9 @@ import ( "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func TestSelectableFieldLabelConversions(t *testing.T) { diff --git a/pkg/registry/core/persistentvolumeclaim/BUILD b/pkg/registry/core/persistentvolumeclaim/BUILD index c19290269dd..c9e86230ac4 100644 --- a/pkg/registry/core/persistentvolumeclaim/BUILD +++ b/pkg/registry/core/persistentvolumeclaim/BUILD @@ -36,6 +36,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", ], ) diff --git a/pkg/registry/core/persistentvolumeclaim/strategy_test.go b/pkg/registry/core/persistentvolumeclaim/strategy_test.go index e8fe5e60273..90824c4db2a 100644 --- a/pkg/registry/core/persistentvolumeclaim/strategy_test.go +++ b/pkg/registry/core/persistentvolumeclaim/strategy_test.go @@ -21,6 +21,9 @@ import ( "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func TestSelectableFieldLabelConversions(t *testing.T) { diff --git a/pkg/registry/core/pod/BUILD b/pkg/registry/core/pod/BUILD index 429a1a9d672..08a1793d439 100644 --- a/pkg/registry/core/pod/BUILD +++ b/pkg/registry/core/pod/BUILD @@ -42,6 +42,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//pkg/kubelet/client:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", diff --git a/pkg/registry/core/pod/strategy_test.go b/pkg/registry/core/pod/strategy_test.go index eed6fcf15fd..e2f34621085 100644 --- a/pkg/registry/core/pod/strategy_test.go +++ b/pkg/registry/core/pod/strategy_test.go @@ -32,6 +32,9 @@ import ( "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/kubelet/client" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func TestMatchPod(t *testing.T) { diff --git a/pkg/registry/core/replicationcontroller/BUILD b/pkg/registry/core/replicationcontroller/BUILD index 2082af00556..6f6465d0ec9 100644 --- a/pkg/registry/core/replicationcontroller/BUILD +++ b/pkg/registry/core/replicationcontroller/BUILD @@ -43,6 +43,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/core/replicationcontroller/strategy_test.go b/pkg/registry/core/replicationcontroller/strategy_test.go index 6c9513cc7bf..1b20fbada47 100644 --- a/pkg/registry/core/replicationcontroller/strategy_test.go +++ b/pkg/registry/core/replicationcontroller/strategy_test.go @@ -24,6 +24,9 @@ import ( genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func TestControllerStrategy(t *testing.T) { diff --git a/pkg/registry/core/secret/BUILD b/pkg/registry/core/secret/BUILD index bc1ccf4563e..6f7d517cb6b 100644 --- a/pkg/registry/core/secret/BUILD +++ b/pkg/registry/core/secret/BUILD @@ -42,6 +42,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/pkg/registry/core/secret/strategy_test.go b/pkg/registry/core/secret/strategy_test.go index f021be5d64e..1e284efa5b9 100644 --- a/pkg/registry/core/secret/strategy_test.go +++ b/pkg/registry/core/secret/strategy_test.go @@ -25,6 +25,9 @@ import ( genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/kubernetes/pkg/api" apitesting "k8s.io/kubernetes/pkg/api/testing" + + // install all api groups for testing + _ "k8s.io/kubernetes/pkg/api/testapi" ) func TestExportSecret(t *testing.T) {