diff --git a/pkg/apis/apps/register.go b/pkg/apis/apps/register.go index aae53d169ef..8b7591807cb 100644 --- a/pkg/apis/apps/register.go +++ b/pkg/apis/apps/register.go @@ -19,6 +19,7 @@ package apps import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/extensions" ) @@ -52,7 +53,7 @@ func addKnownTypes(scheme *runtime.Scheme) error { &extensions.Deployment{}, &extensions.DeploymentList{}, &extensions.DeploymentRollback{}, - &extensions.Scale{}, + &autoscaling.Scale{}, &StatefulSet{}, &StatefulSetList{}, &ControllerRevision{}, diff --git a/pkg/apis/apps/types.go b/pkg/apis/apps/types.go index 1f0bae8f5bd..77af74eecbd 100644 --- a/pkg/apis/apps/types.go +++ b/pkg/apis/apps/types.go @@ -23,8 +23,8 @@ import ( ) // +genclient -// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/extensions.Scale -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/extensions.Scale,result=k8s.io/kubernetes/pkg/apis/extensions.Scale +// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale +// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/autoscaling.Scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // StatefulSet represents a set of pods with consistent identities. diff --git a/pkg/apis/apps/v1beta1/conversion.go b/pkg/apis/apps/v1beta1/conversion.go index 62024692a69..6f4d27cf905 100644 --- a/pkg/apis/apps/v1beta1/conversion.go +++ b/pkg/apis/apps/v1beta1/conversion.go @@ -23,9 +23,11 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/kubernetes/pkg/apis/apps" + "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" "k8s.io/kubernetes/pkg/apis/extensions" @@ -44,8 +46,8 @@ func addConversionFuncs(scheme *runtime.Scheme) error { // extensions // TODO: below conversions should be dropped in favor of auto-generated // ones, see https://github.com/kubernetes/kubernetes/issues/39865 - Convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus, - Convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus, + Convert_v1beta1_ScaleStatus_To_autoscaling_ScaleStatus, + Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus, Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec, Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec, Convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy, @@ -178,48 +180,35 @@ func Convert_apps_StatefulSetUpdateStrategy_To_v1beta1_StatefulSetUpdateStrategy return nil } -func Convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in *extensions.ScaleStatus, out *appsv1beta1.ScaleStatus, s conversion.Scope) error { +func Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus(in *autoscaling.ScaleStatus, out *appsv1beta1.ScaleStatus, s conversion.Scope) error { out.Replicas = int32(in.Replicas) + out.TargetSelector = in.Selector out.Selector = nil - out.TargetSelector = "" - if in.Selector != nil { - if in.Selector.MatchExpressions == nil || len(in.Selector.MatchExpressions) == 0 { - out.Selector = in.Selector.MatchLabels - } - - selector, err := metav1.LabelSelectorAsSelector(in.Selector) - if err != nil { - return fmt.Errorf("invalid label selector: %v", err) - } - out.TargetSelector = selector.String() + selector, err := metav1.ParseToLabelSelector(in.Selector) + if err != nil { + return fmt.Errorf("failed to parse selector: %v", err) } + if len(selector.MatchExpressions) == 0 { + out.Selector = selector.MatchLabels + } + return nil } -func Convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in *appsv1beta1.ScaleStatus, out *extensions.ScaleStatus, s conversion.Scope) error { +func Convert_v1beta1_ScaleStatus_To_autoscaling_ScaleStatus(in *appsv1beta1.ScaleStatus, out *autoscaling.ScaleStatus, s conversion.Scope) error { out.Replicas = in.Replicas - // Normally when 2 fields map to the same internal value we favor the old field, since - // old clients can't be expected to know about new fields but clients that know about the - // new field can be expected to know about the old field (though that's not quite true, due - // to kubectl apply). However, these fields are readonly, so any non-nil value should work. if in.TargetSelector != "" { - labelSelector, err := metav1.ParseToLabelSelector(in.TargetSelector) - if err != nil { - out.Selector = nil - return fmt.Errorf("failed to parse target selector: %v", err) - } - out.Selector = labelSelector + out.Selector = in.TargetSelector } else if in.Selector != nil { - out.Selector = new(metav1.LabelSelector) - selector := make(map[string]string) + set := labels.Set{} for key, val := range in.Selector { - selector[key] = val + set[key] = val } - out.Selector.MatchLabels = selector + out.Selector = labels.SelectorFromSet(set).String() } else { - out.Selector = nil + out.Selector = "" } return nil } diff --git a/pkg/apis/apps/v1beta1/doc.go b/pkg/apis/apps/v1beta1/doc.go index 058dce37f1d..4a11a5834d3 100644 --- a/pkg/apis/apps/v1beta1/doc.go +++ b/pkg/apis/apps/v1beta1/doc.go @@ -15,6 +15,7 @@ limitations under the License. */ // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/apps +// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/autoscaling // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/extensions // +k8s:conversion-gen-external-types=../../../../vendor/k8s.io/api/apps/v1beta1 // +k8s:defaulter-gen=TypeMeta diff --git a/pkg/apis/apps/v1beta2/conversion.go b/pkg/apis/apps/v1beta2/conversion.go index f6292cb96bf..f2457e7e376 100644 --- a/pkg/apis/apps/v1beta2/conversion.go +++ b/pkg/apis/apps/v1beta2/conversion.go @@ -24,9 +24,11 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/kubernetes/pkg/apis/apps" + autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" "k8s.io/kubernetes/pkg/apis/extensions" @@ -57,8 +59,8 @@ func addConversionFuncs(scheme *runtime.Scheme) error { // extensions // TODO: below conversions should be dropped in favor of auto-generated // ones, see https://github.com/kubernetes/kubernetes/issues/39865 - Convert_v1beta2_ScaleStatus_To_extensions_ScaleStatus, - Convert_extensions_ScaleStatus_To_v1beta2_ScaleStatus, + Convert_v1beta2_ScaleStatus_To_autoscaling_ScaleStatus, + Convert_autoscaling_ScaleStatus_To_v1beta2_ScaleStatus, Convert_v1beta2_DeploymentSpec_To_extensions_DeploymentSpec, Convert_extensions_DeploymentSpec_To_v1beta2_DeploymentSpec, Convert_v1beta2_DeploymentStrategy_To_extensions_DeploymentStrategy, @@ -243,26 +245,23 @@ func Convert_apps_StatefulSetStatus_To_v1beta2_StatefulSetStatus(in *apps.Statef return nil } -func Convert_extensions_ScaleStatus_To_v1beta2_ScaleStatus(in *extensions.ScaleStatus, out *appsv1beta2.ScaleStatus, s conversion.Scope) error { +func Convert_autoscaling_ScaleStatus_To_v1beta2_ScaleStatus(in *autoscaling.ScaleStatus, out *appsv1beta2.ScaleStatus, s conversion.Scope) error { out.Replicas = int32(in.Replicas) + out.TargetSelector = in.Selector out.Selector = nil - out.TargetSelector = "" - if in.Selector != nil { - if in.Selector.MatchExpressions == nil || len(in.Selector.MatchExpressions) == 0 { - out.Selector = in.Selector.MatchLabels - } - - selector, err := metav1.LabelSelectorAsSelector(in.Selector) - if err != nil { - return fmt.Errorf("invalid label selector: %v", err) - } - out.TargetSelector = selector.String() + selector, err := metav1.ParseToLabelSelector(in.Selector) + if err != nil { + return fmt.Errorf("failed to parse selector: %v", err) } + if len(selector.MatchExpressions) == 0 { + out.Selector = selector.MatchLabels + } + return nil } -func Convert_v1beta2_ScaleStatus_To_extensions_ScaleStatus(in *appsv1beta2.ScaleStatus, out *extensions.ScaleStatus, s conversion.Scope) error { +func Convert_v1beta2_ScaleStatus_To_autoscaling_ScaleStatus(in *appsv1beta2.ScaleStatus, out *autoscaling.ScaleStatus, s conversion.Scope) error { out.Replicas = in.Replicas // Normally when 2 fields map to the same internal value we favor the old field, since @@ -270,21 +269,15 @@ func Convert_v1beta2_ScaleStatus_To_extensions_ScaleStatus(in *appsv1beta2.Scale // new field can be expected to know about the old field (though that's not quite true, due // to kubectl apply). However, these fields are readonly, so any non-nil value should work. if in.TargetSelector != "" { - labelSelector, err := metav1.ParseToLabelSelector(in.TargetSelector) - if err != nil { - out.Selector = nil - return fmt.Errorf("failed to parse target selector: %v", err) - } - out.Selector = labelSelector + out.Selector = in.TargetSelector } else if in.Selector != nil { - out.Selector = new(metav1.LabelSelector) - selector := make(map[string]string) + set := labels.Set{} for key, val := range in.Selector { - selector[key] = val + set[key] = val } - out.Selector.MatchLabels = selector + out.Selector = labels.SelectorFromSet(set).String() } else { - out.Selector = nil + out.Selector = "" } return nil } diff --git a/pkg/apis/apps/v1beta2/conversion_test.go b/pkg/apis/apps/v1beta2/conversion_test.go index c5f44687cae..7cf4d11a2f6 100644 --- a/pkg/apis/apps/v1beta2/conversion_test.go +++ b/pkg/apis/apps/v1beta2/conversion_test.go @@ -24,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/apps" + "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/extensions" @@ -349,41 +350,41 @@ func TestV1beta2ScaleStatusConversion(t *testing.T) { labelsSelector2, _ := metav1.LabelSelectorAsSelector(selector2) testcases := map[string]struct { - scaleStatus1 *extensions.ScaleStatus + scaleStatus1 *autoscaling.ScaleStatus scaleStatus2 *v1beta2.ScaleStatus }{ "ScaleStatus Conversion 1": { - scaleStatus1: &extensions.ScaleStatus{Replicas: 2}, + scaleStatus1: &autoscaling.ScaleStatus{Replicas: 2}, scaleStatus2: &v1beta2.ScaleStatus{Replicas: 2}, }, "ScaleStatus Conversion 2": { - scaleStatus1: &extensions.ScaleStatus{Replicas: 2, Selector: selector1}, + scaleStatus1: &autoscaling.ScaleStatus{Replicas: 2, Selector: labelsSelector1.String()}, scaleStatus2: &v1beta2.ScaleStatus{Replicas: 2, Selector: matchLabels, TargetSelector: labelsSelector1.String()}, }, "ScaleStatus Conversion 3": { - scaleStatus1: &extensions.ScaleStatus{Replicas: 2, Selector: selector2}, + scaleStatus1: &autoscaling.ScaleStatus{Replicas: 2, Selector: labelsSelector2.String()}, scaleStatus2: &v1beta2.ScaleStatus{Replicas: 2, Selector: map[string]string{}, TargetSelector: labelsSelector2.String()}, }, } for k, tc := range testcases { - // extensions -> v1beta2 + // autoscaling -> v1beta2 internal1 := &v1beta2.ScaleStatus{} if err := legacyscheme.Scheme.Convert(tc.scaleStatus1, internal1, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "extensions -> v1beta2", err) + t.Errorf("%q - %q: unexpected error: %v", k, "autoscaling -> v1beta2", err) } if !apiequality.Semantic.DeepEqual(internal1, tc.scaleStatus2) { - t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "extensions -> v1beta2", tc.scaleStatus2, internal1) + t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "autoscaling -> v1beta2", tc.scaleStatus2, internal1) } - // v1beta2 -> extensions - internal2 := &extensions.ScaleStatus{} + // v1beta2 -> autoscaling + internal2 := &autoscaling.ScaleStatus{} if err := legacyscheme.Scheme.Convert(tc.scaleStatus2, internal2, nil); err != nil { - t.Errorf("%q - %q: unexpected error: %v", k, "v1beta2 -> extensions", err) + t.Errorf("%q - %q: unexpected error: %v", k, "v1beta2 -> autoscaling", err) } if !apiequality.Semantic.DeepEqual(internal2, tc.scaleStatus1) { - t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "v1beta2 -> extensions", tc.scaleStatus1, internal2) + t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "v1beta2 -> autoscaling", tc.scaleStatus1, internal2) } } } diff --git a/pkg/apis/apps/v1beta2/doc.go b/pkg/apis/apps/v1beta2/doc.go index 9a0bb581994..6c8f7c3bc01 100644 --- a/pkg/apis/apps/v1beta2/doc.go +++ b/pkg/apis/apps/v1beta2/doc.go @@ -15,6 +15,7 @@ limitations under the License. */ // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/apps +// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/autoscaling // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/extensions // +k8s:conversion-gen-external-types=../../../../vendor/k8s.io/api/apps/v1beta2 // +k8s:defaulter-gen=TypeMeta diff --git a/pkg/apis/autoscaling/fuzzer/fuzzer.go b/pkg/apis/autoscaling/fuzzer/fuzzer.go index 9915f8092c2..2c1ea0608ca 100644 --- a/pkg/apis/autoscaling/fuzzer/fuzzer.go +++ b/pkg/apis/autoscaling/fuzzer/fuzzer.go @@ -18,7 +18,9 @@ package fuzzer import ( fuzz "github.com/google/gofuzz" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" @@ -27,6 +29,15 @@ import ( // Funcs returns the fuzzer functions for the autoscaling api group. var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ + func(s *autoscaling.ScaleStatus, c fuzz.Continue) { + c.FuzzNoCustom(s) // fuzz self without calling this function again + + // ensure we have a valid selector + metaSelector := &metav1.LabelSelector{} + c.Fuzz(metaSelector) + labelSelector, _ := metav1.LabelSelectorAsSelector(metaSelector) + s.Selector = labelSelector.String() + }, func(s *autoscaling.HorizontalPodAutoscalerSpec, c fuzz.Continue) { c.FuzzNoCustom(s) // fuzz self without calling this function again minReplicas := int32(c.Rand.Int31()) diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go index 0bba0bca2dd..6a127485b4e 100644 --- a/pkg/apis/core/types.go +++ b/pkg/apis/core/types.go @@ -2725,8 +2725,8 @@ type ReplicationControllerCondition struct { } // +genclient -// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/extensions.Scale -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/extensions.Scale,result=k8s.io/kubernetes/pkg/apis/extensions.Scale +// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale +// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/autoscaling.Scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ReplicationController represents the configuration of a replication controller. diff --git a/pkg/apis/extensions/register.go b/pkg/apis/extensions/register.go index 717662f48e4..48137fc6962 100644 --- a/pkg/apis/extensions/register.go +++ b/pkg/apis/extensions/register.go @@ -19,6 +19,7 @@ package extensions import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/networking" ) @@ -51,7 +52,6 @@ func addKnownTypes(scheme *runtime.Scheme) error { &DeploymentList{}, &DeploymentRollback{}, &ReplicationControllerDummy{}, - &Scale{}, &DaemonSetList{}, &DaemonSet{}, &Ingress{}, @@ -60,6 +60,7 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ReplicaSetList{}, &PodSecurityPolicy{}, &PodSecurityPolicyList{}, + &autoscaling.Scale{}, &networking.NetworkPolicy{}, &networking.NetworkPolicyList{}, ) diff --git a/pkg/apis/extensions/types.go b/pkg/apis/extensions/types.go index 1867fe099be..5e3f43688c5 100644 --- a/pkg/apis/extensions/types.go +++ b/pkg/apis/extensions/types.go @@ -42,44 +42,6 @@ const ( SysctlsPodSecurityPolicyAnnotationKey string = "security.alpha.kubernetes.io/sysctls" ) -// describes the attributes of a scale subresource -type ScaleSpec struct { - // desired number of instances for the scaled object. - // +optional - Replicas int32 -} - -// represents the current status of a scale subresource. -type ScaleStatus struct { - // actual number of observed instances of the scaled object. - Replicas int32 - - // label query over pods that should match the replicas count. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors - // +optional - Selector *metav1.LabelSelector -} - -// +genclient -// +genclient:noVerbs -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// represents a scaling request for a resource. -type Scale struct { - metav1.TypeMeta - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata. - // +optional - metav1.ObjectMeta - - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status. - // +optional - Spec ScaleSpec - - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status. Read-only. - // +optional - Status ScaleStatus -} - // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Dummy definition @@ -111,8 +73,8 @@ type CustomMetricCurrentStatusList struct { } // +genclient -// +genclient:method=GetScale,verb=get,subresource=scale,result=Scale -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=Scale,result=Scale +// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale +// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/autoscaling.Scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type Deployment struct { @@ -709,8 +671,8 @@ type IngressBackend struct { } // +genclient -// +genclient:method=GetScale,verb=get,subresource=scale,result=Scale -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=Scale,result=Scale +// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale +// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/kubernetes/pkg/apis/autoscaling.Scale,result=k8s.io/kubernetes/pkg/apis/autoscaling.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ReplicaSet ensures that a specified number of pod replicas are running at any given time. diff --git a/pkg/apis/extensions/v1beta1/conversion.go b/pkg/apis/extensions/v1beta1/conversion.go index 073aabe4737..d236a415e13 100644 --- a/pkg/apis/extensions/v1beta1/conversion.go +++ b/pkg/apis/extensions/v1beta1/conversion.go @@ -24,8 +24,10 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" "k8s.io/kubernetes/pkg/apis/extensions" @@ -35,8 +37,8 @@ import ( func addConversionFuncs(scheme *runtime.Scheme) error { // Add non-generated conversion functions err := scheme.AddConversionFuncs( - Convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus, - Convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus, + Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus, + Convert_v1beta1_ScaleStatus_To_autoscaling_ScaleStatus, Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec, Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec, Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy, @@ -72,48 +74,35 @@ func addConversionFuncs(scheme *runtime.Scheme) error { return nil } -func Convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in *extensions.ScaleStatus, out *extensionsv1beta1.ScaleStatus, s conversion.Scope) error { +func Convert_autoscaling_ScaleStatus_To_v1beta1_ScaleStatus(in *autoscaling.ScaleStatus, out *extensionsv1beta1.ScaleStatus, s conversion.Scope) error { out.Replicas = int32(in.Replicas) + out.TargetSelector = in.Selector out.Selector = nil - out.TargetSelector = "" - if in.Selector != nil { - if in.Selector.MatchExpressions == nil || len(in.Selector.MatchExpressions) == 0 { - out.Selector = in.Selector.MatchLabels - } - - selector, err := metav1.LabelSelectorAsSelector(in.Selector) - if err != nil { - return fmt.Errorf("invalid label selector: %v", err) - } - out.TargetSelector = selector.String() + selector, err := metav1.ParseToLabelSelector(in.Selector) + if err != nil { + return fmt.Errorf("failed to parse selector: %v", err) } + if len(selector.MatchExpressions) == 0 { + out.Selector = selector.MatchLabels + } + return nil } -func Convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in *extensionsv1beta1.ScaleStatus, out *extensions.ScaleStatus, s conversion.Scope) error { +func Convert_v1beta1_ScaleStatus_To_autoscaling_ScaleStatus(in *extensionsv1beta1.ScaleStatus, out *autoscaling.ScaleStatus, s conversion.Scope) error { out.Replicas = in.Replicas - // Normally when 2 fields map to the same internal value we favor the old field, since - // old clients can't be expected to know about new fields but clients that know about the - // new field can be expected to know about the old field (though that's not quite true, due - // to kubectl apply). However, these fields are readonly, so any non-nil value should work. if in.TargetSelector != "" { - labelSelector, err := metav1.ParseToLabelSelector(in.TargetSelector) - if err != nil { - out.Selector = nil - return fmt.Errorf("failed to parse target selector: %v", err) - } - out.Selector = labelSelector + out.Selector = in.TargetSelector } else if in.Selector != nil { - out.Selector = new(metav1.LabelSelector) - selector := make(map[string]string) + set := labels.Set{} for key, val := range in.Selector { - selector[key] = val + set[key] = val } - out.Selector.MatchLabels = selector + out.Selector = labels.SelectorFromSet(set).String() } else { - out.Selector = nil + out.Selector = "" } return nil } diff --git a/pkg/apis/extensions/v1beta1/doc.go b/pkg/apis/extensions/v1beta1/doc.go index fb27eae221a..0d778368f1b 100644 --- a/pkg/apis/extensions/v1beta1/doc.go +++ b/pkg/apis/extensions/v1beta1/doc.go @@ -15,6 +15,7 @@ limitations under the License. */ // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/extensions +// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/autoscaling // +k8s:conversion-gen-external-types=../../../../vendor/k8s.io/api/extensions/v1beta1 // +k8s:defaulter-gen=TypeMeta // +k8s:defaulter-gen-input=../../../../vendor/k8s.io/api/extensions/v1beta1 diff --git a/pkg/apis/extensions/validation/validation.go b/pkg/apis/extensions/validation/validation.go index d97e7bc93c9..1da47041a21 100644 --- a/pkg/apis/extensions/validation/validation.go +++ b/pkg/apis/extensions/validation/validation.go @@ -522,17 +522,6 @@ func validateIngressBackend(backend *extensions.IngressBackend, fldPath *field.P return allErrs } -func ValidateScale(scale *extensions.Scale) field.ErrorList { - allErrs := field.ErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&scale.ObjectMeta, true, apivalidation.NameIsDNSSubdomain, field.NewPath("metadata"))...) - - if scale.Spec.Replicas < 0 { - allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "replicas"), scale.Spec.Replicas, "must be greater than or equal to 0")) - } - - return allErrs -} - // ValidateReplicaSetName can be used to check whether the given ReplicaSet // name is valid. // Prefix indicates this name will be used as part of generation, in which case diff --git a/pkg/apis/extensions/validation/validation_test.go b/pkg/apis/extensions/validation/validation_test.go index eb514945ce8..55b03c65cba 100644 --- a/pkg/apis/extensions/validation/validation_test.go +++ b/pkg/apis/extensions/validation/validation_test.go @@ -1750,70 +1750,6 @@ func TestValidateIngressStatusUpdate(t *testing.T) { } } -func TestValidateScale(t *testing.T) { - successCases := []extensions.Scale{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "frontend", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.ScaleSpec{ - Replicas: 1, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "frontend", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.ScaleSpec{ - Replicas: 10, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "frontend", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.ScaleSpec{ - Replicas: 0, - }, - }, - } - - for _, successCase := range successCases { - if errs := ValidateScale(&successCase); len(errs) != 0 { - t.Errorf("expected success: %v", errs) - } - } - - errorCases := []struct { - scale extensions.Scale - msg string - }{ - { - scale: extensions.Scale{ - ObjectMeta: metav1.ObjectMeta{ - Name: "frontend", - Namespace: metav1.NamespaceDefault, - }, - Spec: extensions.ScaleSpec{ - Replicas: -1, - }, - }, - msg: "must be greater than or equal to 0", - }, - } - - for _, c := range errorCases { - if errs := ValidateScale(&c.scale); len(errs) == 0 { - t.Errorf("expected failure for %s", c.msg) - } else if !strings.Contains(errs[0].Error(), c.msg) { - t.Errorf("unexpected error: %v, expected: %s", errs[0], c.msg) - } - } -} - func TestValidateReplicaSetStatus(t *testing.T) { tests := []struct { name string diff --git a/pkg/registry/apps/statefulset/storage/storage.go b/pkg/registry/apps/statefulset/storage/storage.go index 6adce290dc4..d97f17270e5 100644 --- a/pkg/registry/apps/statefulset/storage/storage.go +++ b/pkg/registry/apps/statefulset/storage/storage.go @@ -30,9 +30,10 @@ import ( "k8s.io/kubernetes/pkg/apis/apps" appsv1beta1 "k8s.io/kubernetes/pkg/apis/apps/v1beta1" appsv1beta2 "k8s.io/kubernetes/pkg/apis/apps/v1beta2" + "k8s.io/kubernetes/pkg/apis/autoscaling" autoscalingv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1" + autoscalingvalidation "k8s.io/kubernetes/pkg/apis/autoscaling/validation" "k8s.io/kubernetes/pkg/apis/extensions" - extvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" printerstorage "k8s.io/kubernetes/pkg/printers/storage" @@ -141,7 +142,7 @@ func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr // New creates a new Scale object func (r *ScaleREST) New() runtime.Object { - return &extensions.Scale{} + return &autoscaling.Scale{} } func (r *ScaleREST) Get(ctx genericapirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { @@ -174,12 +175,12 @@ func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo r if obj == nil { return nil, false, errors.NewBadRequest(fmt.Sprintf("nil update passed to Scale")) } - scale, ok := obj.(*extensions.Scale) + scale, ok := obj.(*autoscaling.Scale) if !ok { return nil, false, errors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj)) } - if errs := extvalidation.ValidateScale(scale); len(errs) > 0 { + if errs := autoscalingvalidation.ValidateScale(scale); len(errs) > 0 { return nil, false, errors.NewInvalid(extensions.Kind("Scale"), scale.Name, errs) } @@ -197,8 +198,12 @@ func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo r } // scaleFromStatefulSet returns a scale subresource for a statefulset. -func scaleFromStatefulSet(ss *apps.StatefulSet) (*extensions.Scale, error) { - return &extensions.Scale{ +func scaleFromStatefulSet(ss *apps.StatefulSet) (*autoscaling.Scale, error) { + selector, err := metav1.LabelSelectorAsSelector(ss.Spec.Selector) + if err != nil { + return nil, err + } + return &autoscaling.Scale{ // TODO: Create a variant of ObjectMeta type that only contains the fields below. ObjectMeta: metav1.ObjectMeta{ Name: ss.Name, @@ -207,12 +212,12 @@ func scaleFromStatefulSet(ss *apps.StatefulSet) (*extensions.Scale, error) { ResourceVersion: ss.ResourceVersion, CreationTimestamp: ss.CreationTimestamp, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: ss.Spec.Replicas, }, - Status: extensions.ScaleStatus{ + Status: autoscaling.ScaleStatus{ Replicas: ss.Status.Replicas, - Selector: ss.Spec.Selector, + Selector: selector.String(), }, }, nil } diff --git a/pkg/registry/apps/statefulset/storage/storage_test.go b/pkg/registry/apps/statefulset/storage/storage_test.go index 50d2f8e35c5..1adaa444805 100644 --- a/pkg/registry/apps/statefulset/storage/storage_test.go +++ b/pkg/registry/apps/statefulset/storage/storage_test.go @@ -30,8 +30,8 @@ import ( "k8s.io/apiserver/pkg/registry/rest" etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" "k8s.io/kubernetes/pkg/apis/apps" + "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/registry/registrytest" ) @@ -224,7 +224,11 @@ func TestScaleGet(t *testing.T) { t.Fatalf("error setting new statefulset (key: %s) %v: %v", key, validStatefulSet, err) } - want := &extensions.Scale{ + selector, err := metav1.LabelSelectorAsSelector(validStatefulSet.Spec.Selector) + if err != nil { + t.Fatal(err) + } + want := &autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: metav1.NamespaceDefault, @@ -232,16 +236,16 @@ func TestScaleGet(t *testing.T) { ResourceVersion: sts.ResourceVersion, CreationTimestamp: sts.CreationTimestamp, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: validStatefulSet.Spec.Replicas, }, - Status: extensions.ScaleStatus{ + Status: autoscaling.ScaleStatus{ Replicas: validStatefulSet.Status.Replicas, - Selector: validStatefulSet.Spec.Selector, + Selector: selector.String(), }, } obj, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) - got := obj.(*extensions.Scale) + got := obj.(*autoscaling.Scale) if err != nil { t.Fatalf("error fetching scale for %s: %v", name, err) } @@ -264,12 +268,12 @@ func TestScaleUpdate(t *testing.T) { t.Fatalf("error setting new statefulset (key: %s) %v: %v", key, validStatefulSet, err) } replicas := 12 - update := extensions.Scale{ + update := autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: metav1.NamespaceDefault, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: int32(replicas), }, } @@ -282,7 +286,7 @@ func TestScaleUpdate(t *testing.T) { if err != nil { t.Fatalf("error fetching scale for %s: %v", name, err) } - scale := obj.(*extensions.Scale) + scale := obj.(*autoscaling.Scale) if scale.Spec.Replicas != int32(replicas) { t.Errorf("wrong replicas count expected: %d got: %d", replicas, scale.Spec.Replicas) } diff --git a/pkg/registry/extensions/controller/storage/storage.go b/pkg/registry/extensions/controller/storage/storage.go index dcc97671349..774a78911f0 100644 --- a/pkg/registry/extensions/controller/storage/storage.go +++ b/pkg/registry/extensions/controller/storage/storage.go @@ -21,13 +21,15 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/kubernetes/pkg/apis/autoscaling" + autoscalingvalidation "k8s.io/kubernetes/pkg/apis/autoscaling/validation" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/extensions" - extvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/registry/core/replicationcontroller" controllerstore "k8s.io/kubernetes/pkg/registry/core/replicationcontroller/storage" ) @@ -58,7 +60,7 @@ var _ = rest.Patcher(&ScaleREST{}) // New creates a new Scale object func (r *ScaleREST) New() runtime.Object { - return &extensions.Scale{} + return &autoscaling.Scale{} } func (r *ScaleREST) Get(ctx genericapirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { @@ -81,12 +83,12 @@ func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo r if obj == nil { return nil, false, errors.NewBadRequest(fmt.Sprintf("nil update passed to Scale")) } - scale, ok := obj.(*extensions.Scale) + scale, ok := obj.(*autoscaling.Scale) if !ok { return nil, false, errors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj)) } - if errs := extvalidation.ValidateScale(scale); len(errs) > 0 { + if errs := autoscalingvalidation.ValidateScale(scale); len(errs) > 0 { return nil, false, errors.NewInvalid(extensions.Kind("Scale"), scale.Name, errs) } @@ -100,8 +102,8 @@ func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo r } // scaleFromRC returns a scale subresource for a replication controller. -func scaleFromRC(rc *api.ReplicationController) *extensions.Scale { - return &extensions.Scale{ +func scaleFromRC(rc *api.ReplicationController) *autoscaling.Scale { + return &autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{ Name: rc.Name, Namespace: rc.Namespace, @@ -109,14 +111,12 @@ func scaleFromRC(rc *api.ReplicationController) *extensions.Scale { ResourceVersion: rc.ResourceVersion, CreationTimestamp: rc.CreationTimestamp, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: rc.Spec.Replicas, }, - Status: extensions.ScaleStatus{ + Status: autoscaling.ScaleStatus{ Replicas: rc.Status.Replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: rc.Spec.Selector, - }, + Selector: labels.SelectorFromSet(labels.Set(rc.Spec.Selector)).String(), }, } } diff --git a/pkg/registry/extensions/controller/storage/storage_test.go b/pkg/registry/extensions/controller/storage/storage_test.go index c224e424956..62689035fb4 100644 --- a/pkg/registry/extensions/controller/storage/storage_test.go +++ b/pkg/registry/extensions/controller/storage/storage_test.go @@ -26,8 +26,8 @@ import ( "k8s.io/apiserver/pkg/storage" etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" "k8s.io/apiserver/pkg/storage/storagebackend/factory" + "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/registry/registrytest" ) @@ -74,16 +74,14 @@ var validController = api.ReplicationController{ Spec: validControllerSpec, } -var validScale = extensions.Scale{ +var validScale = autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"}, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: validReplicas, }, - Status: extensions.ScaleStatus{ + Status: autoscaling.ScaleStatus{ Replicas: 0, - Selector: &metav1.LabelSelector{ - MatchLabels: validPodTemplate.Template.Labels, - }, + Selector: "a=b", }, } @@ -100,7 +98,7 @@ func TestGet(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v", err) } - scale := obj.(*extensions.Scale) + scale := obj.(*autoscaling.Scale) if scale.Spec.Replicas != validReplicas { t.Errorf("wrong replicas count expected: %d got: %d", validReplicas, scale.Spec.Replicas) } @@ -116,9 +114,9 @@ func TestUpdate(t *testing.T) { t.Fatalf("unexpected error: %v", err) } replicas := int32(12) - update := extensions.Scale{ + update := autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"}, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: replicas, }, } @@ -131,7 +129,7 @@ func TestUpdate(t *testing.T) { t.Fatalf("unexpected error: %v", err) } - updated := obj.(*extensions.Scale) + updated := obj.(*autoscaling.Scale) if updated.Spec.Replicas != replicas { t.Errorf("wrong replicas count expected: %d got: %d", replicas, updated.Spec.Replicas) } diff --git a/pkg/registry/extensions/deployment/storage/storage.go b/pkg/registry/extensions/deployment/storage/storage.go index aedccc58bf1..6cf80f8dcc7 100644 --- a/pkg/registry/extensions/deployment/storage/storage.go +++ b/pkg/registry/extensions/deployment/storage/storage.go @@ -32,7 +32,9 @@ import ( storeerr "k8s.io/apiserver/pkg/storage/errors" appsv1beta1 "k8s.io/kubernetes/pkg/apis/apps/v1beta1" appsv1beta2 "k8s.io/kubernetes/pkg/apis/apps/v1beta2" + "k8s.io/kubernetes/pkg/apis/autoscaling" autoscalingv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1" + autoscalingvalidation "k8s.io/kubernetes/pkg/apis/autoscaling/validation" "k8s.io/kubernetes/pkg/apis/extensions" extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" extvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation" @@ -212,7 +214,7 @@ func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr // New creates a new Scale object func (r *ScaleREST) New() runtime.Object { - return &extensions.Scale{} + return &autoscaling.Scale{} } func (r *ScaleREST) Get(ctx genericapirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { @@ -245,12 +247,12 @@ func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo r if obj == nil { return nil, false, errors.NewBadRequest(fmt.Sprintf("nil update passed to Scale")) } - scale, ok := obj.(*extensions.Scale) + scale, ok := obj.(*autoscaling.Scale) if !ok { return nil, false, errors.NewBadRequest(fmt.Sprintf("expected input object type to be Scale, but %T", obj)) } - if errs := extvalidation.ValidateScale(scale); len(errs) > 0 { + if errs := autoscalingvalidation.ValidateScale(scale); len(errs) > 0 { return nil, false, errors.NewInvalid(extensions.Kind("Scale"), name, errs) } @@ -268,8 +270,12 @@ func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo r } // scaleFromDeployment returns a scale subresource for a deployment. -func scaleFromDeployment(deployment *extensions.Deployment) (*extensions.Scale, error) { - return &extensions.Scale{ +func scaleFromDeployment(deployment *extensions.Deployment) (*autoscaling.Scale, error) { + selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector) + if err != nil { + return nil, err + } + return &autoscaling.Scale{ // TODO: Create a variant of ObjectMeta type that only contains the fields below. ObjectMeta: metav1.ObjectMeta{ Name: deployment.Name, @@ -278,12 +284,12 @@ func scaleFromDeployment(deployment *extensions.Deployment) (*extensions.Scale, ResourceVersion: deployment.ResourceVersion, CreationTimestamp: deployment.CreationTimestamp, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: deployment.Spec.Replicas, }, - Status: extensions.ScaleStatus{ + Status: autoscaling.ScaleStatus{ Replicas: deployment.Status.Replicas, - Selector: deployment.Spec.Selector, + Selector: selector.String(), }, }, nil } diff --git a/pkg/registry/extensions/deployment/storage/storage_test.go b/pkg/registry/extensions/deployment/storage/storage_test.go index 3bb2d3cb7cc..aa7764b16fd 100644 --- a/pkg/registry/extensions/deployment/storage/storage_test.go +++ b/pkg/registry/extensions/deployment/storage/storage_test.go @@ -34,6 +34,7 @@ import ( "k8s.io/apiserver/pkg/registry/rest" storeerr "k8s.io/apiserver/pkg/storage/errors" etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" + "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/registry/registrytest" @@ -207,7 +208,11 @@ func TestScaleGet(t *testing.T) { t.Fatalf("error setting new deployment (key: %s) %v: %v", key, validDeployment, err) } - want := &extensions.Scale{ + selector, err := metav1.LabelSelectorAsSelector(validDeployment.Spec.Selector) + if err != nil { + t.Fatal(err) + } + want := &autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -215,19 +220,19 @@ func TestScaleGet(t *testing.T) { ResourceVersion: deployment.ResourceVersion, CreationTimestamp: deployment.CreationTimestamp, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: validDeployment.Spec.Replicas, }, - Status: extensions.ScaleStatus{ + Status: autoscaling.ScaleStatus{ Replicas: validDeployment.Status.Replicas, - Selector: validDeployment.Spec.Selector, + Selector: selector.String(), }, } obj, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) if err != nil { t.Fatalf("error fetching scale for %s: %v", name, err) } - got := obj.(*extensions.Scale) + got := obj.(*autoscaling.Scale) if !apiequality.Semantic.DeepEqual(want, got) { t.Errorf("unexpected scale: %s", diff.ObjectDiff(want, got)) } @@ -244,9 +249,9 @@ func TestScaleUpdate(t *testing.T) { t.Fatalf("error setting new deployment (key: %s) %v: %v", key, validDeployment, err) } replicas := int32(12) - update := extensions.Scale{ + update := autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace}, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: replicas, }, } @@ -258,7 +263,7 @@ func TestScaleUpdate(t *testing.T) { if err != nil { t.Fatalf("error fetching scale for %s: %v", name, err) } - scale := obj.(*extensions.Scale) + scale := obj.(*autoscaling.Scale) if scale.Spec.Replicas != replicas { t.Errorf("wrong replicas count expected: %d got: %d", replicas, deployment.Spec.Replicas) } diff --git a/pkg/registry/extensions/replicaset/storage/storage.go b/pkg/registry/extensions/replicaset/storage/storage.go index de513a337a9..893e66390da 100644 --- a/pkg/registry/extensions/replicaset/storage/storage.go +++ b/pkg/registry/extensions/replicaset/storage/storage.go @@ -31,10 +31,11 @@ import ( "k8s.io/apiserver/pkg/registry/rest" appsv1beta1 "k8s.io/kubernetes/pkg/apis/apps/v1beta1" appsv1beta2 "k8s.io/kubernetes/pkg/apis/apps/v1beta2" + "k8s.io/kubernetes/pkg/apis/autoscaling" autoscalingv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1" + autoscalingvalidation "k8s.io/kubernetes/pkg/apis/autoscaling/validation" "k8s.io/kubernetes/pkg/apis/extensions" extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" - extvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" printerstorage "k8s.io/kubernetes/pkg/printers/storage" @@ -146,7 +147,7 @@ func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr // New creates a new Scale object func (r *ScaleREST) New() runtime.Object { - return &extensions.Scale{} + return &autoscaling.Scale{} } func (r *ScaleREST) Get(ctx genericapirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { @@ -180,12 +181,12 @@ func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo r if obj == nil { return nil, false, errors.NewBadRequest(fmt.Sprintf("nil update passed to Scale")) } - scale, ok := obj.(*extensions.Scale) + scale, ok := obj.(*autoscaling.Scale) if !ok { return nil, false, errors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj)) } - if errs := extvalidation.ValidateScale(scale); len(errs) > 0 { + if errs := autoscalingvalidation.ValidateScale(scale); len(errs) > 0 { return nil, false, errors.NewInvalid(extensions.Kind("Scale"), scale.Name, errs) } @@ -203,8 +204,12 @@ func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo r } // scaleFromReplicaSet returns a scale subresource for a replica set. -func scaleFromReplicaSet(rs *extensions.ReplicaSet) (*extensions.Scale, error) { - return &extensions.Scale{ +func scaleFromReplicaSet(rs *extensions.ReplicaSet) (*autoscaling.Scale, error) { + selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) + if err != nil { + return nil, err + } + return &autoscaling.Scale{ // TODO: Create a variant of ObjectMeta type that only contains the fields below. ObjectMeta: metav1.ObjectMeta{ Name: rs.Name, @@ -213,12 +218,12 @@ func scaleFromReplicaSet(rs *extensions.ReplicaSet) (*extensions.Scale, error) { ResourceVersion: rs.ResourceVersion, CreationTimestamp: rs.CreationTimestamp, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: rs.Spec.Replicas, }, - Status: extensions.ScaleStatus{ + Status: autoscaling.ScaleStatus{ Replicas: rs.Status.Replicas, - Selector: rs.Spec.Selector, + Selector: selector.String(), }, }, nil } diff --git a/pkg/registry/extensions/replicaset/storage/storage_test.go b/pkg/registry/extensions/replicaset/storage/storage_test.go index 96fcfd664fa..a501099c5a1 100644 --- a/pkg/registry/extensions/replicaset/storage/storage_test.go +++ b/pkg/registry/extensions/replicaset/storage/storage_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" + "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/registry/registrytest" @@ -261,7 +262,12 @@ func TestScaleGet(t *testing.T) { t.Fatalf("error setting new replica set (key: %s) %v: %v", key, validReplicaSet, err) } - want := &extensions.Scale{ + selector, err := metav1.LabelSelectorAsSelector(validReplicaSet.Spec.Selector) + if err != nil { + t.Fatal(err) + } + + want := &autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: metav1.NamespaceDefault, @@ -269,16 +275,16 @@ func TestScaleGet(t *testing.T) { ResourceVersion: rs.ResourceVersion, CreationTimestamp: rs.CreationTimestamp, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: validReplicaSet.Spec.Replicas, }, - Status: extensions.ScaleStatus{ + Status: autoscaling.ScaleStatus{ Replicas: validReplicaSet.Status.Replicas, - Selector: validReplicaSet.Spec.Selector, + Selector: selector.String(), }, } obj, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) - got := obj.(*extensions.Scale) + got := obj.(*autoscaling.Scale) if err != nil { t.Fatalf("error fetching scale for %s: %v", name, err) } @@ -301,12 +307,12 @@ func TestScaleUpdate(t *testing.T) { t.Fatalf("error setting new replica set (key: %s) %v: %v", key, validReplicaSet, err) } replicas := 12 - update := extensions.Scale{ + update := autoscaling.Scale{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: metav1.NamespaceDefault, }, - Spec: extensions.ScaleSpec{ + Spec: autoscaling.ScaleSpec{ Replicas: int32(replicas), }, } @@ -319,7 +325,7 @@ func TestScaleUpdate(t *testing.T) { if err != nil { t.Fatalf("error fetching scale for %s: %v", name, err) } - scale := obj.(*extensions.Scale) + scale := obj.(*autoscaling.Scale) if scale.Spec.Replicas != int32(replicas) { t.Errorf("wrong replicas count expected: %d got: %d", replicas, scale.Spec.Replicas) }