mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-04 23:17:50 +00:00
Promotes the StatefulSet, ControllerRevision, Deployment, and ReplicaSet kinds to the apps/v1 group version.
This commit is contained in:
@@ -17,13 +17,18 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
)
|
||||
|
||||
@@ -33,14 +38,33 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
// it, but a plain int32 is more convenient in the internal type. These
|
||||
// functions are the same as the autogenerated ones in every other way.
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_v1_StatefulSetSpec_To_apps_StatefulSetSpec,
|
||||
Convert_apps_StatefulSetSpec_To_v1_StatefulSetSpec,
|
||||
Convert_v1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy,
|
||||
Convert_apps_StatefulSetUpdateStrategy_To_v1_StatefulSetUpdateStrategy,
|
||||
Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet,
|
||||
Convert_v1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet,
|
||||
Convert_v1_StatefulSetStatus_To_apps_StatefulSetStatus,
|
||||
Convert_apps_StatefulSetStatus_To_v1_StatefulSetStatus,
|
||||
Convert_v1_Deployment_To_extensions_Deployment,
|
||||
Convert_extensions_Deployment_To_v1_Deployment,
|
||||
Convert_extensions_DaemonSet_To_v1_DaemonSet,
|
||||
Convert_v1_DaemonSet_To_extensions_DaemonSet,
|
||||
Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec,
|
||||
Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec,
|
||||
Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy,
|
||||
Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy,
|
||||
// extensions
|
||||
// TODO: below conversions should be dropped in favor of auto-generated
|
||||
// ones, see https://github.com/kubernetes/kubernetes/issues/39865
|
||||
Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec,
|
||||
Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec,
|
||||
Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy,
|
||||
Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy,
|
||||
Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment,
|
||||
Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment,
|
||||
Convert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec,
|
||||
Convert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -48,6 +72,150 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(in *appsv1.DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error {
|
||||
if in.Replicas != nil {
|
||||
out.Replicas = *in.Replicas
|
||||
}
|
||||
out.Selector = in.Selector
|
||||
if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.RevisionHistoryLimit = in.RevisionHistoryLimit
|
||||
out.MinReadySeconds = in.MinReadySeconds
|
||||
out.Paused = in.Paused
|
||||
if in.ProgressDeadlineSeconds != nil {
|
||||
out.ProgressDeadlineSeconds = new(int32)
|
||||
*out.ProgressDeadlineSeconds = *in.ProgressDeadlineSeconds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec(in *extensions.DeploymentSpec, out *appsv1.DeploymentSpec, s conversion.Scope) error {
|
||||
out.Replicas = &in.Replicas
|
||||
out.Selector = in.Selector
|
||||
if err := k8s_api_v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
out.RevisionHistoryLimit = new(int32)
|
||||
*out.RevisionHistoryLimit = int32(*in.RevisionHistoryLimit)
|
||||
}
|
||||
out.MinReadySeconds = int32(in.MinReadySeconds)
|
||||
out.Paused = in.Paused
|
||||
if in.ProgressDeadlineSeconds != nil {
|
||||
out.ProgressDeadlineSeconds = new(int32)
|
||||
*out.ProgressDeadlineSeconds = *in.ProgressDeadlineSeconds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_DeploymentStrategy_To_v1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *appsv1.DeploymentStrategy, s conversion.Scope) error {
|
||||
out.Type = appsv1.DeploymentStrategyType(in.Type)
|
||||
if in.RollingUpdate != nil {
|
||||
out.RollingUpdate = new(appsv1.RollingUpdateDeployment)
|
||||
if err := Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.RollingUpdate = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *appsv1.DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error {
|
||||
out.Type = extensions.DeploymentStrategyType(in.Type)
|
||||
if in.RollingUpdate != nil {
|
||||
out.RollingUpdate = new(extensions.RollingUpdateDeployment)
|
||||
if err := Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.RollingUpdate = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *appsv1.RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error {
|
||||
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
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *appsv1.RollingUpdateDeployment, s conversion.Scope) error {
|
||||
if out.MaxUnavailable == nil {
|
||||
out.MaxUnavailable = &intstr.IntOrString{}
|
||||
}
|
||||
if err := s.Convert(&in.MaxUnavailable, out.MaxUnavailable, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if out.MaxSurge == nil {
|
||||
out.MaxSurge = &intstr.IntOrString{}
|
||||
}
|
||||
if err := s.Convert(&in.MaxSurge, out.MaxSurge, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_Deployment_To_extensions_Deployment(in *appsv1.Deployment, out *extensions.Deployment, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1_DeploymentSpec_To_extensions_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy annotation to deprecated rollbackTo field for roundtrip
|
||||
// TODO: remove this conversion after we delete extensions/v1beta1 and apps/v1beta1 Deployment
|
||||
if revision, _ := in.Annotations[appsv1.DeprecatedRollbackTo]; revision != "" {
|
||||
if revision64, err := strconv.ParseInt(revision, 10, 64); err != nil {
|
||||
return fmt.Errorf("failed to parse annotation[%s]=%s as int64: %v", appsv1.DeprecatedRollbackTo, revision, err)
|
||||
} else {
|
||||
out.Spec.RollbackTo = new(extensions.RollbackConfig)
|
||||
out.Spec.RollbackTo.Revision = revision64
|
||||
}
|
||||
delete(out.Annotations, appsv1.DeprecatedRollbackTo)
|
||||
} else {
|
||||
out.Spec.RollbackTo = nil
|
||||
}
|
||||
|
||||
if err := Convert_v1_DeploymentStatus_To_extensions_DeploymentStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_Deployment_To_v1_Deployment(in *extensions.Deployment, out *appsv1.Deployment, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_extensions_DeploymentSpec_To_v1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy deprecated rollbackTo field to annotation for roundtrip
|
||||
// TODO: remove this conversion after we delete extensions/v1beta1 and apps/v1beta1 Deployment
|
||||
if in.Spec.RollbackTo != nil {
|
||||
if out.Annotations == nil {
|
||||
out.Annotations = make(map[string]string)
|
||||
}
|
||||
out.Annotations[appsv1.DeprecatedRollbackTo] = strconv.FormatInt(in.Spec.RollbackTo.Revision, 10)
|
||||
} else {
|
||||
delete(out.Annotations, appsv1.DeprecatedRollbackTo)
|
||||
}
|
||||
|
||||
if err := Convert_extensions_DeploymentStatus_To_v1_DeploymentStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *appsv1.RollingUpdateDaemonSet, s conversion.Scope) error {
|
||||
if out.MaxUnavailable == nil {
|
||||
out.MaxUnavailable = &intstr.IntOrString{}
|
||||
@@ -156,3 +324,163 @@ func Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *extensions.ReplicaSetSpec, out *appsv1.ReplicaSetSpec, s conversion.Scope) error {
|
||||
out.Replicas = new(int32)
|
||||
*out.Replicas = int32(in.Replicas)
|
||||
out.MinReadySeconds = in.MinReadySeconds
|
||||
out.Selector = in.Selector
|
||||
if err := k8s_api_v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *appsv1.ReplicaSetSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error {
|
||||
if in.Replicas != nil {
|
||||
out.Replicas = *in.Replicas
|
||||
}
|
||||
out.MinReadySeconds = in.MinReadySeconds
|
||||
out.Selector = in.Selector
|
||||
if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_StatefulSetSpec_To_apps_StatefulSetSpec(in *appsv1.StatefulSetSpec, out *apps.StatefulSetSpec, s conversion.Scope) error {
|
||||
if in.Replicas != nil {
|
||||
out.Replicas = *in.Replicas
|
||||
}
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(metav1.LabelSelector)
|
||||
if err := s.Convert(*in, *out, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if err := k8s_api_v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.VolumeClaimTemplates != nil {
|
||||
in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates
|
||||
*out = make([]api.PersistentVolumeClaim, len(*in))
|
||||
for i := range *in {
|
||||
if err := s.Convert(&(*in)[i], &(*out)[i], 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.VolumeClaimTemplates = nil
|
||||
}
|
||||
if err := Convert_v1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
out.RevisionHistoryLimit = new(int32)
|
||||
*out.RevisionHistoryLimit = *in.RevisionHistoryLimit
|
||||
} else {
|
||||
out.RevisionHistoryLimit = nil
|
||||
}
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = apps.PodManagementPolicyType(in.PodManagementPolicy)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_apps_StatefulSetSpec_To_v1_StatefulSetSpec(in *apps.StatefulSetSpec, out *appsv1.StatefulSetSpec, s conversion.Scope) error {
|
||||
out.Replicas = new(int32)
|
||||
*out.Replicas = in.Replicas
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(metav1.LabelSelector)
|
||||
if err := s.Convert(*in, *out, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if err := k8s_api_v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.VolumeClaimTemplates != nil {
|
||||
in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates
|
||||
*out = make([]v1.PersistentVolumeClaim, len(*in))
|
||||
for i := range *in {
|
||||
if err := s.Convert(&(*in)[i], &(*out)[i], 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.VolumeClaimTemplates = nil
|
||||
}
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
out.RevisionHistoryLimit = new(int32)
|
||||
*out.RevisionHistoryLimit = *in.RevisionHistoryLimit
|
||||
} else {
|
||||
out.RevisionHistoryLimit = nil
|
||||
}
|
||||
out.ServiceName = in.ServiceName
|
||||
out.PodManagementPolicy = appsv1.PodManagementPolicyType(in.PodManagementPolicy)
|
||||
if err := Convert_apps_StatefulSetUpdateStrategy_To_v1_StatefulSetUpdateStrategy(&in.UpdateStrategy, &out.UpdateStrategy, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_StatefulSetUpdateStrategy_To_apps_StatefulSetUpdateStrategy(in *appsv1.StatefulSetUpdateStrategy, out *apps.StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = apps.StatefulSetUpdateStrategyType(in.Type)
|
||||
if in.RollingUpdate != nil {
|
||||
out.RollingUpdate = new(apps.RollingUpdateStatefulSetStrategy)
|
||||
out.RollingUpdate.Partition = *in.RollingUpdate.Partition
|
||||
} else {
|
||||
out.RollingUpdate = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_apps_StatefulSetUpdateStrategy_To_v1_StatefulSetUpdateStrategy(in *apps.StatefulSetUpdateStrategy, out *appsv1.StatefulSetUpdateStrategy, s conversion.Scope) error {
|
||||
out.Type = appsv1.StatefulSetUpdateStrategyType(in.Type)
|
||||
if in.RollingUpdate != nil {
|
||||
out.RollingUpdate = new(appsv1.RollingUpdateStatefulSetStrategy)
|
||||
out.RollingUpdate.Partition = new(int32)
|
||||
*out.RollingUpdate.Partition = in.RollingUpdate.Partition
|
||||
} else {
|
||||
out.RollingUpdate = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_StatefulSetStatus_To_apps_StatefulSetStatus(in *appsv1.StatefulSetStatus, out *apps.StatefulSetStatus, s conversion.Scope) error {
|
||||
out.ObservedGeneration = new(int64)
|
||||
*out.ObservedGeneration = in.ObservedGeneration
|
||||
out.Replicas = in.Replicas
|
||||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.CurrentReplicas = in.CurrentReplicas
|
||||
out.UpdatedReplicas = in.UpdatedReplicas
|
||||
out.CurrentRevision = in.CurrentRevision
|
||||
out.UpdateRevision = in.UpdateRevision
|
||||
if in.CollisionCount != nil {
|
||||
out.CollisionCount = new(int32)
|
||||
*out.CollisionCount = *in.CollisionCount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_apps_StatefulSetStatus_To_v1_StatefulSetStatus(in *apps.StatefulSetStatus, out *appsv1.StatefulSetStatus, s conversion.Scope) error {
|
||||
if in.ObservedGeneration != nil {
|
||||
out.ObservedGeneration = *in.ObservedGeneration
|
||||
}
|
||||
out.Replicas = in.Replicas
|
||||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.CurrentReplicas = in.CurrentReplicas
|
||||
out.UpdatedReplicas = in.UpdatedReplicas
|
||||
out.CurrentRevision = in.CurrentRevision
|
||||
out.UpdateRevision = in.UpdateRevision
|
||||
if in.CollisionCount != nil {
|
||||
out.CollisionCount = new(int32)
|
||||
*out.CollisionCount = *in.CollisionCount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,13 +20,211 @@ import (
|
||||
"testing"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
)
|
||||
|
||||
func TestV12StatefulSetSpecConversion(t *testing.T) {
|
||||
replicas := newInt32(2)
|
||||
selector := &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}
|
||||
appsv1Template := v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Spec: v1.PodSpec{
|
||||
RestartPolicy: v1.RestartPolicy("bar"),
|
||||
SecurityContext: new(v1.PodSecurityContext),
|
||||
},
|
||||
}
|
||||
apiTemplate := api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicy("bar"),
|
||||
SecurityContext: new(api.PodSecurityContext),
|
||||
},
|
||||
}
|
||||
testcases := map[string]struct {
|
||||
stsSpec1 *apps.StatefulSetSpec
|
||||
stsSepc2 *appsv1.StatefulSetSpec
|
||||
}{
|
||||
"StatefulSetSpec Conversion 1": {
|
||||
stsSpec1: &apps.StatefulSetSpec{
|
||||
Replicas: *replicas,
|
||||
Template: apiTemplate,
|
||||
},
|
||||
stsSepc2: &appsv1.StatefulSetSpec{
|
||||
Replicas: replicas,
|
||||
Template: appsv1Template,
|
||||
},
|
||||
},
|
||||
"StatefulSetSpec Conversion 2": {
|
||||
stsSpec1: &apps.StatefulSetSpec{
|
||||
Replicas: *replicas,
|
||||
Selector: selector,
|
||||
Template: apiTemplate,
|
||||
ServiceName: "foo",
|
||||
PodManagementPolicy: apps.PodManagementPolicyType("bar"),
|
||||
},
|
||||
stsSepc2: &appsv1.StatefulSetSpec{
|
||||
Replicas: replicas,
|
||||
Selector: selector,
|
||||
Template: appsv1Template,
|
||||
ServiceName: "foo",
|
||||
PodManagementPolicy: appsv1.PodManagementPolicyType("bar"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
// apps -> appsv1
|
||||
internal1 := &appsv1.StatefulSetSpec{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.stsSpec1, internal1, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "from extensions to appsv1", err)
|
||||
}
|
||||
|
||||
if !apiequality.Semantic.DeepEqual(internal1, tc.stsSepc2) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from extensions to appsv1", tc.stsSepc2, internal1)
|
||||
}
|
||||
|
||||
// appsv1 -> apps
|
||||
internal2 := &apps.StatefulSetSpec{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.stsSepc2, internal2, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "from appsv1 to extensions", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal2, tc.stsSpec1) {
|
||||
t.Errorf("%q- %q: expected\n\t%#v, got \n\t%#v", k, "from appsv1 to extensions", tc.stsSpec1, internal2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestV1StatefulSetStatusConversion(t *testing.T) {
|
||||
observedGeneration := new(int64)
|
||||
*observedGeneration = 2
|
||||
collisionCount := new(int32)
|
||||
*collisionCount = 1
|
||||
testcases := map[string]struct {
|
||||
stsStatus1 *apps.StatefulSetStatus
|
||||
stsStatus2 *appsv1.StatefulSetStatus
|
||||
}{
|
||||
"StatefulSetStatus Conversion 1": {
|
||||
stsStatus1: &apps.StatefulSetStatus{
|
||||
Replicas: int32(3),
|
||||
ReadyReplicas: int32(1),
|
||||
CurrentReplicas: int32(3),
|
||||
UpdatedReplicas: int32(3),
|
||||
CurrentRevision: "12345",
|
||||
UpdateRevision: "23456",
|
||||
ObservedGeneration: observedGeneration,
|
||||
},
|
||||
stsStatus2: &appsv1.StatefulSetStatus{
|
||||
Replicas: int32(3),
|
||||
ReadyReplicas: int32(1),
|
||||
CurrentReplicas: int32(3),
|
||||
UpdatedReplicas: int32(3),
|
||||
CurrentRevision: "12345",
|
||||
UpdateRevision: "23456",
|
||||
ObservedGeneration: *observedGeneration,
|
||||
},
|
||||
},
|
||||
"StatefulSetStatus Conversion 2": {
|
||||
stsStatus1: &apps.StatefulSetStatus{
|
||||
ObservedGeneration: observedGeneration,
|
||||
Replicas: int32(3),
|
||||
ReadyReplicas: int32(1),
|
||||
CurrentReplicas: int32(3),
|
||||
UpdatedReplicas: int32(3),
|
||||
CurrentRevision: "12345",
|
||||
UpdateRevision: "23456",
|
||||
CollisionCount: collisionCount,
|
||||
},
|
||||
stsStatus2: &appsv1.StatefulSetStatus{
|
||||
ObservedGeneration: *observedGeneration,
|
||||
Replicas: int32(3),
|
||||
ReadyReplicas: int32(1),
|
||||
CurrentReplicas: int32(3),
|
||||
UpdatedReplicas: int32(3),
|
||||
CurrentRevision: "12345",
|
||||
UpdateRevision: "23456",
|
||||
CollisionCount: collisionCount,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
// apps -> appsv1
|
||||
internal1 := &appsv1.StatefulSetStatus{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.stsStatus1, internal1, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "from apps to appsv1", err)
|
||||
}
|
||||
|
||||
if !apiequality.Semantic.DeepEqual(internal1, tc.stsStatus2) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from apps to appsv1", tc.stsStatus2, internal1)
|
||||
}
|
||||
|
||||
// appsv1 -> apps
|
||||
internal2 := &apps.StatefulSetStatus{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.stsStatus2, internal2, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "from appsv1 to apps", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal2, tc.stsStatus1) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from appsv1 to apps", tc.stsStatus1, internal2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestV1StatefulSetUpdateStrategyConversion(t *testing.T) {
|
||||
partition := newInt32(2)
|
||||
appsv1rollingUpdate := new(appsv1.RollingUpdateStatefulSetStrategy)
|
||||
appsv1rollingUpdate.Partition = partition
|
||||
appsrollingUpdate := new(apps.RollingUpdateStatefulSetStrategy)
|
||||
appsrollingUpdate.Partition = *partition
|
||||
testcases := map[string]struct {
|
||||
stsUpdateStrategy1 *apps.StatefulSetUpdateStrategy
|
||||
stsUpdateStrategy2 *appsv1.StatefulSetUpdateStrategy
|
||||
}{
|
||||
"StatefulSetUpdateStrategy Conversion 1": {
|
||||
stsUpdateStrategy1: &apps.StatefulSetUpdateStrategy{Type: apps.StatefulSetUpdateStrategyType("foo")},
|
||||
stsUpdateStrategy2: &appsv1.StatefulSetUpdateStrategy{Type: appsv1.StatefulSetUpdateStrategyType("foo")},
|
||||
},
|
||||
"StatefulSetUpdateStrategy Conversion 2": {
|
||||
stsUpdateStrategy1: &apps.StatefulSetUpdateStrategy{
|
||||
Type: apps.StatefulSetUpdateStrategyType("foo"),
|
||||
RollingUpdate: appsrollingUpdate,
|
||||
},
|
||||
stsUpdateStrategy2: &appsv1.StatefulSetUpdateStrategy{
|
||||
Type: appsv1.StatefulSetUpdateStrategyType("foo"),
|
||||
RollingUpdate: appsv1rollingUpdate,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
// apps -> appsv1
|
||||
internal1 := &appsv1.StatefulSetUpdateStrategy{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.stsUpdateStrategy1, internal1, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", "apps -> appsv1", k, err)
|
||||
}
|
||||
|
||||
if !apiequality.Semantic.DeepEqual(internal1, tc.stsUpdateStrategy2) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", "apps -> appsv1", k, tc.stsUpdateStrategy2, internal1)
|
||||
}
|
||||
|
||||
// appsv1 -> apps
|
||||
internal2 := &apps.StatefulSetUpdateStrategy{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.stsUpdateStrategy2, internal2, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", "appsv1 -> apps", k, err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal2, tc.stsUpdateStrategy1) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", "appsv1 -> apps", k, tc.stsUpdateStrategy1, internal2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestV1RollingUpdateDaemonSetConversion(t *testing.T) {
|
||||
intorstr := intstr.FromInt(1)
|
||||
testcases := map[string]struct {
|
||||
@@ -59,3 +257,344 @@ func TestV1RollingUpdateDaemonSetConversion(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestV1DeploymentConversion(t *testing.T) {
|
||||
replica := newInt32(2)
|
||||
rollbackTo := new(extensions.RollbackConfig)
|
||||
rollbackTo.Revision = int64(2)
|
||||
testcases := map[string]struct {
|
||||
deployment1 *extensions.Deployment
|
||||
deployment2 *appsv1.Deployment
|
||||
}{
|
||||
"Deployment Conversion 1": {
|
||||
deployment1: &extensions.Deployment{
|
||||
Spec: extensions.DeploymentSpec{
|
||||
Replicas: *replica,
|
||||
RollbackTo: rollbackTo,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
SecurityContext: new(api.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
deployment2: &appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{appsv1.DeprecatedRollbackTo: "2"},
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: replica,
|
||||
Template: v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: new(v1.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"Deployment Conversion 2": {
|
||||
deployment1: &extensions.Deployment{
|
||||
Spec: extensions.DeploymentSpec{
|
||||
Replicas: *replica,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
SecurityContext: new(api.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
deployment2: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: replica,
|
||||
Template: v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: new(v1.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
// extensions -> v1beta2
|
||||
internal1 := &appsv1.Deployment{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.deployment1, internal1, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "from extensions to v1beta2", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal1, tc.deployment2) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from extensions to v1beta2", tc.deployment2, internal1)
|
||||
}
|
||||
|
||||
// v1beta2 -> extensions
|
||||
internal2 := &extensions.Deployment{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.deployment2, internal2, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "from v1beta2 to extensions", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal2, tc.deployment1) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from v1beta2 to extensions", tc.deployment1, internal2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestV1DeploymentSpecConversion(t *testing.T) {
|
||||
replica := newInt32(2)
|
||||
revisionHistoryLimit := newInt32(2)
|
||||
progressDeadlineSeconds := newInt32(2)
|
||||
|
||||
testcases := map[string]struct {
|
||||
deploymentSpec1 *extensions.DeploymentSpec
|
||||
deploymentSpec2 *appsv1.DeploymentSpec
|
||||
}{
|
||||
"DeploymentSpec Conversion 1": {
|
||||
deploymentSpec1: &extensions.DeploymentSpec{
|
||||
Replicas: *replica,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
SecurityContext: new(api.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
deploymentSpec2: &appsv1.DeploymentSpec{
|
||||
Replicas: replica,
|
||||
Template: v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: new(v1.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"DeploymentSpec Conversion 2": {
|
||||
deploymentSpec1: &extensions.DeploymentSpec{
|
||||
Replicas: *replica,
|
||||
RevisionHistoryLimit: revisionHistoryLimit,
|
||||
MinReadySeconds: 2,
|
||||
Paused: true,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
SecurityContext: new(api.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
deploymentSpec2: &appsv1.DeploymentSpec{
|
||||
Replicas: replica,
|
||||
RevisionHistoryLimit: revisionHistoryLimit,
|
||||
MinReadySeconds: 2,
|
||||
Paused: true,
|
||||
Template: v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: new(v1.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"DeploymentSpec Conversion 3": {
|
||||
deploymentSpec1: &extensions.DeploymentSpec{
|
||||
Replicas: *replica,
|
||||
ProgressDeadlineSeconds: progressDeadlineSeconds,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
SecurityContext: new(api.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
deploymentSpec2: &appsv1.DeploymentSpec{
|
||||
Replicas: replica,
|
||||
ProgressDeadlineSeconds: progressDeadlineSeconds,
|
||||
Template: v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: new(v1.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// extensions -> appsv1
|
||||
for k, tc := range testcases {
|
||||
internal := &appsv1.DeploymentSpec{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.deploymentSpec1, internal, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", "extensions -> appsv1", k, err)
|
||||
}
|
||||
|
||||
if !apiequality.Semantic.DeepEqual(internal, tc.deploymentSpec2) {
|
||||
t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", "extensions -> appsv1", k, tc.deploymentSpec2, internal)
|
||||
}
|
||||
}
|
||||
|
||||
// appsv1 -> extensions
|
||||
for k, tc := range testcases {
|
||||
internal := &extensions.DeploymentSpec{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.deploymentSpec2, internal, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", "appsv1 -> extensions", k, err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal, tc.deploymentSpec1) {
|
||||
t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", "appsv1 -> extensions", k, tc.deploymentSpec1, internal)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestV1DeploymentStrategyConversion(t *testing.T) {
|
||||
maxUnavailable := intstr.FromInt(2)
|
||||
maxSurge := intstr.FromInt(2)
|
||||
extensionsRollingUpdate := extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge}
|
||||
appsv1RollingUpdate := appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &maxSurge}
|
||||
testcases := map[string]struct {
|
||||
deploymentStrategy1 *extensions.DeploymentStrategy
|
||||
deploymentStrategy2 *appsv1.DeploymentStrategy
|
||||
}{
|
||||
"DeploymentStrategy Conversion 1": {
|
||||
deploymentStrategy1: &extensions.DeploymentStrategy{Type: extensions.DeploymentStrategyType("foo")},
|
||||
deploymentStrategy2: &appsv1.DeploymentStrategy{Type: appsv1.DeploymentStrategyType("foo")},
|
||||
},
|
||||
"DeploymentStrategy Conversion 2": {
|
||||
deploymentStrategy1: &extensions.DeploymentStrategy{Type: extensions.DeploymentStrategyType("foo"), RollingUpdate: &extensionsRollingUpdate},
|
||||
deploymentStrategy2: &appsv1.DeploymentStrategy{Type: appsv1.DeploymentStrategyType("foo"), RollingUpdate: &appsv1RollingUpdate},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
// extensions -> appsv1
|
||||
internal1 := &appsv1.DeploymentStrategy{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.deploymentStrategy1, internal1, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "extensions -> appsv1", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal1, tc.deploymentStrategy2) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "extensions -> appsv1", tc.deploymentStrategy2, internal1)
|
||||
}
|
||||
|
||||
// appsv1 -> extensions
|
||||
internal2 := &extensions.DeploymentStrategy{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.deploymentStrategy2, internal2, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> extensions", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal2, tc.deploymentStrategy1) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "appsv1 -> extensions", tc.deploymentStrategy1, internal2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestV1RollingUpdateDeploymentConversion(t *testing.T) {
|
||||
nilIntStr := intstr.IntOrString{}
|
||||
maxUnavailable := intstr.FromInt(2)
|
||||
maxSurge := intstr.FromInt(2)
|
||||
testcases := map[string]struct {
|
||||
rollingUpdateDeployment1 *extensions.RollingUpdateDeployment
|
||||
rollingUpdateDeployment2 *appsv1.RollingUpdateDeployment
|
||||
}{
|
||||
"RollingUpdateDeployment Conversion 1": {
|
||||
rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{},
|
||||
rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &nilIntStr, MaxSurge: &nilIntStr},
|
||||
},
|
||||
"RollingUpdateDeployment Conversion 2": {
|
||||
rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable},
|
||||
rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &nilIntStr},
|
||||
},
|
||||
"RollingUpdateDeployment Conversion 3": {
|
||||
rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxSurge: maxSurge},
|
||||
rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxSurge: &maxSurge, MaxUnavailable: &nilIntStr},
|
||||
},
|
||||
"RollingUpdateDeployment Conversion 4": {
|
||||
rollingUpdateDeployment1: &extensions.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge},
|
||||
rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &maxSurge},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
// extensions -> appsv1
|
||||
internal1 := &appsv1.RollingUpdateDeployment{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDeployment1, internal1, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "extensions -> appsv1", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal1, tc.rollingUpdateDeployment2) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "extensions -> appsv1", tc.rollingUpdateDeployment2, internal1)
|
||||
}
|
||||
|
||||
// appsv1 -> extensions
|
||||
internal2 := &extensions.RollingUpdateDeployment{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDeployment2, internal2, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> extensions", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal2, tc.rollingUpdateDeployment1) {
|
||||
t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "appsv1 -> extensions", tc.rollingUpdateDeployment1, internal2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestV1ReplicaSetSpecConversion(t *testing.T) {
|
||||
replicas := new(int32)
|
||||
*replicas = 2
|
||||
matchExpressions := []metav1.LabelSelectorRequirement{
|
||||
{Key: "foo", Operator: metav1.LabelSelectorOpIn, Values: []string{"foo"}},
|
||||
}
|
||||
matchLabels := map[string]string{"foo": "bar"}
|
||||
selector := &metav1.LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions}
|
||||
|
||||
testcases := map[string]struct {
|
||||
replicaset1 *extensions.ReplicaSetSpec
|
||||
replicaset2 *appsv1.ReplicaSetSpec
|
||||
}{
|
||||
"ReplicaSetSpec Conversion 1": {
|
||||
replicaset1: &extensions.ReplicaSetSpec{
|
||||
Replicas: *replicas,
|
||||
MinReadySeconds: 2,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
SecurityContext: new(api.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
replicaset2: &appsv1.ReplicaSetSpec{
|
||||
Replicas: replicas,
|
||||
MinReadySeconds: 2,
|
||||
Template: v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: new(v1.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"ReplicaSetSpec Conversion 2": {
|
||||
replicaset1: &extensions.ReplicaSetSpec{
|
||||
Replicas: *replicas,
|
||||
Selector: selector,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
SecurityContext: new(api.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
replicaset2: &appsv1.ReplicaSetSpec{
|
||||
Replicas: replicas,
|
||||
Selector: selector,
|
||||
Template: v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: new(v1.PodSecurityContext),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
// extensions -> appsv1
|
||||
internal1 := &appsv1.ReplicaSetSpec{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.replicaset1, internal1, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "extensions -> appsv1", err)
|
||||
}
|
||||
|
||||
if !apiequality.Semantic.DeepEqual(internal1, tc.replicaset2) {
|
||||
t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "extensions -> appsv1", tc.replicaset2, internal1)
|
||||
}
|
||||
|
||||
// appsv1 -> extensions
|
||||
internal2 := &extensions.ReplicaSetSpec{}
|
||||
if err := legacyscheme.Scheme.Convert(tc.replicaset2, internal2, nil); err != nil {
|
||||
t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> extensions", err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(internal2, tc.replicaset1) {
|
||||
t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "appsv1 -> extensions", tc.replicaset1, internal2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,49 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
// SetDefaults_Deployment sets additional defaults compared to its counterpart
|
||||
// in extensions. These addons are:
|
||||
// - MaxUnavailable during rolling update set to 25% (1 in extensions)
|
||||
// - MaxSurge value during rolling update set to 25% (1 in extensions)
|
||||
// - RevisionHistoryLimit set to 10 (not set in extensions)
|
||||
// - ProgressDeadlineSeconds set to 600s (not set in extensions)
|
||||
func SetDefaults_Deployment(obj *appsv1.Deployment) {
|
||||
// Set DeploymentSpec.Replicas to 1 if it is not set.
|
||||
if obj.Spec.Replicas == nil {
|
||||
obj.Spec.Replicas = new(int32)
|
||||
*obj.Spec.Replicas = 1
|
||||
}
|
||||
strategy := &obj.Spec.Strategy
|
||||
// Set default DeploymentStrategyType as RollingUpdate.
|
||||
if strategy.Type == "" {
|
||||
strategy.Type = appsv1.RollingUpdateDeploymentStrategyType
|
||||
}
|
||||
if strategy.Type == appsv1.RollingUpdateDeploymentStrategyType {
|
||||
if strategy.RollingUpdate == nil {
|
||||
rollingUpdate := appsv1.RollingUpdateDeployment{}
|
||||
strategy.RollingUpdate = &rollingUpdate
|
||||
}
|
||||
if strategy.RollingUpdate.MaxUnavailable == nil {
|
||||
// Set default MaxUnavailable as 25% by default.
|
||||
maxUnavailable := intstr.FromString("25%")
|
||||
strategy.RollingUpdate.MaxUnavailable = &maxUnavailable
|
||||
}
|
||||
if strategy.RollingUpdate.MaxSurge == nil {
|
||||
// Set default MaxSurge as 25% by default.
|
||||
maxSurge := intstr.FromString("25%")
|
||||
strategy.RollingUpdate.MaxSurge = &maxSurge
|
||||
}
|
||||
}
|
||||
if obj.Spec.RevisionHistoryLimit == nil {
|
||||
obj.Spec.RevisionHistoryLimit = new(int32)
|
||||
*obj.Spec.RevisionHistoryLimit = 10
|
||||
}
|
||||
if obj.Spec.ProgressDeadlineSeconds == nil {
|
||||
obj.Spec.ProgressDeadlineSeconds = new(int32)
|
||||
*obj.Spec.ProgressDeadlineSeconds = 600
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_DaemonSet(obj *appsv1.DaemonSet) {
|
||||
updateStrategy := &obj.Spec.UpdateStrategy
|
||||
if updateStrategy.Type == "" {
|
||||
@@ -47,3 +90,38 @@ func SetDefaults_DaemonSet(obj *appsv1.DaemonSet) {
|
||||
*obj.Spec.RevisionHistoryLimit = 10
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_StatefulSet(obj *appsv1.StatefulSet) {
|
||||
if len(obj.Spec.PodManagementPolicy) == 0 {
|
||||
obj.Spec.PodManagementPolicy = appsv1.OrderedReadyPodManagement
|
||||
}
|
||||
|
||||
if obj.Spec.UpdateStrategy.Type == "" {
|
||||
obj.Spec.UpdateStrategy.Type = appsv1.RollingUpdateStatefulSetStrategyType
|
||||
|
||||
// UpdateStrategy.RollingUpdate will take default values below.
|
||||
obj.Spec.UpdateStrategy.RollingUpdate = &appsv1.RollingUpdateStatefulSetStrategy{}
|
||||
}
|
||||
|
||||
if obj.Spec.UpdateStrategy.Type == appsv1.RollingUpdateStatefulSetStrategyType &&
|
||||
obj.Spec.UpdateStrategy.RollingUpdate != nil &&
|
||||
obj.Spec.UpdateStrategy.RollingUpdate.Partition == nil {
|
||||
obj.Spec.UpdateStrategy.RollingUpdate.Partition = new(int32)
|
||||
*obj.Spec.UpdateStrategy.RollingUpdate.Partition = 0
|
||||
}
|
||||
|
||||
if obj.Spec.Replicas == nil {
|
||||
obj.Spec.Replicas = new(int32)
|
||||
*obj.Spec.Replicas = 1
|
||||
}
|
||||
if obj.Spec.RevisionHistoryLimit == nil {
|
||||
obj.Spec.RevisionHistoryLimit = new(int32)
|
||||
*obj.Spec.RevisionHistoryLimit = 10
|
||||
}
|
||||
}
|
||||
func SetDefaults_ReplicaSet(obj *appsv1.ReplicaSet) {
|
||||
if obj.Spec.Replicas == nil {
|
||||
obj.Spec.Replicas = new(int32)
|
||||
*obj.Spec.Replicas = 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
@@ -167,6 +168,382 @@ func TestSetDefaultDaemonSetSpec(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultStatefulSet(t *testing.T) {
|
||||
defaultLabels := map[string]string{"foo": "bar"}
|
||||
var defaultPartition int32 = 0
|
||||
var defaultReplicas int32 = 1
|
||||
|
||||
period := int64(v1.DefaultTerminationGracePeriodSeconds)
|
||||
defaultTemplate := v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
DNSPolicy: v1.DNSClusterFirst,
|
||||
RestartPolicy: v1.RestartPolicyAlways,
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
TerminationGracePeriodSeconds: &period,
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: defaultLabels,
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
original *appsv1.StatefulSet
|
||||
expected *appsv1.StatefulSet
|
||||
}{
|
||||
{ // labels and default update strategy
|
||||
original: &appsv1.StatefulSet{
|
||||
Spec: appsv1.StatefulSetSpec{
|
||||
Template: defaultTemplate,
|
||||
},
|
||||
},
|
||||
expected: &appsv1.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: defaultLabels,
|
||||
},
|
||||
Spec: appsv1.StatefulSetSpec{
|
||||
Replicas: &defaultReplicas,
|
||||
Template: defaultTemplate,
|
||||
PodManagementPolicy: appsv1.OrderedReadyPodManagement,
|
||||
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
|
||||
Type: appsv1.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: &appsv1.RollingUpdateStatefulSetStrategy{
|
||||
Partition: &defaultPartition,
|
||||
},
|
||||
},
|
||||
RevisionHistoryLimit: newInt32(10),
|
||||
},
|
||||
},
|
||||
},
|
||||
{ // Alternate update strategy
|
||||
original: &appsv1.StatefulSet{
|
||||
Spec: appsv1.StatefulSetSpec{
|
||||
Template: defaultTemplate,
|
||||
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
|
||||
Type: appsv1.OnDeleteStatefulSetStrategyType,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &appsv1.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: defaultLabels,
|
||||
},
|
||||
Spec: appsv1.StatefulSetSpec{
|
||||
Replicas: &defaultReplicas,
|
||||
Template: defaultTemplate,
|
||||
PodManagementPolicy: appsv1.OrderedReadyPodManagement,
|
||||
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
|
||||
Type: appsv1.OnDeleteStatefulSetStrategyType,
|
||||
},
|
||||
RevisionHistoryLimit: newInt32(10),
|
||||
},
|
||||
},
|
||||
},
|
||||
{ // Parallel pod management policy.
|
||||
original: &appsv1.StatefulSet{
|
||||
Spec: appsv1.StatefulSetSpec{
|
||||
Template: defaultTemplate,
|
||||
PodManagementPolicy: appsv1.ParallelPodManagement,
|
||||
},
|
||||
},
|
||||
expected: &appsv1.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: defaultLabels,
|
||||
},
|
||||
Spec: appsv1.StatefulSetSpec{
|
||||
Replicas: &defaultReplicas,
|
||||
Template: defaultTemplate,
|
||||
PodManagementPolicy: appsv1.ParallelPodManagement,
|
||||
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
|
||||
Type: appsv1.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: &appsv1.RollingUpdateStatefulSetStrategy{
|
||||
Partition: &defaultPartition,
|
||||
},
|
||||
},
|
||||
RevisionHistoryLimit: newInt32(10),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
original := test.original
|
||||
expected := test.expected
|
||||
obj2 := roundTrip(t, runtime.Object(original))
|
||||
got, ok := obj2.(*appsv1.StatefulSet)
|
||||
if !ok {
|
||||
t.Errorf("(%d) unexpected object: %v", i, got)
|
||||
t.FailNow()
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(got.Spec, expected.Spec) {
|
||||
t.Errorf("(%d) got different than expected\ngot:\n\t%+v\nexpected:\n\t%+v", i, got.Spec, expected.Spec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultDeployment(t *testing.T) {
|
||||
defaultIntOrString := intstr.FromString("25%")
|
||||
differentIntOrString := intstr.FromInt(5)
|
||||
period := int64(v1.DefaultTerminationGracePeriodSeconds)
|
||||
defaultTemplate := v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
DNSPolicy: v1.DNSClusterFirst,
|
||||
RestartPolicy: v1.RestartPolicyAlways,
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
TerminationGracePeriodSeconds: &period,
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
original *appsv1.Deployment
|
||||
expected *appsv1.Deployment
|
||||
}{
|
||||
{
|
||||
original: &appsv1.Deployment{},
|
||||
expected: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(1),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||
RollingUpdate: &appsv1.RollingUpdateDeployment{
|
||||
MaxSurge: &defaultIntOrString,
|
||||
MaxUnavailable: &defaultIntOrString,
|
||||
},
|
||||
},
|
||||
RevisionHistoryLimit: newInt32(10),
|
||||
ProgressDeadlineSeconds: newInt32(600),
|
||||
Template: defaultTemplate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
original: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(5),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
RollingUpdate: &appsv1.RollingUpdateDeployment{
|
||||
MaxSurge: &differentIntOrString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(5),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||
RollingUpdate: &appsv1.RollingUpdateDeployment{
|
||||
MaxSurge: &differentIntOrString,
|
||||
MaxUnavailable: &defaultIntOrString,
|
||||
},
|
||||
},
|
||||
RevisionHistoryLimit: newInt32(10),
|
||||
ProgressDeadlineSeconds: newInt32(600),
|
||||
Template: defaultTemplate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
original: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(3),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||
RollingUpdate: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(3),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||
RollingUpdate: &appsv1.RollingUpdateDeployment{
|
||||
MaxSurge: &defaultIntOrString,
|
||||
MaxUnavailable: &defaultIntOrString,
|
||||
},
|
||||
},
|
||||
RevisionHistoryLimit: newInt32(10),
|
||||
ProgressDeadlineSeconds: newInt32(600),
|
||||
Template: defaultTemplate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
original: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(5),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RecreateDeploymentStrategyType,
|
||||
},
|
||||
RevisionHistoryLimit: newInt32(0),
|
||||
},
|
||||
},
|
||||
expected: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(5),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RecreateDeploymentStrategyType,
|
||||
},
|
||||
RevisionHistoryLimit: newInt32(0),
|
||||
ProgressDeadlineSeconds: newInt32(600),
|
||||
Template: defaultTemplate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
original: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(5),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RecreateDeploymentStrategyType,
|
||||
},
|
||||
ProgressDeadlineSeconds: newInt32(30),
|
||||
RevisionHistoryLimit: newInt32(2),
|
||||
},
|
||||
},
|
||||
expected: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: newInt32(5),
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RecreateDeploymentStrategyType,
|
||||
},
|
||||
ProgressDeadlineSeconds: newInt32(30),
|
||||
RevisionHistoryLimit: newInt32(2),
|
||||
Template: defaultTemplate,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
original := test.original
|
||||
expected := test.expected
|
||||
obj2 := roundTrip(t, runtime.Object(original))
|
||||
got, ok := obj2.(*appsv1.Deployment)
|
||||
if !ok {
|
||||
t.Errorf("unexpected object: %v", got)
|
||||
t.FailNow()
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(got.Spec, expected.Spec) {
|
||||
t.Errorf("object mismatch!\nexpected:\n\t%+v\ngot:\n\t%+v", got.Spec, expected.Spec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultDeploymentAvailability(t *testing.T) {
|
||||
d := roundTrip(t, runtime.Object(&appsv1.Deployment{})).(*appsv1.Deployment)
|
||||
|
||||
maxUnavailable, err := intstr.GetValueFromIntOrPercent(d.Spec.Strategy.RollingUpdate.MaxUnavailable, int(*(d.Spec.Replicas)), false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if *(d.Spec.Replicas)-int32(maxUnavailable) <= 0 {
|
||||
t.Fatalf("the default value of maxUnavailable can lead to no active replicas during rolling update")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultReplicaSetReplicas(t *testing.T) {
|
||||
tests := []struct {
|
||||
rs appsv1.ReplicaSet
|
||||
expectReplicas int32
|
||||
}{
|
||||
{
|
||||
rs: appsv1.ReplicaSet{
|
||||
Spec: appsv1.ReplicaSetSpec{
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectReplicas: 1,
|
||||
},
|
||||
{
|
||||
rs: appsv1.ReplicaSet{
|
||||
Spec: appsv1.ReplicaSetSpec{
|
||||
Replicas: newInt32(0),
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectReplicas: 0,
|
||||
},
|
||||
{
|
||||
rs: appsv1.ReplicaSet{
|
||||
Spec: appsv1.ReplicaSetSpec{
|
||||
Replicas: newInt32(3),
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectReplicas: 3,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
rs := &test.rs
|
||||
obj2 := roundTrip(t, runtime.Object(rs))
|
||||
rs2, ok := obj2.(*appsv1.ReplicaSet)
|
||||
if !ok {
|
||||
t.Errorf("unexpected object: %v", rs2)
|
||||
t.FailNow()
|
||||
}
|
||||
if rs2.Spec.Replicas == nil {
|
||||
t.Errorf("unexpected nil Replicas")
|
||||
} else if test.expectReplicas != *rs2.Spec.Replicas {
|
||||
t.Errorf("expected: %d replicas, got: %d", test.expectReplicas, *rs2.Spec.Replicas)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultRequestIsNotSetForReplicaSet(t *testing.T) {
|
||||
s := v1.PodSpec{}
|
||||
s.Containers = []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("100m"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
rs := &appsv1.ReplicaSet{
|
||||
Spec: appsv1.ReplicaSetSpec{
|
||||
Replicas: newInt32(3),
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Spec: s,
|
||||
},
|
||||
},
|
||||
}
|
||||
output := roundTrip(t, runtime.Object(rs))
|
||||
rs2 := output.(*appsv1.ReplicaSet)
|
||||
defaultRequest := rs2.Spec.Template.Spec.Containers[0].Resources.Requests
|
||||
requestValue := defaultRequest[v1.ResourceCPU]
|
||||
if requestValue.String() != "0" {
|
||||
t.Errorf("Expected 0 request value, got: %s", requestValue.String())
|
||||
}
|
||||
}
|
||||
|
||||
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
|
||||
data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(SchemeGroupVersion), obj)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user