github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go (about)

     1  /*
     2  Copyright 2015 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package v1
    18  
    19  import (
    20  	"strings"
    21  
    22  	"k8s.io/kubernetes/pkg/api"
    23  	"k8s.io/kubernetes/pkg/util"
    24  	"k8s.io/kubernetes/pkg/util/intstr"
    25  )
    26  
    27  func addDefaultingFuncs() {
    28  	api.Scheme.AddDefaultingFuncs(
    29  		func(obj *ReplicationController) {
    30  			var labels map[string]string
    31  			if obj.Spec.Template != nil {
    32  				labels = obj.Spec.Template.Labels
    33  			}
    34  			// TODO: support templates defined elsewhere when we support them in the API
    35  			if labels != nil {
    36  				if len(obj.Spec.Selector) == 0 {
    37  					obj.Spec.Selector = labels
    38  				}
    39  				if len(obj.Labels) == 0 {
    40  					obj.Labels = labels
    41  				}
    42  			}
    43  			if obj.Spec.Replicas == nil {
    44  				obj.Spec.Replicas = new(int)
    45  				*obj.Spec.Replicas = 1
    46  			}
    47  		},
    48  		func(obj *Volume) {
    49  			if util.AllPtrFieldsNil(&obj.VolumeSource) {
    50  				obj.VolumeSource = VolumeSource{
    51  					EmptyDir: &EmptyDirVolumeSource{},
    52  				}
    53  			}
    54  		},
    55  		func(obj *ContainerPort) {
    56  			if obj.Protocol == "" {
    57  				obj.Protocol = ProtocolTCP
    58  			}
    59  		},
    60  		func(obj *Container) {
    61  			if obj.ImagePullPolicy == "" {
    62  				// TODO(dchen1107): Move ParseImageName code to pkg/util
    63  				parts := strings.Split(obj.Image, ":")
    64  				// Check image tag
    65  				if parts[len(parts)-1] == "latest" {
    66  					obj.ImagePullPolicy = PullAlways
    67  				} else {
    68  					obj.ImagePullPolicy = PullIfNotPresent
    69  				}
    70  			}
    71  			if obj.TerminationMessagePath == "" {
    72  				obj.TerminationMessagePath = TerminationMessagePathDefault
    73  			}
    74  		},
    75  		func(obj *ServiceSpec) {
    76  			if obj.SessionAffinity == "" {
    77  				obj.SessionAffinity = ServiceAffinityNone
    78  			}
    79  			if obj.Type == "" {
    80  				obj.Type = ServiceTypeClusterIP
    81  			}
    82  			for i := range obj.Ports {
    83  				sp := &obj.Ports[i]
    84  				if sp.Protocol == "" {
    85  					sp.Protocol = ProtocolTCP
    86  				}
    87  				if sp.TargetPort == intstr.FromInt(0) || sp.TargetPort == intstr.FromString("") {
    88  					sp.TargetPort = intstr.FromInt(sp.Port)
    89  				}
    90  			}
    91  		},
    92  		func(obj *Pod) {
    93  			// If limits are specified, but requests are not, default requests to limits
    94  			// This is done here rather than a more specific defaulting pass on ResourceRequirements
    95  			// because we only want this defaulting semantic to take place on a Pod and not a PodTemplate
    96  			for i := range obj.Spec.Containers {
    97  				// set requests to limits if requests are not specified, but limits are
    98  				if obj.Spec.Containers[i].Resources.Limits != nil {
    99  					if obj.Spec.Containers[i].Resources.Requests == nil {
   100  						obj.Spec.Containers[i].Resources.Requests = make(ResourceList)
   101  					}
   102  					for key, value := range obj.Spec.Containers[i].Resources.Limits {
   103  						if _, exists := obj.Spec.Containers[i].Resources.Requests[key]; !exists {
   104  							obj.Spec.Containers[i].Resources.Requests[key] = *(value.Copy())
   105  						}
   106  					}
   107  				}
   108  			}
   109  		},
   110  		func(obj *PodSpec) {
   111  			if obj.DNSPolicy == "" {
   112  				obj.DNSPolicy = DNSClusterFirst
   113  			}
   114  			if obj.RestartPolicy == "" {
   115  				obj.RestartPolicy = RestartPolicyAlways
   116  			}
   117  			if obj.HostNetwork {
   118  				defaultHostNetworkPorts(&obj.Containers)
   119  			}
   120  			if obj.SecurityContext == nil {
   121  				obj.SecurityContext = &PodSecurityContext{}
   122  			}
   123  			if obj.TerminationGracePeriodSeconds == nil {
   124  				period := int64(DefaultTerminationGracePeriodSeconds)
   125  				obj.TerminationGracePeriodSeconds = &period
   126  			}
   127  		},
   128  		func(obj *Probe) {
   129  			if obj.TimeoutSeconds == 0 {
   130  				obj.TimeoutSeconds = 1
   131  			}
   132  			if obj.PeriodSeconds == 0 {
   133  				obj.PeriodSeconds = 10
   134  			}
   135  			if obj.SuccessThreshold == 0 {
   136  				obj.SuccessThreshold = 1
   137  			}
   138  			if obj.FailureThreshold == 0 {
   139  				obj.FailureThreshold = 3
   140  			}
   141  		},
   142  		func(obj *Secret) {
   143  			if obj.Type == "" {
   144  				obj.Type = SecretTypeOpaque
   145  			}
   146  		},
   147  		func(obj *PersistentVolume) {
   148  			if obj.Status.Phase == "" {
   149  				obj.Status.Phase = VolumePending
   150  			}
   151  			if obj.Spec.PersistentVolumeReclaimPolicy == "" {
   152  				obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain
   153  			}
   154  		},
   155  		func(obj *PersistentVolumeClaim) {
   156  			if obj.Status.Phase == "" {
   157  				obj.Status.Phase = ClaimPending
   158  			}
   159  		},
   160  		func(obj *Endpoints) {
   161  			for i := range obj.Subsets {
   162  				ss := &obj.Subsets[i]
   163  				for i := range ss.Ports {
   164  					ep := &ss.Ports[i]
   165  					if ep.Protocol == "" {
   166  						ep.Protocol = ProtocolTCP
   167  					}
   168  				}
   169  			}
   170  		},
   171  		func(obj *HTTPGetAction) {
   172  			if obj.Path == "" {
   173  				obj.Path = "/"
   174  			}
   175  			if obj.Scheme == "" {
   176  				obj.Scheme = URISchemeHTTP
   177  			}
   178  		},
   179  		func(obj *NamespaceStatus) {
   180  			if obj.Phase == "" {
   181  				obj.Phase = NamespaceActive
   182  			}
   183  		},
   184  		func(obj *Node) {
   185  			if obj.Spec.ExternalID == "" {
   186  				obj.Spec.ExternalID = obj.Name
   187  			}
   188  		},
   189  		func(obj *ObjectFieldSelector) {
   190  			if obj.APIVersion == "" {
   191  				obj.APIVersion = "v1"
   192  			}
   193  		},
   194  		func(obj *LimitRangeItem) {
   195  			// for container limits, we apply default values
   196  			if obj.Type == LimitTypeContainer {
   197  
   198  				if obj.Default == nil {
   199  					obj.Default = make(ResourceList)
   200  				}
   201  				if obj.DefaultRequest == nil {
   202  					obj.DefaultRequest = make(ResourceList)
   203  				}
   204  
   205  				// If a default limit is unspecified, but the max is specified, default the limit to the max
   206  				for key, value := range obj.Max {
   207  					if _, exists := obj.Default[key]; !exists {
   208  						obj.Default[key] = *(value.Copy())
   209  					}
   210  				}
   211  				// If a default limit is specified, but the default request is not, default request to limit
   212  				for key, value := range obj.Default {
   213  					if _, exists := obj.DefaultRequest[key]; !exists {
   214  						obj.DefaultRequest[key] = *(value.Copy())
   215  					}
   216  				}
   217  				// If a default request is not specified, but the min is provided, default request to the min
   218  				for key, value := range obj.Min {
   219  					if _, exists := obj.DefaultRequest[key]; !exists {
   220  						obj.DefaultRequest[key] = *(value.Copy())
   221  					}
   222  				}
   223  			}
   224  		},
   225  	)
   226  }
   227  
   228  // With host networking default all container ports to host ports.
   229  func defaultHostNetworkPorts(containers *[]Container) {
   230  	for i := range *containers {
   231  		for j := range (*containers)[i].Ports {
   232  			if (*containers)[i].Ports[j].HostPort == 0 {
   233  				(*containers)[i].Ports[j].HostPort = (*containers)[i].Ports[j].ContainerPort
   234  			}
   235  		}
   236  	}
   237  }