Пример #1
0
// TestTypes will try to roundtrip all OpenShift and Kubernetes stable api types
func TestTypes(t *testing.T) {
	for kind, reflectType := range kapi.Scheme.KnownTypes(osapi.SchemeGroupVersion) {
		if !strings.Contains(reflectType.PkgPath(), "/origin/") && reflectType.PkgPath() != "k8s.io/kubernetes/pkg/api" {
			continue
		}
		if nonInternalRoundTrippableTypes.Has(kind) {
			continue
		}
		// Try a few times, since runTest uses random values.
		for i := 0; i < fuzzIters; i++ {
			item, err := kapi.Scheme.New(osapi.SchemeGroupVersion.WithKind(kind))
			if err != nil {
				t.Errorf("Couldn't make a %v? %v", kind, err)
				continue
			}
			if _, err := meta.TypeAccessor(item); err != nil {
				t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
			}
			seed := rand.Int63()

			if versions, ok := skipStandardVersions[kind]; ok {
				for _, v := range versions {
					t.Logf("About to test %v with %q", kind, v)
					fuzzInternalObject(t, v, item, seed)
					roundTrip(t, kapi.Codecs.LegacyCodec(v), item)
				}
				continue
			}
			t.Logf(`About to test %v with "v1"`, kind)
			fuzzInternalObject(t, v1.SchemeGroupVersion, item, seed)
			roundTrip(t, kapi.Codecs.LegacyCodec(v1.SchemeGroupVersion), item)
		}
	}
}
Пример #2
0
func TestTypes(t *testing.T) {
	for kind, reflectType := range api.Scheme.KnownTypes("") {
		if !strings.Contains(reflectType.PkgPath(), "/origin/") {
			continue
		}
		t.Logf("About to test %v", reflectType)
		// Try a few times, since runTest uses random values.
		for i := 0; i < fuzzIters; i++ {
			item, err := api.Scheme.New("", kind)
			if err != nil {
				t.Errorf("Couldn't make a %v? %v", kind, err)
				continue
			}
			if _, err := meta.TypeAccessor(item); err != nil {
				t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
			}
			seed := rand.Int63()

			if versions, ok := skipStandardVersions[kind]; ok {
				for _, v := range versions {
					fuzzInternalObject(t, "", item, seed)
					roundTrip(t, runtime.CodecFor(api.Scheme, v), item)
				}
				continue
			}
			fuzzInternalObject(t, "", item, seed)
			roundTrip(t, osapi.Codec, item)
			fuzzInternalObject(t, "v1beta3", item, seed)
			roundTrip(t, v1beta3.Codec, item)
			fuzzInternalObject(t, "v1", item, seed)
			roundTrip(t, v1.Codec, item)
		}
	}
}
Пример #3
0
func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item runtime.Object, seed int64) runtime.Object {
	apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed)).Fuzz(item)

	j, err := meta.TypeAccessor(item)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, item)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return item
}
Пример #4
0
func doRoundTripTest(kind string, t *testing.T) {
	item, err := api.Scheme.New("", kind)
	if err != nil {
		t.Fatalf("Couldn't make a %v? %v", kind, err)
	}
	if _, err := meta.TypeAccessor(item); err != nil {
		t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
	}
	roundTripSame(t, item, nonRoundTrippableTypesByVersion[kind]...)
	if !nonInternalRoundTrippableTypes.Has(kind) {
		roundTrip(t, api.Codec, fuzzInternalObject(t, "", item, rand.Int63()))
	}
}
Пример #5
0
func TestGenericTypeMeta(t *testing.T) {
	type TypeMeta struct {
		Kind              string               `json:"kind,omitempty"`
		Namespace         string               `json:"namespace,omitempty"`
		Name              string               `json:"name,omitempty"`
		GenerateName      string               `json:"generateName,omitempty"`
		UID               string               `json:"uid,omitempty"`
		CreationTimestamp unversioned.Time     `json:"creationTimestamp,omitempty"`
		SelfLink          string               `json:"selfLink,omitempty"`
		ResourceVersion   string               `json:"resourceVersion,omitempty"`
		APIVersion        string               `json:"apiVersion,omitempty"`
		Labels            map[string]string    `json:"labels,omitempty"`
		Annotations       map[string]string    `json:"annotations,omitempty"`
		OwnerReferences   []api.OwnerReference `json:"ownerReferences,omitempty"`
		Finalizers        []string             `json:"finalizers,omitempty"`
	}

	j := struct{ TypeMeta }{TypeMeta{APIVersion: "a", Kind: "b"}}

	typeAccessor, err := meta.TypeAccessor(&j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "b", typeAccessor.GetKind(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	typeAccessor.SetAPIVersion("c")
	typeAccessor.SetKind("d")

	if e, a := "c", j.APIVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "d", j.Kind; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	typeAccessor.SetAPIVersion("d")
	typeAccessor.SetKind("e")

	if e, a := "d", j.APIVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "e", j.Kind; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
}
Пример #6
0
func doRoundTripTest(group testapi.TestGroup, kind string, t *testing.T) {
	item, err := api.Scheme.New(group.InternalGroupVersion().WithKind(kind))
	if err != nil {
		t.Fatalf("Couldn't make a %v? %v", kind, err)
	}
	if _, err := meta.TypeAccessor(item); err != nil {
		t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
	}
	if api.Scheme.Recognizes(group.GroupVersion().WithKind(kind)) {
		roundTripSame(t, group, item, nonRoundTrippableTypesByVersion[kind]...)
	}
	if !nonInternalRoundTrippableTypes.Has(kind) && api.Scheme.Recognizes(group.GroupVersion().WithKind(kind)) {
		roundTrip(t, group.Codec(), fuzzInternalObject(t, group.InternalGroupVersion(), item, rand.Int63()))
	}
}
Пример #7
0
// TestTypes will try to roundtrip all OpenShift and Kubernetes stable api types
func TestTypes(t *testing.T) {
	for kind := range configapi.Scheme.KnownTypes(configapi.SchemeGroupVersion) {
		// Try a few times, since runTest uses random values.
		for i := 0; i < fuzzIters; i++ {
			item, err := configapi.Scheme.New(configapi.SchemeGroupVersion.WithKind(kind))
			if err != nil {
				t.Errorf("Couldn't make a %v? %v", kind, err)
				continue
			}
			if _, err := meta.TypeAccessor(item); err != nil {
				t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
			}
			seed := rand.Int63()

			fuzzInternalObject(t, configapiv1.SchemeGroupVersion, item, seed)
			roundTrip(t, serializer.NewCodecFactory(configapi.Scheme).LegacyCodec(configapiv1.SchemeGroupVersion), item)
		}
	}
}
Пример #8
0
// TestTypes will try to roundtrip all OpenShift and Kubernetes stable api types
func TestTypes(t *testing.T) {
	internalVersionToExternalVersions := map[unversioned.GroupVersion][]unversioned.GroupVersion{
		osapi.SchemeGroupVersion:    {v1.SchemeGroupVersion},
		quotaapi.SchemeGroupVersion: {quotaapiv1.SchemeGroupVersion},
	}

	for internalVersion, externalVersions := range internalVersionToExternalVersions {
		for kind, reflectType := range kapi.Scheme.KnownTypes(internalVersion) {
			if !strings.Contains(reflectType.PkgPath(), "github.com/openshift/origin/") && reflectType.PkgPath() != "github.com/openshift/origin/vendor/k8s.io/kubernetes/pkg/api" {
				continue
			}
			if nonInternalRoundTrippableTypes.Has(kind) {
				continue
			}

			for _, externalVersion := range externalVersions {
				// Try a few times, since runTest uses random values.
				for i := 0; i < fuzzIters; i++ {
					item, err := kapi.Scheme.New(internalVersion.WithKind(kind))
					if err != nil {
						t.Errorf("Couldn't make a %v? %v", kind, err)
						continue
					}
					if _, err := meta.TypeAccessor(item); err != nil {
						t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
					}
					seed := rand.Int63()

					if versions, ok := skipStandardVersions[kind]; ok {
						for _, v := range versions {
							fuzzInternalObject(t, v, item, seed)
							roundTrip(t, kapi.Codecs.LegacyCodec(v), item)
						}
						continue
					}
					fuzzInternalObject(t, externalVersion, item, seed)
					roundTripWithAllCodecs(t, externalVersion, item)
				}
			}
		}

	}
}
Пример #9
0
func fuzzImageSignature(t *testing.T, signature *api.ImageSignature, seed int64) *api.ImageSignature {
	f := apitesting.FuzzerFor(t, v1.SchemeGroupVersion, rand.NewSource(seed))
	f.Funcs(
		func(j *api.ImageSignature, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Annotations = make(map[string]string)
			j.Labels = make(map[string]string)
			j.Conditions = []api.SignatureCondition{}
			j.SignedClaims = make(map[string]string)

			j.Content = []byte(c.RandString())
			for i := 0; i < c.Rand.Intn(3)+2; i++ {
				j.Labels[c.RandString()] = c.RandString()
				j.Annotations[c.RandString()] = c.RandString()
				j.SignedClaims[c.RandString()] = c.RandString()
			}
			for i := 0; i < c.Rand.Intn(3)+2; i++ {
				cond := api.SignatureCondition{}
				c.Fuzz(&cond)
				j.Conditions = append(j.Conditions, cond)
			}
		},
	)

	updated := api.ImageSignature{}
	f.Fuzz(&updated)
	updated.Namespace = signature.Namespace
	updated.Name = signature.Name

	j, err := meta.TypeAccessor(signature)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, signature)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return &updated
}
Пример #10
0
func fuzzImage(t *testing.T, image *api.Image, seed int64) *api.Image {
	f := apitesting.FuzzerFor(t, v1.SchemeGroupVersion, rand.NewSource(seed))
	f.Funcs(
		func(j *api.Image, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Annotations = make(map[string]string)
			j.Labels = make(map[string]string)
			j.Signatures = make([]api.ImageSignature, c.Rand.Intn(3)+2)
			for i := range j.Signatures {
				sign := &j.Signatures[i]
				c.Fuzz(sign)
				sign.Conditions = make([]api.SignatureCondition, c.Rand.Intn(3)+2)
				for ci := range sign.Conditions {
					cond := &sign.Conditions[ci]
					c.Fuzz(cond)
				}
			}
			for i := 0; i < c.Rand.Intn(3)+2; i++ {
				j.Labels[c.RandString()] = c.RandString()
				j.Annotations[c.RandString()] = c.RandString()
			}
		},
	)

	updated := api.Image{}
	f.Fuzz(&updated)
	updated.Namespace = image.Namespace
	updated.Name = image.Name

	j, err := meta.TypeAccessor(image)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, image)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return &updated
}
Пример #11
0
func TestRoundTripTypes(t *testing.T) {
	// api.Scheme.Log(t)
	// defer api.Scheme.Log(nil)

	for kind := range api.Scheme.KnownTypes("") {
		if nonRoundTrippableTypes.Has(kind) {
			continue
		}
		// Try a few times, since runTest uses random values.
		for i := 0; i < *fuzzIters; i++ {
			item, err := api.Scheme.New("", kind)
			if err != nil {
				t.Fatalf("Couldn't make a %v? %v", kind, err)
			}
			if _, err := meta.TypeAccessor(item); err != nil {
				t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
			}
			roundTripSame(t, item, nonRoundTrippableTypesByVersion[kind]...)
			if !nonInternalRoundTrippableTypes.Has(kind) {
				roundTrip(t, api.Codec, fuzzInternalObject(t, "", item, rand.Int63()))
			}
		}
	}
}
Пример #12
0
func fuzzInternalObject(t *testing.T, forVersion string, item runtime.Object, seed int64) runtime.Object {
	f := apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed))
	f.Funcs(
		// Roles and RoleBindings maps are never nil
		func(j *authorizationapi.Policy, c fuzz.Continue) {
			j.Roles = make(map[string]*authorizationapi.Role)
		},
		func(j *authorizationapi.PolicyBinding, c fuzz.Continue) {
			j.RoleBindings = make(map[string]*authorizationapi.RoleBinding)
		},
		func(j *authorizationapi.ClusterPolicy, c fuzz.Continue) {
			j.Roles = make(map[string]*authorizationapi.ClusterRole)
		},
		func(j *authorizationapi.ClusterPolicyBinding, c fuzz.Continue) {
			j.RoleBindings = make(map[string]*authorizationapi.ClusterRoleBinding)
		},
		func(j *authorizationapi.RoleBinding, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			for i := range j.Subjects {
				kinds := []string{authorizationapi.UserKind, authorizationapi.SystemUserKind, authorizationapi.GroupKind, authorizationapi.SystemGroupKind, authorizationapi.ServiceAccountKind}
				j.Subjects[i].Kind = kinds[c.Intn(len(kinds))]
				switch j.Subjects[i].Kind {
				case authorizationapi.UserKind:
					j.Subjects[i].Namespace = ""
					if valid, _ := uservalidation.ValidateUserName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("validusername%d", i)
					}

				case authorizationapi.GroupKind:
					j.Subjects[i].Namespace = ""
					if valid, _ := uservalidation.ValidateGroupName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("validgroupname%d", i)
					}

				case authorizationapi.ServiceAccountKind:
					if valid, _ := validation.ValidateNamespaceName(j.Subjects[i].Namespace, false); !valid {
						j.Subjects[i].Namespace = fmt.Sprintf("sanamespacehere%d", i)
					}
					if valid, _ := validation.ValidateServiceAccountName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("sanamehere%d", i)
					}

				case authorizationapi.SystemUserKind, authorizationapi.SystemGroupKind:
					j.Subjects[i].Namespace = ""
					j.Subjects[i].Name = ":" + j.Subjects[i].Name

				}

				j.Subjects[i].UID = types.UID("")
				j.Subjects[i].APIVersion = ""
				j.Subjects[i].ResourceVersion = ""
				j.Subjects[i].FieldPath = ""
			}
		},
		func(j *authorizationapi.ClusterRoleBinding, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			for i := range j.Subjects {
				kinds := []string{authorizationapi.UserKind, authorizationapi.SystemUserKind, authorizationapi.GroupKind, authorizationapi.SystemGroupKind, authorizationapi.ServiceAccountKind}
				j.Subjects[i].Kind = kinds[c.Intn(len(kinds))]
				switch j.Subjects[i].Kind {
				case authorizationapi.UserKind:
					j.Subjects[i].Namespace = ""
					if valid, _ := uservalidation.ValidateUserName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("validusername%d", i)
					}

				case authorizationapi.GroupKind:
					j.Subjects[i].Namespace = ""
					if valid, _ := uservalidation.ValidateGroupName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("validgroupname%d", i)
					}

				case authorizationapi.ServiceAccountKind:
					if valid, _ := validation.ValidateNamespaceName(j.Subjects[i].Namespace, false); !valid {
						j.Subjects[i].Namespace = fmt.Sprintf("sanamespacehere%d", i)
					}
					if valid, _ := validation.ValidateServiceAccountName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("sanamehere%d", i)
					}

				case authorizationapi.SystemUserKind, authorizationapi.SystemGroupKind:
					j.Subjects[i].Namespace = ""
					j.Subjects[i].Name = ":" + j.Subjects[i].Name

				}

				j.Subjects[i].UID = types.UID("")
				j.Subjects[i].APIVersion = ""
				j.Subjects[i].ResourceVersion = ""
				j.Subjects[i].FieldPath = ""
			}
		},
		func(j *template.Template, c fuzz.Continue) {
			c.Fuzz(&j.ObjectMeta)
			c.Fuzz(&j.Parameters)
			// TODO: replace with structured type definition
			j.Objects = []runtime.Object{}
		},
		func(j *image.Image, c fuzz.Continue) {
			c.Fuzz(&j.ObjectMeta)
			c.Fuzz(&j.DockerImageMetadata)
			j.DockerImageMetadata.APIVersion = ""
			j.DockerImageMetadata.Kind = ""
			j.DockerImageMetadataVersion = []string{"pre012", "1.0"}[c.Rand.Intn(2)]
			j.DockerImageReference = c.RandString()
		},
		func(j *image.ImageStreamMapping, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.DockerImageRepository = ""
		},
		func(j *image.ImageStreamImage, c fuzz.Continue) {
			c.Fuzz(&j.Image)
			// because we de-embedded Image from ImageStreamImage, in order to round trip
			// successfully, the ImageStreamImage's ObjectMeta must match the Image's.
			j.ObjectMeta = j.Image.ObjectMeta
		},
		func(j *image.ImageStreamTag, c fuzz.Continue) {
			c.Fuzz(&j.Image)
			// because we de-embedded Image from ImageStreamTag, in order to round trip
			// successfully, the ImageStreamTag's ObjectMeta must match the Image's.
			j.ObjectMeta = j.Image.ObjectMeta
		},
		func(j *image.TagReference, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.From != nil {
				specs := []string{"", "ImageStreamTag", "ImageStreamImage"}
				j.From.Kind = specs[c.Intn(len(specs))]
			}
		},
		func(j *build.SourceBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.CustomBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.DockerBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.BuildOutput, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.To != nil && (len(j.To.Kind) == 0 || j.To.Kind == "ImageStream") {
				j.To.Kind = "ImageStreamTag"
			}
			if j.To != nil && strings.Contains(j.To.Name, ":") {
				j.To.Name = strings.Replace(j.To.Name, ":", "-", -1)
			}
		},
		func(j *route.RouteSpec, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.To = api.ObjectReference{
				Kind: "Service",
				Name: j.To.Name,
			}
		},
		func(j *deploy.DeploymentConfig, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Triggers = []deploy.DeploymentTriggerPolicy{{Type: deploy.DeploymentTriggerOnConfigChange}}
		},
		func(j *deploy.DeploymentStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			mkintp := func(i int) *int64 {
				v := int64(i)
				return &v
			}
			switch c.Intn(3) {
			case 0:
				// TODO: we should not have to set defaults, instead we should be able
				// to detect defaults were applied.
				j.Type = deploy.DeploymentStrategyTypeRolling
				j.RollingParams = &deploy.RollingDeploymentStrategyParams{
					IntervalSeconds:     mkintp(1),
					UpdatePeriodSeconds: mkintp(1),
					TimeoutSeconds:      mkintp(120),
				}
			case 1:
				j.Type = deploy.DeploymentStrategyTypeRecreate
				j.RollingParams = nil
			case 2:
				j.Type = deploy.DeploymentStrategyTypeCustom
				j.RollingParams = nil
			}
		},
		func(j *deploy.DeploymentCauseImageTrigger, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			specs := []string{"", "a/b", "a/b/c", "a:5000/b/c", "a/b", "a/b"}
			tags := []string{"", "stuff", "other"}
			j.RepositoryName = specs[c.Intn(len(specs))]
			if len(j.RepositoryName) > 0 {
				j.Tag = tags[c.Intn(len(tags))]
			} else {
				j.Tag = ""
			}
		},
		func(j *deploy.DeploymentTriggerImageChangeParams, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			specs := []string{"a/b", "a/b/c", "a:5000/b/c", "a/b:latest", "a/b@test"}
			j.From.Kind = "DockerImage"
			j.From.Name = specs[c.Intn(len(specs))]
			if ref, err := image.ParseDockerImageReference(j.From.Name); err == nil {
				j.Tag = ref.Tag
				ref.Tag, ref.ID = "", ""
				j.RepositoryName = ref.String()
			}
		},
		func(j *runtime.EmbeddedObject, c fuzz.Continue) {
			// runtime.EmbeddedObject causes a panic inside of fuzz because runtime.Object isn't handled.
		},
		func(t *time.Time, c fuzz.Continue) {
			// This is necessary because the standard fuzzed time.Time object is
			// completely nil, but when JSON unmarshals dates it fills in the
			// unexported loc field with the time.UTC object, resulting in
			// reflect.DeepEqual returning false in the round trip tests. We solve it
			// by using a date that will be identical to the one JSON unmarshals.
			*t = time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC)
		},
		func(u64 *uint64, c fuzz.Continue) {
			// TODO: uint64's are NOT handled right.
			*u64 = c.RandUint64() >> 8
		},
	)

	f.Fuzz(item)

	j, err := meta.TypeAccessor(item)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, item)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return item
}
Пример #13
0
func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item runtime.Object, seed int64) runtime.Object {
	f := fuzzerFor(t, forVersion, rand.NewSource(seed))
	f.Funcs(
		// these follow defaulting rules
		func(obj *configapi.MasterConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.APILevels) == 0 {
				obj.APILevels = configapi.DefaultOpenShiftAPILevels
			}
			if len(obj.Controllers) == 0 {
				obj.Controllers = configapi.ControllersAll
			}
			if obj.ServingInfo.RequestTimeoutSeconds == 0 {
				obj.ServingInfo.RequestTimeoutSeconds = 60 * 60
			}
			if obj.ServingInfo.MaxRequestsInFlight == 0 {
				obj.ServingInfo.MaxRequestsInFlight = 500
			}
			if len(obj.PolicyConfig.OpenShiftInfrastructureNamespace) == 0 {
				obj.PolicyConfig.OpenShiftInfrastructureNamespace = bootstrappolicy.DefaultOpenShiftInfraNamespace
			}
			if len(obj.RoutingConfig.Subdomain) == 0 {
				obj.RoutingConfig.Subdomain = "router.default.svc.cluster.local"
			}

			// Populate the new NetworkConfig.ServiceNetworkCIDR field from the KubernetesMasterConfig.ServicesSubnet field if needed
			if len(obj.NetworkConfig.ServiceNetworkCIDR) == 0 {
				if obj.KubernetesMasterConfig != nil && len(obj.KubernetesMasterConfig.ServicesSubnet) > 0 {
					// if a subnet is set in the kubernetes master config, use that
					obj.NetworkConfig.ServiceNetworkCIDR = obj.KubernetesMasterConfig.ServicesSubnet
				} else {
					// default ServiceClusterIPRange used by kubernetes if nothing is specified
					obj.NetworkConfig.ServiceNetworkCIDR = "10.0.0.0/24"
				}
			}

			// Historically, the clientCA was incorrectly used as the master's server cert CA bundle
			// If missing from the config, migrate the ClientCA into that field
			if obj.OAuthConfig != nil && obj.OAuthConfig.MasterCA == nil {
				s := obj.ServingInfo.ClientCA
				// The final value of OAuthConfig.MasterCA should never be nil
				obj.OAuthConfig.MasterCA = &s
			}
		},
		func(obj *configapi.KubernetesMasterConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if obj.MasterCount == 0 {
				obj.MasterCount = 1
			}
			if len(obj.ServicesNodePortRange) == 0 {
				obj.ServicesNodePortRange = "30000-32767"
			}
			if len(obj.PodEvictionTimeout) == 0 {
				obj.PodEvictionTimeout = "5m"
			}
		},
		func(obj *configapi.JenkinsPipelineConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if obj.Enabled == nil {
				v := c.RandBool()
				obj.Enabled = &v
			}
			if len(obj.TemplateNamespace) == 0 {
				obj.TemplateNamespace = "value"
			}
			if len(obj.TemplateName) == 0 {
				obj.TemplateName = "anothervalue"
			}
			if len(obj.ServiceName) == 0 {
				obj.ServiceName = "thirdvalue"
			}
		},
		func(obj *configapi.NodeConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			// Defaults/migrations for NetworkConfig
			if len(obj.NetworkConfig.NetworkPluginName) == 0 {
				obj.NetworkConfig.NetworkPluginName = "plugin-name"
			}
			if obj.NetworkConfig.MTU == 0 {
				obj.NetworkConfig.MTU = 1450
			}
			if len(obj.IPTablesSyncPeriod) == 0 {
				obj.IPTablesSyncPeriod = "5s"
			}

			// Auth cache defaults
			if len(obj.AuthConfig.AuthenticationCacheTTL) == 0 {
				obj.AuthConfig.AuthenticationCacheTTL = "5m"
			}
			if obj.AuthConfig.AuthenticationCacheSize == 0 {
				obj.AuthConfig.AuthenticationCacheSize = 1000
			}
			if len(obj.AuthConfig.AuthorizationCacheTTL) == 0 {
				obj.AuthConfig.AuthorizationCacheTTL = "5m"
			}
			if obj.AuthConfig.AuthorizationCacheSize == 0 {
				obj.AuthConfig.AuthorizationCacheSize = 1000
			}
		},
		func(obj *configapi.EtcdStorageConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.KubernetesStorageVersion) == 0 {
				obj.KubernetesStorageVersion = "v1"
			}
			if len(obj.KubernetesStoragePrefix) == 0 {
				obj.KubernetesStoragePrefix = "kubernetes.io"
			}
			if len(obj.OpenShiftStorageVersion) == 0 {
				obj.OpenShiftStorageVersion = configapi.DefaultOpenShiftStorageVersionLevel
			}
			if len(obj.OpenShiftStoragePrefix) == 0 {
				obj.OpenShiftStoragePrefix = "openshift.io"
			}
		},
		func(obj *configapi.DockerConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.ExecHandlerName) == 0 {
				obj.ExecHandlerName = configapi.DockerExecHandlerNative
			}
		},
		func(obj *configapi.ServingInfo, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.BindNetwork) == 0 {
				obj.BindNetwork = "tcp4"
			}
		},
		func(obj *configapi.ImagePolicyConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if obj.MaxImagesBulkImportedPerRepository == 0 {
				obj.MaxImagesBulkImportedPerRepository = 5
			}
			if obj.MaxScheduledImageImportsPerMinute == 0 {
				obj.MaxScheduledImageImportsPerMinute = 60
			}
			if obj.ScheduledImageImportMinimumIntervalSeconds == 0 {
				obj.ScheduledImageImportMinimumIntervalSeconds = 15 * 60
			}
		},
		func(obj *configapi.DNSConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.BindNetwork) == 0 {
				obj.BindNetwork = "tcp4"
			}
		},
		func(obj *configapi.SecurityAllocator, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.UIDAllocatorRange) == 0 {
				obj.UIDAllocatorRange = "1000000000-1999999999/10000"
			}
			if len(obj.MCSAllocatorRange) == 0 {
				obj.MCSAllocatorRange = "s0:/2"
			}
			if obj.MCSLabelsPerProject == 0 {
				obj.MCSLabelsPerProject = 5
			}
		},
		func(obj *configapi.IdentityProvider, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.MappingMethod) == 0 {
				// By default, only let one identity provider authenticate a particular user
				// If multiple identity providers collide, the second one in will fail to auth
				// The admin can set this to "add" if they want to allow new identities to join existing users
				obj.MappingMethod = "claim"
			}
		},
		func(s *configapi.StringSource, c fuzz.Continue) {
			if c.RandBool() {
				c.Fuzz(&s.Value)
			} else {
				c.Fuzz(&s.StringSourceSpec)
			}
		},
		func(obj *podnodeapi.PodNodeConstraintsConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if obj.NodeSelectorLabelBlacklist == nil {
				obj.NodeSelectorLabelBlacklist = []string{"kubernetes.io/hostname"}
			}
		},
		func(obj *configapi.GrantConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.ServiceAccountMethod) == 0 {
				obj.ServiceAccountMethod = "prompt"
			}
		},
	)

	f.Fuzz(item)

	j, err := meta.TypeAccessor(item)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, item)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return item
}
Пример #14
0
// Dequeueing an event from eventQueue, updating graph, populating dirty_queue.
func (p *Propagator) processEvent() {
	key, quit := p.eventQueue.Get()
	if quit {
		return
	}
	defer p.eventQueue.Done(key)
	event, ok := key.(event)
	if !ok {
		utilruntime.HandleError(fmt.Errorf("expect an event, got %v", key))
		return
	}
	obj := event.obj
	accessor, err := meta.Accessor(obj)
	if err != nil {
		utilruntime.HandleError(fmt.Errorf("cannot access obj: %v", err))
		return
	}
	typeAccessor, err := meta.TypeAccessor(obj)
	if err != nil {
		utilruntime.HandleError(fmt.Errorf("cannot access obj: %v", err))
		return
	}
	glog.V(6).Infof("Propagator process object: %s/%s, namespace %s, name %s, event type %s", typeAccessor.GetAPIVersion(), typeAccessor.GetKind(), accessor.GetNamespace(), accessor.GetName(), event.eventType)
	// Check if the node already exsits
	existingNode, found := p.uidToNode.Read(accessor.GetUID())
	switch {
	case (event.eventType == addEvent || event.eventType == updateEvent) && !found:
		newNode := &node{
			identity: objectReference{
				OwnerReference: metatypes.OwnerReference{
					APIVersion: typeAccessor.GetAPIVersion(),
					Kind:       typeAccessor.GetKind(),
					UID:        accessor.GetUID(),
					Name:       accessor.GetName(),
				},
				Namespace: accessor.GetNamespace(),
			},
			dependentsLock: &sync.RWMutex{},
			dependents:     make(map[*node]struct{}),
			owners:         accessor.GetOwnerReferences(),
		}
		p.insertNode(newNode)
		// the underlying delta_fifo may combine a creation and deletion into one event
		if shouldOrphanDependents(event, accessor) {
			glog.V(6).Infof("add %s to the orphanQueue", newNode.identity)
			p.gc.orphanQueue.Add(newNode)
		}
	case (event.eventType == addEvent || event.eventType == updateEvent) && found:
		// caveat: if GC observes the creation of the dependents later than the
		// deletion of the owner, then the orphaning finalizer won't be effective.
		if shouldOrphanDependents(event, accessor) {
			glog.V(6).Infof("add %s to the orphanQueue", existingNode.identity)
			p.gc.orphanQueue.Add(existingNode)
		}
		// add/remove owner refs
		added, removed := referencesDiffs(existingNode.owners, accessor.GetOwnerReferences())
		if len(added) == 0 && len(removed) == 0 {
			glog.V(6).Infof("The updateEvent %#v doesn't change node references, ignore", event)
			return
		}
		// update the node itself
		existingNode.owners = accessor.GetOwnerReferences()
		// Add the node to its new owners' dependent lists.
		p.addDependentToOwners(existingNode, added)
		// remove the node from the dependent list of node that are no long in
		// the node's owners list.
		p.removeDependentFromOwners(existingNode, removed)
	case event.eventType == deleteEvent:
		if !found {
			glog.V(6).Infof("%v doesn't exist in the graph, this shouldn't happen", accessor.GetUID())
			return
		}
		p.removeNode(existingNode)
		existingNode.dependentsLock.RLock()
		defer existingNode.dependentsLock.RUnlock()
		for dep := range existingNode.dependents {
			p.gc.dirtyQueue.Add(dep)
		}
	}
}
Пример #15
0
func TestGenericListMeta(t *testing.T) {
	type TypeMeta struct {
		Kind       string `json:"kind,omitempty"`
		APIVersion string `json:"apiVersion,omitempty"`
	}
	type ListMeta struct {
		SelfLink        string `json:"selfLink,omitempty"`
		ResourceVersion string `json:"resourceVersion,omitempty"`
	}
	type Object struct {
		TypeMeta `json:",inline"`
		ListMeta `json:"metadata"`
	}
	j := Object{
		TypeMeta{
			APIVersion: "a",
			Kind:       "b",
		},
		ListMeta{
			ResourceVersion: "1",
			SelfLink:        "some/place/only/we/know",
		},
	}
	accessor, err := meta.Accessor(&j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if e, a := "", accessor.GetName(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "", string(accessor.GetUID()); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "1", accessor.GetResourceVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "some/place/only/we/know", accessor.GetSelfLink(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	typeAccessor, err := meta.TypeAccessor(&j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "b", typeAccessor.GetKind(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	accessor.SetName("bar")
	accessor.SetUID("other")
	typeAccessor.SetAPIVersion("c")
	typeAccessor.SetKind("d")
	accessor.SetResourceVersion("2")
	accessor.SetSelfLink("google.com")

	// Prove that accessor changes the original object.
	if e, a := "c", j.APIVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "d", j.Kind; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "2", j.ResourceVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "google.com", j.SelfLink; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
}
Пример #16
0
func TestGenericObjectMeta(t *testing.T) {
	type TypeMeta struct {
		Kind       string `json:"kind,omitempty"`
		APIVersion string `json:"apiVersion,omitempty"`
	}
	type ObjectMeta struct {
		Namespace         string               `json:"namespace,omitempty"`
		Name              string               `json:"name,omitempty"`
		GenerateName      string               `json:"generateName,omitempty"`
		UID               string               `json:"uid,omitempty"`
		CreationTimestamp unversioned.Time     `json:"creationTimestamp,omitempty"`
		SelfLink          string               `json:"selfLink,omitempty"`
		ResourceVersion   string               `json:"resourceVersion,omitempty"`
		Labels            map[string]string    `json:"labels,omitempty"`
		Annotations       map[string]string    `json:"annotations,omitempty"`
		Finalizers        []string             `json:"finalizers,omitempty"`
		OwnerReferences   []api.OwnerReference `json:"ownerReferences,omitempty"`
	}
	type Object struct {
		TypeMeta   `json:",inline"`
		ObjectMeta `json:"metadata"`
	}
	j := Object{
		TypeMeta{
			APIVersion: "a",
			Kind:       "b",
		},
		ObjectMeta{
			Namespace:       "bar",
			Name:            "foo",
			GenerateName:    "prefix",
			UID:             "uid",
			ResourceVersion: "1",
			SelfLink:        "some/place/only/we/know",
			Labels:          map[string]string{"foo": "bar"},
			Annotations:     map[string]string{"a": "b"},
			Finalizers: []string{
				"finalizer.1",
				"finalizer.2",
			},
		},
	}
	accessor, err := meta.Accessor(&j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if e, a := "bar", accessor.GetNamespace(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "foo", accessor.GetName(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "prefix", accessor.GetGenerateName(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "uid", string(accessor.GetUID()); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "1", accessor.GetResourceVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "some/place/only/we/know", accessor.GetSelfLink(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := 1, len(accessor.GetLabels()); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := 1, len(accessor.GetAnnotations()); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := []string{"finalizer.1", "finalizer.2"}, accessor.GetFinalizers(); !reflect.DeepEqual(e, a) {
		t.Errorf("expected %v, got %v", e, a)
	}

	typeAccessor, err := meta.TypeAccessor(&j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "b", typeAccessor.GetKind(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	accessor.SetNamespace("baz")
	accessor.SetName("bar")
	accessor.SetGenerateName("generate")
	accessor.SetUID("other")
	typeAccessor.SetAPIVersion("c")
	typeAccessor.SetKind("d")
	accessor.SetResourceVersion("2")
	accessor.SetSelfLink("google.com")
	accessor.SetLabels(map[string]string{"other": "label"})
	accessor.SetAnnotations(map[string]string{"c": "d"})
	accessor.SetFinalizers([]string{"finalizer.3"})

	// Prove that accessor changes the original object.
	if e, a := "baz", j.Namespace; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "bar", j.Name; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "generate", j.GenerateName; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "other", j.UID; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "c", j.APIVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "d", j.Kind; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "2", j.ResourceVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "google.com", j.SelfLink; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := map[string]string{"other": "label"}, j.Labels; !reflect.DeepEqual(e, a) {
		t.Errorf("expected %#v, got %#v", e, a)
	}
	if e, a := map[string]string{"c": "d"}, j.Annotations; !reflect.DeepEqual(e, a) {
		t.Errorf("expected %#v, got %#v", e, a)
	}
	if e, a := []string{"finalizer.3"}, j.Finalizers; !reflect.DeepEqual(e, a) {
		t.Errorf("expected %v, got %v", e, a)
	}
}
Пример #17
0
func TestAPIObjectMeta(t *testing.T) {
	j := &api.Pod{
		TypeMeta: unversioned.TypeMeta{APIVersion: "/a", Kind: "b"},
		ObjectMeta: api.ObjectMeta{
			Namespace:       "bar",
			Name:            "foo",
			GenerateName:    "prefix",
			UID:             "uid",
			ResourceVersion: "1",
			SelfLink:        "some/place/only/we/know",
			Labels:          map[string]string{"foo": "bar"},
			Annotations:     map[string]string{"x": "y"},
			Finalizers: []string{
				"finalizer.1",
				"finalizer.2",
			},
		},
	}
	var _ meta.Object = &j.ObjectMeta
	var _ meta.ObjectMetaAccessor = j
	accessor, err := meta.Accessor(j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if accessor != meta.Object(&j.ObjectMeta) {
		t.Fatalf("should have returned the same pointer: %#v %#v", accessor, j)
	}
	if e, a := "bar", accessor.GetNamespace(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "foo", accessor.GetName(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "prefix", accessor.GetGenerateName(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "uid", string(accessor.GetUID()); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "1", accessor.GetResourceVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "some/place/only/we/know", accessor.GetSelfLink(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := []string{"finalizer.1", "finalizer.2"}, accessor.GetFinalizers(); !reflect.DeepEqual(e, a) {
		t.Errorf("expected %v, got %v", e, a)
	}

	typeAccessor, err := meta.TypeAccessor(j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "b", typeAccessor.GetKind(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	accessor.SetNamespace("baz")
	accessor.SetName("bar")
	accessor.SetGenerateName("generate")
	accessor.SetUID("other")
	typeAccessor.SetAPIVersion("c")
	typeAccessor.SetKind("d")
	accessor.SetResourceVersion("2")
	accessor.SetSelfLink("google.com")
	accessor.SetFinalizers([]string{"finalizer.3"})

	// Prove that accessor changes the original object.
	if e, a := "baz", j.Namespace; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "bar", j.Name; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "generate", j.GenerateName; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := types.UID("other"), j.UID; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "c", j.APIVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "d", j.Kind; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "2", j.ResourceVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "google.com", j.SelfLink; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := []string{"finalizer.3"}, j.Finalizers; !reflect.DeepEqual(e, a) {
		t.Errorf("expected %v, got %v", e, a)
	}

	typeAccessor.SetAPIVersion("d")
	typeAccessor.SetKind("e")
	if e, a := "d", j.APIVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "e", j.Kind; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
}
Пример #18
0
func fuzzInternalObject(t *testing.T, forVersion string, item runtime.Object, seed int64) runtime.Object {
	f := apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed))
	f.Funcs(
		// Roles and RoleBindings maps are never nil
		func(j *authorizationapi.Policy, c fuzz.Continue) {
			j.Roles = make(map[string]*authorizationapi.Role)
		},
		func(j *authorizationapi.PolicyBinding, c fuzz.Continue) {
			j.RoleBindings = make(map[string]*authorizationapi.RoleBinding)
		},
		func(j *authorizationapi.ClusterPolicy, c fuzz.Continue) {
			j.Roles = make(map[string]*authorizationapi.ClusterRole)
		},
		func(j *authorizationapi.ClusterPolicyBinding, c fuzz.Continue) {
			j.RoleBindings = make(map[string]*authorizationapi.ClusterRoleBinding)
		},
		func(j *authorizationapi.RoleBinding, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			for i := range j.Subjects {
				kinds := []string{authorizationapi.UserKind, authorizationapi.SystemUserKind, authorizationapi.GroupKind, authorizationapi.SystemGroupKind, authorizationapi.ServiceAccountKind}
				j.Subjects[i].Kind = kinds[c.Intn(len(kinds))]
				switch j.Subjects[i].Kind {
				case authorizationapi.UserKind:
					j.Subjects[i].Namespace = ""
					if valid, _ := uservalidation.ValidateUserName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("validusername%d", i)
					}

				case authorizationapi.GroupKind:
					j.Subjects[i].Namespace = ""
					if valid, _ := uservalidation.ValidateGroupName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("validgroupname%d", i)
					}

				case authorizationapi.ServiceAccountKind:
					if valid, _ := validation.ValidateNamespaceName(j.Subjects[i].Namespace, false); !valid {
						j.Subjects[i].Namespace = fmt.Sprintf("sanamespacehere%d", i)
					}
					if valid, _ := validation.ValidateServiceAccountName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("sanamehere%d", i)
					}

				case authorizationapi.SystemUserKind, authorizationapi.SystemGroupKind:
					j.Subjects[i].Namespace = ""
					j.Subjects[i].Name = ":" + j.Subjects[i].Name

				}

				j.Subjects[i].UID = types.UID("")
				j.Subjects[i].APIVersion = ""
				j.Subjects[i].ResourceVersion = ""
				j.Subjects[i].FieldPath = ""
			}
		},
		func(j *authorizationapi.ClusterRoleBinding, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			for i := range j.Subjects {
				kinds := []string{authorizationapi.UserKind, authorizationapi.SystemUserKind, authorizationapi.GroupKind, authorizationapi.SystemGroupKind, authorizationapi.ServiceAccountKind}
				j.Subjects[i].Kind = kinds[c.Intn(len(kinds))]
				switch j.Subjects[i].Kind {
				case authorizationapi.UserKind:
					j.Subjects[i].Namespace = ""
					if valid, _ := uservalidation.ValidateUserName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("validusername%d", i)
					}

				case authorizationapi.GroupKind:
					j.Subjects[i].Namespace = ""
					if valid, _ := uservalidation.ValidateGroupName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("validgroupname%d", i)
					}

				case authorizationapi.ServiceAccountKind:
					if valid, _ := validation.ValidateNamespaceName(j.Subjects[i].Namespace, false); !valid {
						j.Subjects[i].Namespace = fmt.Sprintf("sanamespacehere%d", i)
					}
					if valid, _ := validation.ValidateServiceAccountName(j.Subjects[i].Name, false); !valid {
						j.Subjects[i].Name = fmt.Sprintf("sanamehere%d", i)
					}

				case authorizationapi.SystemUserKind, authorizationapi.SystemGroupKind:
					j.Subjects[i].Namespace = ""
					j.Subjects[i].Name = ":" + j.Subjects[i].Name

				}

				j.Subjects[i].UID = types.UID("")
				j.Subjects[i].APIVersion = ""
				j.Subjects[i].ResourceVersion = ""
				j.Subjects[i].FieldPath = ""
			}
		},
		func(j *template.Template, c fuzz.Continue) {
			c.Fuzz(&j.ObjectMeta)
			c.Fuzz(&j.Parameters)
			// TODO: replace with structured type definition
			j.Objects = []runtime.Object{}
		},
		func(j *image.Image, c fuzz.Continue) {
			c.Fuzz(&j.ObjectMeta)
			c.Fuzz(&j.DockerImageMetadata)
			j.DockerImageMetadata.APIVersion = ""
			j.DockerImageMetadata.Kind = ""
			j.DockerImageMetadataVersion = []string{"pre012", "1.0"}[c.Rand.Intn(2)]
			j.DockerImageReference = c.RandString()
		},
		func(j *image.ImageStreamMapping, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.DockerImageRepository = ""
		},
		func(j *image.ImageImportSpec, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.To == nil {
				// To is defaulted to be not nil
				j.To = &api.LocalObjectReference{}
			}
		},
		func(j *image.ImageStreamImage, c fuzz.Continue) {
			c.Fuzz(&j.Image)
			// because we de-embedded Image from ImageStreamImage, in order to round trip
			// successfully, the ImageStreamImage's ObjectMeta must match the Image's.
			j.ObjectMeta = j.Image.ObjectMeta
		},
		func(j *image.ImageStreamSpec, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			// if the generated fuzz value has a tag or image id, strip it
			if strings.ContainsAny(j.DockerImageRepository, ":@") {
				j.DockerImageRepository = ""
			}
			if j.Tags == nil {
				j.Tags = make(map[string]image.TagReference)
			}
		},
		func(j *image.ImageStreamStatus, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			// if the generated fuzz value has a tag or image id, strip it
			if strings.ContainsAny(j.DockerImageRepository, ":@") {
				j.DockerImageRepository = ""
			}
		},
		func(j *image.ImageStreamTag, c fuzz.Continue) {
			c.Fuzz(&j.Image)
			// because we de-embedded Image from ImageStreamTag, in order to round trip
			// successfully, the ImageStreamTag's ObjectMeta must match the Image's.
			j.ObjectMeta = j.Image.ObjectMeta
		},
		func(j *image.TagReference, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.From != nil {
				specs := []string{"", "ImageStreamTag", "ImageStreamImage"}
				j.From.Kind = specs[c.Intn(len(specs))]
			}
		},
		func(j *build.SourceBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.CustomBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.DockerBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.BuildOutput, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.To != nil && (len(j.To.Kind) == 0 || j.To.Kind == "ImageStream") {
				j.To.Kind = "ImageStreamTag"
			}
			if j.To != nil && strings.Contains(j.To.Name, ":") {
				j.To.Name = strings.Replace(j.To.Name, ":", "-", -1)
			}
		},
		func(j *route.RouteSpec, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.To = api.ObjectReference{
				Kind: "Service",
				Name: j.To.Name,
			}
		},
		func(j *route.TLSConfig, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if len(j.Termination) == 0 && len(j.DestinationCACertificate) == 0 {
				j.Termination = route.TLSTerminationEdge
			}
		},
		func(j *deploy.DeploymentConfig, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Spec.Triggers = []deploy.DeploymentTriggerPolicy{{Type: deploy.DeploymentTriggerOnConfigChange}}
			if forVersion == "v1beta3" {
				// v1beta3 does not contain the PodSecurityContext type.  For this API version, only fuzz
				// the host namespace fields.  The fields set to nil here are the other fields of the
				// PodSecurityContext that will not roundtrip correctly from internal->v1beta3->internal.
				j.Spec.Template.Spec.SecurityContext.SELinuxOptions = nil
				j.Spec.Template.Spec.SecurityContext.RunAsUser = nil
				j.Spec.Template.Spec.SecurityContext.RunAsNonRoot = nil
				j.Spec.Template.Spec.SecurityContext.SupplementalGroups = nil
				j.Spec.Template.Spec.SecurityContext.FSGroup = nil
			}
		},
		func(j *deploy.DeploymentStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			strategyTypes := []deploy.DeploymentStrategyType{deploy.DeploymentStrategyTypeRecreate, deploy.DeploymentStrategyTypeRolling, deploy.DeploymentStrategyTypeCustom}
			j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))]
			switch j.Type {
			case deploy.DeploymentStrategyTypeRolling:
				params := &deploy.RollingDeploymentStrategyParams{}
				randInt64 := func() *int64 {
					p := int64(c.RandUint64())
					return &p
				}
				params.TimeoutSeconds = randInt64()
				params.IntervalSeconds = randInt64()
				params.UpdatePeriodSeconds = randInt64()

				policyTypes := []deploy.LifecycleHookFailurePolicy{
					deploy.LifecycleHookFailurePolicyRetry,
					deploy.LifecycleHookFailurePolicyAbort,
					deploy.LifecycleHookFailurePolicyIgnore,
				}
				if c.RandBool() {
					params.Pre = &deploy.LifecycleHook{
						FailurePolicy: policyTypes[c.Rand.Intn(len(policyTypes))],
						ExecNewPod: &deploy.ExecNewPodHook{
							ContainerName: c.RandString(),
						},
					}
				}
				if c.RandBool() {
					params.Post = &deploy.LifecycleHook{
						FailurePolicy: policyTypes[c.Rand.Intn(len(policyTypes))],
						ExecNewPod: &deploy.ExecNewPodHook{
							ContainerName: c.RandString(),
						},
					}
				}
				if c.RandBool() {
					params.MaxUnavailable = util.NewIntOrStringFromInt(int(c.RandUint64()))
					params.MaxSurge = util.NewIntOrStringFromInt(int(c.RandUint64()))
				} else {
					params.MaxSurge = util.NewIntOrStringFromString(fmt.Sprintf("%d%%", c.RandUint64()))
					params.MaxUnavailable = util.NewIntOrStringFromString(fmt.Sprintf("%d%%", c.RandUint64()))
				}
				j.RollingParams = params
			default:
				j.RollingParams = nil
			}
		},
		func(j *deploy.DeploymentCauseImageTrigger, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			specs := []string{"", "a/b", "a/b/c", "a:5000/b/c", "a/b", "a/b"}
			tags := []string{"stuff", "other"}
			j.From.Name = specs[c.Intn(len(specs))]
			if len(j.From.Name) > 0 {
				j.From.Name = image.JoinImageStreamTag(j.From.Name, tags[c.Intn(len(tags))])
			}
		},
		func(j *deploy.DeploymentTriggerImageChangeParams, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			specs := []string{"a/b", "a/b/c", "a:5000/b/c", "a/b:latest", "a/b@test"}
			j.From.Kind = "DockerImage"
			j.From.Name = specs[c.Intn(len(specs))]
		},
		func(j *runtime.EmbeddedObject, c fuzz.Continue) {
			// runtime.EmbeddedObject causes a panic inside of fuzz because runtime.Object isn't handled.
		},
		func(t *time.Time, c fuzz.Continue) {
			// This is necessary because the standard fuzzed time.Time object is
			// completely nil, but when JSON unmarshals dates it fills in the
			// unexported loc field with the time.UTC object, resulting in
			// reflect.DeepEqual returning false in the round trip tests. We solve it
			// by using a date that will be identical to the one JSON unmarshals.
			*t = time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC)
		},
		func(u64 *uint64, c fuzz.Continue) {
			// TODO: uint64's are NOT handled right.
			*u64 = c.RandUint64() >> 8
		},
	)

	f.Fuzz(item)

	j, err := meta.TypeAccessor(item)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, item)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return item
}
Пример #19
0
func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item runtime.Object, seed int64) runtime.Object {
	f := fuzzerFor(t, forVersion, rand.NewSource(seed))
	f.Funcs(
		// these follow defaulting rules
		func(obj *configapi.MasterConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.APILevels) == 0 {
				obj.APILevels = configapi.DefaultOpenShiftAPILevels
			}
			if len(obj.Controllers) == 0 {
				obj.Controllers = configapi.ControllersAll
			}
			if obj.ServingInfo.RequestTimeoutSeconds == 0 {
				obj.ServingInfo.RequestTimeoutSeconds = 60 * 60
			}
			if obj.ServingInfo.MaxRequestsInFlight == 0 {
				obj.ServingInfo.MaxRequestsInFlight = 500
			}
			if len(obj.PolicyConfig.OpenShiftInfrastructureNamespace) == 0 {
				obj.PolicyConfig.OpenShiftInfrastructureNamespace = bootstrappolicy.DefaultOpenShiftInfraNamespace
			}
			if len(obj.RoutingConfig.Subdomain) == 0 {
				obj.RoutingConfig.Subdomain = "router.default.svc.cluster.local"
			}

			if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides == nil {
				obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides = &configapi.ClientConnectionOverrides{
					AcceptContentTypes: "test/second",
					ContentType:        "test/first",
				}
			}
			if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.QPS <= 0 {
				obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.QPS = 2.0
			}
			if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.Burst <= 0 {
				obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.Burst = 2
			}
			if len(obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.AcceptContentTypes) == 0 {
				obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.AcceptContentTypes = "test/fourth"
			}
			if len(obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.ContentType) == 0 {
				obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.ContentType = "test/fifth"
			}
			if obj.MasterClients.ExternalKubernetesClientConnectionOverrides == nil {
				obj.MasterClients.ExternalKubernetesClientConnectionOverrides = &configapi.ClientConnectionOverrides{
					AcceptContentTypes: "test/other",
					ContentType:        "test/third",
				}
			}
			if obj.MasterClients.ExternalKubernetesClientConnectionOverrides.QPS <= 0 {
				obj.MasterClients.ExternalKubernetesClientConnectionOverrides.QPS = 2.0
			}
			if obj.MasterClients.ExternalKubernetesClientConnectionOverrides.Burst <= 0 {
				obj.MasterClients.ExternalKubernetesClientConnectionOverrides.Burst = 2
			}
			if len(obj.MasterClients.ExternalKubernetesClientConnectionOverrides.AcceptContentTypes) == 0 {
				obj.MasterClients.ExternalKubernetesClientConnectionOverrides.AcceptContentTypes = "test/fourth"
			}
			if len(obj.MasterClients.ExternalKubernetesClientConnectionOverrides.ContentType) == 0 {
				obj.MasterClients.ExternalKubernetesClientConnectionOverrides.ContentType = "test/fifth"
			}

			// Populate the new NetworkConfig.ServiceNetworkCIDR field from the KubernetesMasterConfig.ServicesSubnet field if needed
			if len(obj.NetworkConfig.ServiceNetworkCIDR) == 0 {
				if obj.KubernetesMasterConfig != nil && len(obj.KubernetesMasterConfig.ServicesSubnet) > 0 {
					// if a subnet is set in the kubernetes master config, use that
					obj.NetworkConfig.ServiceNetworkCIDR = obj.KubernetesMasterConfig.ServicesSubnet
				} else {
					// default ServiceClusterIPRange used by kubernetes if nothing is specified
					obj.NetworkConfig.ServiceNetworkCIDR = "10.0.0.0/24"
				}
			}

			// TODO stop duplicating the conversion in the test.
			kubeConfig := obj.KubernetesMasterConfig
			noCloudProvider := kubeConfig != nil && (len(kubeConfig.ControllerArguments["cloud-provider"]) == 0 || kubeConfig.ControllerArguments["cloud-provider"][0] == "")
			if noCloudProvider && len(obj.NetworkConfig.IngressIPNetworkCIDR) == 0 {
				cidr := "172.46.0.0/16"
				if !(configapi.CIDRsOverlap(cidr, obj.NetworkConfig.ClusterNetworkCIDR) || configapi.CIDRsOverlap(cidr, obj.NetworkConfig.ServiceNetworkCIDR)) {
					obj.NetworkConfig.IngressIPNetworkCIDR = cidr
				}
			}

			// Historically, the clientCA was incorrectly used as the master's server cert CA bundle
			// If missing from the config, migrate the ClientCA into that field
			if obj.OAuthConfig != nil && obj.OAuthConfig.MasterCA == nil {
				s := obj.ServingInfo.ClientCA
				// The final value of OAuthConfig.MasterCA should never be nil
				obj.OAuthConfig.MasterCA = &s
			}

			// test an admission plugin nested for round tripping
			if c.RandBool() {
				obj.AdmissionConfig.PluginConfig = map[string]configapi.AdmissionPluginConfig{
					"abc": {
						Location: "test",
						Configuration: &configapi.LDAPSyncConfig{
							URL: "ldap://*****:*****@server:8080/test",
						},
					},
				}
			}
			// test a Kubernetes admission plugin nested for round tripping
			if obj.KubernetesMasterConfig != nil && c.RandBool() {
				obj.KubernetesMasterConfig.AdmissionConfig.PluginConfig = map[string]configapi.AdmissionPluginConfig{
					"abc": {
						Location: "test",
						Configuration: &configapi.LDAPSyncConfig{
							URL: "ldap://*****:*****@server:8080/test",
						},
					},
				}
			}
			if obj.OAuthConfig != nil && c.RandBool() {
				obj.OAuthConfig.IdentityProviders = []configapi.IdentityProvider{
					{
						MappingMethod: "claim",
						Provider: &configapi.LDAPSyncConfig{
							URL: "ldap://*****:*****@server:8080/test",
						},
					},
				}
			}
		},
		func(obj *configapi.KubernetesMasterConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if obj.MasterCount == 0 {
				obj.MasterCount = 1
			}
			if len(obj.ServicesNodePortRange) == 0 {
				obj.ServicesNodePortRange = "30000-32767"
			}
			if len(obj.PodEvictionTimeout) == 0 {
				obj.PodEvictionTimeout = "5m"
			}
		},
		func(obj *configapi.JenkinsPipelineConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if obj.AutoProvisionEnabled == nil {
				v := c.RandBool()
				obj.AutoProvisionEnabled = &v
			}
			if len(obj.TemplateNamespace) == 0 {
				obj.TemplateNamespace = "value"
			}
			if len(obj.TemplateName) == 0 {
				obj.TemplateName = "anothervalue"
			}
			if len(obj.ServiceName) == 0 {
				obj.ServiceName = "thirdvalue"
			}
		},
		func(obj *configapi.NodeConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			// Defaults/migrations for NetworkConfig
			if len(obj.NetworkConfig.NetworkPluginName) == 0 {
				obj.NetworkConfig.NetworkPluginName = "plugin-name"
			}
			if obj.NetworkConfig.MTU == 0 {
				obj.NetworkConfig.MTU = 1450
			}
			if len(obj.IPTablesSyncPeriod) == 0 {
				obj.IPTablesSyncPeriod = "5s"
			}

			if obj.MasterClientConnectionOverrides == nil {
				obj.MasterClientConnectionOverrides = &configapi.ClientConnectionOverrides{
					QPS:                1.0,
					Burst:              1,
					AcceptContentTypes: "test/other",
					ContentType:        "test/third",
				}
			}
			if len(obj.MasterClientConnectionOverrides.AcceptContentTypes) == 0 {
				obj.MasterClientConnectionOverrides.AcceptContentTypes = "test/fourth"
			}
			if len(obj.MasterClientConnectionOverrides.ContentType) == 0 {
				obj.MasterClientConnectionOverrides.ContentType = "test/fifth"
			}

			// Auth cache defaults
			if len(obj.AuthConfig.AuthenticationCacheTTL) == 0 {
				obj.AuthConfig.AuthenticationCacheTTL = "5m"
			}
			if obj.AuthConfig.AuthenticationCacheSize == 0 {
				obj.AuthConfig.AuthenticationCacheSize = 1000
			}
			if len(obj.AuthConfig.AuthorizationCacheTTL) == 0 {
				obj.AuthConfig.AuthorizationCacheTTL = "5m"
			}
			if obj.AuthConfig.AuthorizationCacheSize == 0 {
				obj.AuthConfig.AuthorizationCacheSize = 1000
			}
		},
		func(obj *configapi.EtcdStorageConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.KubernetesStorageVersion) == 0 {
				obj.KubernetesStorageVersion = "v1"
			}
			if len(obj.KubernetesStoragePrefix) == 0 {
				obj.KubernetesStoragePrefix = "kubernetes.io"
			}
			if len(obj.OpenShiftStorageVersion) == 0 {
				obj.OpenShiftStorageVersion = configapi.DefaultOpenShiftStorageVersionLevel
			}
			if len(obj.OpenShiftStoragePrefix) == 0 {
				obj.OpenShiftStoragePrefix = "openshift.io"
			}
		},
		func(obj *configapi.DockerConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.ExecHandlerName) == 0 {
				obj.ExecHandlerName = configapi.DockerExecHandlerNative
			}
		},
		func(obj *configapi.ServingInfo, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.BindNetwork) == 0 {
				obj.BindNetwork = "tcp4"
			}
		},
		func(obj *configapi.ImagePolicyConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if obj.MaxImagesBulkImportedPerRepository == 0 {
				obj.MaxImagesBulkImportedPerRepository = 5
			}
			if obj.MaxScheduledImageImportsPerMinute == 0 {
				obj.MaxScheduledImageImportsPerMinute = 60
			}
			if obj.ScheduledImageImportMinimumIntervalSeconds == 0 {
				obj.ScheduledImageImportMinimumIntervalSeconds = 15 * 60
			}
		},
		func(obj *configapi.DNSConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.BindNetwork) == 0 {
				obj.BindNetwork = "tcp4"
			}
		},
		func(obj *configapi.SecurityAllocator, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.UIDAllocatorRange) == 0 {
				obj.UIDAllocatorRange = "1000000000-1999999999/10000"
			}
			if len(obj.MCSAllocatorRange) == 0 {
				obj.MCSAllocatorRange = "s0:/2"
			}
			if obj.MCSLabelsPerProject == 0 {
				obj.MCSLabelsPerProject = 5
			}
		},
		func(obj *configapi.IdentityProvider, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.MappingMethod) == 0 {
				// By default, only let one identity provider authenticate a particular user
				// If multiple identity providers collide, the second one in will fail to auth
				// The admin can set this to "add" if they want to allow new identities to join existing users
				obj.MappingMethod = "claim"
			}
		},
		func(s *configapi.StringSource, c fuzz.Continue) {
			if c.RandBool() {
				c.Fuzz(&s.Value)
			} else {
				c.Fuzz(&s.StringSourceSpec)
			}
		},
		func(obj *podnodeapi.PodNodeConstraintsConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if obj.NodeSelectorLabelBlacklist == nil {
				obj.NodeSelectorLabelBlacklist = []string{"kubernetes.io/hostname"}
			}
		},
		func(obj *labels.Selector, c fuzz.Continue) {
		},
		func(obj *imagepolicyapi.ImagePolicyConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			for i := range obj.ExecutionRules {
				if len(obj.ExecutionRules[i].OnResources) == 0 {
					obj.ExecutionRules[i].OnResources = []unversioned.GroupResource{{Resource: "pods"}}
				}
				obj.ExecutionRules[i].MatchImageLabelSelectors = nil
			}
			if len(obj.ResolveImages) == 0 {
				obj.ResolveImages = imagepolicyapi.Attempt
			}
		},
		func(obj *configapi.GrantConfig, c fuzz.Continue) {
			c.FuzzNoCustom(obj)
			if len(obj.ServiceAccountMethod) == 0 {
				obj.ServiceAccountMethod = "prompt"
			}
		},
	)

	f.Fuzz(item)

	j, err := meta.TypeAccessor(item)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, item)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return item
}
Пример #20
0
func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item runtime.Object, seed int64) runtime.Object {
	f := apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed))
	f.Funcs(
		// Roles and RoleBindings maps are never nil
		func(j *authorizationapi.Policy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.Roles != nil {
				j.Roles = make(map[string]*authorizationapi.Role)
			}
			for k, v := range j.Roles {
				if v == nil {
					delete(j.Roles, k)
				}
			}
		},
		func(j *authorizationapi.PolicyBinding, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.RoleBindings == nil {
				j.RoleBindings = make(map[string]*authorizationapi.RoleBinding)
			}
			for k, v := range j.RoleBindings {
				if v == nil {
					delete(j.RoleBindings, k)
				}
			}
		},
		func(j *authorizationapi.ClusterPolicy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.Roles == nil {
				j.Roles = make(map[string]*authorizationapi.ClusterRole)
			}
			for k, v := range j.Roles {
				if v == nil {
					delete(j.Roles, k)
				}
			}
		},
		func(j *authorizationapi.ClusterPolicyBinding, c fuzz.Continue) {
			j.RoleBindings = make(map[string]*authorizationapi.ClusterRoleBinding)
		},
		func(j *authorizationapi.RoleBinding, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			for i := range j.Subjects {
				kinds := []string{authorizationapi.UserKind, authorizationapi.SystemUserKind, authorizationapi.GroupKind, authorizationapi.SystemGroupKind, authorizationapi.ServiceAccountKind}
				j.Subjects[i].Kind = kinds[c.Intn(len(kinds))]
				switch j.Subjects[i].Kind {
				case authorizationapi.UserKind:
					j.Subjects[i].Namespace = ""
					if len(uservalidation.ValidateUserName(j.Subjects[i].Name, false)) != 0 {
						j.Subjects[i].Name = fmt.Sprintf("validusername%d", i)
					}

				case authorizationapi.GroupKind:
					j.Subjects[i].Namespace = ""
					if len(uservalidation.ValidateGroupName(j.Subjects[i].Name, false)) != 0 {
						j.Subjects[i].Name = fmt.Sprintf("validgroupname%d", i)
					}

				case authorizationapi.ServiceAccountKind:
					if len(validation.ValidateNamespaceName(j.Subjects[i].Namespace, false)) != 0 {
						j.Subjects[i].Namespace = fmt.Sprintf("sanamespacehere%d", i)
					}
					if len(validation.ValidateServiceAccountName(j.Subjects[i].Name, false)) != 0 {
						j.Subjects[i].Name = fmt.Sprintf("sanamehere%d", i)
					}

				case authorizationapi.SystemUserKind, authorizationapi.SystemGroupKind:
					j.Subjects[i].Namespace = ""
					j.Subjects[i].Name = ":" + j.Subjects[i].Name

				}

				j.Subjects[i].UID = types.UID("")
				j.Subjects[i].APIVersion = ""
				j.Subjects[i].ResourceVersion = ""
				j.Subjects[i].FieldPath = ""
			}
		},
		func(j *authorizationapi.PolicyRule, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			// if no groups are found, then we assume "".  This matches defaulting
			if len(j.APIGroups) == 0 {
				j.APIGroups = []string{""}
			}
			switch c.Intn(3) {
			case 0:
				j.AttributeRestrictions = &authorizationapi.IsPersonalSubjectAccessReview{}
			case 1:
				j.AttributeRestrictions = &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "Type", APIVersion: "other"}, ContentType: "application/json", Raw: []byte(`{"apiVersion":"other","kind":"Type"}`)}
			default:
				j.AttributeRestrictions = nil
			}
		},
		func(j *authorizationapi.ClusterRoleBinding, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			for i := range j.Subjects {
				kinds := []string{authorizationapi.UserKind, authorizationapi.SystemUserKind, authorizationapi.GroupKind, authorizationapi.SystemGroupKind, authorizationapi.ServiceAccountKind}
				j.Subjects[i].Kind = kinds[c.Intn(len(kinds))]
				switch j.Subjects[i].Kind {
				case authorizationapi.UserKind:
					j.Subjects[i].Namespace = ""
					if len(uservalidation.ValidateUserName(j.Subjects[i].Name, false)) != 0 {
						j.Subjects[i].Name = fmt.Sprintf("validusername%d", i)
					}

				case authorizationapi.GroupKind:
					j.Subjects[i].Namespace = ""
					if len(uservalidation.ValidateGroupName(j.Subjects[i].Name, false)) != 0 {
						j.Subjects[i].Name = fmt.Sprintf("validgroupname%d", i)
					}

				case authorizationapi.ServiceAccountKind:
					if len(validation.ValidateNamespaceName(j.Subjects[i].Namespace, false)) != 0 {
						j.Subjects[i].Namespace = fmt.Sprintf("sanamespacehere%d", i)
					}
					if len(validation.ValidateServiceAccountName(j.Subjects[i].Name, false)) != 0 {
						j.Subjects[i].Name = fmt.Sprintf("sanamehere%d", i)
					}

				case authorizationapi.SystemUserKind, authorizationapi.SystemGroupKind:
					j.Subjects[i].Namespace = ""
					j.Subjects[i].Name = ":" + j.Subjects[i].Name

				}

				j.Subjects[i].UID = types.UID("")
				j.Subjects[i].APIVersion = ""
				j.Subjects[i].ResourceVersion = ""
				j.Subjects[i].FieldPath = ""
			}
		},
		func(j *template.Template, c fuzz.Continue) {
			c.Fuzz(&j.ObjectMeta)
			c.Fuzz(&j.Parameters)
			// TODO: replace with structured type definition
			j.Objects = []runtime.Object{}
		},
		func(j *image.Image, c fuzz.Continue) {
			c.Fuzz(&j.ObjectMeta)
			c.Fuzz(&j.DockerImageMetadata)
			c.Fuzz(&j.Signatures)
			j.DockerImageMetadata.APIVersion = ""
			j.DockerImageMetadata.Kind = ""
			j.DockerImageMetadataVersion = []string{"pre012", "1.0"}[c.Rand.Intn(2)]
			j.DockerImageReference = c.RandString()
		},
		func(j *image.ImageSignature, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Conditions = nil
			j.ImageIdentity = ""
			j.SignedClaims = nil
			j.Created = nil
			j.IssuedBy = nil
			j.IssuedTo = nil
		},
		func(j *image.ImageStreamMapping, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.DockerImageRepository = ""
		},
		func(j *image.ImageImportSpec, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.To == nil {
				// To is defaulted to be not nil
				j.To = &kapi.LocalObjectReference{}
			}
		},
		func(j *image.ImageStreamImage, c fuzz.Continue) {
			c.Fuzz(&j.Image)
			// because we de-embedded Image from ImageStreamImage, in order to round trip
			// successfully, the ImageStreamImage's ObjectMeta must match the Image's.
			j.ObjectMeta = j.Image.ObjectMeta
		},
		func(j *image.ImageStreamSpec, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			// if the generated fuzz value has a tag or image id, strip it
			if strings.ContainsAny(j.DockerImageRepository, ":@") {
				j.DockerImageRepository = ""
			}
			if j.Tags == nil {
				j.Tags = make(map[string]image.TagReference)
			}
			for k, v := range j.Tags {
				v.Name = k
				j.Tags[k] = v
			}
		},
		func(j *image.ImageStreamStatus, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			// if the generated fuzz value has a tag or image id, strip it
			if strings.ContainsAny(j.DockerImageRepository, ":@") {
				j.DockerImageRepository = ""
			}
		},
		func(j *image.ImageStreamTag, c fuzz.Continue) {
			c.Fuzz(&j.Image)
			// because we de-embedded Image from ImageStreamTag, in order to round trip
			// successfully, the ImageStreamTag's ObjectMeta must match the Image's.
			j.ObjectMeta = j.Image.ObjectMeta
		},
		func(j *image.TagReference, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.From != nil {
				specs := []string{"", "ImageStreamTag", "ImageStreamImage"}
				j.From.Kind = specs[c.Intn(len(specs))]
			}
		},
		func(j *build.BuildConfigSpec, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.RunPolicy = build.BuildRunPolicySerial
		},
		func(j *build.SourceBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.CustomBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.DockerBuildStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.From.Kind = "ImageStreamTag"
			j.From.Name = "image:tag"
			j.From.APIVersion = ""
			j.From.ResourceVersion = ""
			j.From.FieldPath = ""
		},
		func(j *build.BuildOutput, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if j.To != nil && (len(j.To.Kind) == 0 || j.To.Kind == "ImageStream") {
				j.To.Kind = "ImageStreamTag"
			}
			if j.To != nil && strings.Contains(j.To.Name, ":") {
				j.To.Name = strings.Replace(j.To.Name, ":", "-", -1)
			}
		},
		func(j *route.RouteTargetReference, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Kind = "Service"
			j.Weight = new(int32)
			*j.Weight = 100
		},
		func(j *route.TLSConfig, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if len(j.Termination) == 0 && len(j.DestinationCACertificate) == 0 {
				j.Termination = route.TLSTerminationEdge
			}
		},
		func(j *deploy.DeploymentConfig, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Spec.Triggers = []deploy.DeploymentTriggerPolicy{{Type: deploy.DeploymentTriggerOnConfigChange}}
			if j.Spec.Template != nil && len(j.Spec.Template.Spec.Containers) == 1 {
				containerName := j.Spec.Template.Spec.Containers[0].Name
				if p := j.Spec.Strategy.RecreateParams; p != nil {
					defaultHookContainerName(p.Pre, containerName)
					defaultHookContainerName(p.Mid, containerName)
					defaultHookContainerName(p.Post, containerName)
				}
				if p := j.Spec.Strategy.RollingParams; p != nil {
					defaultHookContainerName(p.Pre, containerName)
					defaultHookContainerName(p.Post, containerName)
				}
			}
		},
		func(j *deploy.DeploymentStrategy, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.RecreateParams, j.RollingParams, j.CustomParams = nil, nil, nil
			strategyTypes := []deploy.DeploymentStrategyType{deploy.DeploymentStrategyTypeRecreate, deploy.DeploymentStrategyTypeRolling, deploy.DeploymentStrategyTypeCustom}
			j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))]
			switch j.Type {
			case deploy.DeploymentStrategyTypeRecreate:
				params := &deploy.RecreateDeploymentStrategyParams{}
				c.Fuzz(params)
				if params.TimeoutSeconds == nil {
					s := int64(120)
					params.TimeoutSeconds = &s
				}
				j.RecreateParams = params
			case deploy.DeploymentStrategyTypeRolling:
				params := &deploy.RollingDeploymentStrategyParams{}
				randInt64 := func() *int64 {
					p := int64(c.RandUint64())
					return &p
				}
				params.TimeoutSeconds = randInt64()
				params.IntervalSeconds = randInt64()
				params.UpdatePeriodSeconds = randInt64()

				policyTypes := []deploy.LifecycleHookFailurePolicy{
					deploy.LifecycleHookFailurePolicyRetry,
					deploy.LifecycleHookFailurePolicyAbort,
					deploy.LifecycleHookFailurePolicyIgnore,
				}
				if c.RandBool() {
					params.Pre = &deploy.LifecycleHook{
						FailurePolicy: policyTypes[c.Rand.Intn(len(policyTypes))],
						ExecNewPod: &deploy.ExecNewPodHook{
							ContainerName: c.RandString(),
						},
					}
				}
				if c.RandBool() {
					params.Post = &deploy.LifecycleHook{
						FailurePolicy: policyTypes[c.Rand.Intn(len(policyTypes))],
						ExecNewPod: &deploy.ExecNewPodHook{
							ContainerName: c.RandString(),
						},
					}
				}
				if c.RandBool() {
					params.MaxUnavailable = intstr.FromInt(int(c.RandUint64()))
					params.MaxSurge = intstr.FromInt(int(c.RandUint64()))
				} else {
					params.MaxSurge = intstr.FromString(fmt.Sprintf("%d%%", c.RandUint64()))
					params.MaxUnavailable = intstr.FromString(fmt.Sprintf("%d%%", c.RandUint64()))
				}
				j.RollingParams = params
			}
		},
		func(j *deploy.DeploymentCauseImageTrigger, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			specs := []string{"", "a/b", "a/b/c", "a:5000/b/c", "a/b", "a/b"}
			tags := []string{"stuff", "other"}
			j.From.Name = specs[c.Intn(len(specs))]
			if len(j.From.Name) > 0 {
				j.From.Name = image.JoinImageStreamTag(j.From.Name, tags[c.Intn(len(tags))])
			}
		},
		func(j *deploy.DeploymentTriggerImageChangeParams, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			specs := []string{"a/b", "a/b/c", "a:5000/b/c", "a/b:latest", "a/b@test"}
			j.From.Kind = "DockerImage"
			j.From.Name = specs[c.Intn(len(specs))]
		},

		// TODO: uncomment when round tripping for init containers is available (the annotation is
		// not supported on security context review for now)
		func(j *securityapi.PodSecurityPolicyReview, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Spec.Template.Spec.InitContainers = nil
			for i := range j.Status.AllowedServiceAccounts {
				j.Status.AllowedServiceAccounts[i].Template.Spec.InitContainers = nil
			}
		},
		func(j *securityapi.PodSecurityPolicySelfSubjectReview, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Spec.Template.Spec.InitContainers = nil
			j.Status.Template.Spec.InitContainers = nil
		},
		func(j *securityapi.PodSecurityPolicySubjectReview, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			j.Spec.Template.Spec.InitContainers = nil
			j.Status.Template.Spec.InitContainers = nil
		},
		func(j *oauthapi.OAuthAuthorizeToken, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if len(j.CodeChallenge) > 0 && len(j.CodeChallengeMethod) == 0 {
				j.CodeChallengeMethod = "plain"
			}
		},
		func(j *oauthapi.OAuthClientAuthorization, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if len(j.Scopes) == 0 {
				j.Scopes = append(j.Scopes, "user:full")
			}
		},
		func(j *route.RouteSpec, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if len(j.WildcardPolicy) == 0 {
				j.WildcardPolicy = route.WildcardPolicyNone
			}
		},
		func(j *route.RouteIngress, c fuzz.Continue) {
			c.FuzzNoCustom(j)
			if len(j.WildcardPolicy) == 0 {
				j.WildcardPolicy = route.WildcardPolicyNone
			}
		},

		func(j *runtime.Object, c fuzz.Continue) {
			// runtime.EmbeddedObject causes a panic inside of fuzz because runtime.Object isn't handled.
		},
		func(t *time.Time, c fuzz.Continue) {
			// This is necessary because the standard fuzzed time.Time object is
			// completely nil, but when JSON unmarshals dates it fills in the
			// unexported loc field with the time.UTC object, resulting in
			// reflect.DeepEqual returning false in the round trip tests. We solve it
			// by using a date that will be identical to the one JSON unmarshals.
			*t = time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC)
		},
		func(u64 *uint64, c fuzz.Continue) {
			// TODO: uint64's are NOT handled right.
			*u64 = c.RandUint64() >> 8
		},
	)

	f.Fuzz(item)

	j, err := meta.TypeAccessor(item)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, item)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return item
}
Пример #21
0
func TestGenericTypeMeta(t *testing.T) {
	type TypeMeta struct {
		Kind              string            `json:"kind,omitempty"`
		Namespace         string            `json:"namespace,omitempty"`
		Name              string            `json:"name,omitempty"`
		GenerateName      string            `json:"generateName,omitempty"`
		UID               string            `json:"uid,omitempty"`
		CreationTimestamp unversioned.Time  `json:"creationTimestamp,omitempty"`
		SelfLink          string            `json:"selfLink,omitempty"`
		ResourceVersion   string            `json:"resourceVersion,omitempty"`
		APIVersion        string            `json:"apiVersion,omitempty"`
		Labels            map[string]string `json:"labels,omitempty"`
		Annotations       map[string]string `json:"annotations,omitempty"`
	}
	type Object struct {
		TypeMeta `json:",inline"`
	}
	j := Object{
		TypeMeta{
			Namespace:       "bar",
			Name:            "foo",
			GenerateName:    "prefix",
			UID:             "uid",
			APIVersion:      "a",
			Kind:            "b",
			ResourceVersion: "1",
			SelfLink:        "some/place/only/we/know",
			Labels:          map[string]string{"foo": "bar"},
			Annotations:     map[string]string{"x": "y"},
		},
	}
	accessor, err := meta.Accessor(&j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if e, a := "bar", accessor.GetNamespace(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "foo", accessor.GetName(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "prefix", accessor.GetGenerateName(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "uid", string(accessor.GetUID()); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "1", accessor.GetResourceVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "some/place/only/we/know", accessor.GetSelfLink(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	typeAccessor, err := meta.TypeAccessor(&j)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "b", typeAccessor.GetKind(); e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	accessor.SetNamespace("baz")
	accessor.SetName("bar")
	accessor.SetGenerateName("generate")
	accessor.SetUID("other")
	typeAccessor.SetAPIVersion("c")
	typeAccessor.SetKind("d")
	accessor.SetResourceVersion("2")
	accessor.SetSelfLink("google.com")

	// Prove that accessor changes the original object.
	if e, a := "baz", j.Namespace; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "bar", j.Name; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "generate", j.GenerateName; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "other", j.UID; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "c", j.APIVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "d", j.Kind; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "2", j.ResourceVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "google.com", j.SelfLink; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}

	typeAccessor.SetAPIVersion("d")
	typeAccessor.SetKind("e")
	if e, a := "d", j.APIVersion; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
	if e, a := "e", j.Kind; e != a {
		t.Errorf("expected %v, got %v", e, a)
	}
}