conversion.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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. "fmt"
  16. "reflect"
  17. v1 "k8s.io/api/core/v1"
  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/kubernetes/pkg/apis/apps"
  23. "k8s.io/kubernetes/pkg/apis/core"
  24. )
  25. func addConversionFuncs(scheme *runtime.Scheme) error {
  26. // Add non-generated conversion functions
  27. err := scheme.AddConversionFuncs(
  28. Convert_core_Pod_To_v1_Pod,
  29. Convert_core_PodSpec_To_v1_PodSpec,
  30. Convert_core_ReplicationControllerSpec_To_v1_ReplicationControllerSpec,
  31. Convert_core_ServiceSpec_To_v1_ServiceSpec,
  32. Convert_v1_Pod_To_core_Pod,
  33. Convert_v1_PodSpec_To_core_PodSpec,
  34. Convert_v1_ReplicationControllerSpec_To_core_ReplicationControllerSpec,
  35. Convert_v1_Secret_To_core_Secret,
  36. Convert_v1_ServiceSpec_To_core_ServiceSpec,
  37. Convert_v1_ResourceList_To_core_ResourceList,
  38. Convert_v1_ReplicationController_To_apps_ReplicaSet,
  39. Convert_v1_ReplicationControllerSpec_To_apps_ReplicaSetSpec,
  40. Convert_v1_ReplicationControllerStatus_To_apps_ReplicaSetStatus,
  41. Convert_apps_ReplicaSet_To_v1_ReplicationController,
  42. Convert_apps_ReplicaSetSpec_To_v1_ReplicationControllerSpec,
  43. Convert_apps_ReplicaSetStatus_To_v1_ReplicationControllerStatus,
  44. )
  45. if err != nil {
  46. return err
  47. }
  48. // Add field conversion funcs.
  49. err = scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Pod"),
  50. func(label, value string) (string, string, error) {
  51. switch label {
  52. case "metadata.name",
  53. "metadata.namespace",
  54. "spec.nodeName",
  55. "spec.restartPolicy",
  56. "spec.schedulerName",
  57. "spec.serviceAccountName",
  58. "status.phase",
  59. "status.podIP",
  60. "status.nominatedNodeName":
  61. return label, value, nil
  62. // This is for backwards compatibility with old v1 clients which send spec.host
  63. case "spec.host":
  64. return "spec.nodeName", value, nil
  65. default:
  66. return "", "", fmt.Errorf("field label not supported: %s", label)
  67. }
  68. },
  69. )
  70. if err != nil {
  71. return err
  72. }
  73. err = scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Node"),
  74. func(label, value string) (string, string, error) {
  75. switch label {
  76. case "metadata.name":
  77. return label, value, nil
  78. case "spec.unschedulable":
  79. return label, value, nil
  80. default:
  81. return "", "", fmt.Errorf("field label not supported: %s", label)
  82. }
  83. },
  84. )
  85. if err != nil {
  86. return err
  87. }
  88. err = scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("ReplicationController"),
  89. func(label, value string) (string, string, error) {
  90. switch label {
  91. case "metadata.name",
  92. "metadata.namespace",
  93. "status.replicas":
  94. return label, value, nil
  95. default:
  96. return "", "", fmt.Errorf("field label not supported: %s", label)
  97. }
  98. })
  99. if err != nil {
  100. return err
  101. }
  102. if err := AddFieldLabelConversionsForEvent(scheme); err != nil {
  103. return err
  104. }
  105. if err := AddFieldLabelConversionsForNamespace(scheme); err != nil {
  106. return err
  107. }
  108. if err := AddFieldLabelConversionsForSecret(scheme); err != nil {
  109. return err
  110. }
  111. return nil
  112. }
  113. func Convert_v1_ReplicationController_To_apps_ReplicaSet(in *v1.ReplicationController, out *apps.ReplicaSet, s conversion.Scope) error {
  114. out.ObjectMeta = in.ObjectMeta
  115. if err := Convert_v1_ReplicationControllerSpec_To_apps_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil {
  116. return err
  117. }
  118. if err := Convert_v1_ReplicationControllerStatus_To_apps_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil {
  119. return err
  120. }
  121. return nil
  122. }
  123. func Convert_v1_ReplicationControllerSpec_To_apps_ReplicaSetSpec(in *v1.ReplicationControllerSpec, out *apps.ReplicaSetSpec, s conversion.Scope) error {
  124. out.Replicas = *in.Replicas
  125. out.MinReadySeconds = in.MinReadySeconds
  126. if in.Selector != nil {
  127. out.Selector = new(metav1.LabelSelector)
  128. metav1.Convert_Map_string_To_string_To_v1_LabelSelector(&in.Selector, out.Selector, s)
  129. }
  130. if in.Template != nil {
  131. if err := Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(in.Template, &out.Template, s); err != nil {
  132. return err
  133. }
  134. }
  135. return nil
  136. }
  137. func Convert_v1_ReplicationControllerStatus_To_apps_ReplicaSetStatus(in *v1.ReplicationControllerStatus, out *apps.ReplicaSetStatus, s conversion.Scope) error {
  138. out.Replicas = in.Replicas
  139. out.FullyLabeledReplicas = in.FullyLabeledReplicas
  140. out.ReadyReplicas = in.ReadyReplicas
  141. out.AvailableReplicas = in.AvailableReplicas
  142. out.ObservedGeneration = in.ObservedGeneration
  143. for _, cond := range in.Conditions {
  144. out.Conditions = append(out.Conditions, apps.ReplicaSetCondition{
  145. Type: apps.ReplicaSetConditionType(cond.Type),
  146. Status: core.ConditionStatus(cond.Status),
  147. LastTransitionTime: cond.LastTransitionTime,
  148. Reason: cond.Reason,
  149. Message: cond.Message,
  150. })
  151. }
  152. return nil
  153. }
  154. func Convert_apps_ReplicaSet_To_v1_ReplicationController(in *apps.ReplicaSet, out *v1.ReplicationController, s conversion.Scope) error {
  155. out.ObjectMeta = in.ObjectMeta
  156. if err := Convert_apps_ReplicaSetSpec_To_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil {
  157. fieldErr, ok := err.(*field.Error)
  158. if !ok {
  159. return err
  160. }
  161. if out.Annotations == nil {
  162. out.Annotations = make(map[string]string)
  163. }
  164. out.Annotations[v1.NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String()
  165. }
  166. if err := Convert_apps_ReplicaSetStatus_To_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil {
  167. return err
  168. }
  169. return nil
  170. }
  171. func Convert_apps_ReplicaSetSpec_To_v1_ReplicationControllerSpec(in *apps.ReplicaSetSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error {
  172. out.Replicas = new(int32)
  173. *out.Replicas = in.Replicas
  174. out.MinReadySeconds = in.MinReadySeconds
  175. var invalidErr error
  176. if in.Selector != nil {
  177. invalidErr = metav1.Convert_v1_LabelSelector_To_Map_string_To_string(in.Selector, &out.Selector, s)
  178. }
  179. out.Template = new(v1.PodTemplateSpec)
  180. if err := Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, out.Template, s); err != nil {
  181. return err
  182. }
  183. return invalidErr
  184. }
  185. func Convert_apps_ReplicaSetStatus_To_v1_ReplicationControllerStatus(in *apps.ReplicaSetStatus, out *v1.ReplicationControllerStatus, s conversion.Scope) error {
  186. out.Replicas = in.Replicas
  187. out.FullyLabeledReplicas = in.FullyLabeledReplicas
  188. out.ReadyReplicas = in.ReadyReplicas
  189. out.AvailableReplicas = in.AvailableReplicas
  190. out.ObservedGeneration = in.ObservedGeneration
  191. for _, cond := range in.Conditions {
  192. out.Conditions = append(out.Conditions, v1.ReplicationControllerCondition{
  193. Type: v1.ReplicationControllerConditionType(cond.Type),
  194. Status: v1.ConditionStatus(cond.Status),
  195. LastTransitionTime: cond.LastTransitionTime,
  196. Reason: cond.Reason,
  197. Message: cond.Message,
  198. })
  199. }
  200. return nil
  201. }
  202. func Convert_core_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *core.ReplicationControllerSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error {
  203. out.Replicas = &in.Replicas
  204. out.MinReadySeconds = in.MinReadySeconds
  205. out.Selector = in.Selector
  206. if in.Template != nil {
  207. out.Template = new(v1.PodTemplateSpec)
  208. if err := Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil {
  209. return err
  210. }
  211. } else {
  212. out.Template = nil
  213. }
  214. return nil
  215. }
  216. func Convert_v1_ReplicationControllerSpec_To_core_ReplicationControllerSpec(in *v1.ReplicationControllerSpec, out *core.ReplicationControllerSpec, s conversion.Scope) error {
  217. if in.Replicas != nil {
  218. out.Replicas = *in.Replicas
  219. }
  220. out.MinReadySeconds = in.MinReadySeconds
  221. out.Selector = in.Selector
  222. if in.Template != nil {
  223. out.Template = new(core.PodTemplateSpec)
  224. if err := Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(in.Template, out.Template, s); err != nil {
  225. return err
  226. }
  227. } else {
  228. out.Template = nil
  229. }
  230. return nil
  231. }
  232. func Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(in *core.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error {
  233. if err := autoConvert_core_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s); err != nil {
  234. return err
  235. }
  236. // drop init container annotations so they don't take effect on legacy kubelets.
  237. // remove this once the oldest supported kubelet no longer honors the annotations over the field.
  238. out.Annotations = dropInitContainerAnnotations(out.Annotations)
  239. return nil
  240. }
  241. func Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(in *v1.PodTemplateSpec, out *core.PodTemplateSpec, s conversion.Scope) error {
  242. if err := autoConvert_v1_PodTemplateSpec_To_core_PodTemplateSpec(in, out, s); err != nil {
  243. return err
  244. }
  245. // drop init container annotations so they don't show up as differences when receiving requests from old clients
  246. out.Annotations = dropInitContainerAnnotations(out.Annotations)
  247. return nil
  248. }
  249. // The following two v1.PodSpec conversions are done here to support v1.ServiceAccount
  250. // as an alias for ServiceAccountName.
  251. func Convert_core_PodSpec_To_v1_PodSpec(in *core.PodSpec, out *v1.PodSpec, s conversion.Scope) error {
  252. if err := autoConvert_core_PodSpec_To_v1_PodSpec(in, out, s); err != nil {
  253. return err
  254. }
  255. // DeprecatedServiceAccount is an alias for ServiceAccountName.
  256. out.DeprecatedServiceAccount = in.ServiceAccountName
  257. if in.SecurityContext != nil {
  258. // the host namespace fields have to be handled here for backward compatibility
  259. // with v1.0.0
  260. out.HostPID = in.SecurityContext.HostPID
  261. out.HostNetwork = in.SecurityContext.HostNetwork
  262. out.HostIPC = in.SecurityContext.HostIPC
  263. out.ShareProcessNamespace = in.SecurityContext.ShareProcessNamespace
  264. }
  265. return nil
  266. }
  267. func Convert_v1_PodSpec_To_core_PodSpec(in *v1.PodSpec, out *core.PodSpec, s conversion.Scope) error {
  268. if err := autoConvert_v1_PodSpec_To_core_PodSpec(in, out, s); err != nil {
  269. return err
  270. }
  271. // We support DeprecatedServiceAccount as an alias for ServiceAccountName.
  272. // If both are specified, ServiceAccountName (the new field) wins.
  273. if in.ServiceAccountName == "" {
  274. out.ServiceAccountName = in.DeprecatedServiceAccount
  275. }
  276. // the host namespace fields have to be handled specially for backward compatibility
  277. // with v1.0.0
  278. if out.SecurityContext == nil {
  279. out.SecurityContext = new(core.PodSecurityContext)
  280. }
  281. out.SecurityContext.HostNetwork = in.HostNetwork
  282. out.SecurityContext.HostPID = in.HostPID
  283. out.SecurityContext.HostIPC = in.HostIPC
  284. out.SecurityContext.ShareProcessNamespace = in.ShareProcessNamespace
  285. return nil
  286. }
  287. func Convert_v1_Pod_To_core_Pod(in *v1.Pod, out *core.Pod, s conversion.Scope) error {
  288. if err := autoConvert_v1_Pod_To_core_Pod(in, out, s); err != nil {
  289. return err
  290. }
  291. // drop init container annotations so they don't show up as differences when receiving requests from old clients
  292. out.Annotations = dropInitContainerAnnotations(out.Annotations)
  293. return nil
  294. }
  295. func Convert_core_Pod_To_v1_Pod(in *core.Pod, out *v1.Pod, s conversion.Scope) error {
  296. if err := autoConvert_core_Pod_To_v1_Pod(in, out, s); err != nil {
  297. return err
  298. }
  299. // drop init container annotations so they don't take effect on legacy kubelets.
  300. // remove this once the oldest supported kubelet no longer honors the annotations over the field.
  301. out.Annotations = dropInitContainerAnnotations(out.Annotations)
  302. return nil
  303. }
  304. func Convert_v1_Secret_To_core_Secret(in *v1.Secret, out *core.Secret, s conversion.Scope) error {
  305. if err := autoConvert_v1_Secret_To_core_Secret(in, out, s); err != nil {
  306. return err
  307. }
  308. // StringData overwrites Data
  309. if len(in.StringData) > 0 {
  310. if out.Data == nil {
  311. out.Data = map[string][]byte{}
  312. }
  313. for k, v := range in.StringData {
  314. out.Data[k] = []byte(v)
  315. }
  316. }
  317. return nil
  318. }
  319. // +k8s:conversion-fn=copy-only
  320. func Convert_v1_ResourceList_To_core_ResourceList(in *v1.ResourceList, out *core.ResourceList, s conversion.Scope) error {
  321. if *in == nil {
  322. return nil
  323. }
  324. if *out == nil {
  325. *out = make(core.ResourceList, len(*in))
  326. }
  327. for key, val := range *in {
  328. // Moved to defaults
  329. // TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
  330. // In the future, we should instead reject values that need rounding.
  331. // const milliScale = -3
  332. // val.RoundUp(milliScale)
  333. (*out)[core.ResourceName(key)] = val
  334. }
  335. return nil
  336. }
  337. func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
  338. return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Event"),
  339. func(label, value string) (string, string, error) {
  340. switch label {
  341. case "involvedObject.kind",
  342. "involvedObject.namespace",
  343. "involvedObject.name",
  344. "involvedObject.uid",
  345. "involvedObject.apiVersion",
  346. "involvedObject.resourceVersion",
  347. "involvedObject.fieldPath",
  348. "reason",
  349. "source",
  350. "type",
  351. "metadata.namespace",
  352. "metadata.name":
  353. return label, value, nil
  354. default:
  355. return "", "", fmt.Errorf("field label not supported: %s", label)
  356. }
  357. })
  358. }
  359. func AddFieldLabelConversionsForNamespace(scheme *runtime.Scheme) error {
  360. return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Namespace"),
  361. func(label, value string) (string, string, error) {
  362. switch label {
  363. case "status.phase",
  364. "metadata.name":
  365. return label, value, nil
  366. default:
  367. return "", "", fmt.Errorf("field label not supported: %s", label)
  368. }
  369. })
  370. }
  371. func AddFieldLabelConversionsForSecret(scheme *runtime.Scheme) error {
  372. return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Secret"),
  373. func(label, value string) (string, string, error) {
  374. switch label {
  375. case "type",
  376. "metadata.namespace",
  377. "metadata.name":
  378. return label, value, nil
  379. default:
  380. return "", "", fmt.Errorf("field label not supported: %s", label)
  381. }
  382. })
  383. }
  384. var initContainerAnnotations = map[string]bool{
  385. "pod.beta.kubernetes.io/init-containers": true,
  386. "pod.alpha.kubernetes.io/init-containers": true,
  387. "pod.beta.kubernetes.io/init-container-statuses": true,
  388. "pod.alpha.kubernetes.io/init-container-statuses": true,
  389. }
  390. // dropInitContainerAnnotations returns a copy of the annotations with init container annotations removed,
  391. // or the original annotations if no init container annotations were present.
  392. //
  393. // this can be removed once no clients prior to 1.8 are supported, and no kubelets prior to 1.8 can be run
  394. // (we don't support kubelets older than 2 versions skewed from the apiserver, but we don't prevent them, either)
  395. func dropInitContainerAnnotations(oldAnnotations map[string]string) map[string]string {
  396. if len(oldAnnotations) == 0 {
  397. return oldAnnotations
  398. }
  399. found := false
  400. for k := range initContainerAnnotations {
  401. if _, ok := oldAnnotations[k]; ok {
  402. found = true
  403. break
  404. }
  405. }
  406. if !found {
  407. return oldAnnotations
  408. }
  409. newAnnotations := make(map[string]string, len(oldAnnotations))
  410. for k, v := range oldAnnotations {
  411. if !initContainerAnnotations[k] {
  412. newAnnotations[k] = v
  413. }
  414. }
  415. return newAnnotations
  416. }
  417. // Convert_core_PersistentVolumeSpec_To_v1_PersistentVolumeSpec is defined outside the autogenerated file for use by other API packages
  418. func Convert_core_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in *core.PersistentVolumeSpec, out *v1.PersistentVolumeSpec, s conversion.Scope) error {
  419. return autoConvert_core_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in, out, s)
  420. }
  421. // Convert_v1_PersistentVolumeSpec_To_core_PersistentVolumeSpec is defined outside the autogenerated file for use by other API packages
  422. func Convert_v1_PersistentVolumeSpec_To_core_PersistentVolumeSpec(in *v1.PersistentVolumeSpec, out *core.PersistentVolumeSpec, s conversion.Scope) error {
  423. return autoConvert_v1_PersistentVolumeSpec_To_core_PersistentVolumeSpec(in, out, s)
  424. }