From 30a58321e8c17f2f7d59c2787260c4ffe147e080 Mon Sep 17 00:00:00 2001 From: nikhiljindal Date: Tue, 1 Sep 2015 02:48:53 -0700 Subject: [PATCH] Adding defaults to Deployment --- pkg/api/testing/fuzzer.go | 18 +++- pkg/expapi/deep_copy_generated.go | 7 +- pkg/expapi/types.go | 2 +- pkg/expapi/v1/conversion.go | 65 ++++++++++-- pkg/expapi/v1/conversion_generated.go | 47 --------- pkg/expapi/v1/deep_copy_generated.go | 18 +++- pkg/expapi/v1/defaults.go | 37 ++++++- pkg/expapi/v1/defaults_test.go | 118 ++++++++++++++++++++++ pkg/expapi/v1/types.go | 6 +- pkg/expapi/validation/validation.go | 4 +- pkg/expapi/validation/validation_test.go | 4 +- pkg/registry/deployment/etcd/etcd_test.go | 1 + pkg/util/util.go | 3 + 13 files changed, 253 insertions(+), 77 deletions(-) diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index 44aef44e58..e5385910c1 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -17,6 +17,7 @@ limitations under the License. package testing import ( + "fmt" "math/rand" "reflect" "strconv" @@ -120,8 +121,23 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { c.FuzzNoCustom(j) // fuzz self without calling this function again //j.TemplateRef = nil // this is required for round trip }, - func(j *expapi.DaemonSpec, c fuzz.Continue) { + func(j *expapi.DeploymentStrategy, c fuzz.Continue) { c.FuzzNoCustom(j) // fuzz self without calling this function again + // Ensure that strategyType is one of valid values. + strategyTypes := []expapi.DeploymentType{expapi.DeploymentRecreate, expapi.DeploymentRollingUpdate} + j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] + if j.Type != expapi.DeploymentRollingUpdate { + j.RollingUpdate = nil + } else { + rollingUpdate := expapi.RollingUpdateDeployment{} + if c.RandBool() { + rollingUpdate.MaxUnavailable = util.NewIntOrStringFromInt(int(c.RandUint64())) + rollingUpdate.MaxSurge = util.NewIntOrStringFromInt(int(c.RandUint64())) + } else { + rollingUpdate.MaxSurge = util.NewIntOrStringFromString(fmt.Sprintf("%d%%", c.RandUint64())) + } + j.RollingUpdate = &rollingUpdate + } }, func(j *api.List, c fuzz.Continue) { c.FuzzNoCustom(j) // fuzz self without calling this function again diff --git a/pkg/expapi/deep_copy_generated.go b/pkg/expapi/deep_copy_generated.go index f61479a258..0f15facef0 100644 --- a/pkg/expapi/deep_copy_generated.go +++ b/pkg/expapi/deep_copy_generated.go @@ -822,12 +822,7 @@ func deepCopy_expapi_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *c if err := deepCopy_expapi_DeploymentStrategy(in.Strategy, &out.Strategy, c); err != nil { return err } - if in.UniqueLabelKey != nil { - out.UniqueLabelKey = new(string) - *out.UniqueLabelKey = *in.UniqueLabelKey - } else { - out.UniqueLabelKey = nil - } + out.UniqueLabelKey = in.UniqueLabelKey return nil } diff --git a/pkg/expapi/types.go b/pkg/expapi/types.go index 2cb481d8a0..f32fac1334 100644 --- a/pkg/expapi/types.go +++ b/pkg/expapi/types.go @@ -199,7 +199,7 @@ type DeploymentSpec struct { // not add any selector and label. If unspecified, system uses // "deployment.kubernetes.io/podTemplateHash". // Value of this key is hash of DeploymentSpec.PodTemplateSpec. - UniqueLabelKey *string `json:"uniqueLabel,omitempty"` + UniqueLabelKey string `json:"uniqueLabelKey,omitempty"` } type DeploymentStrategy struct { diff --git a/pkg/expapi/v1/conversion.go b/pkg/expapi/v1/conversion.go index b3b5888ed3..f977ec4bcc 100644 --- a/pkg/expapi/v1/conversion.go +++ b/pkg/expapi/v1/conversion.go @@ -23,6 +23,7 @@ import ( v1 "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/expapi" + "k8s.io/kubernetes/pkg/util" ) func addConversionFuncs() { @@ -32,7 +33,10 @@ func addConversionFuncs() { convert_v1_PodSpec_To_api_PodSpec, convert_expapi_DeploymentSpec_To_v1_DeploymentSpec, convert_v1_DeploymentSpec_To_expapi_DeploymentSpec, + convert_expapi_DeploymentStrategy_To_v1_DeploymentStrategy, convert_v1_DeploymentStrategy_To_expapi_DeploymentStrategy, + convert_expapi_RollingUpdateDeployment_To_v1_RollingUpdateDeployment, + convert_v1_RollingUpdateDeployment_To_expapi_RollingUpdateDeployment, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. @@ -199,12 +203,8 @@ func convert_expapi_DeploymentSpec_To_v1_DeploymentSpec(in *expapi.DeploymentSpe if err := convert_expapi_DeploymentStrategy_To_v1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } - if in.UniqueLabelKey != nil { - out.UniqueLabelKey = new(string) - *out.UniqueLabelKey = *in.UniqueLabelKey - } else { - out.UniqueLabelKey = nil - } + out.UniqueLabelKey = new(string) + *out.UniqueLabelKey = in.UniqueLabelKey return nil } @@ -235,10 +235,23 @@ func convert_v1_DeploymentSpec_To_expapi_DeploymentSpec(in *DeploymentSpec, out return err } if in.UniqueLabelKey != nil { - out.UniqueLabelKey = new(string) - *out.UniqueLabelKey = *in.UniqueLabelKey + out.UniqueLabelKey = *in.UniqueLabelKey + } + return nil +} + +func convert_expapi_DeploymentStrategy_To_v1_DeploymentStrategy(in *expapi.DeploymentStrategy, out *DeploymentStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*expapi.DeploymentStrategy))(in) + } + out.Type = DeploymentType(in.Type) + if in.RollingUpdate != nil { + out.RollingUpdate = new(RollingUpdateDeployment) + if err := convert_expapi_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + return err + } } else { - out.UniqueLabelKey = nil + out.RollingUpdate = nil } return nil } @@ -258,3 +271,37 @@ func convert_v1_DeploymentStrategy_To_expapi_DeploymentStrategy(in *DeploymentSt } return nil } + +func convert_expapi_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in *expapi.RollingUpdateDeployment, out *RollingUpdateDeployment, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*expapi.RollingUpdateDeployment))(in) + } + if out.MaxUnavailable == nil { + out.MaxUnavailable = &util.IntOrString{} + } + if err := s.Convert(&in.MaxUnavailable, out.MaxUnavailable, 0); err != nil { + return err + } + if out.MaxSurge == nil { + out.MaxSurge = &util.IntOrString{} + } + if err := s.Convert(&in.MaxSurge, out.MaxSurge, 0); err != nil { + return err + } + out.MinReadySeconds = in.MinReadySeconds + return nil +} + +func convert_v1_RollingUpdateDeployment_To_expapi_RollingUpdateDeployment(in *RollingUpdateDeployment, out *expapi.RollingUpdateDeployment, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*RollingUpdateDeployment))(in) + } + if err := s.Convert(in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { + return err + } + if err := s.Convert(in.MaxSurge, &out.MaxSurge, 0); err != nil { + return err + } + out.MinReadySeconds = in.MinReadySeconds + return nil +} diff --git a/pkg/expapi/v1/conversion_generated.go b/pkg/expapi/v1/conversion_generated.go index a6409c8b8e..31b0cf3b06 100644 --- a/pkg/expapi/v1/conversion_generated.go +++ b/pkg/expapi/v1/conversion_generated.go @@ -1557,22 +1557,6 @@ func convert_expapi_DeploymentStatus_To_v1_DeploymentStatus(in *expapi.Deploymen return nil } -func convert_expapi_DeploymentStrategy_To_v1_DeploymentStrategy(in *expapi.DeploymentStrategy, out *DeploymentStrategy, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*expapi.DeploymentStrategy))(in) - } - out.Type = DeploymentType(in.Type) - if in.RollingUpdate != nil { - out.RollingUpdate = new(RollingUpdateDeployment) - if err := convert_expapi_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { - return err - } - } else { - out.RollingUpdate = nil - } - return nil -} - func convert_expapi_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(in *expapi.HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*expapi.HorizontalPodAutoscaler))(in) @@ -1685,20 +1669,6 @@ func convert_expapi_ResourceConsumption_To_v1_ResourceConsumption(in *expapi.Res return nil } -func convert_expapi_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in *expapi.RollingUpdateDeployment, out *RollingUpdateDeployment, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*expapi.RollingUpdateDeployment))(in) - } - if err := s.Convert(&in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { - return err - } - if err := s.Convert(&in.MaxSurge, &out.MaxSurge, 0); err != nil { - return err - } - out.MinReadySeconds = in.MinReadySeconds - return nil -} - func convert_expapi_Scale_To_v1_Scale(in *expapi.Scale, out *Scale, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*expapi.Scale))(in) @@ -2048,20 +2018,6 @@ func convert_v1_ResourceConsumption_To_expapi_ResourceConsumption(in *ResourceCo return nil } -func convert_v1_RollingUpdateDeployment_To_expapi_RollingUpdateDeployment(in *RollingUpdateDeployment, out *expapi.RollingUpdateDeployment, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*RollingUpdateDeployment))(in) - } - if err := s.Convert(&in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { - return err - } - if err := s.Convert(&in.MaxSurge, &out.MaxSurge, 0); err != nil { - return err - } - out.MinReadySeconds = in.MinReadySeconds - return nil -} - func convert_v1_Scale_To_expapi_Scale(in *Scale, out *expapi.Scale, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Scale))(in) @@ -2208,7 +2164,6 @@ func init() { convert_expapi_Daemon_To_v1_Daemon, convert_expapi_DeploymentList_To_v1_DeploymentList, convert_expapi_DeploymentStatus_To_v1_DeploymentStatus, - convert_expapi_DeploymentStrategy_To_v1_DeploymentStrategy, convert_expapi_Deployment_To_v1_Deployment, convert_expapi_HorizontalPodAutoscalerList_To_v1_HorizontalPodAutoscalerList, convert_expapi_HorizontalPodAutoscalerSpec_To_v1_HorizontalPodAutoscalerSpec, @@ -2216,7 +2171,6 @@ func init() { convert_expapi_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler, convert_expapi_ReplicationControllerDummy_To_v1_ReplicationControllerDummy, convert_expapi_ResourceConsumption_To_v1_ResourceConsumption, - convert_expapi_RollingUpdateDeployment_To_v1_RollingUpdateDeployment, convert_expapi_ScaleSpec_To_v1_ScaleSpec, convert_expapi_ScaleStatus_To_v1_ScaleStatus, convert_expapi_Scale_To_v1_Scale, @@ -2264,7 +2218,6 @@ func init() { convert_v1_ReplicationControllerDummy_To_expapi_ReplicationControllerDummy, convert_v1_ResourceConsumption_To_expapi_ResourceConsumption, convert_v1_ResourceRequirements_To_api_ResourceRequirements, - convert_v1_RollingUpdateDeployment_To_expapi_RollingUpdateDeployment, convert_v1_SELinuxOptions_To_api_SELinuxOptions, convert_v1_ScaleSpec_To_expapi_ScaleSpec, convert_v1_ScaleStatus_To_expapi_ScaleStatus, diff --git a/pkg/expapi/v1/deep_copy_generated.go b/pkg/expapi/v1/deep_copy_generated.go index a73e1b458d..15eb2f9420 100644 --- a/pkg/expapi/v1/deep_copy_generated.go +++ b/pkg/expapi/v1/deep_copy_generated.go @@ -953,11 +953,21 @@ func deepCopy_v1_ResourceConsumption(in ResourceConsumption, out *ResourceConsum } func deepCopy_v1_RollingUpdateDeployment(in RollingUpdateDeployment, out *RollingUpdateDeployment, c *conversion.Cloner) error { - if err := deepCopy_util_IntOrString(in.MaxUnavailable, &out.MaxUnavailable, c); err != nil { - return err + if in.MaxUnavailable != nil { + out.MaxUnavailable = new(util.IntOrString) + if err := deepCopy_util_IntOrString(*in.MaxUnavailable, out.MaxUnavailable, c); err != nil { + return err + } + } else { + out.MaxUnavailable = nil } - if err := deepCopy_util_IntOrString(in.MaxSurge, &out.MaxSurge, c); err != nil { - return err + if in.MaxSurge != nil { + out.MaxSurge = new(util.IntOrString) + if err := deepCopy_util_IntOrString(*in.MaxSurge, out.MaxSurge, c); err != nil { + return err + } + } else { + out.MaxSurge = nil } out.MinReadySeconds = in.MinReadySeconds return nil diff --git a/pkg/expapi/v1/defaults.go b/pkg/expapi/v1/defaults.go index f1869111d8..105a49ee3d 100644 --- a/pkg/expapi/v1/defaults.go +++ b/pkg/expapi/v1/defaults.go @@ -16,7 +16,10 @@ limitations under the License. package v1 -import "k8s.io/kubernetes/pkg/api" +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util" +) func addDefaultingFuncs() { api.Scheme.AddDefaultingFuncs( @@ -40,5 +43,37 @@ func addDefaultingFuncs() { } } }, + func(obj *Deployment) { + // Set DeploymentSpec.Replicas to 1 if it is not set. + if obj.Spec.Replicas == nil { + obj.Spec.Replicas = new(int) + *obj.Spec.Replicas = 1 + } + strategy := &obj.Spec.Strategy + // Set default DeploymentType as RollingUpdate. + if strategy.Type == "" { + strategy.Type = DeploymentRollingUpdate + } + if strategy.Type == DeploymentRollingUpdate { + if strategy.RollingUpdate == nil { + rollingUpdate := RollingUpdateDeployment{} + strategy.RollingUpdate = &rollingUpdate + } + if strategy.RollingUpdate.MaxUnavailable == nil { + // Set default MaxUnavailable as 1 by default. + maxUnavailable := util.NewIntOrStringFromInt(1) + strategy.RollingUpdate.MaxUnavailable = &maxUnavailable + } + if strategy.RollingUpdate.MaxSurge == nil { + // Set default MaxSurge as 1 by default. + maxSurge := util.NewIntOrStringFromInt(1) + strategy.RollingUpdate.MaxSurge = &maxSurge + } + } + if obj.Spec.UniqueLabelKey == nil { + obj.Spec.UniqueLabelKey = new(string) + *obj.Spec.UniqueLabelKey = "deployment.kubernetes.io/podTemplateHash" + } + }, ) } diff --git a/pkg/expapi/v1/defaults_test.go b/pkg/expapi/v1/defaults_test.go index 104c57ca7f..3463534fc9 100644 --- a/pkg/expapi/v1/defaults_test.go +++ b/pkg/expapi/v1/defaults_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" ) func TestSetDefaultDaemon(t *testing.T) { @@ -83,6 +84,111 @@ func TestSetDefaultDaemon(t *testing.T) { } } +func TestSetDefaultDeployment(t *testing.T) { + defaultIntOrString := util.NewIntOrStringFromInt(1) + differentIntOrString := util.NewIntOrStringFromInt(5) + deploymentLabelKey := "deployment.kubernetes.io/podTemplateHash" + tests := []struct { + original *Deployment + expected *Deployment + }{ + { + original: &Deployment{}, + expected: &Deployment{ + Spec: DeploymentSpec{ + Replicas: newInt(1), + Strategy: DeploymentStrategy{ + Type: DeploymentRollingUpdate, + RollingUpdate: &RollingUpdateDeployment{ + MaxSurge: &defaultIntOrString, + MaxUnavailable: &defaultIntOrString, + }, + }, + UniqueLabelKey: newString(deploymentLabelKey), + }, + }, + }, + { + original: &Deployment{ + Spec: DeploymentSpec{ + Replicas: newInt(5), + Strategy: DeploymentStrategy{ + RollingUpdate: &RollingUpdateDeployment{ + MaxSurge: &differentIntOrString, + }, + }, + }, + }, + expected: &Deployment{ + Spec: DeploymentSpec{ + Replicas: newInt(5), + Strategy: DeploymentStrategy{ + Type: DeploymentRollingUpdate, + RollingUpdate: &RollingUpdateDeployment{ + MaxSurge: &differentIntOrString, + MaxUnavailable: &defaultIntOrString, + }, + }, + UniqueLabelKey: newString(deploymentLabelKey), + }, + }, + }, + { + original: &Deployment{ + Spec: DeploymentSpec{ + Replicas: newInt(5), + Strategy: DeploymentStrategy{ + Type: DeploymentRecreate, + }, + }, + }, + expected: &Deployment{ + Spec: DeploymentSpec{ + Replicas: newInt(5), + Strategy: DeploymentStrategy{ + Type: DeploymentRecreate, + }, + UniqueLabelKey: newString(deploymentLabelKey), + }, + }, + }, + { + original: &Deployment{ + Spec: DeploymentSpec{ + Replicas: newInt(5), + Strategy: DeploymentStrategy{ + Type: DeploymentRecreate, + }, + UniqueLabelKey: newString("customDeploymentKey"), + }, + }, + expected: &Deployment{ + Spec: DeploymentSpec{ + Replicas: newInt(5), + Strategy: DeploymentStrategy{ + Type: DeploymentRecreate, + }, + UniqueLabelKey: newString("customDeploymentKey"), + }, + }, + }, + } + + for _, test := range tests { + original := test.original + expected := test.expected + obj2 := roundTrip(t, runtime.Object(original)) + got, ok := obj2.(*Deployment) + if !ok { + t.Errorf("unexpected object: %v", got) + t.FailNow() + } + if !reflect.DeepEqual(got.Spec, expected.Spec) { + t.Errorf("got different than expected: %v, %v", got, expected) + } + } +} + func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { data, err := v1.Codec.Encode(obj) if err != nil { @@ -102,3 +208,15 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { } return obj3 } + +func newInt(val int) *int { + p := new(int) + *p = val + return p +} + +func newString(val string) *string { + p := new(string) + *p = val + return p +} diff --git a/pkg/expapi/v1/types.go b/pkg/expapi/v1/types.go index 2a19aa868d..9e25d8399b 100644 --- a/pkg/expapi/v1/types.go +++ b/pkg/expapi/v1/types.go @@ -186,7 +186,7 @@ type DeploymentSpec struct { // not add any selector and label. If unspecified, system uses // "deployment.kubernetes.io/podTemplateHash". // Value of this key is hash of DeploymentSpec.PodTemplateSpec. - UniqueLabelKey *string `json:"uniqueLabel,omitempty" description:"key of the label that is added to existing pods to distinguish them from new ones; deployment.kubernetes.io/podTemplateHash is used by default; value of this label is hash of pod template spec; no label is added if this is set to empty string"` + UniqueLabelKey *string `json:"uniqueLabelKey,omitempty" description:"key of the label that is added to existing pods to distinguish them from new ones; deployment.kubernetes.io/podTemplateHash is used by default; value of this label is hash of pod template spec; no label is added if this is set to empty string"` } type DeploymentStrategy struct { @@ -222,7 +222,7 @@ type RollingUpdateDeployment struct { // can be scaled down further, followed by scaling up the new RC, ensuring // that at least 70% of original number of pods are available at all times // during the update. - MaxUnavailable util.IntOrString `json:"maxUnavailable,omitempty" description:"max number of pods that can be unavailable during the update; value can be an absolute number or a percentage of total pods at start of update"` + MaxUnavailable *util.IntOrString `json:"maxUnavailable,omitempty" description:"max number of pods that can be unavailable during the update; value can be an absolute number or a percentage of total pods at start of update"` // The maximum number of pods that can be scheduled above the original number of // pods. @@ -234,7 +234,7 @@ type RollingUpdateDeployment struct { // immediately when the rolling update starts. Once old pods have been killed, // new RC can be scaled up further, ensuring that total number of pods running // at any time during the update is atmost 130% of original pods. - MaxSurge util.IntOrString `json:"maxSurge,omitempty" description:"max number of pods that can be scheduled above the original number of pods; value can be an absolute number or a percentage of total pods at start of update"` + MaxSurge *util.IntOrString `json:"maxSurge,omitempty" description:"max number of pods that can be scheduled above the original number of pods; value can be an absolute number or a percentage of total pods at start of update"` // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. diff --git a/pkg/expapi/validation/validation.go b/pkg/expapi/validation/validation.go index 2bc02d80e5..9d60b7bdf9 100644 --- a/pkg/expapi/validation/validation.go +++ b/pkg/expapi/validation/validation.go @@ -238,9 +238,7 @@ func ValidateDeploymentSpec(spec *expapi.DeploymentSpec) errs.ValidationErrorLis allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(spec.Replicas), "replicas")...) allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, "template")...) allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, "strategy")...) - if spec.UniqueLabelKey != nil { - allErrs = append(allErrs, apivalidation.ValidateLabelName(*spec.UniqueLabelKey, "uniqueLabel")...) - } + allErrs = append(allErrs, apivalidation.ValidateLabelName(spec.UniqueLabelKey, "uniqueLabel")...) return allErrs } diff --git a/pkg/expapi/validation/validation_test.go b/pkg/expapi/validation/validation_test.go index 4aaf939481..14ca897420 100644 --- a/pkg/expapi/validation/validation_test.go +++ b/pkg/expapi/validation/validation_test.go @@ -572,6 +572,7 @@ func validDeployment() *expapi.Deployment { }, }, }, + UniqueLabelKey: "my-label", }, } } @@ -606,8 +607,7 @@ func TestValidateDeployment(t *testing.T) { // invalid unique label key. invalidUniqueLabelDeployment := validDeployment() - invalidUniqueLabel := "abc/def/ghi" - invalidUniqueLabelDeployment.Spec.UniqueLabelKey = &invalidUniqueLabel + invalidUniqueLabelDeployment.Spec.UniqueLabelKey = "abc/def/ghi" errorCases["spec.uniqueLabel: invalid value"] = invalidUniqueLabelDeployment // rollingUpdate should be nil for recreate. diff --git a/pkg/registry/deployment/etcd/etcd_test.go b/pkg/registry/deployment/etcd/etcd_test.go index c9c35e955c..e8294056ba 100755 --- a/pkg/registry/deployment/etcd/etcd_test.go +++ b/pkg/registry/deployment/etcd/etcd_test.go @@ -69,6 +69,7 @@ func validNewDeployment() *expapi.Deployment { DNSPolicy: api.DNSClusterFirst, }, }, + UniqueLabelKey: "my-label", }, } } diff --git a/pkg/util/util.go b/pkg/util/util.go index f75b59c709..4a22b1a53b 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -172,6 +172,9 @@ func (intstr IntOrString) MarshalJSON() ([]byte, error) { } func (intstr *IntOrString) Fuzz(c fuzz.Continue) { + if intstr == nil { + return + } if c.RandBool() { intstr.Kind = IntstrInt c.Fuzz(&intstr.IntVal)