defaults.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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. "k8s.io/apimachinery/pkg/runtime"
  16. "k8s.io/apimachinery/pkg/util/intstr"
  17. "k8s.io/client-go/pkg/util"
  18. "k8s.io/client-go/pkg/util/parsers"
  19. )
  20. func addDefaultingFuncs(scheme *runtime.Scheme) error {
  21. RegisterDefaults(scheme)
  22. return scheme.AddDefaultingFuncs(
  23. SetDefaults_PodExecOptions,
  24. SetDefaults_PodAttachOptions,
  25. SetDefaults_ReplicationController,
  26. SetDefaults_Volume,
  27. SetDefaults_ContainerPort,
  28. SetDefaults_Container,
  29. SetDefaults_ServiceSpec,
  30. SetDefaults_Pod,
  31. SetDefaults_PodSpec,
  32. SetDefaults_Probe,
  33. SetDefaults_SecretVolumeSource,
  34. SetDefaults_ConfigMapVolumeSource,
  35. SetDefaults_DownwardAPIVolumeSource,
  36. SetDefaults_ProjectedVolumeSource,
  37. SetDefaults_Secret,
  38. SetDefaults_PersistentVolume,
  39. SetDefaults_PersistentVolumeClaim,
  40. SetDefaults_ISCSIVolumeSource,
  41. SetDefaults_Endpoints,
  42. SetDefaults_HTTPGetAction,
  43. SetDefaults_NamespaceStatus,
  44. SetDefaults_Node,
  45. SetDefaults_NodeStatus,
  46. SetDefaults_ObjectFieldSelector,
  47. SetDefaults_LimitRangeItem,
  48. SetDefaults_ConfigMap,
  49. SetDefaults_RBDVolumeSource,
  50. SetDefaults_ResourceList,
  51. )
  52. }
  53. func SetDefaults_ResourceList(obj *ResourceList) {
  54. for key, val := range *obj {
  55. // TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
  56. // In the future, we should instead reject values that need rounding.
  57. const milliScale = -3
  58. val.RoundUp(milliScale)
  59. (*obj)[ResourceName(key)] = val
  60. }
  61. }
  62. func SetDefaults_PodExecOptions(obj *PodExecOptions) {
  63. obj.Stdout = true
  64. obj.Stderr = true
  65. }
  66. func SetDefaults_PodAttachOptions(obj *PodAttachOptions) {
  67. obj.Stdout = true
  68. obj.Stderr = true
  69. }
  70. func SetDefaults_ReplicationController(obj *ReplicationController) {
  71. var labels map[string]string
  72. if obj.Spec.Template != nil {
  73. labels = obj.Spec.Template.Labels
  74. }
  75. // TODO: support templates defined elsewhere when we support them in the API
  76. if labels != nil {
  77. if len(obj.Spec.Selector) == 0 {
  78. obj.Spec.Selector = labels
  79. }
  80. if len(obj.Labels) == 0 {
  81. obj.Labels = labels
  82. }
  83. }
  84. if obj.Spec.Replicas == nil {
  85. obj.Spec.Replicas = new(int32)
  86. *obj.Spec.Replicas = 1
  87. }
  88. }
  89. func SetDefaults_Volume(obj *Volume) {
  90. if util.AllPtrFieldsNil(&obj.VolumeSource) {
  91. obj.VolumeSource = VolumeSource{
  92. EmptyDir: &EmptyDirVolumeSource{},
  93. }
  94. }
  95. }
  96. func SetDefaults_ContainerPort(obj *ContainerPort) {
  97. if obj.Protocol == "" {
  98. obj.Protocol = ProtocolTCP
  99. }
  100. }
  101. func SetDefaults_Container(obj *Container) {
  102. if obj.ImagePullPolicy == "" {
  103. // Ignore error and assume it has been validated elsewhere
  104. _, tag, _, _ := parsers.ParseImageName(obj.Image)
  105. // Check image tag
  106. if tag == "latest" {
  107. obj.ImagePullPolicy = PullAlways
  108. } else {
  109. obj.ImagePullPolicy = PullIfNotPresent
  110. }
  111. }
  112. if obj.TerminationMessagePath == "" {
  113. obj.TerminationMessagePath = TerminationMessagePathDefault
  114. }
  115. if obj.TerminationMessagePolicy == "" {
  116. obj.TerminationMessagePolicy = TerminationMessageReadFile
  117. }
  118. }
  119. func SetDefaults_ServiceSpec(obj *ServiceSpec) {
  120. if obj.SessionAffinity == "" {
  121. obj.SessionAffinity = ServiceAffinityNone
  122. }
  123. if obj.Type == "" {
  124. obj.Type = ServiceTypeClusterIP
  125. }
  126. for i := range obj.Ports {
  127. sp := &obj.Ports[i]
  128. if sp.Protocol == "" {
  129. sp.Protocol = ProtocolTCP
  130. }
  131. if sp.TargetPort == intstr.FromInt(0) || sp.TargetPort == intstr.FromString("") {
  132. sp.TargetPort = intstr.FromInt(int(sp.Port))
  133. }
  134. }
  135. }
  136. func SetDefaults_Pod(obj *Pod) {
  137. // If limits are specified, but requests are not, default requests to limits
  138. // This is done here rather than a more specific defaulting pass on ResourceRequirements
  139. // because we only want this defaulting semantic to take place on a Pod and not a PodTemplate
  140. for i := range obj.Spec.Containers {
  141. // set requests to limits if requests are not specified, but limits are
  142. if obj.Spec.Containers[i].Resources.Limits != nil {
  143. if obj.Spec.Containers[i].Resources.Requests == nil {
  144. obj.Spec.Containers[i].Resources.Requests = make(ResourceList)
  145. }
  146. for key, value := range obj.Spec.Containers[i].Resources.Limits {
  147. if _, exists := obj.Spec.Containers[i].Resources.Requests[key]; !exists {
  148. obj.Spec.Containers[i].Resources.Requests[key] = *(value.Copy())
  149. }
  150. }
  151. }
  152. }
  153. for i := range obj.Spec.InitContainers {
  154. if obj.Spec.InitContainers[i].Resources.Limits != nil {
  155. if obj.Spec.InitContainers[i].Resources.Requests == nil {
  156. obj.Spec.InitContainers[i].Resources.Requests = make(ResourceList)
  157. }
  158. for key, value := range obj.Spec.InitContainers[i].Resources.Limits {
  159. if _, exists := obj.Spec.InitContainers[i].Resources.Requests[key]; !exists {
  160. obj.Spec.InitContainers[i].Resources.Requests[key] = *(value.Copy())
  161. }
  162. }
  163. }
  164. }
  165. }
  166. func SetDefaults_PodSpec(obj *PodSpec) {
  167. if obj.DNSPolicy == "" {
  168. obj.DNSPolicy = DNSClusterFirst
  169. }
  170. if obj.RestartPolicy == "" {
  171. obj.RestartPolicy = RestartPolicyAlways
  172. }
  173. if obj.HostNetwork {
  174. defaultHostNetworkPorts(&obj.Containers)
  175. defaultHostNetworkPorts(&obj.InitContainers)
  176. }
  177. if obj.SecurityContext == nil {
  178. obj.SecurityContext = &PodSecurityContext{}
  179. }
  180. if obj.TerminationGracePeriodSeconds == nil {
  181. period := int64(DefaultTerminationGracePeriodSeconds)
  182. obj.TerminationGracePeriodSeconds = &period
  183. }
  184. if obj.SchedulerName == "" {
  185. obj.SchedulerName = DefaultSchedulerName
  186. }
  187. }
  188. func SetDefaults_Probe(obj *Probe) {
  189. if obj.TimeoutSeconds == 0 {
  190. obj.TimeoutSeconds = 1
  191. }
  192. if obj.PeriodSeconds == 0 {
  193. obj.PeriodSeconds = 10
  194. }
  195. if obj.SuccessThreshold == 0 {
  196. obj.SuccessThreshold = 1
  197. }
  198. if obj.FailureThreshold == 0 {
  199. obj.FailureThreshold = 3
  200. }
  201. }
  202. func SetDefaults_SecretVolumeSource(obj *SecretVolumeSource) {
  203. if obj.DefaultMode == nil {
  204. perm := int32(SecretVolumeSourceDefaultMode)
  205. obj.DefaultMode = &perm
  206. }
  207. }
  208. func SetDefaults_ConfigMapVolumeSource(obj *ConfigMapVolumeSource) {
  209. if obj.DefaultMode == nil {
  210. perm := int32(ConfigMapVolumeSourceDefaultMode)
  211. obj.DefaultMode = &perm
  212. }
  213. }
  214. func SetDefaults_DownwardAPIVolumeSource(obj *DownwardAPIVolumeSource) {
  215. if obj.DefaultMode == nil {
  216. perm := int32(DownwardAPIVolumeSourceDefaultMode)
  217. obj.DefaultMode = &perm
  218. }
  219. }
  220. func SetDefaults_Secret(obj *Secret) {
  221. if obj.Type == "" {
  222. obj.Type = SecretTypeOpaque
  223. }
  224. }
  225. func SetDefaults_ProjectedVolumeSource(obj *ProjectedVolumeSource) {
  226. if obj.DefaultMode == nil {
  227. perm := int32(ProjectedVolumeSourceDefaultMode)
  228. obj.DefaultMode = &perm
  229. }
  230. }
  231. func SetDefaults_PersistentVolume(obj *PersistentVolume) {
  232. if obj.Status.Phase == "" {
  233. obj.Status.Phase = VolumePending
  234. }
  235. if obj.Spec.PersistentVolumeReclaimPolicy == "" {
  236. obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain
  237. }
  238. }
  239. func SetDefaults_PersistentVolumeClaim(obj *PersistentVolumeClaim) {
  240. if obj.Status.Phase == "" {
  241. obj.Status.Phase = ClaimPending
  242. }
  243. }
  244. func SetDefaults_ISCSIVolumeSource(obj *ISCSIVolumeSource) {
  245. if obj.ISCSIInterface == "" {
  246. obj.ISCSIInterface = "default"
  247. }
  248. }
  249. func SetDefaults_AzureDiskVolumeSource(obj *AzureDiskVolumeSource) {
  250. if obj.CachingMode == nil {
  251. obj.CachingMode = new(AzureDataDiskCachingMode)
  252. *obj.CachingMode = AzureDataDiskCachingNone
  253. }
  254. if obj.FSType == nil {
  255. obj.FSType = new(string)
  256. *obj.FSType = "ext4"
  257. }
  258. if obj.ReadOnly == nil {
  259. obj.ReadOnly = new(bool)
  260. *obj.ReadOnly = false
  261. }
  262. }
  263. func SetDefaults_Endpoints(obj *Endpoints) {
  264. for i := range obj.Subsets {
  265. ss := &obj.Subsets[i]
  266. for i := range ss.Ports {
  267. ep := &ss.Ports[i]
  268. if ep.Protocol == "" {
  269. ep.Protocol = ProtocolTCP
  270. }
  271. }
  272. }
  273. }
  274. func SetDefaults_HTTPGetAction(obj *HTTPGetAction) {
  275. if obj.Path == "" {
  276. obj.Path = "/"
  277. }
  278. if obj.Scheme == "" {
  279. obj.Scheme = URISchemeHTTP
  280. }
  281. }
  282. func SetDefaults_NamespaceStatus(obj *NamespaceStatus) {
  283. if obj.Phase == "" {
  284. obj.Phase = NamespaceActive
  285. }
  286. }
  287. func SetDefaults_Node(obj *Node) {
  288. if obj.Spec.ExternalID == "" {
  289. obj.Spec.ExternalID = obj.Name
  290. }
  291. }
  292. func SetDefaults_NodeStatus(obj *NodeStatus) {
  293. if obj.Allocatable == nil && obj.Capacity != nil {
  294. obj.Allocatable = make(ResourceList, len(obj.Capacity))
  295. for key, value := range obj.Capacity {
  296. obj.Allocatable[key] = *(value.Copy())
  297. }
  298. obj.Allocatable = obj.Capacity
  299. }
  300. }
  301. func SetDefaults_ObjectFieldSelector(obj *ObjectFieldSelector) {
  302. if obj.APIVersion == "" {
  303. obj.APIVersion = "v1"
  304. }
  305. }
  306. func SetDefaults_LimitRangeItem(obj *LimitRangeItem) {
  307. // for container limits, we apply default values
  308. if obj.Type == LimitTypeContainer {
  309. if obj.Default == nil {
  310. obj.Default = make(ResourceList)
  311. }
  312. if obj.DefaultRequest == nil {
  313. obj.DefaultRequest = make(ResourceList)
  314. }
  315. // If a default limit is unspecified, but the max is specified, default the limit to the max
  316. for key, value := range obj.Max {
  317. if _, exists := obj.Default[key]; !exists {
  318. obj.Default[key] = *(value.Copy())
  319. }
  320. }
  321. // If a default limit is specified, but the default request is not, default request to limit
  322. for key, value := range obj.Default {
  323. if _, exists := obj.DefaultRequest[key]; !exists {
  324. obj.DefaultRequest[key] = *(value.Copy())
  325. }
  326. }
  327. // If a default request is not specified, but the min is provided, default request to the min
  328. for key, value := range obj.Min {
  329. if _, exists := obj.DefaultRequest[key]; !exists {
  330. obj.DefaultRequest[key] = *(value.Copy())
  331. }
  332. }
  333. }
  334. }
  335. func SetDefaults_ConfigMap(obj *ConfigMap) {
  336. if obj.Data == nil {
  337. obj.Data = make(map[string]string)
  338. }
  339. }
  340. // With host networking default all container ports to host ports.
  341. func defaultHostNetworkPorts(containers *[]Container) {
  342. for i := range *containers {
  343. for j := range (*containers)[i].Ports {
  344. if (*containers)[i].Ports[j].HostPort == 0 {
  345. (*containers)[i].Ports[j].HostPort = (*containers)[i].Ports[j].ContainerPort
  346. }
  347. }
  348. }
  349. }
  350. func SetDefaults_RBDVolumeSource(obj *RBDVolumeSource) {
  351. if obj.RBDPool == "" {
  352. obj.RBDPool = "rbd"
  353. }
  354. if obj.RadosUser == "" {
  355. obj.RadosUser = "admin"
  356. }
  357. if obj.Keyring == "" {
  358. obj.Keyring = "/etc/ceph/keyring"
  359. }
  360. }
  361. func SetDefaults_ScaleIOVolumeSource(obj *ScaleIOVolumeSource) {
  362. if obj.ProtectionDomain == "" {
  363. obj.ProtectionDomain = "default"
  364. }
  365. if obj.StoragePool == "" {
  366. obj.StoragePool = "default"
  367. }
  368. if obj.StorageMode == "" {
  369. obj.StorageMode = "ThinProvisioned"
  370. }
  371. if obj.FSType == "" {
  372. obj.FSType = "xfs"
  373. }
  374. }