1/*
2Copyright 2015 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package v1
18
19import (
20	"encoding/json"
21	"fmt"
22	"reflect"
23
24	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25	"k8s.io/apimachinery/pkg/conversion"
26	"k8s.io/apimachinery/pkg/runtime"
27	"k8s.io/apimachinery/pkg/util/validation/field"
28	"k8s.io/client-go/pkg/api"
29	"k8s.io/client-go/pkg/apis/extensions"
30)
31
32// This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are
33// converted the most in the cluster.
34// TODO: generate one of these for every external API group - this is to prove the impact
35func addFastPathConversionFuncs(scheme *runtime.Scheme) error {
36	scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) {
37		switch a := objA.(type) {
38		case *Pod:
39			switch b := objB.(type) {
40			case *api.Pod:
41				return true, Convert_v1_Pod_To_api_Pod(a, b, s)
42			}
43		case *api.Pod:
44			switch b := objB.(type) {
45			case *Pod:
46				return true, Convert_api_Pod_To_v1_Pod(a, b, s)
47			}
48
49		case *Event:
50			switch b := objB.(type) {
51			case *api.Event:
52				return true, Convert_v1_Event_To_api_Event(a, b, s)
53			}
54		case *api.Event:
55			switch b := objB.(type) {
56			case *Event:
57				return true, Convert_api_Event_To_v1_Event(a, b, s)
58			}
59
60		case *ReplicationController:
61			switch b := objB.(type) {
62			case *api.ReplicationController:
63				return true, Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s)
64			}
65		case *api.ReplicationController:
66			switch b := objB.(type) {
67			case *ReplicationController:
68				return true, Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s)
69			}
70
71		case *Node:
72			switch b := objB.(type) {
73			case *api.Node:
74				return true, Convert_v1_Node_To_api_Node(a, b, s)
75			}
76		case *api.Node:
77			switch b := objB.(type) {
78			case *Node:
79				return true, Convert_api_Node_To_v1_Node(a, b, s)
80			}
81
82		case *Namespace:
83			switch b := objB.(type) {
84			case *api.Namespace:
85				return true, Convert_v1_Namespace_To_api_Namespace(a, b, s)
86			}
87		case *api.Namespace:
88			switch b := objB.(type) {
89			case *Namespace:
90				return true, Convert_api_Namespace_To_v1_Namespace(a, b, s)
91			}
92
93		case *Service:
94			switch b := objB.(type) {
95			case *api.Service:
96				return true, Convert_v1_Service_To_api_Service(a, b, s)
97			}
98		case *api.Service:
99			switch b := objB.(type) {
100			case *Service:
101				return true, Convert_api_Service_To_v1_Service(a, b, s)
102			}
103
104		case *Endpoints:
105			switch b := objB.(type) {
106			case *api.Endpoints:
107				return true, Convert_v1_Endpoints_To_api_Endpoints(a, b, s)
108			}
109		case *api.Endpoints:
110			switch b := objB.(type) {
111			case *Endpoints:
112				return true, Convert_api_Endpoints_To_v1_Endpoints(a, b, s)
113			}
114
115		case *metav1.WatchEvent:
116			switch b := objB.(type) {
117			case *metav1.InternalEvent:
118				return true, metav1.Convert_versioned_Event_to_versioned_InternalEvent(a, b, s)
119			}
120		case *metav1.InternalEvent:
121			switch b := objB.(type) {
122			case *metav1.WatchEvent:
123				return true, metav1.Convert_versioned_InternalEvent_to_versioned_Event(a, b, s)
124			}
125		}
126		return false, nil
127	})
128	return nil
129}
130
131func addConversionFuncs(scheme *runtime.Scheme) error {
132	// Add non-generated conversion functions
133	err := scheme.AddConversionFuncs(
134		Convert_api_Pod_To_v1_Pod,
135		Convert_api_PodSpec_To_v1_PodSpec,
136		Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec,
137		Convert_api_ServiceSpec_To_v1_ServiceSpec,
138		Convert_v1_Pod_To_api_Pod,
139		Convert_v1_PodSpec_To_api_PodSpec,
140		Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec,
141		Convert_v1_Secret_To_api_Secret,
142		Convert_v1_ServiceSpec_To_api_ServiceSpec,
143		Convert_v1_ResourceList_To_api_ResourceList,
144		Convert_v1_ReplicationController_to_extensions_ReplicaSet,
145		Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec,
146		Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus,
147		Convert_extensions_ReplicaSet_to_v1_ReplicationController,
148		Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec,
149		Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus,
150	)
151	if err != nil {
152		return err
153	}
154
155	// Add field label conversions for kinds having selectable nothing but ObjectMeta fields.
156	for _, k := range []string{
157		"Endpoints",
158		"ResourceQuota",
159		"PersistentVolumeClaim",
160		"Service",
161		"ServiceAccount",
162		"ConfigMap",
163	} {
164		kind := k // don't close over range variables
165		err = scheme.AddFieldLabelConversionFunc("v1", kind,
166			func(label, value string) (string, string, error) {
167				switch label {
168				case "metadata.namespace",
169					"metadata.name":
170					return label, value, nil
171				default:
172					return "", "", fmt.Errorf("field label %q not supported for %q", label, kind)
173				}
174			},
175		)
176		if err != nil {
177			return err
178		}
179	}
180
181	// Add field conversion funcs.
182	err = scheme.AddFieldLabelConversionFunc("v1", "Pod",
183		func(label, value string) (string, string, error) {
184			switch label {
185			case "metadata.annotations",
186				"metadata.labels",
187				"metadata.name",
188				"metadata.namespace",
189				"spec.nodeName",
190				"spec.restartPolicy",
191				"spec.serviceAccountName",
192				"status.phase",
193				"status.podIP":
194				return label, value, nil
195				// This is for backwards compatibility with old v1 clients which send spec.host
196			case "spec.host":
197				return "spec.nodeName", value, nil
198			default:
199				return "", "", fmt.Errorf("field label not supported: %s", label)
200			}
201		},
202	)
203	if err != nil {
204		return err
205	}
206	err = scheme.AddFieldLabelConversionFunc("v1", "Node",
207		func(label, value string) (string, string, error) {
208			switch label {
209			case "metadata.name":
210				return label, value, nil
211			case "spec.unschedulable":
212				return label, value, nil
213			default:
214				return "", "", fmt.Errorf("field label not supported: %s", label)
215			}
216		},
217	)
218	if err != nil {
219		return err
220	}
221	err = scheme.AddFieldLabelConversionFunc("v1", "ReplicationController",
222		func(label, value string) (string, string, error) {
223			switch label {
224			case "metadata.name",
225				"metadata.namespace",
226				"status.replicas":
227				return label, value, nil
228			default:
229				return "", "", fmt.Errorf("field label not supported: %s", label)
230			}
231		})
232	if err != nil {
233		return err
234	}
235	err = scheme.AddFieldLabelConversionFunc("v1", "PersistentVolume",
236		func(label, value string) (string, string, error) {
237			switch label {
238			case "metadata.name":
239				return label, value, nil
240			default:
241				return "", "", fmt.Errorf("field label not supported: %s", label)
242			}
243		},
244	)
245	if err != nil {
246		return err
247	}
248	if err := AddFieldLabelConversionsForEvent(scheme); err != nil {
249		return err
250	}
251	if err := AddFieldLabelConversionsForNamespace(scheme); err != nil {
252		return err
253	}
254	if err := AddFieldLabelConversionsForSecret(scheme); err != nil {
255		return err
256	}
257	return nil
258}
259
260func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *ReplicationController, out *extensions.ReplicaSet, s conversion.Scope) error {
261	out.ObjectMeta = in.ObjectMeta
262	if err := Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil {
263		return err
264	}
265	if err := Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil {
266		return err
267	}
268	return nil
269}
270
271func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error {
272	out.Replicas = *in.Replicas
273	if in.Selector != nil {
274		metav1.Convert_map_to_unversioned_LabelSelector(&in.Selector, out.Selector, s)
275	}
276	if in.Template != nil {
277		if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, &out.Template, s); err != nil {
278			return err
279		}
280	}
281	return nil
282}
283
284func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *ReplicationControllerStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error {
285	out.Replicas = in.Replicas
286	out.FullyLabeledReplicas = in.FullyLabeledReplicas
287	out.ReadyReplicas = in.ReadyReplicas
288	out.AvailableReplicas = in.AvailableReplicas
289	out.ObservedGeneration = in.ObservedGeneration
290	return nil
291}
292
293func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.ReplicaSet, out *ReplicationController, s conversion.Scope) error {
294	out.ObjectMeta = in.ObjectMeta
295	if err := Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil {
296		fieldErr, ok := err.(*field.Error)
297		if !ok {
298			return err
299		}
300		if out.Annotations == nil {
301			out.Annotations = make(map[string]string)
302		}
303		out.Annotations[api.NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String()
304	}
305	if err := Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil {
306		return err
307	}
308	return nil
309}
310
311func Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(in *extensions.ReplicaSetSpec, out *ReplicationControllerSpec, s conversion.Scope) error {
312	out.Replicas = new(int32)
313	*out.Replicas = in.Replicas
314	out.MinReadySeconds = in.MinReadySeconds
315	var invalidErr error
316	if in.Selector != nil {
317		invalidErr = metav1.Convert_unversioned_LabelSelector_to_map(in.Selector, &out.Selector, s)
318	}
319	out.Template = new(PodTemplateSpec)
320	if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, out.Template, s); err != nil {
321		return err
322	}
323	return invalidErr
324}
325
326func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *extensions.ReplicaSetStatus, out *ReplicationControllerStatus, s conversion.Scope) error {
327	out.Replicas = in.Replicas
328	out.FullyLabeledReplicas = in.FullyLabeledReplicas
329	out.ReadyReplicas = in.ReadyReplicas
330	out.AvailableReplicas = in.AvailableReplicas
331	out.ObservedGeneration = in.ObservedGeneration
332	return nil
333}
334
335func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *ReplicationControllerSpec, s conversion.Scope) error {
336	out.Replicas = &in.Replicas
337	out.MinReadySeconds = in.MinReadySeconds
338	out.Selector = in.Selector
339	if in.Template != nil {
340		out.Template = new(PodTemplateSpec)
341		if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil {
342			return err
343		}
344	} else {
345		out.Template = nil
346	}
347	return nil
348}
349
350func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error {
351	if in.Replicas != nil {
352		out.Replicas = *in.Replicas
353	}
354	out.MinReadySeconds = in.MinReadySeconds
355	out.Selector = in.Selector
356	if in.Template != nil {
357		out.Template = new(api.PodTemplateSpec)
358		if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil {
359			return err
360		}
361	} else {
362		out.Template = nil
363	}
364	return nil
365}
366
367func Convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error {
368	if err := autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in, out, s); err != nil {
369		return err
370	}
371
372	if old := out.Annotations; old != nil {
373		out.Annotations = make(map[string]string, len(old))
374		for k, v := range old {
375			out.Annotations[k] = v
376		}
377	}
378	if len(out.Status.InitContainerStatuses) > 0 {
379		if out.Annotations == nil {
380			out.Annotations = make(map[string]string)
381		}
382		value, err := json.Marshal(out.Status.InitContainerStatuses)
383		if err != nil {
384			return err
385		}
386		out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value)
387		out.Annotations[PodInitContainerStatusesBetaAnnotationKey] = string(value)
388	} else {
389		delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
390		delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
391	}
392	return nil
393}
394
395func Convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error {
396	// TODO: sometime after we move init container to stable, remove these conversions
397	// If there is a beta annotation, copy to alpha key.
398	// See commit log for PR #31026 for why we do this.
399	if valueBeta, okBeta := in.Annotations[PodInitContainerStatusesBetaAnnotationKey]; okBeta {
400		in.Annotations[PodInitContainerStatusesAnnotationKey] = valueBeta
401	}
402	// Move the annotation to the internal repr. field
403	if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok {
404		var values []ContainerStatus
405		if err := json.Unmarshal([]byte(value), &values); err != nil {
406			return err
407		}
408		// Conversion from external to internal version exists more to
409		// satisfy the needs of the decoder than it does to be a general
410		// purpose tool. And Decode always creates an intermediate object
411		// to decode to. Thus the caller of UnsafeConvertToVersion is
412		// taking responsibility to ensure mutation of in is not exposed
413		// back to the caller.
414		in.Status.InitContainerStatuses = values
415	}
416
417	if err := autoConvert_v1_PodStatusResult_To_api_PodStatusResult(in, out, s); err != nil {
418		return err
419	}
420	if len(out.Annotations) > 0 {
421		old := out.Annotations
422		out.Annotations = make(map[string]string, len(old))
423		for k, v := range old {
424			out.Annotations[k] = v
425		}
426		delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
427		delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
428	}
429	return nil
430}
431
432func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error {
433	if err := autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s); err != nil {
434		return err
435	}
436
437	// TODO: sometime after we move init container to stable, remove these conversions.
438	if old := out.Annotations; old != nil {
439		out.Annotations = make(map[string]string, len(old))
440		for k, v := range old {
441			out.Annotations[k] = v
442		}
443	}
444	if len(out.Spec.InitContainers) > 0 {
445		if out.Annotations == nil {
446			out.Annotations = make(map[string]string)
447		}
448		value, err := json.Marshal(out.Spec.InitContainers)
449		if err != nil {
450			return err
451		}
452		out.Annotations[PodInitContainersAnnotationKey] = string(value)
453		out.Annotations[PodInitContainersBetaAnnotationKey] = string(value)
454	} else {
455		delete(out.Annotations, PodInitContainersAnnotationKey)
456		delete(out.Annotations, PodInitContainersBetaAnnotationKey)
457	}
458	return nil
459}
460
461func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error {
462	// TODO: sometime after we move init container to stable, remove these conversions
463	// If there is a beta annotation, copy to alpha key.
464	// See commit log for PR #31026 for why we do this.
465	if valueBeta, okBeta := in.Annotations[PodInitContainersBetaAnnotationKey]; okBeta {
466		in.Annotations[PodInitContainersAnnotationKey] = valueBeta
467	}
468	// Move the annotation to the internal repr. field
469	if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok {
470		var values []Container
471		if err := json.Unmarshal([]byte(value), &values); err != nil {
472			return err
473		}
474		// Conversion from external to internal version exists more to
475		// satisfy the needs of the decoder than it does to be a general
476		// purpose tool. And Decode always creates an intermediate object
477		// to decode to. Thus the caller of UnsafeConvertToVersion is
478		// taking responsibility to ensure mutation of in is not exposed
479		// back to the caller.
480		in.Spec.InitContainers = values
481
482		// Call defaulters explicitly until annotations are removed
483		for i := range in.Spec.InitContainers {
484			c := &in.Spec.InitContainers[i]
485			SetDefaults_Container(c)
486		}
487	}
488
489	if err := autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s); err != nil {
490		return err
491	}
492	if len(out.Annotations) > 0 {
493		old := out.Annotations
494		out.Annotations = make(map[string]string, len(old))
495		for k, v := range old {
496			out.Annotations[k] = v
497		}
498		delete(out.Annotations, PodInitContainersAnnotationKey)
499		delete(out.Annotations, PodInitContainersBetaAnnotationKey)
500	}
501	return nil
502}
503
504// The following two PodSpec conversions are done here to support ServiceAccount
505// as an alias for ServiceAccountName.
506func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error {
507	if err := autoConvert_api_PodSpec_To_v1_PodSpec(in, out, s); err != nil {
508		return err
509	}
510
511	// DeprecatedServiceAccount is an alias for ServiceAccountName.
512	out.DeprecatedServiceAccount = in.ServiceAccountName
513
514	if in.SecurityContext != nil {
515		// the host namespace fields have to be handled here for backward compatibility
516		// with v1.0.0
517		out.HostPID = in.SecurityContext.HostPID
518		out.HostNetwork = in.SecurityContext.HostNetwork
519		out.HostIPC = in.SecurityContext.HostIPC
520	}
521
522	return nil
523}
524
525func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error {
526	if err := autoConvert_v1_PodSpec_To_api_PodSpec(in, out, s); err != nil {
527		return err
528	}
529
530	// We support DeprecatedServiceAccount as an alias for ServiceAccountName.
531	// If both are specified, ServiceAccountName (the new field) wins.
532	if in.ServiceAccountName == "" {
533		out.ServiceAccountName = in.DeprecatedServiceAccount
534	}
535
536	// the host namespace fields have to be handled specially for backward compatibility
537	// with v1.0.0
538	if out.SecurityContext == nil {
539		out.SecurityContext = new(api.PodSecurityContext)
540	}
541	out.SecurityContext.HostNetwork = in.HostNetwork
542	out.SecurityContext.HostPID = in.HostPID
543	out.SecurityContext.HostIPC = in.HostIPC
544
545	return nil
546}
547
548func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error {
549	if err := autoConvert_api_Pod_To_v1_Pod(in, out, s); err != nil {
550		return err
551	}
552
553	// TODO: sometime after we move init container to stable, remove these conversions
554	if len(out.Spec.InitContainers) > 0 || len(out.Status.InitContainerStatuses) > 0 {
555		old := out.Annotations
556		out.Annotations = make(map[string]string, len(old))
557		for k, v := range old {
558			out.Annotations[k] = v
559		}
560		delete(out.Annotations, PodInitContainersAnnotationKey)
561		delete(out.Annotations, PodInitContainersBetaAnnotationKey)
562		delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
563		delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
564	}
565	if len(out.Spec.InitContainers) > 0 {
566		value, err := json.Marshal(out.Spec.InitContainers)
567		if err != nil {
568			return err
569		}
570		out.Annotations[PodInitContainersAnnotationKey] = string(value)
571		out.Annotations[PodInitContainersBetaAnnotationKey] = string(value)
572	}
573	if len(out.Status.InitContainerStatuses) > 0 {
574		value, err := json.Marshal(out.Status.InitContainerStatuses)
575		if err != nil {
576			return err
577		}
578		out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value)
579		out.Annotations[PodInitContainerStatusesBetaAnnotationKey] = string(value)
580	}
581
582	return nil
583}
584
585func Convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error {
586	// If there is a beta annotation, copy to alpha key.
587	// See commit log for PR #31026 for why we do this.
588	if valueBeta, okBeta := in.Annotations[PodInitContainersBetaAnnotationKey]; okBeta {
589		in.Annotations[PodInitContainersAnnotationKey] = valueBeta
590	}
591	// TODO: sometime after we move init container to stable, remove these conversions
592	// Move the annotation to the internal repr. field
593	if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok {
594		var values []Container
595		if err := json.Unmarshal([]byte(value), &values); err != nil {
596			return err
597		}
598		// Conversion from external to internal version exists more to
599		// satisfy the needs of the decoder than it does to be a general
600		// purpose tool. And Decode always creates an intermediate object
601		// to decode to. Thus the caller of UnsafeConvertToVersion is
602		// taking responsibility to ensure mutation of in is not exposed
603		// back to the caller.
604		in.Spec.InitContainers = values
605		// Call defaulters explicitly until annotations are removed
606		for i := range in.Spec.InitContainers {
607			c := &in.Spec.InitContainers[i]
608			SetDefaults_Container(c)
609		}
610	}
611	// If there is a beta annotation, copy to alpha key.
612	// See commit log for PR #31026 for why we do this.
613	if valueBeta, okBeta := in.Annotations[PodInitContainerStatusesBetaAnnotationKey]; okBeta {
614		in.Annotations[PodInitContainerStatusesAnnotationKey] = valueBeta
615	}
616	if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok {
617		var values []ContainerStatus
618		if err := json.Unmarshal([]byte(value), &values); err != nil {
619			return err
620		}
621		// Conversion from external to internal version exists more to
622		// satisfy the needs of the decoder than it does to be a general
623		// purpose tool. And Decode always creates an intermediate object
624		// to decode to. Thus the caller of UnsafeConvertToVersion is
625		// taking responsibility to ensure mutation of in is not exposed
626		// back to the caller.
627		in.Status.InitContainerStatuses = values
628	}
629
630	if err := autoConvert_v1_Pod_To_api_Pod(in, out, s); err != nil {
631		return err
632	}
633	if len(out.Annotations) > 0 {
634		old := out.Annotations
635		out.Annotations = make(map[string]string, len(old))
636		for k, v := range old {
637			out.Annotations[k] = v
638		}
639		delete(out.Annotations, PodInitContainersAnnotationKey)
640		delete(out.Annotations, PodInitContainersBetaAnnotationKey)
641		delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
642		delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
643	}
644	return nil
645}
646
647func Convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error {
648	if err := autoConvert_api_ServiceSpec_To_v1_ServiceSpec(in, out, s); err != nil {
649		return err
650	}
651	// Publish both externalIPs and deprecatedPublicIPs fields in v1.
652	out.DeprecatedPublicIPs = in.ExternalIPs
653	return nil
654}
655
656func Convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error {
657	if err := autoConvert_v1_Secret_To_api_Secret(in, out, s); err != nil {
658		return err
659	}
660
661	// StringData overwrites Data
662	if len(in.StringData) > 0 {
663		if out.Data == nil {
664			out.Data = map[string][]byte{}
665		}
666		for k, v := range in.StringData {
667			out.Data[k] = []byte(v)
668		}
669	}
670
671	return nil
672}
673
674func Convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error {
675	if err := autoConvert_v1_ServiceSpec_To_api_ServiceSpec(in, out, s); err != nil {
676		return err
677	}
678	// Prefer the legacy deprecatedPublicIPs field, if provided.
679	if len(in.DeprecatedPublicIPs) > 0 {
680		out.ExternalIPs = in.DeprecatedPublicIPs
681	}
682	return nil
683}
684
685func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *PodSecurityContext, s conversion.Scope) error {
686	out.SupplementalGroups = in.SupplementalGroups
687	if in.SELinuxOptions != nil {
688		out.SELinuxOptions = new(SELinuxOptions)
689		if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
690			return err
691		}
692	} else {
693		out.SELinuxOptions = nil
694	}
695	out.RunAsUser = in.RunAsUser
696	out.RunAsNonRoot = in.RunAsNonRoot
697	out.FSGroup = in.FSGroup
698	return nil
699}
700
701func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
702	out.SupplementalGroups = in.SupplementalGroups
703	if in.SELinuxOptions != nil {
704		out.SELinuxOptions = new(api.SELinuxOptions)
705		if err := Convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
706			return err
707		}
708	} else {
709		out.SELinuxOptions = nil
710	}
711	out.RunAsUser = in.RunAsUser
712	out.RunAsNonRoot = in.RunAsNonRoot
713	out.FSGroup = in.FSGroup
714	return nil
715}
716
717// +k8s:conversion-fn=copy-only
718func Convert_v1_ResourceList_To_api_ResourceList(in *ResourceList, out *api.ResourceList, s conversion.Scope) error {
719	if *in == nil {
720		return nil
721	}
722	if *out == nil {
723		*out = make(api.ResourceList, len(*in))
724	}
725	for key, val := range *in {
726		// Moved to defaults
727		// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
728		// In the future, we should instead reject values that need rounding.
729		// const milliScale = -3
730		// val.RoundUp(milliScale)
731
732		(*out)[api.ResourceName(key)] = val
733	}
734	return nil
735}
736
737func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
738	return scheme.AddFieldLabelConversionFunc("v1", "Event",
739		func(label, value string) (string, string, error) {
740			switch label {
741			case "involvedObject.kind",
742				"involvedObject.namespace",
743				"involvedObject.name",
744				"involvedObject.uid",
745				"involvedObject.apiVersion",
746				"involvedObject.resourceVersion",
747				"involvedObject.fieldPath",
748				"reason",
749				"source",
750				"type",
751				"metadata.namespace",
752				"metadata.name":
753				return label, value, nil
754			default:
755				return "", "", fmt.Errorf("field label not supported: %s", label)
756			}
757		})
758}
759
760func AddFieldLabelConversionsForNamespace(scheme *runtime.Scheme) error {
761	return scheme.AddFieldLabelConversionFunc("v1", "Namespace",
762		func(label, value string) (string, string, error) {
763			switch label {
764			case "status.phase",
765				"metadata.name":
766				return label, value, nil
767			default:
768				return "", "", fmt.Errorf("field label not supported: %s", label)
769			}
770		})
771}
772
773func AddFieldLabelConversionsForSecret(scheme *runtime.Scheme) error {
774	return scheme.AddFieldLabelConversionFunc("v1", "Secret",
775		func(label, value string) (string, string, error) {
776			switch label {
777			case "type",
778				"metadata.namespace",
779				"metadata.name":
780				return label, value, nil
781			default:
782				return "", "", fmt.Errorf("field label not supported: %s", label)
783			}
784		})
785}
786