2015-04-28 19:23:13 +00:00
|
|
|
/*
|
2016-06-03 00:25:58 +00:00
|
|
|
Copyright 2015 The Kubernetes Authors.
|
2015-04-28 19:23:13 +00:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package v1
|
|
|
|
|
|
|
|
import (
|
2016-03-29 02:13:16 +00:00
|
|
|
"encoding/json"
|
2015-04-28 19:23:13 +00:00
|
|
|
"fmt"
|
2016-07-13 07:59:17 +00:00
|
|
|
"reflect"
|
2015-04-28 19:23:13 +00:00
|
|
|
|
2017-06-22 17:25:57 +00:00
|
|
|
"k8s.io/api/core/v1"
|
|
|
|
|
2017-01-11 14:09:48 +00:00
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
"k8s.io/apimachinery/pkg/conversion"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
|
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/api"
|
2016-07-13 07:59:17 +00:00
|
|
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
2015-04-28 19:23:13 +00:00
|
|
|
)
|
|
|
|
|
2016-05-13 00:07:50 +00:00
|
|
|
// This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are
|
|
|
|
// converted the most in the cluster.
|
|
|
|
// TODO: generate one of these for every external API group - this is to prove the impact
|
|
|
|
func addFastPathConversionFuncs(scheme *runtime.Scheme) error {
|
|
|
|
scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) {
|
|
|
|
switch a := objA.(type) {
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Pod:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
|
|
|
case *api.Pod:
|
|
|
|
return true, Convert_v1_Pod_To_api_Pod(a, b, s)
|
|
|
|
}
|
|
|
|
case *api.Pod:
|
|
|
|
switch b := objB.(type) {
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Pod:
|
2016-05-13 00:07:50 +00:00
|
|
|
return true, Convert_api_Pod_To_v1_Pod(a, b, s)
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Event:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
|
|
|
case *api.Event:
|
|
|
|
return true, Convert_v1_Event_To_api_Event(a, b, s)
|
|
|
|
}
|
|
|
|
case *api.Event:
|
|
|
|
switch b := objB.(type) {
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Event:
|
2016-05-13 00:07:50 +00:00
|
|
|
return true, Convert_api_Event_To_v1_Event(a, b, s)
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.ReplicationController:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
|
|
|
case *api.ReplicationController:
|
|
|
|
return true, Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s)
|
|
|
|
}
|
|
|
|
case *api.ReplicationController:
|
|
|
|
switch b := objB.(type) {
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.ReplicationController:
|
2016-05-13 00:07:50 +00:00
|
|
|
return true, Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s)
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Node:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
|
|
|
case *api.Node:
|
|
|
|
return true, Convert_v1_Node_To_api_Node(a, b, s)
|
|
|
|
}
|
|
|
|
case *api.Node:
|
|
|
|
switch b := objB.(type) {
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Node:
|
2016-05-13 00:07:50 +00:00
|
|
|
return true, Convert_api_Node_To_v1_Node(a, b, s)
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Namespace:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
|
|
|
case *api.Namespace:
|
|
|
|
return true, Convert_v1_Namespace_To_api_Namespace(a, b, s)
|
|
|
|
}
|
|
|
|
case *api.Namespace:
|
|
|
|
switch b := objB.(type) {
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Namespace:
|
2016-05-13 00:07:50 +00:00
|
|
|
return true, Convert_api_Namespace_To_v1_Namespace(a, b, s)
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Service:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
|
|
|
case *api.Service:
|
|
|
|
return true, Convert_v1_Service_To_api_Service(a, b, s)
|
|
|
|
}
|
|
|
|
case *api.Service:
|
|
|
|
switch b := objB.(type) {
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Service:
|
2016-05-13 00:07:50 +00:00
|
|
|
return true, Convert_api_Service_To_v1_Service(a, b, s)
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Endpoints:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
|
|
|
case *api.Endpoints:
|
|
|
|
return true, Convert_v1_Endpoints_To_api_Endpoints(a, b, s)
|
|
|
|
}
|
|
|
|
case *api.Endpoints:
|
|
|
|
switch b := objB.(type) {
|
2017-06-22 17:25:12 +00:00
|
|
|
case *v1.Endpoints:
|
2016-05-13 00:07:50 +00:00
|
|
|
return true, Convert_api_Endpoints_To_v1_Endpoints(a, b, s)
|
|
|
|
}
|
|
|
|
|
2017-01-05 20:10:34 +00:00
|
|
|
case *metav1.WatchEvent:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
2017-01-04 20:14:42 +00:00
|
|
|
case *metav1.InternalEvent:
|
|
|
|
return true, metav1.Convert_versioned_Event_to_versioned_InternalEvent(a, b, s)
|
2016-05-13 00:07:50 +00:00
|
|
|
}
|
2017-01-04 20:14:42 +00:00
|
|
|
case *metav1.InternalEvent:
|
2016-05-13 00:07:50 +00:00
|
|
|
switch b := objB.(type) {
|
2017-01-05 20:10:34 +00:00
|
|
|
case *metav1.WatchEvent:
|
2017-01-04 20:14:42 +00:00
|
|
|
return true, metav1.Convert_versioned_InternalEvent_to_versioned_Event(a, b, s)
|
2016-05-13 00:07:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false, nil
|
|
|
|
})
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func addConversionFuncs(scheme *runtime.Scheme) error {
|
2015-05-20 06:23:16 +00:00
|
|
|
// Add non-generated conversion functions
|
2015-12-24 06:55:06 +00:00
|
|
|
err := scheme.AddConversionFuncs(
|
2015-12-23 07:07:10 +00:00
|
|
|
Convert_api_Pod_To_v1_Pod,
|
|
|
|
Convert_api_PodSpec_To_v1_PodSpec,
|
|
|
|
Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec,
|
|
|
|
Convert_api_ServiceSpec_To_v1_ServiceSpec,
|
|
|
|
Convert_v1_Pod_To_api_Pod,
|
|
|
|
Convert_v1_PodSpec_To_api_PodSpec,
|
|
|
|
Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec,
|
2016-06-30 03:07:53 +00:00
|
|
|
Convert_v1_Secret_To_api_Secret,
|
2015-12-23 07:07:10 +00:00
|
|
|
Convert_v1_ServiceSpec_To_api_ServiceSpec,
|
2016-01-07 22:55:19 +00:00
|
|
|
Convert_v1_ResourceList_To_api_ResourceList,
|
2016-07-13 07:59:17 +00:00
|
|
|
Convert_v1_ReplicationController_to_extensions_ReplicaSet,
|
|
|
|
Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec,
|
|
|
|
Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus,
|
|
|
|
Convert_extensions_ReplicaSet_to_v1_ReplicationController,
|
|
|
|
Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec,
|
|
|
|
Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus,
|
2015-05-18 20:19:43 +00:00
|
|
|
)
|
2015-05-11 15:03:38 +00:00
|
|
|
if err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-05-11 15:03:38 +00:00
|
|
|
}
|
2015-04-28 19:23:13 +00:00
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
// Add field label conversions for kinds having selectable nothing but v1.ObjectMeta fields.
|
2016-08-20 05:18:30 +00:00
|
|
|
for _, k := range []string{
|
2015-10-29 16:34:59 +00:00
|
|
|
"Endpoints",
|
|
|
|
"ResourceQuota",
|
|
|
|
"PersistentVolumeClaim",
|
|
|
|
"Service",
|
|
|
|
"ServiceAccount",
|
2016-01-15 16:48:36 +00:00
|
|
|
"ConfigMap",
|
2015-10-29 16:34:59 +00:00
|
|
|
} {
|
2016-08-20 05:18:30 +00:00
|
|
|
kind := k // don't close over range variables
|
2016-08-10 21:51:30 +00:00
|
|
|
err = scheme.AddFieldLabelConversionFunc("v1", kind,
|
2015-10-29 16:34:59 +00:00
|
|
|
func(label, value string) (string, string, error) {
|
|
|
|
switch label {
|
|
|
|
case "metadata.namespace",
|
|
|
|
"metadata.name":
|
|
|
|
return label, value, nil
|
|
|
|
default:
|
|
|
|
return "", "", fmt.Errorf("field label %q not supported for %q", label, kind)
|
|
|
|
}
|
2016-05-13 00:07:50 +00:00
|
|
|
},
|
|
|
|
)
|
2015-10-29 16:34:59 +00:00
|
|
|
if err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-10-29 16:34:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-28 19:23:13 +00:00
|
|
|
// Add field conversion funcs.
|
2016-08-10 21:51:30 +00:00
|
|
|
err = scheme.AddFieldLabelConversionFunc("v1", "Pod",
|
2015-04-28 19:23:13 +00:00
|
|
|
func(label, value string) (string, string, error) {
|
|
|
|
switch label {
|
2016-06-22 16:27:17 +00:00
|
|
|
case "metadata.annotations",
|
2015-02-20 05:36:23 +00:00
|
|
|
"metadata.labels",
|
2016-06-22 16:27:17 +00:00
|
|
|
"metadata.name",
|
|
|
|
"metadata.namespace",
|
2017-06-27 08:54:35 +00:00
|
|
|
"metadata.uid",
|
2016-01-17 19:59:56 +00:00
|
|
|
"spec.nodeName",
|
2016-06-22 16:27:17 +00:00
|
|
|
"spec.restartPolicy",
|
|
|
|
"spec.serviceAccountName",
|
|
|
|
"status.phase",
|
2017-03-08 08:08:09 +00:00
|
|
|
"status.hostIP",
|
2016-06-22 16:27:17 +00:00
|
|
|
"status.podIP":
|
2015-04-28 19:23:13 +00:00
|
|
|
return label, value, nil
|
2015-08-08 21:29:57 +00:00
|
|
|
// This is for backwards compatibility with old v1 clients which send spec.host
|
2015-07-10 22:13:43 +00:00
|
|
|
case "spec.host":
|
|
|
|
return "spec.nodeName", value, nil
|
2015-04-28 19:23:13 +00:00
|
|
|
default:
|
|
|
|
return "", "", fmt.Errorf("field label not supported: %s", label)
|
|
|
|
}
|
2016-05-13 00:07:50 +00:00
|
|
|
},
|
|
|
|
)
|
2015-04-28 19:23:13 +00:00
|
|
|
if err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-04-28 19:23:13 +00:00
|
|
|
}
|
2016-08-10 21:51:30 +00:00
|
|
|
err = scheme.AddFieldLabelConversionFunc("v1", "Node",
|
2015-04-28 19:23:13 +00:00
|
|
|
func(label, value string) (string, string, error) {
|
|
|
|
switch label {
|
|
|
|
case "metadata.name":
|
|
|
|
return label, value, nil
|
|
|
|
case "spec.unschedulable":
|
|
|
|
return label, value, nil
|
|
|
|
default:
|
|
|
|
return "", "", fmt.Errorf("field label not supported: %s", label)
|
|
|
|
}
|
2016-05-13 00:07:50 +00:00
|
|
|
},
|
|
|
|
)
|
2015-04-28 19:23:13 +00:00
|
|
|
if err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-04-28 19:23:13 +00:00
|
|
|
}
|
2016-08-10 21:51:30 +00:00
|
|
|
err = scheme.AddFieldLabelConversionFunc("v1", "ReplicationController",
|
2015-04-28 19:23:13 +00:00
|
|
|
func(label, value string) (string, string, error) {
|
|
|
|
switch label {
|
|
|
|
case "metadata.name",
|
2015-11-30 21:31:40 +00:00
|
|
|
"metadata.namespace",
|
2015-04-28 19:23:13 +00:00
|
|
|
"status.replicas":
|
|
|
|
return label, value, nil
|
|
|
|
default:
|
|
|
|
return "", "", fmt.Errorf("field label not supported: %s", label)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
if err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-04-28 19:23:13 +00:00
|
|
|
}
|
2016-08-10 21:51:30 +00:00
|
|
|
err = scheme.AddFieldLabelConversionFunc("v1", "PersistentVolume",
|
2015-04-28 19:23:13 +00:00
|
|
|
func(label, value string) (string, string, error) {
|
|
|
|
switch label {
|
2016-08-10 21:51:30 +00:00
|
|
|
case "metadata.name":
|
2015-04-28 19:23:13 +00:00
|
|
|
return label, value, nil
|
|
|
|
default:
|
|
|
|
return "", "", fmt.Errorf("field label not supported: %s", label)
|
|
|
|
}
|
2016-05-13 00:07:50 +00:00
|
|
|
},
|
|
|
|
)
|
2015-04-28 19:23:13 +00:00
|
|
|
if err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-04-28 19:23:13 +00:00
|
|
|
}
|
2016-08-10 21:51:30 +00:00
|
|
|
if err := AddFieldLabelConversionsForEvent(scheme); err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-06-02 17:22:10 +00:00
|
|
|
}
|
2016-08-10 21:51:30 +00:00
|
|
|
if err := AddFieldLabelConversionsForNamespace(scheme); err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-11-30 21:31:40 +00:00
|
|
|
}
|
2016-08-10 21:51:30 +00:00
|
|
|
if err := AddFieldLabelConversionsForSecret(scheme); err != nil {
|
2016-05-13 00:07:50 +00:00
|
|
|
return err
|
2015-04-28 19:23:13 +00:00
|
|
|
}
|
2016-05-13 00:07:50 +00:00
|
|
|
return nil
|
2015-04-28 19:23:13 +00:00
|
|
|
}
|
2015-05-18 20:19:43 +00:00
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *v1.ReplicationController, out *extensions.ReplicaSet, s conversion.Scope) error {
|
2017-01-11 20:28:46 +00:00
|
|
|
out.ObjectMeta = in.ObjectMeta
|
2016-07-13 07:59:17 +00:00
|
|
|
if err := Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *v1.ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error {
|
2016-07-13 07:59:17 +00:00
|
|
|
out.Replicas = *in.Replicas
|
|
|
|
if in.Selector != nil {
|
2017-02-14 16:32:04 +00:00
|
|
|
metav1.Convert_map_to_unversioned_LabelSelector(&in.Selector, out.Selector, s)
|
2016-07-13 07:59:17 +00:00
|
|
|
}
|
|
|
|
if in.Template != nil {
|
|
|
|
if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, &out.Template, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *v1.ReplicationControllerStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error {
|
2016-07-13 07:59:17 +00:00
|
|
|
out.Replicas = in.Replicas
|
|
|
|
out.FullyLabeledReplicas = in.FullyLabeledReplicas
|
2016-09-15 14:37:30 +00:00
|
|
|
out.ReadyReplicas = in.ReadyReplicas
|
|
|
|
out.AvailableReplicas = in.AvailableReplicas
|
2016-07-13 07:59:17 +00:00
|
|
|
out.ObservedGeneration = in.ObservedGeneration
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.ReplicaSet, out *v1.ReplicationController, s conversion.Scope) error {
|
2017-01-11 20:28:46 +00:00
|
|
|
out.ObjectMeta = in.ObjectMeta
|
2016-07-13 07:59:17 +00:00
|
|
|
if err := Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil {
|
|
|
|
fieldErr, ok := err.(*field.Error)
|
|
|
|
if !ok {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if out.Annotations == nil {
|
|
|
|
out.Annotations = make(map[string]string)
|
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
out.Annotations[v1.NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String()
|
2016-07-13 07:59:17 +00:00
|
|
|
}
|
|
|
|
if err := Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(in *extensions.ReplicaSetSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error {
|
2016-07-13 07:59:17 +00:00
|
|
|
out.Replicas = new(int32)
|
|
|
|
*out.Replicas = in.Replicas
|
2016-09-15 14:37:30 +00:00
|
|
|
out.MinReadySeconds = in.MinReadySeconds
|
2016-07-13 07:59:17 +00:00
|
|
|
var invalidErr error
|
|
|
|
if in.Selector != nil {
|
2017-02-14 16:32:04 +00:00
|
|
|
invalidErr = metav1.Convert_unversioned_LabelSelector_to_map(in.Selector, &out.Selector, s)
|
2016-07-13 07:59:17 +00:00
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
out.Template = new(v1.PodTemplateSpec)
|
2016-07-13 07:59:17 +00:00
|
|
|
if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, out.Template, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return invalidErr
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *extensions.ReplicaSetStatus, out *v1.ReplicationControllerStatus, s conversion.Scope) error {
|
2016-07-13 07:59:17 +00:00
|
|
|
out.Replicas = in.Replicas
|
|
|
|
out.FullyLabeledReplicas = in.FullyLabeledReplicas
|
2016-09-15 14:37:30 +00:00
|
|
|
out.ReadyReplicas = in.ReadyReplicas
|
|
|
|
out.AvailableReplicas = in.AvailableReplicas
|
2016-07-13 07:59:17 +00:00
|
|
|
out.ObservedGeneration = in.ObservedGeneration
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error {
|
2016-05-20 19:02:33 +00:00
|
|
|
out.Replicas = &in.Replicas
|
2016-09-15 14:37:30 +00:00
|
|
|
out.MinReadySeconds = in.MinReadySeconds
|
2016-05-20 19:02:33 +00:00
|
|
|
out.Selector = in.Selector
|
2015-05-20 06:23:16 +00:00
|
|
|
if in.Template != nil {
|
2017-06-22 17:25:12 +00:00
|
|
|
out.Template = new(v1.PodTemplateSpec)
|
2015-12-23 07:07:10 +00:00
|
|
|
if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil {
|
2015-05-20 06:23:16 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
out.Template = nil
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *v1.ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error {
|
2016-09-25 16:08:50 +00:00
|
|
|
if in.Replicas != nil {
|
|
|
|
out.Replicas = *in.Replicas
|
|
|
|
}
|
2016-09-15 14:37:30 +00:00
|
|
|
out.MinReadySeconds = in.MinReadySeconds
|
2016-05-20 19:02:33 +00:00
|
|
|
out.Selector = in.Selector
|
2015-05-20 06:23:16 +00:00
|
|
|
if in.Template != nil {
|
|
|
|
out.Template = new(api.PodTemplateSpec)
|
2015-12-23 07:07:10 +00:00
|
|
|
if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil {
|
2015-05-20 06:23:16 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
out.Template = nil
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2015-07-16 19:02:12 +00:00
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *v1.PodStatusResult, s conversion.Scope) error {
|
2016-03-29 02:13:16 +00:00
|
|
|
if err := autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in, out, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-05-20 19:02:33 +00:00
|
|
|
if old := out.Annotations; old != nil {
|
|
|
|
out.Annotations = make(map[string]string, len(old))
|
|
|
|
for k, v := range old {
|
|
|
|
out.Annotations[k] = v
|
|
|
|
}
|
|
|
|
}
|
2016-03-29 02:13:16 +00:00
|
|
|
if len(out.Status.InitContainerStatuses) > 0 {
|
|
|
|
if out.Annotations == nil {
|
|
|
|
out.Annotations = make(map[string]string)
|
|
|
|
}
|
|
|
|
value, err := json.Marshal(out.Status.InitContainerStatuses)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
out.Annotations[v1.PodInitContainerStatusesAnnotationKey] = string(value)
|
|
|
|
out.Annotations[v1.PodInitContainerStatusesBetaAnnotationKey] = string(value)
|
2016-03-29 02:13:16 +00:00
|
|
|
} else {
|
2017-06-22 17:25:12 +00:00
|
|
|
delete(out.Annotations, v1.PodInitContainerStatusesAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainerStatusesBetaAnnotationKey)
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_PodStatusResult_To_api_PodStatusResult(in *v1.PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error {
|
Move init-container feature from alpha to beta.
```relnote
Moved init-container feature from alpha to beta.
In 1.3, an init container is specified with this annotation key
on the pod or pod template: `pods.alpha.kubernetes.io/init-containers`.
In 1.4, either that key or this key: pods.beta.kubernetes.io/init-containers`,
can be used.
When you GET an object, you will see both annotation keys with the same values.
You can safely roll back from 1.4 to 1.3, and things with init-containers
will still work (pods, deployments, etc).
If you are running 1.3, only use the alpha annotation, or it may be lost when
rolling forward.
The status has moved from annotation key
`pods.beta.kubernetes.io/init-container-statuses` to
`pods.beta.kubernetes.io/init-container-statuses`.
Any code that inspects this annotation should be changed to use the new key.
State of Initialization will continue to be reported in both pods.alpha.kubernetes.io/initialized
and in `podStatus.conditions.{status: "True", type: Initialized}`
```
Mini-design for this change:
Goals:
1. A user can create an object with the beta annotation
on 1.4, and it works. The fact that the annotation has beta
in it communicates to the user that the feature is beta,
and so the user should have confidence in using it. Preferably,
when the user gets the annotation back, he see the beta
annotation.
1) If someone had an existing alpha object in their apiserver,
such as a RS with a pod template with an init-containers
annotation on it, it should continue to work (init containers
run) when stack upgraded to 1.4.
2) If someone is using a chart or blog post that has alpha
annotation on it and they create it on a 1.4 cluster, it should
work.
3) If someone had something with an init container in 1.4
and they roll back stack to 1.3, it should not silently stop
working (init containers don't run anymore).
To meet all these, we mirror an absent beta label from the alpha
key and vice versa. If they are out of sync, we use the alpha
one. We do this in conversion since there was already logic there.
In 1.3 code, all annotations are preserved across a round trip
(v1 -> api -> v1), and the alpha annotation turns into the internal
field that kubelet uses.
In 1.4 code, the alpha annotation is always preserved across
a round trip, and a beta annotation is always set equal to
the alpha one, after a round trip.
Currently, the kubelet always sees the object after a round trip
when it GETs it. But, we don't want to rely on that behavior,
since it will break when fastpath is implemented.
So, we rely on this:
all objects either are created with an alpha annotation (1.3 or 1.4
code) or are created with a beta annotation under 1.4. In the later
case, they are round tripped at creation time, and so get both
annotations. So all subsequent GETs see both labels.
2016-08-19 10:25:17 +00:00
|
|
|
// TODO: sometime after we move init container to stable, remove these conversions
|
2016-09-19 23:19:43 +00:00
|
|
|
// If there is a beta annotation, copy to alpha key.
|
|
|
|
// See commit log for PR #31026 for why we do this.
|
2017-06-22 17:25:12 +00:00
|
|
|
if valueBeta, okBeta := in.Annotations[v1.PodInitContainerStatusesBetaAnnotationKey]; okBeta {
|
|
|
|
in.Annotations[v1.PodInitContainerStatusesAnnotationKey] = valueBeta
|
2016-09-19 23:19:43 +00:00
|
|
|
}
|
|
|
|
// Move the annotation to the internal repr. field
|
2017-06-22 17:25:12 +00:00
|
|
|
if value, ok := in.Annotations[v1.PodInitContainerStatusesAnnotationKey]; ok {
|
|
|
|
var values []v1.ContainerStatus
|
2016-03-29 02:13:16 +00:00
|
|
|
if err := json.Unmarshal([]byte(value), &values); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-31 13:15:51 +00:00
|
|
|
// Conversion from external to internal version exists more to
|
|
|
|
// satisfy the needs of the decoder than it does to be a general
|
|
|
|
// purpose tool. And Decode always creates an intermediate object
|
|
|
|
// to decode to. Thus the caller of UnsafeConvertToVersion is
|
|
|
|
// taking responsibility to ensure mutation of in is not exposed
|
|
|
|
// back to the caller.
|
2016-03-29 02:13:16 +00:00
|
|
|
in.Status.InitContainerStatuses = values
|
|
|
|
}
|
|
|
|
|
2016-05-19 21:53:59 +00:00
|
|
|
if err := autoConvert_v1_PodStatusResult_To_api_PodStatusResult(in, out, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-20 19:02:33 +00:00
|
|
|
if len(out.Annotations) > 0 {
|
|
|
|
old := out.Annotations
|
|
|
|
out.Annotations = make(map[string]string, len(old))
|
|
|
|
for k, v := range old {
|
|
|
|
out.Annotations[k] = v
|
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
delete(out.Annotations, v1.PodInitContainerStatusesAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainerStatusesBetaAnnotationKey)
|
2016-05-20 19:02:33 +00:00
|
|
|
}
|
2016-05-19 21:53:59 +00:00
|
|
|
return nil
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error {
|
2016-03-29 02:13:16 +00:00
|
|
|
if err := autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
Move init-container feature from alpha to beta.
```relnote
Moved init-container feature from alpha to beta.
In 1.3, an init container is specified with this annotation key
on the pod or pod template: `pods.alpha.kubernetes.io/init-containers`.
In 1.4, either that key or this key: pods.beta.kubernetes.io/init-containers`,
can be used.
When you GET an object, you will see both annotation keys with the same values.
You can safely roll back from 1.4 to 1.3, and things with init-containers
will still work (pods, deployments, etc).
If you are running 1.3, only use the alpha annotation, or it may be lost when
rolling forward.
The status has moved from annotation key
`pods.beta.kubernetes.io/init-container-statuses` to
`pods.beta.kubernetes.io/init-container-statuses`.
Any code that inspects this annotation should be changed to use the new key.
State of Initialization will continue to be reported in both pods.alpha.kubernetes.io/initialized
and in `podStatus.conditions.{status: "True", type: Initialized}`
```
Mini-design for this change:
Goals:
1. A user can create an object with the beta annotation
on 1.4, and it works. The fact that the annotation has beta
in it communicates to the user that the feature is beta,
and so the user should have confidence in using it. Preferably,
when the user gets the annotation back, he see the beta
annotation.
1) If someone had an existing alpha object in their apiserver,
such as a RS with a pod template with an init-containers
annotation on it, it should continue to work (init containers
run) when stack upgraded to 1.4.
2) If someone is using a chart or blog post that has alpha
annotation on it and they create it on a 1.4 cluster, it should
work.
3) If someone had something with an init container in 1.4
and they roll back stack to 1.3, it should not silently stop
working (init containers don't run anymore).
To meet all these, we mirror an absent beta label from the alpha
key and vice versa. If they are out of sync, we use the alpha
one. We do this in conversion since there was already logic there.
In 1.3 code, all annotations are preserved across a round trip
(v1 -> api -> v1), and the alpha annotation turns into the internal
field that kubelet uses.
In 1.4 code, the alpha annotation is always preserved across
a round trip, and a beta annotation is always set equal to
the alpha one, after a round trip.
Currently, the kubelet always sees the object after a round trip
when it GETs it. But, we don't want to rely on that behavior,
since it will break when fastpath is implemented.
So, we rely on this:
all objects either are created with an alpha annotation (1.3 or 1.4
code) or are created with a beta annotation under 1.4. In the later
case, they are round tripped at creation time, and so get both
annotations. So all subsequent GETs see both labels.
2016-08-19 10:25:17 +00:00
|
|
|
// TODO: sometime after we move init container to stable, remove these conversions.
|
2016-05-20 19:02:33 +00:00
|
|
|
if old := out.Annotations; old != nil {
|
|
|
|
out.Annotations = make(map[string]string, len(old))
|
|
|
|
for k, v := range old {
|
|
|
|
out.Annotations[k] = v
|
|
|
|
}
|
|
|
|
}
|
2016-03-29 02:13:16 +00:00
|
|
|
if len(out.Spec.InitContainers) > 0 {
|
|
|
|
if out.Annotations == nil {
|
|
|
|
out.Annotations = make(map[string]string)
|
|
|
|
}
|
|
|
|
value, err := json.Marshal(out.Spec.InitContainers)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
out.Annotations[v1.PodInitContainersAnnotationKey] = string(value)
|
|
|
|
out.Annotations[v1.PodInitContainersBetaAnnotationKey] = string(value)
|
2016-03-29 02:13:16 +00:00
|
|
|
} else {
|
2017-06-22 17:25:12 +00:00
|
|
|
delete(out.Annotations, v1.PodInitContainersAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainersBetaAnnotationKey)
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *v1.PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error {
|
Move init-container feature from alpha to beta.
```relnote
Moved init-container feature from alpha to beta.
In 1.3, an init container is specified with this annotation key
on the pod or pod template: `pods.alpha.kubernetes.io/init-containers`.
In 1.4, either that key or this key: pods.beta.kubernetes.io/init-containers`,
can be used.
When you GET an object, you will see both annotation keys with the same values.
You can safely roll back from 1.4 to 1.3, and things with init-containers
will still work (pods, deployments, etc).
If you are running 1.3, only use the alpha annotation, or it may be lost when
rolling forward.
The status has moved from annotation key
`pods.beta.kubernetes.io/init-container-statuses` to
`pods.beta.kubernetes.io/init-container-statuses`.
Any code that inspects this annotation should be changed to use the new key.
State of Initialization will continue to be reported in both pods.alpha.kubernetes.io/initialized
and in `podStatus.conditions.{status: "True", type: Initialized}`
```
Mini-design for this change:
Goals:
1. A user can create an object with the beta annotation
on 1.4, and it works. The fact that the annotation has beta
in it communicates to the user that the feature is beta,
and so the user should have confidence in using it. Preferably,
when the user gets the annotation back, he see the beta
annotation.
1) If someone had an existing alpha object in their apiserver,
such as a RS with a pod template with an init-containers
annotation on it, it should continue to work (init containers
run) when stack upgraded to 1.4.
2) If someone is using a chart or blog post that has alpha
annotation on it and they create it on a 1.4 cluster, it should
work.
3) If someone had something with an init container in 1.4
and they roll back stack to 1.3, it should not silently stop
working (init containers don't run anymore).
To meet all these, we mirror an absent beta label from the alpha
key and vice versa. If they are out of sync, we use the alpha
one. We do this in conversion since there was already logic there.
In 1.3 code, all annotations are preserved across a round trip
(v1 -> api -> v1), and the alpha annotation turns into the internal
field that kubelet uses.
In 1.4 code, the alpha annotation is always preserved across
a round trip, and a beta annotation is always set equal to
the alpha one, after a round trip.
Currently, the kubelet always sees the object after a round trip
when it GETs it. But, we don't want to rely on that behavior,
since it will break when fastpath is implemented.
So, we rely on this:
all objects either are created with an alpha annotation (1.3 or 1.4
code) or are created with a beta annotation under 1.4. In the later
case, they are round tripped at creation time, and so get both
annotations. So all subsequent GETs see both labels.
2016-08-19 10:25:17 +00:00
|
|
|
// TODO: sometime after we move init container to stable, remove these conversions
|
|
|
|
// If there is a beta annotation, copy to alpha key.
|
|
|
|
// See commit log for PR #31026 for why we do this.
|
2017-06-22 17:25:12 +00:00
|
|
|
if valueBeta, okBeta := in.Annotations[v1.PodInitContainersBetaAnnotationKey]; okBeta {
|
|
|
|
in.Annotations[v1.PodInitContainersAnnotationKey] = valueBeta
|
Move init-container feature from alpha to beta.
```relnote
Moved init-container feature from alpha to beta.
In 1.3, an init container is specified with this annotation key
on the pod or pod template: `pods.alpha.kubernetes.io/init-containers`.
In 1.4, either that key or this key: pods.beta.kubernetes.io/init-containers`,
can be used.
When you GET an object, you will see both annotation keys with the same values.
You can safely roll back from 1.4 to 1.3, and things with init-containers
will still work (pods, deployments, etc).
If you are running 1.3, only use the alpha annotation, or it may be lost when
rolling forward.
The status has moved from annotation key
`pods.beta.kubernetes.io/init-container-statuses` to
`pods.beta.kubernetes.io/init-container-statuses`.
Any code that inspects this annotation should be changed to use the new key.
State of Initialization will continue to be reported in both pods.alpha.kubernetes.io/initialized
and in `podStatus.conditions.{status: "True", type: Initialized}`
```
Mini-design for this change:
Goals:
1. A user can create an object with the beta annotation
on 1.4, and it works. The fact that the annotation has beta
in it communicates to the user that the feature is beta,
and so the user should have confidence in using it. Preferably,
when the user gets the annotation back, he see the beta
annotation.
1) If someone had an existing alpha object in their apiserver,
such as a RS with a pod template with an init-containers
annotation on it, it should continue to work (init containers
run) when stack upgraded to 1.4.
2) If someone is using a chart or blog post that has alpha
annotation on it and they create it on a 1.4 cluster, it should
work.
3) If someone had something with an init container in 1.4
and they roll back stack to 1.3, it should not silently stop
working (init containers don't run anymore).
To meet all these, we mirror an absent beta label from the alpha
key and vice versa. If they are out of sync, we use the alpha
one. We do this in conversion since there was already logic there.
In 1.3 code, all annotations are preserved across a round trip
(v1 -> api -> v1), and the alpha annotation turns into the internal
field that kubelet uses.
In 1.4 code, the alpha annotation is always preserved across
a round trip, and a beta annotation is always set equal to
the alpha one, after a round trip.
Currently, the kubelet always sees the object after a round trip
when it GETs it. But, we don't want to rely on that behavior,
since it will break when fastpath is implemented.
So, we rely on this:
all objects either are created with an alpha annotation (1.3 or 1.4
code) or are created with a beta annotation under 1.4. In the later
case, they are round tripped at creation time, and so get both
annotations. So all subsequent GETs see both labels.
2016-08-19 10:25:17 +00:00
|
|
|
}
|
|
|
|
// Move the annotation to the internal repr. field
|
2017-06-22 17:25:12 +00:00
|
|
|
if value, ok := in.Annotations[v1.PodInitContainersAnnotationKey]; ok {
|
|
|
|
var values []v1.Container
|
2016-03-29 02:13:16 +00:00
|
|
|
if err := json.Unmarshal([]byte(value), &values); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-31 13:15:51 +00:00
|
|
|
// Conversion from external to internal version exists more to
|
|
|
|
// satisfy the needs of the decoder than it does to be a general
|
|
|
|
// purpose tool. And Decode always creates an intermediate object
|
|
|
|
// to decode to. Thus the caller of UnsafeConvertToVersion is
|
|
|
|
// taking responsibility to ensure mutation of in is not exposed
|
|
|
|
// back to the caller.
|
2016-03-29 02:13:16 +00:00
|
|
|
in.Spec.InitContainers = values
|
2016-12-11 08:15:37 +00:00
|
|
|
|
|
|
|
// Call defaulters explicitly until annotations are removed
|
2017-06-22 17:25:12 +00:00
|
|
|
tmpPodTemp := &v1.PodTemplate{
|
|
|
|
Template: v1.PodTemplateSpec{
|
|
|
|
Spec: v1.PodSpec{
|
2017-03-01 04:57:01 +00:00
|
|
|
HostNetwork: in.Spec.HostNetwork,
|
|
|
|
InitContainers: values,
|
|
|
|
},
|
|
|
|
},
|
2016-12-11 08:15:37 +00:00
|
|
|
}
|
2017-03-01 04:57:01 +00:00
|
|
|
SetObjectDefaults_PodTemplate(tmpPodTemp)
|
|
|
|
in.Spec.InitContainers = tmpPodTemp.Template.Spec.InitContainers
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
|
|
|
|
2016-05-19 21:53:59 +00:00
|
|
|
if err := autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-20 19:02:33 +00:00
|
|
|
if len(out.Annotations) > 0 {
|
|
|
|
old := out.Annotations
|
|
|
|
out.Annotations = make(map[string]string, len(old))
|
|
|
|
for k, v := range old {
|
|
|
|
out.Annotations[k] = v
|
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
delete(out.Annotations, v1.PodInitContainersAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainersBetaAnnotationKey)
|
2016-05-20 19:02:33 +00:00
|
|
|
}
|
2016-05-19 21:53:59 +00:00
|
|
|
return nil
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
// The following two v1.PodSpec conversions are done here to support v1.ServiceAccount
|
2015-07-16 19:02:12 +00:00
|
|
|
// as an alias for ServiceAccountName.
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *v1.PodSpec, s conversion.Scope) error {
|
2016-06-27 08:27:05 +00:00
|
|
|
if err := autoConvert_api_PodSpec_To_v1_PodSpec(in, out, s); err != nil {
|
|
|
|
return err
|
2015-07-16 19:02:12 +00:00
|
|
|
}
|
2016-05-20 19:02:33 +00:00
|
|
|
|
2015-07-16 19:02:12 +00:00
|
|
|
// DeprecatedServiceAccount is an alias for ServiceAccountName.
|
|
|
|
out.DeprecatedServiceAccount = in.ServiceAccountName
|
2015-09-14 21:56:51 +00:00
|
|
|
|
2016-06-27 08:27:05 +00:00
|
|
|
if in.SecurityContext != nil {
|
2016-02-12 19:33:32 +00:00
|
|
|
// the host namespace fields have to be handled here for backward compatibility
|
2015-10-20 18:03:32 +00:00
|
|
|
// with v1.0.0
|
2015-09-14 21:56:51 +00:00
|
|
|
out.HostPID = in.SecurityContext.HostPID
|
|
|
|
out.HostNetwork = in.SecurityContext.HostNetwork
|
|
|
|
out.HostIPC = in.SecurityContext.HostIPC
|
|
|
|
}
|
2016-06-27 08:27:05 +00:00
|
|
|
|
2015-07-16 19:02:12 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s conversion.Scope) error {
|
2016-06-27 08:27:05 +00:00
|
|
|
if err := autoConvert_v1_PodSpec_To_api_PodSpec(in, out, s); err != nil {
|
|
|
|
return err
|
2015-07-16 19:02:12 +00:00
|
|
|
}
|
2016-06-27 08:27:05 +00:00
|
|
|
|
2015-07-16 19:02:12 +00:00
|
|
|
// We support DeprecatedServiceAccount as an alias for ServiceAccountName.
|
|
|
|
// If both are specified, ServiceAccountName (the new field) wins.
|
|
|
|
if in.ServiceAccountName == "" {
|
|
|
|
out.ServiceAccountName = in.DeprecatedServiceAccount
|
|
|
|
}
|
2015-10-20 18:03:32 +00:00
|
|
|
|
|
|
|
// the host namespace fields have to be handled specially for backward compatibility
|
|
|
|
// with v1.0.0
|
2015-09-14 21:56:51 +00:00
|
|
|
if out.SecurityContext == nil {
|
|
|
|
out.SecurityContext = new(api.PodSecurityContext)
|
|
|
|
}
|
|
|
|
out.SecurityContext.HostNetwork = in.HostNetwork
|
|
|
|
out.SecurityContext.HostPID = in.HostPID
|
|
|
|
out.SecurityContext.HostIPC = in.HostIPC
|
2016-06-27 08:27:05 +00:00
|
|
|
|
2015-07-16 19:02:12 +00:00
|
|
|
return nil
|
|
|
|
}
|
2015-09-24 00:46:18 +00:00
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *v1.Pod, s conversion.Scope) error {
|
2015-12-23 07:07:10 +00:00
|
|
|
if err := autoConvert_api_Pod_To_v1_Pod(in, out, s); err != nil {
|
2015-10-21 21:11:32 +00:00
|
|
|
return err
|
|
|
|
}
|
2016-03-29 02:13:16 +00:00
|
|
|
|
Move init-container feature from alpha to beta.
```relnote
Moved init-container feature from alpha to beta.
In 1.3, an init container is specified with this annotation key
on the pod or pod template: `pods.alpha.kubernetes.io/init-containers`.
In 1.4, either that key or this key: pods.beta.kubernetes.io/init-containers`,
can be used.
When you GET an object, you will see both annotation keys with the same values.
You can safely roll back from 1.4 to 1.3, and things with init-containers
will still work (pods, deployments, etc).
If you are running 1.3, only use the alpha annotation, or it may be lost when
rolling forward.
The status has moved from annotation key
`pods.beta.kubernetes.io/init-container-statuses` to
`pods.beta.kubernetes.io/init-container-statuses`.
Any code that inspects this annotation should be changed to use the new key.
State of Initialization will continue to be reported in both pods.alpha.kubernetes.io/initialized
and in `podStatus.conditions.{status: "True", type: Initialized}`
```
Mini-design for this change:
Goals:
1. A user can create an object with the beta annotation
on 1.4, and it works. The fact that the annotation has beta
in it communicates to the user that the feature is beta,
and so the user should have confidence in using it. Preferably,
when the user gets the annotation back, he see the beta
annotation.
1) If someone had an existing alpha object in their apiserver,
such as a RS with a pod template with an init-containers
annotation on it, it should continue to work (init containers
run) when stack upgraded to 1.4.
2) If someone is using a chart or blog post that has alpha
annotation on it and they create it on a 1.4 cluster, it should
work.
3) If someone had something with an init container in 1.4
and they roll back stack to 1.3, it should not silently stop
working (init containers don't run anymore).
To meet all these, we mirror an absent beta label from the alpha
key and vice versa. If they are out of sync, we use the alpha
one. We do this in conversion since there was already logic there.
In 1.3 code, all annotations are preserved across a round trip
(v1 -> api -> v1), and the alpha annotation turns into the internal
field that kubelet uses.
In 1.4 code, the alpha annotation is always preserved across
a round trip, and a beta annotation is always set equal to
the alpha one, after a round trip.
Currently, the kubelet always sees the object after a round trip
when it GETs it. But, we don't want to rely on that behavior,
since it will break when fastpath is implemented.
So, we rely on this:
all objects either are created with an alpha annotation (1.3 or 1.4
code) or are created with a beta annotation under 1.4. In the later
case, they are round tripped at creation time, and so get both
annotations. So all subsequent GETs see both labels.
2016-08-19 10:25:17 +00:00
|
|
|
// TODO: sometime after we move init container to stable, remove these conversions
|
2016-05-20 19:02:33 +00:00
|
|
|
if len(out.Spec.InitContainers) > 0 || len(out.Status.InitContainerStatuses) > 0 {
|
|
|
|
old := out.Annotations
|
|
|
|
out.Annotations = make(map[string]string, len(old))
|
|
|
|
for k, v := range old {
|
|
|
|
out.Annotations[k] = v
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
delete(out.Annotations, v1.PodInitContainersAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainersBetaAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainerStatusesAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainerStatusesBetaAnnotationKey)
|
2016-05-20 19:02:33 +00:00
|
|
|
}
|
|
|
|
if len(out.Spec.InitContainers) > 0 {
|
2016-03-29 02:13:16 +00:00
|
|
|
value, err := json.Marshal(out.Spec.InitContainers)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
out.Annotations[v1.PodInitContainersAnnotationKey] = string(value)
|
|
|
|
out.Annotations[v1.PodInitContainersBetaAnnotationKey] = string(value)
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
|
|
|
if len(out.Status.InitContainerStatuses) > 0 {
|
|
|
|
value, err := json.Marshal(out.Status.InitContainerStatuses)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
out.Annotations[v1.PodInitContainerStatusesAnnotationKey] = string(value)
|
|
|
|
out.Annotations[v1.PodInitContainerStatusesBetaAnnotationKey] = string(value)
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
|
|
|
|
2015-10-21 21:11:32 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_Pod_To_api_Pod(in *v1.Pod, out *api.Pod, s conversion.Scope) error {
|
Move init-container feature from alpha to beta.
```relnote
Moved init-container feature from alpha to beta.
In 1.3, an init container is specified with this annotation key
on the pod or pod template: `pods.alpha.kubernetes.io/init-containers`.
In 1.4, either that key or this key: pods.beta.kubernetes.io/init-containers`,
can be used.
When you GET an object, you will see both annotation keys with the same values.
You can safely roll back from 1.4 to 1.3, and things with init-containers
will still work (pods, deployments, etc).
If you are running 1.3, only use the alpha annotation, or it may be lost when
rolling forward.
The status has moved from annotation key
`pods.beta.kubernetes.io/init-container-statuses` to
`pods.beta.kubernetes.io/init-container-statuses`.
Any code that inspects this annotation should be changed to use the new key.
State of Initialization will continue to be reported in both pods.alpha.kubernetes.io/initialized
and in `podStatus.conditions.{status: "True", type: Initialized}`
```
Mini-design for this change:
Goals:
1. A user can create an object with the beta annotation
on 1.4, and it works. The fact that the annotation has beta
in it communicates to the user that the feature is beta,
and so the user should have confidence in using it. Preferably,
when the user gets the annotation back, he see the beta
annotation.
1) If someone had an existing alpha object in their apiserver,
such as a RS with a pod template with an init-containers
annotation on it, it should continue to work (init containers
run) when stack upgraded to 1.4.
2) If someone is using a chart or blog post that has alpha
annotation on it and they create it on a 1.4 cluster, it should
work.
3) If someone had something with an init container in 1.4
and they roll back stack to 1.3, it should not silently stop
working (init containers don't run anymore).
To meet all these, we mirror an absent beta label from the alpha
key and vice versa. If they are out of sync, we use the alpha
one. We do this in conversion since there was already logic there.
In 1.3 code, all annotations are preserved across a round trip
(v1 -> api -> v1), and the alpha annotation turns into the internal
field that kubelet uses.
In 1.4 code, the alpha annotation is always preserved across
a round trip, and a beta annotation is always set equal to
the alpha one, after a round trip.
Currently, the kubelet always sees the object after a round trip
when it GETs it. But, we don't want to rely on that behavior,
since it will break when fastpath is implemented.
So, we rely on this:
all objects either are created with an alpha annotation (1.3 or 1.4
code) or are created with a beta annotation under 1.4. In the later
case, they are round tripped at creation time, and so get both
annotations. So all subsequent GETs see both labels.
2016-08-19 10:25:17 +00:00
|
|
|
// If there is a beta annotation, copy to alpha key.
|
|
|
|
// See commit log for PR #31026 for why we do this.
|
2017-06-22 17:25:12 +00:00
|
|
|
if valueBeta, okBeta := in.Annotations[v1.PodInitContainersBetaAnnotationKey]; okBeta {
|
|
|
|
in.Annotations[v1.PodInitContainersAnnotationKey] = valueBeta
|
Move init-container feature from alpha to beta.
```relnote
Moved init-container feature from alpha to beta.
In 1.3, an init container is specified with this annotation key
on the pod or pod template: `pods.alpha.kubernetes.io/init-containers`.
In 1.4, either that key or this key: pods.beta.kubernetes.io/init-containers`,
can be used.
When you GET an object, you will see both annotation keys with the same values.
You can safely roll back from 1.4 to 1.3, and things with init-containers
will still work (pods, deployments, etc).
If you are running 1.3, only use the alpha annotation, or it may be lost when
rolling forward.
The status has moved from annotation key
`pods.beta.kubernetes.io/init-container-statuses` to
`pods.beta.kubernetes.io/init-container-statuses`.
Any code that inspects this annotation should be changed to use the new key.
State of Initialization will continue to be reported in both pods.alpha.kubernetes.io/initialized
and in `podStatus.conditions.{status: "True", type: Initialized}`
```
Mini-design for this change:
Goals:
1. A user can create an object with the beta annotation
on 1.4, and it works. The fact that the annotation has beta
in it communicates to the user that the feature is beta,
and so the user should have confidence in using it. Preferably,
when the user gets the annotation back, he see the beta
annotation.
1) If someone had an existing alpha object in their apiserver,
such as a RS with a pod template with an init-containers
annotation on it, it should continue to work (init containers
run) when stack upgraded to 1.4.
2) If someone is using a chart or blog post that has alpha
annotation on it and they create it on a 1.4 cluster, it should
work.
3) If someone had something with an init container in 1.4
and they roll back stack to 1.3, it should not silently stop
working (init containers don't run anymore).
To meet all these, we mirror an absent beta label from the alpha
key and vice versa. If they are out of sync, we use the alpha
one. We do this in conversion since there was already logic there.
In 1.3 code, all annotations are preserved across a round trip
(v1 -> api -> v1), and the alpha annotation turns into the internal
field that kubelet uses.
In 1.4 code, the alpha annotation is always preserved across
a round trip, and a beta annotation is always set equal to
the alpha one, after a round trip.
Currently, the kubelet always sees the object after a round trip
when it GETs it. But, we don't want to rely on that behavior,
since it will break when fastpath is implemented.
So, we rely on this:
all objects either are created with an alpha annotation (1.3 or 1.4
code) or are created with a beta annotation under 1.4. In the later
case, they are round tripped at creation time, and so get both
annotations. So all subsequent GETs see both labels.
2016-08-19 10:25:17 +00:00
|
|
|
}
|
|
|
|
// TODO: sometime after we move init container to stable, remove these conversions
|
|
|
|
// Move the annotation to the internal repr. field
|
2017-06-22 17:25:12 +00:00
|
|
|
if value, ok := in.Annotations[v1.PodInitContainersAnnotationKey]; ok {
|
|
|
|
var values []v1.Container
|
2016-03-29 02:13:16 +00:00
|
|
|
if err := json.Unmarshal([]byte(value), &values); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-31 13:15:51 +00:00
|
|
|
// Conversion from external to internal version exists more to
|
|
|
|
// satisfy the needs of the decoder than it does to be a general
|
|
|
|
// purpose tool. And Decode always creates an intermediate object
|
|
|
|
// to decode to. Thus the caller of UnsafeConvertToVersion is
|
|
|
|
// taking responsibility to ensure mutation of in is not exposed
|
|
|
|
// back to the caller.
|
2016-03-29 02:13:16 +00:00
|
|
|
in.Spec.InitContainers = values
|
2016-09-30 03:09:48 +00:00
|
|
|
// Call defaulters explicitly until annotations are removed
|
2017-06-22 17:25:12 +00:00
|
|
|
tmpPod := &v1.Pod{
|
|
|
|
Spec: v1.PodSpec{
|
2017-03-01 04:57:01 +00:00
|
|
|
HostNetwork: in.Spec.HostNetwork,
|
|
|
|
InitContainers: values,
|
|
|
|
},
|
2016-09-30 03:09:48 +00:00
|
|
|
}
|
2017-03-01 04:57:01 +00:00
|
|
|
SetObjectDefaults_Pod(tmpPod)
|
|
|
|
in.Spec.InitContainers = tmpPod.Spec.InitContainers
|
2016-03-29 02:13:16 +00:00
|
|
|
}
|
2016-09-19 23:19:43 +00:00
|
|
|
// If there is a beta annotation, copy to alpha key.
|
|
|
|
// See commit log for PR #31026 for why we do this.
|
2017-06-22 17:25:12 +00:00
|
|
|
if valueBeta, okBeta := in.Annotations[v1.PodInitContainerStatusesBetaAnnotationKey]; okBeta {
|
|
|
|
in.Annotations[v1.PodInitContainerStatusesAnnotationKey] = valueBeta
|
2016-09-19 23:19:43 +00:00
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
if value, ok := in.Annotations[v1.PodInitContainerStatusesAnnotationKey]; ok {
|
|
|
|
var values []v1.ContainerStatus
|
2016-03-29 02:13:16 +00:00
|
|
|
if err := json.Unmarshal([]byte(value), &values); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-31 13:15:51 +00:00
|
|
|
// Conversion from external to internal version exists more to
|
|
|
|
// satisfy the needs of the decoder than it does to be a general
|
|
|
|
// purpose tool. And Decode always creates an intermediate object
|
|
|
|
// to decode to. Thus the caller of UnsafeConvertToVersion is
|
|
|
|
// taking responsibility to ensure mutation of in is not exposed
|
|
|
|
// back to the caller.
|
2016-03-29 02:13:16 +00:00
|
|
|
in.Status.InitContainerStatuses = values
|
|
|
|
}
|
|
|
|
|
2016-05-19 21:53:59 +00:00
|
|
|
if err := autoConvert_v1_Pod_To_api_Pod(in, out, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-20 19:02:33 +00:00
|
|
|
if len(out.Annotations) > 0 {
|
|
|
|
old := out.Annotations
|
|
|
|
out.Annotations = make(map[string]string, len(old))
|
|
|
|
for k, v := range old {
|
|
|
|
out.Annotations[k] = v
|
|
|
|
}
|
2017-06-22 17:25:12 +00:00
|
|
|
delete(out.Annotations, v1.PodInitContainersAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainersBetaAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainerStatusesAnnotationKey)
|
|
|
|
delete(out.Annotations, v1.PodInitContainerStatusesBetaAnnotationKey)
|
2016-05-20 19:02:33 +00:00
|
|
|
}
|
2016-05-19 21:53:59 +00:00
|
|
|
return nil
|
2015-10-21 21:11:32 +00:00
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_Secret_To_api_Secret(in *v1.Secret, out *api.Secret, s conversion.Scope) error {
|
2016-06-30 03:07:53 +00:00
|
|
|
if err := autoConvert_v1_Secret_To_api_Secret(in, out, s); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// StringData overwrites Data
|
|
|
|
if len(in.StringData) > 0 {
|
|
|
|
if out.Data == nil {
|
|
|
|
out.Data = map[string][]byte{}
|
|
|
|
}
|
|
|
|
for k, v := range in.StringData {
|
|
|
|
out.Data[k] = []byte(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2015-09-24 00:46:18 +00:00
|
|
|
}
|
2015-09-14 21:56:51 +00:00
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *v1.PodSecurityContext, s conversion.Scope) error {
|
2015-10-15 17:45:16 +00:00
|
|
|
out.SupplementalGroups = in.SupplementalGroups
|
2015-10-20 18:03:32 +00:00
|
|
|
if in.SELinuxOptions != nil {
|
2017-06-22 17:25:12 +00:00
|
|
|
out.SELinuxOptions = new(v1.SELinuxOptions)
|
2015-12-23 07:07:10 +00:00
|
|
|
if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
|
2015-10-20 18:03:32 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
out.SELinuxOptions = nil
|
|
|
|
}
|
2016-05-20 19:02:33 +00:00
|
|
|
out.RunAsUser = in.RunAsUser
|
|
|
|
out.RunAsNonRoot = in.RunAsNonRoot
|
|
|
|
out.FSGroup = in.FSGroup
|
2015-09-14 21:56:51 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *v1.PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
|
2015-10-15 17:45:16 +00:00
|
|
|
out.SupplementalGroups = in.SupplementalGroups
|
2015-10-20 18:03:32 +00:00
|
|
|
if in.SELinuxOptions != nil {
|
|
|
|
out.SELinuxOptions = new(api.SELinuxOptions)
|
2015-12-23 07:07:10 +00:00
|
|
|
if err := Convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
|
2015-10-20 18:03:32 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
out.SELinuxOptions = nil
|
|
|
|
}
|
2016-05-20 19:02:33 +00:00
|
|
|
out.RunAsUser = in.RunAsUser
|
|
|
|
out.RunAsNonRoot = in.RunAsNonRoot
|
|
|
|
out.FSGroup = in.FSGroup
|
2015-09-14 21:56:51 +00:00
|
|
|
return nil
|
|
|
|
}
|
2016-01-07 22:55:19 +00:00
|
|
|
|
2016-10-14 04:50:10 +00:00
|
|
|
// +k8s:conversion-fn=copy-only
|
2017-06-22 17:25:12 +00:00
|
|
|
func Convert_v1_ResourceList_To_api_ResourceList(in *v1.ResourceList, out *api.ResourceList, s conversion.Scope) error {
|
2016-01-07 22:55:19 +00:00
|
|
|
if *in == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2016-05-20 19:02:33 +00:00
|
|
|
if *out == nil {
|
|
|
|
*out = make(api.ResourceList, len(*in))
|
|
|
|
}
|
2016-01-07 22:55:19 +00:00
|
|
|
for key, val := range *in {
|
2016-10-26 16:18:33 +00:00
|
|
|
// Moved to defaults
|
2016-01-07 22:55:19 +00:00
|
|
|
// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
|
|
|
|
// In the future, we should instead reject values that need rounding.
|
2016-10-26 16:18:33 +00:00
|
|
|
// const milliScale = -3
|
|
|
|
// val.RoundUp(milliScale)
|
2016-01-07 22:55:19 +00:00
|
|
|
|
2016-05-20 19:02:33 +00:00
|
|
|
(*out)[api.ResourceName(key)] = val
|
2016-01-07 22:55:19 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2016-08-10 21:51:30 +00:00
|
|
|
|
|
|
|
func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
|
|
|
|
return scheme.AddFieldLabelConversionFunc("v1", "Event",
|
|
|
|
func(label, value string) (string, string, error) {
|
|
|
|
switch label {
|
|
|
|
case "involvedObject.kind",
|
|
|
|
"involvedObject.namespace",
|
|
|
|
"involvedObject.name",
|
|
|
|
"involvedObject.uid",
|
|
|
|
"involvedObject.apiVersion",
|
|
|
|
"involvedObject.resourceVersion",
|
|
|
|
"involvedObject.fieldPath",
|
|
|
|
"reason",
|
|
|
|
"source",
|
|
|
|
"type",
|
|
|
|
"metadata.namespace",
|
|
|
|
"metadata.name":
|
|
|
|
return label, value, nil
|
|
|
|
default:
|
|
|
|
return "", "", fmt.Errorf("field label not supported: %s", label)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func AddFieldLabelConversionsForNamespace(scheme *runtime.Scheme) error {
|
|
|
|
return scheme.AddFieldLabelConversionFunc("v1", "Namespace",
|
|
|
|
func(label, value string) (string, string, error) {
|
|
|
|
switch label {
|
|
|
|
case "status.phase",
|
|
|
|
"metadata.name":
|
|
|
|
return label, value, nil
|
|
|
|
default:
|
|
|
|
return "", "", fmt.Errorf("field label not supported: %s", label)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func AddFieldLabelConversionsForSecret(scheme *runtime.Scheme) error {
|
|
|
|
return scheme.AddFieldLabelConversionFunc("v1", "Secret",
|
|
|
|
func(label, value string) (string, string, error) {
|
|
|
|
switch label {
|
|
|
|
case "type",
|
|
|
|
"metadata.namespace",
|
|
|
|
"metadata.name":
|
|
|
|
return label, value, nil
|
|
|
|
default:
|
|
|
|
return "", "", fmt.Errorf("field label not supported: %s", label)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|