Restore fuzzer test

This commit is contained in:
fabriziopandini 2018-09-28 10:43:45 +02:00
parent 8e887e1eee
commit 19be8be4f3
3 changed files with 97 additions and 101 deletions

View File

@ -17,119 +17,123 @@ limitations under the License.
package fuzzer package fuzzer
import ( import (
"time"
fuzz "github.com/google/gofuzz" fuzz "github.com/google/gofuzz"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
kubeproxyconfigv1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" "k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
utilpointer "k8s.io/utils/pointer"
) )
// NOTE: Right now this code is unused, as the test utilizing this is disabled.
// Funcs returns the fuzzer functions for the kubeadm apis. // Funcs returns the fuzzer functions for the kubeadm apis.
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{ return []interface{}{
func(obj *kubeadm.ClusterConfiguration, c fuzz.Continue) { fuzzInitConfiguration,
c.FuzzNoCustom(obj) fuzzClusterConfiguration,
fuzzClusterConfig(obj) fuzzAuditPolicyConfiguration,
}, fuzzComponentConfigs,
func(obj *kubeadm.InitConfiguration, c fuzz.Continue) { fuzzNodeRegistration,
c.FuzzNoCustom(obj) fuzzLocalEtcd,
fuzzClusterConfig(&obj.ClusterConfiguration) fuzzNetworking,
fuzzBootstrapTokens(&obj.BootstrapTokens) fuzzJoinConfiguration,
fuzzNodeRegistration(&obj.NodeRegistration)
fuzzAPIEndpoint(&obj.APIEndpoint)
},
func(obj *kubeadm.JoinConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj)
fuzzNodeRegistration(&obj.NodeRegistration)
fuzzAPIEndpoint(&obj.APIEndpoint)
obj.CACertPath = "foo"
obj.DiscoveryFile = "foo"
obj.DiscoveryToken = "foo"
obj.DiscoveryTokenAPIServers = []string{"foo"}
obj.DiscoveryTimeout = &metav1.Duration{Duration: 1}
obj.TLSBootstrapToken = "foo"
obj.Token = "foo"
obj.ClusterName = "foo"
},
} }
} }
func fuzzBootstrapTokens(obj *[]kubeadm.BootstrapToken) { func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c fuzz.Continue) {
obj = &[]kubeadm.BootstrapToken{ c.FuzzNoCustom(obj)
{
Token: &kubeadm.BootstrapTokenString{ // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
ID: "abcdef",
Secret: "abcdef0123456789", // Since ClusterConfiguration never get serialized in the external variant of InitConfiguration,
// it is necessary to apply external api defaults here to get the round trip internal->external->internal working.
// More specifically:
// internal with manually applied defaults -> external object : loosing ClusterConfiguration) -> internal object with automatically applied defaults
obj.ClusterConfiguration = kubeadm.ClusterConfiguration{
AuditPolicyConfiguration: kubeadm.AuditPolicyConfiguration{
LogDir: constants.StaticPodAuditPolicyLogDir,
LogMaxAge: &v1alpha3.DefaultAuditPolicyLogMaxAge,
},
CertificatesDir: v1alpha3.DefaultCertificatesDir,
ClusterName: v1alpha3.DefaultClusterName,
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: v1alpha3.DefaultEtcdDataDir,
}, },
TTL: &metav1.Duration{Duration: 1 * time.Hour}, },
Usages: []string{"foo"}, ImageRepository: v1alpha3.DefaultImageRepository,
KubernetesVersion: v1alpha3.DefaultKubernetesVersion,
Networking: kubeadm.Networking{
ServiceSubnet: v1alpha3.DefaultServicesSubnet,
DNSDomain: v1alpha3.DefaultServiceDNSDomain,
},
}
// Adds the default bootstrap token to get the round working
obj.BootstrapTokens = []kubeadm.BootstrapToken{
{
// Description
// Expires
Groups: []string{"foo"}, Groups: []string{"foo"},
// Token
TTL: &metav1.Duration{Duration: 1234},
Usages: []string{"foo"},
}, },
} }
} }
func fuzzNodeRegistration(obj *kubeadm.NodeRegistrationOptions) { func fuzzNodeRegistration(obj *kubeadm.NodeRegistrationOptions, c fuzz.Continue) {
c.FuzzNoCustom(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.CRISocket = "foo" obj.CRISocket = "foo"
obj.Name = "foo"
obj.Taints = []v1.Taint{}
} }
func fuzzAPIEndpoint(obj *kubeadm.APIEndpoint) { func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue) {
obj.BindPort = 20 c.FuzzNoCustom(obj)
obj.AdvertiseAddress = "foo"
}
func fuzzClusterConfig(obj *kubeadm.ClusterConfiguration) { // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.KubernetesVersion = "v10"
obj.Networking.ServiceSubnet = "10.96.0.0/12"
obj.Networking.DNSDomain = "cluster.local"
obj.CertificatesDir = "foo" obj.CertificatesDir = "foo"
obj.APIServerCertSANs = []string{"foo"} obj.CIImageRepository = "" //This fields doesn't exists in public API >> using default to get the roundtrip test pass
obj.ImageRepository = "foo" obj.ClusterName = "bar"
obj.CIImageRepository = "" obj.ImageRepository = "baz"
obj.UnifiedControlPlaneImage = "foo" obj.KubernetesVersion = "qux"
obj.FeatureGates = map[string]bool{"foo": true} }
obj.ClusterName = "foo"
obj.APIServerExtraArgs = map[string]string{"foo": "foo"} func fuzzAuditPolicyConfiguration(obj *kubeadm.AuditPolicyConfiguration, c fuzz.Continue) {
obj.APIServerExtraVolumes = []kubeadm.HostPathMount{{ c.FuzzNoCustom(obj)
Name: "foo",
HostPath: "foo", // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
MountPath: "foo", obj.LogDir = "foo"
Writable: false, obj.LogMaxAge = new(int32)
}} }
obj.Etcd.Local = &kubeadm.LocalEtcd{
Image: "foo", func fuzzComponentConfigs(obj *kubeadm.ComponentConfigs, c fuzz.Continue) {
DataDir: "foo", // This is intentionally empty because component config does not exists in the public api
ServerCertSANs: []string{"foo"}, // (empty mean all ComponentConfigs fields nil, and this is necessary for getting roundtrip passing)
PeerCertSANs: []string{"foo"}, }
ExtraArgs: map[string]string{"foo": "foo"},
} func fuzzLocalEtcd(obj *kubeadm.LocalEtcd, c fuzz.Continue) {
obj.AuditPolicyConfiguration = kubeadm.AuditPolicyConfiguration{ c.FuzzNoCustom(obj)
Path: "foo",
LogDir: "/foo", // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
LogMaxAge: utilpointer.Int32Ptr(0), obj.DataDir = "foo"
} }
// Set the Kubelet ComponentConfig to an empty, defaulted struct
extkubeletconfig := &kubeletconfigv1beta1.KubeletConfiguration{} func fuzzNetworking(obj *kubeadm.Networking, c fuzz.Continue) {
obj.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{} c.FuzzNoCustom(obj)
componentconfigs.Scheme.Default(extkubeletconfig)
componentconfigs.Scheme.Convert(extkubeletconfig, obj.ComponentConfigs.Kubelet, nil) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
componentconfigs.DefaultKubeletConfiguration(obj) obj.DNSDomain = "foo"
// Set the KubeProxy ComponentConfig to an empty, defaulted struct obj.ServiceSubnet = "bar"
extkubeproxyconfig := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{} }
obj.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
componentconfigs.Scheme.Default(extkubeproxyconfig) func fuzzJoinConfiguration(obj *kubeadm.JoinConfiguration, c fuzz.Continue) {
componentconfigs.Scheme.Convert(extkubeproxyconfig, obj.ComponentConfigs.KubeProxy, nil) c.FuzzNoCustom(obj)
componentconfigs.DefaultKubeProxyConfiguration(obj)
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.CACertPath = "foo"
obj.ClusterName = "bar"
obj.DiscoveryTimeout = &metav1.Duration{Duration: 1234}
obj.DiscoveryToken = "baz"
obj.TLSBootstrapToken = "qux"
} }

View File

@ -21,7 +21,7 @@ package fuzzer
// earlier now have moved out it's not possible to do a lossless roundtrip "the normal way" // earlier now have moved out it's not possible to do a lossless roundtrip "the normal way"
// When we support v1alpha3 and higher only, we can reenable this // When we support v1alpha3 and higher only, we can reenable this
/*import ( import (
"testing" "testing"
"k8s.io/apimachinery/pkg/api/apitesting/roundtrip" "k8s.io/apimachinery/pkg/api/apitesting/roundtrip"
@ -30,4 +30,4 @@ package fuzzer
func TestRoundTripTypes(t *testing.T) { func TestRoundTripTypes(t *testing.T) {
roundtrip.RoundTripTestForAPIGroup(t, scheme.AddToScheme, Funcs) roundtrip.RoundTripTestForAPIGroup(t, scheme.AddToScheme, Funcs)
}*/ }

View File

@ -17,8 +17,6 @@ limitations under the License.
package kubeadm package kubeadm
import ( import (
fuzz "github.com/google/gofuzz"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
@ -143,12 +141,6 @@ type ComponentConfigs struct {
KubeProxy *kubeproxyconfig.KubeProxyConfiguration KubeProxy *kubeproxyconfig.KubeProxyConfiguration
} }
// Fuzz is a dummy function here to get the roundtrip tests working in cmd/kubeadm/app/apis/kubeadm/fuzzer working.
// This makes the fuzzer not go and randomize all fields in the ComponentConfigs struct, as that wouldn't work for
// a roundtrip. A roundtrip to the v1alpha3 API obviously doesn't work as it's not stored there at all. With this,
// the roundtrip is considered valid, as semi-static values are set and preserved during a roundtrip.
func (cc ComponentConfigs) Fuzz(c fuzz.Continue) {}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ClusterStatus contains the cluster status. The ClusterStatus will be stored in the kubeadm-config // ClusterStatus contains the cluster status. The ClusterStatus will be stored in the kubeadm-config