conversion.go 25 KB

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