Switch to autoscaling.Scale internally
This commit is contained in:
@@ -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{},
|
||||
)
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user