mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 11:13:48 +00:00
Promotes the StatefulSet, ControllerRevision, Deployment, and ReplicaSet kinds to the apps/v1 group version.
This commit is contained in:
parent
dc35709eee
commit
26bf978c07
@ -203,7 +203,7 @@ var apiVersionPriorities = map[schema.GroupVersion]priority{
|
|||||||
{Group: "extensions", Version: "v1beta1"}: {group: 17900, version: 1},
|
{Group: "extensions", Version: "v1beta1"}: {group: 17900, version: 1},
|
||||||
// to my knowledge, nothing below here collides
|
// to my knowledge, nothing below here collides
|
||||||
{Group: "apps", Version: "v1beta1"}: {group: 17800, version: 1},
|
{Group: "apps", Version: "v1beta1"}: {group: 17800, version: 1},
|
||||||
{Group: "apps", Version: "v1beta2"}: {group: 17800, version: 1},
|
{Group: "apps", Version: "v1beta2"}: {group: 17800, version: 9},
|
||||||
{Group: "apps", Version: "v1"}: {group: 17800, version: 15},
|
{Group: "apps", Version: "v1"}: {group: 17800, version: 15},
|
||||||
{Group: "authentication.k8s.io", Version: "v1"}: {group: 17700, version: 15},
|
{Group: "authentication.k8s.io", Version: "v1"}: {group: 17700, version: 15},
|
||||||
{Group: "authentication.k8s.io", Version: "v1beta1"}: {group: 17700, version: 9},
|
{Group: "authentication.k8s.io", Version: "v1beta1"}: {group: 17700, version: 9},
|
||||||
|
@ -74,6 +74,8 @@ func TestDefaulting(t *testing.T) {
|
|||||||
{Group: "apps", Version: "v1beta1", Kind: "StatefulSetList"}: {},
|
{Group: "apps", Version: "v1beta1", Kind: "StatefulSetList"}: {},
|
||||||
{Group: "apps", Version: "v1beta2", Kind: "StatefulSet"}: {},
|
{Group: "apps", Version: "v1beta2", Kind: "StatefulSet"}: {},
|
||||||
{Group: "apps", Version: "v1beta2", Kind: "StatefulSetList"}: {},
|
{Group: "apps", Version: "v1beta2", Kind: "StatefulSetList"}: {},
|
||||||
|
{Group: "apps", Version: "v1", Kind: "StatefulSet"}: {},
|
||||||
|
{Group: "apps", Version: "v1", Kind: "StatefulSetList"}: {},
|
||||||
{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscaler"}: {},
|
{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscaler"}: {},
|
||||||
{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscalerList"}: {},
|
{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscalerList"}: {},
|
||||||
{Group: "autoscaling", Version: "v2beta1", Kind: "HorizontalPodAutoscaler"}: {},
|
{Group: "autoscaling", Version: "v2beta1", Kind: "HorizontalPodAutoscaler"}: {},
|
||||||
@ -107,10 +109,14 @@ func TestDefaulting(t *testing.T) {
|
|||||||
{Group: "apps", Version: "v1beta1", Kind: "DeploymentList"}: {},
|
{Group: "apps", Version: "v1beta1", Kind: "DeploymentList"}: {},
|
||||||
{Group: "apps", Version: "v1beta2", Kind: "Deployment"}: {},
|
{Group: "apps", Version: "v1beta2", Kind: "Deployment"}: {},
|
||||||
{Group: "apps", Version: "v1beta2", Kind: "DeploymentList"}: {},
|
{Group: "apps", Version: "v1beta2", Kind: "DeploymentList"}: {},
|
||||||
|
{Group: "apps", Version: "v1", Kind: "Deployment"}: {},
|
||||||
|
{Group: "apps", Version: "v1", Kind: "DeploymentList"}: {},
|
||||||
{Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicy"}: {},
|
{Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicy"}: {},
|
||||||
{Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicyList"}: {},
|
{Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicyList"}: {},
|
||||||
{Group: "apps", Version: "v1beta2", Kind: "ReplicaSet"}: {},
|
{Group: "apps", Version: "v1beta2", Kind: "ReplicaSet"}: {},
|
||||||
{Group: "apps", Version: "v1beta2", Kind: "ReplicaSetList"}: {},
|
{Group: "apps", Version: "v1beta2", Kind: "ReplicaSetList"}: {},
|
||||||
|
{Group: "apps", Version: "v1", Kind: "ReplicaSet"}: {},
|
||||||
|
{Group: "apps", Version: "v1", Kind: "ReplicaSetList"}: {},
|
||||||
{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSet"}: {},
|
{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSet"}: {},
|
||||||
{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSetList"}: {},
|
{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSetList"}: {},
|
||||||
{Group: "extensions", Version: "v1beta1", Kind: "NetworkPolicy"}: {},
|
{Group: "extensions", Version: "v1beta1", Kind: "NetworkPolicy"}: {},
|
||||||
|
@ -17,13 +17,18 @@ limitations under the License.
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
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/conversion"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
|
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/apps"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"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
|
// 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.
|
// functions are the same as the autogenerated ones in every other way.
|
||||||
err := scheme.AddConversionFuncs(
|
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_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet,
|
||||||
Convert_v1_RollingUpdateDaemonSet_To_extensions_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_extensions_DaemonSet_To_v1_DaemonSet,
|
||||||
Convert_v1_DaemonSet_To_extensions_DaemonSet,
|
Convert_v1_DaemonSet_To_extensions_DaemonSet,
|
||||||
Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec,
|
Convert_extensions_DaemonSetSpec_To_v1_DaemonSetSpec,
|
||||||
Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec,
|
Convert_v1_DaemonSetSpec_To_extensions_DaemonSetSpec,
|
||||||
Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy,
|
Convert_extensions_DaemonSetUpdateStrategy_To_v1_DaemonSetUpdateStrategy,
|
||||||
Convert_v1_DaemonSetUpdateStrategy_To_extensions_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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -48,6 +72,150 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
|||||||
return nil
|
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 {
|
func Convert_extensions_RollingUpdateDaemonSet_To_v1_RollingUpdateDaemonSet(in *extensions.RollingUpdateDaemonSet, out *appsv1.RollingUpdateDaemonSet, s conversion.Scope) error {
|
||||||
if out.MaxUnavailable == nil {
|
if out.MaxUnavailable == nil {
|
||||||
out.MaxUnavailable = &intstr.IntOrString{}
|
out.MaxUnavailable = &intstr.IntOrString{}
|
||||||
@ -156,3 +324,163 @@ func Convert_v1_DaemonSetUpdateStrategy_To_extensions_DaemonSetUpdateStrategy(in
|
|||||||
}
|
}
|
||||||
return nil
|
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"
|
"testing"
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
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/apimachinery/pkg/util/intstr"
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/apps"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
|
|
||||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
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) {
|
func TestV1RollingUpdateDaemonSetConversion(t *testing.T) {
|
||||||
intorstr := intstr.FromInt(1)
|
intorstr := intstr.FromInt(1)
|
||||||
testcases := map[string]struct {
|
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)
|
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) {
|
func SetDefaults_DaemonSet(obj *appsv1.DaemonSet) {
|
||||||
updateStrategy := &obj.Spec.UpdateStrategy
|
updateStrategy := &obj.Spec.UpdateStrategy
|
||||||
if updateStrategy.Type == "" {
|
if updateStrategy.Type == "" {
|
||||||
@ -47,3 +90,38 @@ func SetDefaults_DaemonSet(obj *appsv1.DaemonSet) {
|
|||||||
*obj.Spec.RevisionHistoryLimit = 10
|
*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"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||||
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"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 {
|
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
|
||||||
data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(SchemeGroupVersion), obj)
|
data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(SchemeGroupVersion), obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -118,11 +118,30 @@ func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.API
|
|||||||
version := appsapiv1.SchemeGroupVersion
|
version := appsapiv1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
|
if apiResourceConfigSource.ResourceEnabled(version.WithResource("deployments")) {
|
||||||
|
deploymentStorage := deploymentstore.NewStorage(restOptionsGetter)
|
||||||
|
storage["deployments"] = deploymentStorage.Deployment
|
||||||
|
storage["deployments/status"] = deploymentStorage.Status
|
||||||
|
}
|
||||||
|
if apiResourceConfigSource.ResourceEnabled(version.WithResource("statefulsets")) {
|
||||||
|
statefulSetStorage := statefulsetstore.NewStorage(restOptionsGetter)
|
||||||
|
storage["statefulsets"] = statefulSetStorage.StatefulSet
|
||||||
|
storage["statefulsets/status"] = statefulSetStorage.Status
|
||||||
|
}
|
||||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("daemonsets")) {
|
if apiResourceConfigSource.ResourceEnabled(version.WithResource("daemonsets")) {
|
||||||
daemonSetStorage, daemonSetStatusStorage := daemonsetstore.NewREST(restOptionsGetter)
|
daemonSetStorage, daemonSetStatusStorage := daemonsetstore.NewREST(restOptionsGetter)
|
||||||
storage["daemonsets"] = daemonSetStorage
|
storage["daemonsets"] = daemonSetStorage
|
||||||
storage["daemonsets/status"] = daemonSetStatusStorage
|
storage["daemonsets/status"] = daemonSetStatusStorage
|
||||||
}
|
}
|
||||||
|
if apiResourceConfigSource.ResourceEnabled(version.WithResource("replicasets")) {
|
||||||
|
replicaSetStorage := replicasetstore.NewStorage(restOptionsGetter)
|
||||||
|
storage["replicasets"] = replicaSetStorage.ReplicaSet
|
||||||
|
storage["replicasets/status"] = replicaSetStorage.Status
|
||||||
|
}
|
||||||
|
if apiResourceConfigSource.ResourceEnabled(version.WithResource("controllerrevisions")) {
|
||||||
|
historyStorage := controllerrevisionsstore.NewREST(restOptionsGetter)
|
||||||
|
storage["controllerrevisions"] = historyStorage
|
||||||
|
}
|
||||||
return storage
|
return storage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package deployment
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||||
@ -117,7 +118,7 @@ func (deploymentStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old
|
|||||||
// no-op for compatibility
|
// no-op for compatibility
|
||||||
case extensionsv1beta1.SchemeGroupVersion:
|
case extensionsv1beta1.SchemeGroupVersion:
|
||||||
// no-op for compatibility
|
// no-op for compatibility
|
||||||
case appsv1beta2.SchemeGroupVersion:
|
case appsv1beta2.SchemeGroupVersion, appsv1.SchemeGroupVersion:
|
||||||
// disallow mutation of selector
|
// disallow mutation of selector
|
||||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(newDeployment.Spec.Selector, oldDeployment.Spec.Selector, field.NewPath("spec").Child("selector"))...)
|
allErrs = append(allErrs, apivalidation.ValidateImmutableField(newDeployment.Spec.Selector, oldDeployment.Spec.Selector, field.NewPath("spec").Child("selector"))...)
|
||||||
default:
|
default:
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||||
@ -127,7 +128,7 @@ func (rsStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime
|
|||||||
switch groupVersion {
|
switch groupVersion {
|
||||||
case extensionsv1beta1.SchemeGroupVersion:
|
case extensionsv1beta1.SchemeGroupVersion:
|
||||||
// no-op for compatibility
|
// no-op for compatibility
|
||||||
case appsv1beta2.SchemeGroupVersion:
|
case appsv1beta2.SchemeGroupVersion, appsv1.SchemeGroupVersion:
|
||||||
// disallow mutation of selector
|
// disallow mutation of selector
|
||||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(newReplicaSet.Spec.Selector, oldReplicaSet.Spec.Selector, field.NewPath("spec").Child("selector"))...)
|
allErrs = append(allErrs, apivalidation.ValidateImmutableField(newReplicaSet.Spec.Selector, oldReplicaSet.Spec.Selector, field.NewPath("spec").Child("selector"))...)
|
||||||
default:
|
default:
|
||||||
|
@ -44,8 +44,16 @@ var (
|
|||||||
// Adds the list of known types to the given scheme.
|
// Adds the list of known types to the given scheme.
|
||||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||||
|
&Deployment{},
|
||||||
|
&DeploymentList{},
|
||||||
|
&StatefulSet{},
|
||||||
|
&StatefulSetList{},
|
||||||
&DaemonSet{},
|
&DaemonSet{},
|
||||||
&DaemonSetList{},
|
&DaemonSetList{},
|
||||||
|
&ReplicaSet{},
|
||||||
|
&ReplicaSetList{},
|
||||||
|
&ControllerRevision{},
|
||||||
|
&ControllerRevisionList{},
|
||||||
)
|
)
|
||||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||||
return nil
|
return nil
|
||||||
|
@ -19,14 +19,415 @@ package v1
|
|||||||
import (
|
import (
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ControllerRevisionHashLabelKey = "controller-revision-hash"
|
ControllerRevisionHashLabelKey = "controller-revision-hash"
|
||||||
|
StatefulSetRevisionLabel = ControllerRevisionHashLabelKey
|
||||||
|
DeprecatedRollbackTo = "deprecated.deployment.rollback.to"
|
||||||
DeprecatedTemplateGeneration = "deprecated.daemonset.template.generation"
|
DeprecatedTemplateGeneration = "deprecated.daemonset.template.generation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// +genclient
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// StatefulSet represents a set of pods with consistent identities.
|
||||||
|
// Identities are defined as:
|
||||||
|
// - Network: A single stable DNS and hostname.
|
||||||
|
// - Storage: As many VolumeClaims as requested.
|
||||||
|
// The StatefulSet guarantees that a given network identity will always
|
||||||
|
// map to the same storage identity.
|
||||||
|
type StatefulSet struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
// +optional
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||||
|
|
||||||
|
// Spec defines the desired identities of pods in this set.
|
||||||
|
// +optional
|
||||||
|
Spec StatefulSetSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
|
||||||
|
|
||||||
|
// Status is the current status of Pods in this StatefulSet. This data
|
||||||
|
// may be out of date by some window of time.
|
||||||
|
// +optional
|
||||||
|
Status StatefulSetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PodManagementPolicyType defines the policy for creating pods under a stateful set.
|
||||||
|
type PodManagementPolicyType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// OrderedReadyPodManagement will create pods in strictly increasing order on
|
||||||
|
// scale up and strictly decreasing order on scale down, progressing only when
|
||||||
|
// the previous pod is ready or terminated. At most one pod will be changed
|
||||||
|
// at any time.
|
||||||
|
OrderedReadyPodManagement PodManagementPolicyType = "OrderedReady"
|
||||||
|
// ParallelPodManagement will create and delete pods as soon as the stateful set
|
||||||
|
// replica count is changed, and will not wait for pods to be ready or complete
|
||||||
|
// termination.
|
||||||
|
ParallelPodManagement = "Parallel"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
|
||||||
|
// controller will use to perform updates. It includes any additional parameters
|
||||||
|
// necessary to perform the update for the indicated strategy.
|
||||||
|
type StatefulSetUpdateStrategy struct {
|
||||||
|
// Type indicates the type of the StatefulSetUpdateStrategy.
|
||||||
|
// Default is RollingUpdate.
|
||||||
|
// +optional
|
||||||
|
Type StatefulSetUpdateStrategyType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type,casttype=StatefulSetStrategyType"`
|
||||||
|
// RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType.
|
||||||
|
// +optional
|
||||||
|
RollingUpdate *RollingUpdateStatefulSetStrategy `json:"rollingUpdate,omitempty" protobuf:"bytes,2,opt,name=rollingUpdate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatefulSetUpdateStrategyType is a string enumeration type that enumerates
|
||||||
|
// all possible update strategies for the StatefulSet controller.
|
||||||
|
type StatefulSetUpdateStrategyType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RollingUpdateStatefulSetStrategyType indicates that update will be
|
||||||
|
// applied to all Pods in the StatefulSet with respect to the StatefulSet
|
||||||
|
// ordering constraints. When a scale operation is performed with this
|
||||||
|
// strategy, new Pods will be created from the specification version indicated
|
||||||
|
// by the StatefulSet's updateRevision.
|
||||||
|
RollingUpdateStatefulSetStrategyType = "RollingUpdate"
|
||||||
|
// OnDeleteStatefulSetStrategyType triggers the legacy behavior. Version
|
||||||
|
// tracking and ordered rolling restarts are disabled. Pods are recreated
|
||||||
|
// from the StatefulSetSpec when they are manually deleted. When a scale
|
||||||
|
// operation is performed with this strategy,specification version indicated
|
||||||
|
// by the StatefulSet's currentRevision.
|
||||||
|
OnDeleteStatefulSetStrategyType = "OnDelete"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.
|
||||||
|
type RollingUpdateStatefulSetStrategy struct {
|
||||||
|
// Partition indicates the ordinal at which the StatefulSet should be
|
||||||
|
// partitioned.
|
||||||
|
// Default value is 0.
|
||||||
|
// +optional
|
||||||
|
Partition *int32 `json:"partition,omitempty" protobuf:"varint,1,opt,name=partition"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A StatefulSetSpec is the specification of a StatefulSet.
|
||||||
|
type StatefulSetSpec struct {
|
||||||
|
// replicas is the desired number of replicas of the given Template.
|
||||||
|
// These are replicas in the sense that they are instantiations of the
|
||||||
|
// same Template, but individual replicas also have a consistent identity.
|
||||||
|
// If unspecified, defaults to 1.
|
||||||
|
// TODO: Consider a rename of this field.
|
||||||
|
// +optional
|
||||||
|
Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`
|
||||||
|
|
||||||
|
// selector is a label query over pods that should match the replica count.
|
||||||
|
// If empty, defaulted to labels on the pod template.
|
||||||
|
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
|
||||||
|
// +optional
|
||||||
|
Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"`
|
||||||
|
|
||||||
|
// template is the object that describes the pod that will be created if
|
||||||
|
// insufficient replicas are detected. Each pod stamped out by the StatefulSet
|
||||||
|
// will fulfill this Template, but have a unique identity from the rest
|
||||||
|
// of the StatefulSet.
|
||||||
|
Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"`
|
||||||
|
|
||||||
|
// volumeClaimTemplates is a list of claims that pods are allowed to reference.
|
||||||
|
// The StatefulSet controller is responsible for mapping network identities to
|
||||||
|
// claims in a way that maintains the identity of a pod. Every claim in
|
||||||
|
// this list must have at least one matching (by name) volumeMount in one
|
||||||
|
// container in the template. A claim in this list takes precedence over
|
||||||
|
// any volumes in the template, with the same name.
|
||||||
|
// TODO: Define the behavior if a claim already exists with the same name.
|
||||||
|
// +optional
|
||||||
|
VolumeClaimTemplates []v1.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty" protobuf:"bytes,4,rep,name=volumeClaimTemplates"`
|
||||||
|
|
||||||
|
// serviceName is the name of the service that governs this StatefulSet.
|
||||||
|
// This service must exist before the StatefulSet, and is responsible for
|
||||||
|
// the network identity of the set. Pods get DNS/hostnames that follow the
|
||||||
|
// pattern: pod-specific-string.serviceName.default.svc.cluster.local
|
||||||
|
// where "pod-specific-string" is managed by the StatefulSet controller.
|
||||||
|
ServiceName string `json:"serviceName" protobuf:"bytes,5,opt,name=serviceName"`
|
||||||
|
|
||||||
|
// podManagementPolicy controls how pods are created during initial scale up,
|
||||||
|
// when replacing pods on nodes, or when scaling down. The default policy is
|
||||||
|
// `OrderedReady`, where pods are created in increasing order (pod-0, then
|
||||||
|
// pod-1, etc) and the controller will wait until each pod is ready before
|
||||||
|
// continuing. When scaling down, the pods are removed in the opposite order.
|
||||||
|
// The alternative policy is `Parallel` which will create pods in parallel
|
||||||
|
// to match the desired scale without waiting, and on scale down will delete
|
||||||
|
// all pods at once.
|
||||||
|
// +optional
|
||||||
|
PodManagementPolicy PodManagementPolicyType `json:"podManagementPolicy,omitempty" protobuf:"bytes,6,opt,name=podManagementPolicy,casttype=PodManagementPolicyType"`
|
||||||
|
|
||||||
|
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
|
||||||
|
// employed to update Pods in the StatefulSet when a revision is made to
|
||||||
|
// Template.
|
||||||
|
UpdateStrategy StatefulSetUpdateStrategy `json:"updateStrategy,omitempty" protobuf:"bytes,7,opt,name=updateStrategy"`
|
||||||
|
|
||||||
|
// revisionHistoryLimit is the maximum number of revisions that will
|
||||||
|
// be maintained in the StatefulSet's revision history. The revision history
|
||||||
|
// consists of all revisions not represented by a currently applied
|
||||||
|
// StatefulSetSpec version. The default value is 10.
|
||||||
|
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,8,opt,name=revisionHistoryLimit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatefulSetStatus represents the current state of a StatefulSet.
|
||||||
|
type StatefulSetStatus struct {
|
||||||
|
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
|
||||||
|
// StatefulSet's generation, which is updated on mutation by the API Server.
|
||||||
|
// +optional
|
||||||
|
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
|
||||||
|
|
||||||
|
// replicas is the number of Pods created by the StatefulSet controller.
|
||||||
|
Replicas int32 `json:"replicas" protobuf:"varint,2,opt,name=replicas"`
|
||||||
|
|
||||||
|
// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.
|
||||||
|
ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,3,opt,name=readyReplicas"`
|
||||||
|
|
||||||
|
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||||
|
// indicated by currentRevision.
|
||||||
|
CurrentReplicas int32 `json:"currentReplicas,omitempty" protobuf:"varint,4,opt,name=currentReplicas"`
|
||||||
|
|
||||||
|
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||||
|
// indicated by updateRevision.
|
||||||
|
UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,5,opt,name=updatedReplicas"`
|
||||||
|
|
||||||
|
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
|
||||||
|
// sequence [0,currentReplicas).
|
||||||
|
CurrentRevision string `json:"currentRevision,omitempty" protobuf:"bytes,6,opt,name=currentRevision"`
|
||||||
|
|
||||||
|
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||||
|
// [replicas-updatedReplicas,replicas)
|
||||||
|
UpdateRevision string `json:"updateRevision,omitempty" protobuf:"bytes,7,opt,name=updateRevision"`
|
||||||
|
|
||||||
|
// collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller
|
||||||
|
// uses this field as a collision avoidance mechanism when it needs to create the name for the
|
||||||
|
// newest ControllerRevision.
|
||||||
|
// +optional
|
||||||
|
CollisionCount *int32 `json:"collisionCount,omitempty" protobuf:"varint,9,opt,name=collisionCount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// StatefulSetList is a collection of StatefulSets.
|
||||||
|
type StatefulSetList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
// +optional
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||||
|
Items []StatefulSet `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +genclient
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// Deployment enables declarative updates for Pods and ReplicaSets.
|
||||||
|
type Deployment struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
// Standard object metadata.
|
||||||
|
// +optional
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||||
|
|
||||||
|
// Specification of the desired behavior of the Deployment.
|
||||||
|
// +optional
|
||||||
|
Spec DeploymentSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
|
||||||
|
|
||||||
|
// Most recently observed status of the Deployment.
|
||||||
|
// +optional
|
||||||
|
Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeploymentSpec is the specification of the desired behavior of the Deployment.
|
||||||
|
type DeploymentSpec struct {
|
||||||
|
// Number of desired pods. This is a pointer to distinguish between explicit
|
||||||
|
// zero and not specified. Defaults to 1.
|
||||||
|
// +optional
|
||||||
|
Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`
|
||||||
|
|
||||||
|
// Label selector for pods. Existing ReplicaSets whose pods are
|
||||||
|
// selected by this will be the ones affected by this deployment.
|
||||||
|
// +optional
|
||||||
|
Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"`
|
||||||
|
|
||||||
|
// Template describes the pods that will be created.
|
||||||
|
Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"`
|
||||||
|
|
||||||
|
// The deployment strategy to use to replace existing pods with new ones.
|
||||||
|
// +optional
|
||||||
|
Strategy DeploymentStrategy `json:"strategy,omitempty" protobuf:"bytes,4,opt,name=strategy"`
|
||||||
|
|
||||||
|
// Minimum number of seconds for which a newly created pod should be ready
|
||||||
|
// without any of its container crashing, for it to be considered available.
|
||||||
|
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
||||||
|
// +optional
|
||||||
|
MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,5,opt,name=minReadySeconds"`
|
||||||
|
|
||||||
|
// The number of old ReplicaSets to retain to allow rollback.
|
||||||
|
// This is a pointer to distinguish between explicit zero and not specified.
|
||||||
|
// Defaults to 10.
|
||||||
|
// +optional
|
||||||
|
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,6,opt,name=revisionHistoryLimit"`
|
||||||
|
|
||||||
|
// Indicates that the deployment is paused.
|
||||||
|
// +optional
|
||||||
|
Paused bool `json:"paused,omitempty" protobuf:"varint,7,opt,name=paused"`
|
||||||
|
|
||||||
|
// The maximum time in seconds for a deployment to make progress before it
|
||||||
|
// is considered to be failed. The deployment controller will continue to
|
||||||
|
// process failed deployments and a condition with a ProgressDeadlineExceeded
|
||||||
|
// reason will be surfaced in the deployment status. Note that progress will
|
||||||
|
// not be estimated during the time a deployment is paused. Defaults to 600s.
|
||||||
|
ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty" protobuf:"varint,9,opt,name=progressDeadlineSeconds"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultDeploymentUniqueLabelKey is the default key of the selector that is added
|
||||||
|
// to existing RCs (and label key that is added to its pods) to prevent the existing RCs
|
||||||
|
// to select new pods (and old pods being select by new RC).
|
||||||
|
DefaultDeploymentUniqueLabelKey string = "pod-template-hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeploymentStrategy describes how to replace existing pods with new ones.
|
||||||
|
type DeploymentStrategy struct {
|
||||||
|
// Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate.
|
||||||
|
// +optional
|
||||||
|
Type DeploymentStrategyType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type,casttype=DeploymentStrategyType"`
|
||||||
|
|
||||||
|
// Rolling update config params. Present only if DeploymentStrategyType =
|
||||||
|
// RollingUpdate.
|
||||||
|
//---
|
||||||
|
// TODO: Update this to follow our convention for oneOf, whatever we decide it
|
||||||
|
// to be.
|
||||||
|
// +optional
|
||||||
|
RollingUpdate *RollingUpdateDeployment `json:"rollingUpdate,omitempty" protobuf:"bytes,2,opt,name=rollingUpdate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentStrategyType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Kill all existing pods before creating new ones.
|
||||||
|
RecreateDeploymentStrategyType DeploymentStrategyType = "Recreate"
|
||||||
|
|
||||||
|
// Replace the old RCs by new one using rolling update i.e gradually scale down the old RCs and scale up the new one.
|
||||||
|
RollingUpdateDeploymentStrategyType DeploymentStrategyType = "RollingUpdate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Spec to control the desired behavior of rolling update.
|
||||||
|
type RollingUpdateDeployment struct {
|
||||||
|
// The maximum number of pods that can be unavailable during the update.
|
||||||
|
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
|
||||||
|
// Absolute number is calculated from percentage by rounding down.
|
||||||
|
// This can not be 0 if MaxSurge is 0.
|
||||||
|
// Defaults to 25%.
|
||||||
|
// Example: when this is set to 30%, the old RC can be scaled down to 70% of desired pods
|
||||||
|
// immediately when the rolling update starts. Once new pods are ready, old RC
|
||||||
|
// can be scaled down further, followed by scaling up the new RC, ensuring
|
||||||
|
// that the total number of pods available at all times during the update is at
|
||||||
|
// least 70% of desired pods.
|
||||||
|
// +optional
|
||||||
|
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,1,opt,name=maxUnavailable"`
|
||||||
|
|
||||||
|
// The maximum number of pods that can be scheduled above the desired number of
|
||||||
|
// pods.
|
||||||
|
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
|
||||||
|
// This can not be 0 if MaxUnavailable is 0.
|
||||||
|
// Absolute number is calculated from percentage by rounding up.
|
||||||
|
// Defaults to 25%.
|
||||||
|
// Example: when this is set to 30%, the new RC can be scaled up immediately when
|
||||||
|
// the rolling update starts, such that the total number of old and new pods do not exceed
|
||||||
|
// 130% of desired pods. Once old pods have been killed,
|
||||||
|
// new RC can be scaled up further, ensuring that total number of pods running
|
||||||
|
// at any time during the update is atmost 130% of desired pods.
|
||||||
|
// +optional
|
||||||
|
MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty" protobuf:"bytes,2,opt,name=maxSurge"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeploymentStatus is the most recently observed status of the Deployment.
|
||||||
|
type DeploymentStatus struct {
|
||||||
|
// The generation observed by the deployment controller.
|
||||||
|
// +optional
|
||||||
|
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
|
||||||
|
|
||||||
|
// Total number of non-terminated pods targeted by this deployment (their labels match the selector).
|
||||||
|
// +optional
|
||||||
|
Replicas int32 `json:"replicas,omitempty" protobuf:"varint,2,opt,name=replicas"`
|
||||||
|
|
||||||
|
// Total number of non-terminated pods targeted by this deployment that have the desired template spec.
|
||||||
|
// +optional
|
||||||
|
UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,3,opt,name=updatedReplicas"`
|
||||||
|
|
||||||
|
// Total number of ready pods targeted by this deployment.
|
||||||
|
// +optional
|
||||||
|
ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,7,opt,name=readyReplicas"`
|
||||||
|
|
||||||
|
// Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.
|
||||||
|
// +optional
|
||||||
|
AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,4,opt,name=availableReplicas"`
|
||||||
|
|
||||||
|
// Total number of unavailable pods targeted by this deployment. This is the total number of
|
||||||
|
// pods that are still required for the deployment to have 100% available capacity. They may
|
||||||
|
// either be pods that are running but not yet available or pods that still have not been created.
|
||||||
|
// +optional
|
||||||
|
UnavailableReplicas int32 `json:"unavailableReplicas,omitempty" protobuf:"varint,5,opt,name=unavailableReplicas"`
|
||||||
|
|
||||||
|
// Represents the latest available observations of a deployment's current state.
|
||||||
|
// +patchMergeKey=type
|
||||||
|
// +patchStrategy=merge
|
||||||
|
Conditions []DeploymentCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,6,rep,name=conditions"`
|
||||||
|
|
||||||
|
// Count of hash collisions for the Deployment. The Deployment controller uses this
|
||||||
|
// field as a collision avoidance mechanism when it needs to create the name for the
|
||||||
|
// newest ReplicaSet.
|
||||||
|
// +optional
|
||||||
|
CollisionCount *int32 `json:"collisionCount,omitempty" protobuf:"varint,8,opt,name=collisionCount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentConditionType string
|
||||||
|
|
||||||
|
// These are valid conditions of a deployment.
|
||||||
|
const (
|
||||||
|
// Available means the deployment is available, ie. at least the minimum available
|
||||||
|
// replicas required are up and running for at least minReadySeconds.
|
||||||
|
DeploymentAvailable DeploymentConditionType = "Available"
|
||||||
|
// Progressing means the deployment is progressing. Progress for a deployment is
|
||||||
|
// considered when a new replica set is created or adopted, and when new pods scale
|
||||||
|
// up or old pods scale down. Progress is not estimated for paused deployments or
|
||||||
|
// when progressDeadlineSeconds is not specified.
|
||||||
|
DeploymentProgressing DeploymentConditionType = "Progressing"
|
||||||
|
// ReplicaFailure is added in a deployment when one of its pods fails to be created
|
||||||
|
// or deleted.
|
||||||
|
DeploymentReplicaFailure DeploymentConditionType = "ReplicaFailure"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeploymentCondition describes the state of a deployment at a certain point.
|
||||||
|
type DeploymentCondition struct {
|
||||||
|
// Type of deployment condition.
|
||||||
|
Type DeploymentConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=DeploymentConditionType"`
|
||||||
|
// Status of the condition, one of True, False, Unknown.
|
||||||
|
Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"`
|
||||||
|
// The last time this condition was updated.
|
||||||
|
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty" protobuf:"bytes,6,opt,name=lastUpdateTime"`
|
||||||
|
// Last time the condition transitioned from one status to another.
|
||||||
|
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,7,opt,name=lastTransitionTime"`
|
||||||
|
// The reason for the condition's last transition.
|
||||||
|
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
|
||||||
|
// A human readable message indicating details about the transition.
|
||||||
|
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// DeploymentList is a list of Deployments.
|
||||||
|
type DeploymentList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
// Standard list metadata.
|
||||||
|
// +optional
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||||
|
|
||||||
|
// Items is the list of Deployments.
|
||||||
|
Items []Deployment `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||||
|
}
|
||||||
|
|
||||||
// DaemonSetUpdateStrategy is a struct used to control the update strategy for a DaemonSet.
|
// DaemonSetUpdateStrategy is a struct used to control the update strategy for a DaemonSet.
|
||||||
type DaemonSetUpdateStrategy struct {
|
type DaemonSetUpdateStrategy struct {
|
||||||
// Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate.
|
// Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate.
|
||||||
@ -199,3 +600,170 @@ type DaemonSetList struct {
|
|||||||
// A list of daemon sets.
|
// A list of daemon sets.
|
||||||
Items []DaemonSet `json:"items" protobuf:"bytes,2,rep,name=items"`
|
Items []DaemonSet `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +genclient
|
||||||
|
// +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.
|
||||||
|
type ReplicaSet struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
|
// If the Labels of a ReplicaSet are empty, they are defaulted to
|
||||||
|
// be the same as the Pod(s) that the ReplicaSet manages.
|
||||||
|
// Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||||
|
// +optional
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||||
|
|
||||||
|
// Spec defines the specification of the desired behavior of the ReplicaSet.
|
||||||
|
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
|
||||||
|
// +optional
|
||||||
|
Spec ReplicaSetSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
|
||||||
|
|
||||||
|
// Status is the most recently observed status of the ReplicaSet.
|
||||||
|
// This data may be out of date by some window of time.
|
||||||
|
// Populated by the system.
|
||||||
|
// Read-only.
|
||||||
|
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
|
||||||
|
// +optional
|
||||||
|
Status ReplicaSetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// ReplicaSetList is a collection of ReplicaSets.
|
||||||
|
type ReplicaSetList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
// Standard list metadata.
|
||||||
|
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
|
||||||
|
// +optional
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||||
|
|
||||||
|
// List of ReplicaSets.
|
||||||
|
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
|
||||||
|
Items []ReplicaSet `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplicaSetSpec is the specification of a ReplicaSet.
|
||||||
|
type ReplicaSetSpec struct {
|
||||||
|
// Replicas is the number of desired replicas.
|
||||||
|
// This is a pointer to distinguish between explicit zero and unspecified.
|
||||||
|
// Defaults to 1.
|
||||||
|
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
|
||||||
|
// +optional
|
||||||
|
Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`
|
||||||
|
|
||||||
|
// Minimum number of seconds for which a newly created pod should be ready
|
||||||
|
// without any of its container crashing, for it to be considered available.
|
||||||
|
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
||||||
|
// +optional
|
||||||
|
MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,4,opt,name=minReadySeconds"`
|
||||||
|
|
||||||
|
// Selector is a label query over pods that should match the replica count.
|
||||||
|
// If the selector is empty, it is defaulted to the labels present on the pod template.
|
||||||
|
// Label keys and values that must match in order to be controlled by this replica set.
|
||||||
|
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
|
||||||
|
// +optional
|
||||||
|
Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"`
|
||||||
|
|
||||||
|
// Template is the object that describes the pod that will be created if
|
||||||
|
// insufficient replicas are detected.
|
||||||
|
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template
|
||||||
|
// +optional
|
||||||
|
Template v1.PodTemplateSpec `json:"template,omitempty" protobuf:"bytes,3,opt,name=template"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplicaSetStatus represents the current status of a ReplicaSet.
|
||||||
|
type ReplicaSetStatus struct {
|
||||||
|
// Replicas is the most recently oberved number of replicas.
|
||||||
|
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
|
||||||
|
Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"`
|
||||||
|
|
||||||
|
// The number of pods that have labels matching the labels of the pod template of the replicaset.
|
||||||
|
// +optional
|
||||||
|
FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty" protobuf:"varint,2,opt,name=fullyLabeledReplicas"`
|
||||||
|
|
||||||
|
// The number of ready replicas for this replica set.
|
||||||
|
// +optional
|
||||||
|
ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,4,opt,name=readyReplicas"`
|
||||||
|
|
||||||
|
// The number of available replicas (ready for at least minReadySeconds) for this replica set.
|
||||||
|
// +optional
|
||||||
|
AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,5,opt,name=availableReplicas"`
|
||||||
|
|
||||||
|
// ObservedGeneration reflects the generation of the most recently observed ReplicaSet.
|
||||||
|
// +optional
|
||||||
|
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"`
|
||||||
|
|
||||||
|
// Represents the latest available observations of a replica set's current state.
|
||||||
|
// +optional
|
||||||
|
// +patchMergeKey=type
|
||||||
|
// +patchStrategy=merge
|
||||||
|
Conditions []ReplicaSetCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,6,rep,name=conditions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReplicaSetConditionType string
|
||||||
|
|
||||||
|
// These are valid conditions of a replica set.
|
||||||
|
const (
|
||||||
|
// ReplicaSetReplicaFailure is added in a replica set when one of its pods fails to be created
|
||||||
|
// due to insufficient quota, limit ranges, pod security policy, node selectors, etc. or deleted
|
||||||
|
// due to kubelet being down or finalizers are failing.
|
||||||
|
ReplicaSetReplicaFailure ReplicaSetConditionType = "ReplicaFailure"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReplicaSetCondition describes the state of a replica set at a certain point.
|
||||||
|
type ReplicaSetCondition struct {
|
||||||
|
// Type of replica set condition.
|
||||||
|
Type ReplicaSetConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=ReplicaSetConditionType"`
|
||||||
|
// Status of the condition, one of True, False, Unknown.
|
||||||
|
Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"`
|
||||||
|
// The last time the condition transitioned from one status to another.
|
||||||
|
// +optional
|
||||||
|
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"`
|
||||||
|
// The reason for the condition's last transition.
|
||||||
|
// +optional
|
||||||
|
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
|
||||||
|
// A human readable message indicating details about the transition.
|
||||||
|
// +optional
|
||||||
|
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +genclient
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// ControllerRevision implements an immutable snapshot of state data. Clients
|
||||||
|
// are responsible for serializing and deserializing the objects that contain
|
||||||
|
// their internal state.
|
||||||
|
// Once a ControllerRevision has been successfully created, it can not be updated.
|
||||||
|
// The API Server will fail validation of all requests that attempt to mutate
|
||||||
|
// the Data field. ControllerRevisions may, however, be deleted. Note that, due to its use by both
|
||||||
|
// the DaemonSet and StatefulSet controllers for update and rollback, this object is beta. However,
|
||||||
|
// it may be subject to name and representation changes in future releases, and clients should not
|
||||||
|
// depend on its stability. It is primarily for internal use by controllers.
|
||||||
|
type ControllerRevision struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
// Standard object's metadata.
|
||||||
|
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||||
|
// +optional
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||||
|
|
||||||
|
// Data is the serialized representation of the state.
|
||||||
|
Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,2,opt,name=data"`
|
||||||
|
|
||||||
|
// Revision indicates the revision of the state represented by Data.
|
||||||
|
Revision int64 `json:"revision" protobuf:"varint,3,opt,name=revision"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// ControllerRevisionList is a resource containing a list of ControllerRevision objects.
|
||||||
|
type ControllerRevisionList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
|
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||||
|
// +optional
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||||
|
|
||||||
|
// Items is the list of ControllerRevisions
|
||||||
|
Items []ControllerRevision `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||||
|
}
|
||||||
|
@ -181,6 +181,26 @@ var etcdStorageData = map[schema.GroupVersionResource]struct {
|
|||||||
expectedEtcdPath: "/registry/daemonsets/etcdstoragepathtestnamespace/ds6",
|
expectedEtcdPath: "/registry/daemonsets/etcdstoragepathtestnamespace/ds6",
|
||||||
expectedGVK: gvkP("extensions", "v1beta1", "DaemonSet"),
|
expectedGVK: gvkP("extensions", "v1beta1", "DaemonSet"),
|
||||||
},
|
},
|
||||||
|
gvr("apps", "v1", "deployments"): {
|
||||||
|
stub: `{"metadata": {"name": "deployment4"}, "spec": {"selector": {"matchLabels": {"f": "z"}}, "template": {"metadata": {"labels": {"f": "z"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container6"}]}}}}`,
|
||||||
|
expectedEtcdPath: "/registry/deployments/etcdstoragepathtestnamespace/deployment4",
|
||||||
|
expectedGVK: gvkP("extensions", "v1beta1", "Deployment"),
|
||||||
|
},
|
||||||
|
gvr("apps", "v1", "statefulsets"): {
|
||||||
|
stub: `{"metadata": {"name": "ss3"}, "spec": {"selector": {"matchLabels": {"a": "b"}}, "template": {"metadata": {"labels": {"a": "b"}}}}}`,
|
||||||
|
expectedEtcdPath: "/registry/statefulsets/etcdstoragepathtestnamespace/ss3",
|
||||||
|
expectedGVK: gvkP("apps", "v1beta1", "StatefulSet"),
|
||||||
|
},
|
||||||
|
gvr("apps", "v1", "replicasets"): {
|
||||||
|
stub: `{"metadata": {"name": "rs3"}, "spec": {"selector": {"matchLabels": {"g": "h"}}, "template": {"metadata": {"labels": {"g": "h"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container4"}]}}}}`,
|
||||||
|
expectedEtcdPath: "/registry/replicasets/etcdstoragepathtestnamespace/rs3",
|
||||||
|
expectedGVK: gvkP("extensions", "v1beta1", "ReplicaSet"),
|
||||||
|
},
|
||||||
|
gvr("apps", "v1", "controllerrevisions"): {
|
||||||
|
stub: `{"metadata":{"name":"crs3"},"data":{"name":"abc","namespace":"default","creationTimestamp":null,"Spec":{"Replicas":0,"Selector":{"matchLabels":{"foo":"bar"}},"Template":{"creationTimestamp":null,"labels":{"foo":"bar"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":null,"RestartPolicy":"Always","TerminationGracePeriodSeconds":null,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":null,"ImagePullSecrets":null,"Hostname":"","Subdomain":"","Affinity":null,"SchedulerName":"","Tolerations":null,"HostAliases":null}},"VolumeClaimTemplates":null,"ServiceName":""},"Status":{"ObservedGeneration":null,"Replicas":0}},"revision":0}`,
|
||||||
|
expectedEtcdPath: "/registry/controllerrevisions/etcdstoragepathtestnamespace/crs3",
|
||||||
|
expectedGVK: gvkP("apps", "v1beta1", "ControllerRevision"),
|
||||||
|
},
|
||||||
// --
|
// --
|
||||||
|
|
||||||
// k8s.io/kubernetes/pkg/apis/autoscaling/v1
|
// k8s.io/kubernetes/pkg/apis/autoscaling/v1
|
||||||
|
Loading…
Reference in New Issue
Block a user