github.com/aclisp/heapster@v0.19.2-0.20160613100040-51756f899a96/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.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  	"fmt"
    21  
    22  	inf "gopkg.in/inf.v0"
    23  
    24  	"k8s.io/kubernetes/pkg/api"
    25  	"k8s.io/kubernetes/pkg/conversion"
    26  	"k8s.io/kubernetes/pkg/runtime"
    27  )
    28  
    29  const (
    30  	// Annotation key used to identify mirror pods.
    31  	mirrorAnnotationKey = "kubernetes.io/config.mirror"
    32  
    33  	// Value used to identify mirror pods from pre-v1.1 kubelet.
    34  	mirrorAnnotationValue_1_0 = "mirror"
    35  )
    36  
    37  func addConversionFuncs(scheme *runtime.Scheme) {
    38  	// Add non-generated conversion functions
    39  	err := scheme.AddConversionFuncs(
    40  		Convert_api_Pod_To_v1_Pod,
    41  		Convert_api_PodSpec_To_v1_PodSpec,
    42  		Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec,
    43  		Convert_api_ServiceSpec_To_v1_ServiceSpec,
    44  		Convert_v1_Pod_To_api_Pod,
    45  		Convert_v1_PodSpec_To_api_PodSpec,
    46  		Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec,
    47  		Convert_v1_ServiceSpec_To_api_ServiceSpec,
    48  		Convert_v1_ResourceList_To_api_ResourceList,
    49  	)
    50  	if err != nil {
    51  		// If one of the conversion functions is malformed, detect it immediately.
    52  		panic(err)
    53  	}
    54  
    55  	// Add field label conversions for kinds having selectable nothing but ObjectMeta fields.
    56  	for _, kind := range []string{
    57  		"Endpoints",
    58  		"ResourceQuota",
    59  		"PersistentVolumeClaim",
    60  		"Service",
    61  		"ServiceAccount",
    62  		"ConfigMap",
    63  	} {
    64  		err = api.Scheme.AddFieldLabelConversionFunc("v1", kind,
    65  			func(label, value string) (string, string, error) {
    66  				switch label {
    67  				case "metadata.namespace",
    68  					"metadata.name":
    69  					return label, value, nil
    70  				default:
    71  					return "", "", fmt.Errorf("field label %q not supported for %q", label, kind)
    72  				}
    73  			})
    74  		if err != nil {
    75  			// If one of the conversion functions is malformed, detect it immediately.
    76  			panic(err)
    77  		}
    78  	}
    79  
    80  	// Add field conversion funcs.
    81  	err = api.Scheme.AddFieldLabelConversionFunc("v1", "Pod",
    82  		func(label, value string) (string, string, error) {
    83  			switch label {
    84  			case "metadata.name",
    85  				"metadata.namespace",
    86  				"metadata.labels",
    87  				"metadata.annotations",
    88  				"status.phase",
    89  				"status.podIP",
    90  				"spec.nodeName",
    91  				"spec.restartPolicy":
    92  				return label, value, nil
    93  				// This is for backwards compatibility with old v1 clients which send spec.host
    94  			case "spec.host":
    95  				return "spec.nodeName", value, nil
    96  			default:
    97  				return "", "", fmt.Errorf("field label not supported: %s", label)
    98  			}
    99  		})
   100  	if err != nil {
   101  		// If one of the conversion functions is malformed, detect it immediately.
   102  		panic(err)
   103  	}
   104  	err = api.Scheme.AddFieldLabelConversionFunc("v1", "Node",
   105  		func(label, value string) (string, string, error) {
   106  			switch label {
   107  			case "metadata.name":
   108  				return label, value, nil
   109  			case "spec.unschedulable":
   110  				return label, value, nil
   111  			default:
   112  				return "", "", fmt.Errorf("field label not supported: %s", label)
   113  			}
   114  		})
   115  	if err != nil {
   116  		// If one of the conversion functions is malformed, detect it immediately.
   117  		panic(err)
   118  	}
   119  	err = api.Scheme.AddFieldLabelConversionFunc("v1", "ReplicationController",
   120  		func(label, value string) (string, string, error) {
   121  			switch label {
   122  			case "metadata.name",
   123  				"metadata.namespace",
   124  				"status.replicas":
   125  				return label, value, nil
   126  			default:
   127  				return "", "", fmt.Errorf("field label not supported: %s", label)
   128  			}
   129  		})
   130  	if err != nil {
   131  		// If one of the conversion functions is malformed, detect it immediately.
   132  		panic(err)
   133  	}
   134  	err = api.Scheme.AddFieldLabelConversionFunc("v1", "Event",
   135  		func(label, value string) (string, string, error) {
   136  			switch label {
   137  			case "involvedObject.kind",
   138  				"involvedObject.namespace",
   139  				"involvedObject.name",
   140  				"involvedObject.uid",
   141  				"involvedObject.apiVersion",
   142  				"involvedObject.resourceVersion",
   143  				"involvedObject.fieldPath",
   144  				"reason",
   145  				"source",
   146  				"type",
   147  				"metadata.namespace",
   148  				"metadata.name":
   149  				return label, value, nil
   150  			default:
   151  				return "", "", fmt.Errorf("field label not supported: %s", label)
   152  			}
   153  		})
   154  	if err != nil {
   155  		// If one of the conversion functions is malformed, detect it immediately.
   156  		panic(err)
   157  	}
   158  	err = api.Scheme.AddFieldLabelConversionFunc("v1", "Namespace",
   159  		func(label, value string) (string, string, error) {
   160  			switch label {
   161  			case "status.phase",
   162  				"metadata.name":
   163  				return label, value, nil
   164  			default:
   165  				return "", "", fmt.Errorf("field label not supported: %s", label)
   166  			}
   167  		})
   168  	if err != nil {
   169  		// If one of the conversion functions is malformed, detect it immediately.
   170  		panic(err)
   171  	}
   172  	err = api.Scheme.AddFieldLabelConversionFunc("v1", "PersistentVolume",
   173  		func(label, value string) (string, string, error) {
   174  			switch label {
   175  			case "metadata.name":
   176  				return label, value, nil
   177  			default:
   178  				return "", "", fmt.Errorf("field label not supported: %s", label)
   179  			}
   180  		})
   181  	if err != nil {
   182  		// If one of the conversion functions is malformed, detect it immediately.
   183  		panic(err)
   184  	}
   185  	err = api.Scheme.AddFieldLabelConversionFunc("v1", "Secret",
   186  		func(label, value string) (string, string, error) {
   187  			switch label {
   188  			case "type",
   189  				"metadata.namespace",
   190  				"metadata.name":
   191  				return label, value, nil
   192  			default:
   193  				return "", "", fmt.Errorf("field label not supported: %s", label)
   194  			}
   195  		})
   196  	if err != nil {
   197  		// If one of the conversion functions is malformed, detect it immediately.
   198  		panic(err)
   199  	}
   200  }
   201  
   202  func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *ReplicationControllerSpec, s conversion.Scope) error {
   203  	out.Replicas = new(int32)
   204  	*out.Replicas = int32(in.Replicas)
   205  	if in.Selector != nil {
   206  		out.Selector = make(map[string]string)
   207  		for key, val := range in.Selector {
   208  			out.Selector[key] = val
   209  		}
   210  	} else {
   211  		out.Selector = nil
   212  	}
   213  	//if in.TemplateRef != nil {
   214  	//	out.TemplateRef = new(ObjectReference)
   215  	//	if err := Convert_api_ObjectReference_To_v1_ObjectReference(in.TemplateRef, out.TemplateRef, s); err != nil {
   216  	//		return err
   217  	//	}
   218  	//} else {
   219  	//	out.TemplateRef = nil
   220  	//}
   221  	if in.Template != nil {
   222  		out.Template = new(PodTemplateSpec)
   223  		if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil {
   224  			return err
   225  		}
   226  	} else {
   227  		out.Template = nil
   228  	}
   229  	return nil
   230  }
   231  
   232  func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error {
   233  	out.Replicas = *in.Replicas
   234  	if in.Selector != nil {
   235  		out.Selector = make(map[string]string)
   236  		for key, val := range in.Selector {
   237  			out.Selector[key] = val
   238  		}
   239  	} else {
   240  		out.Selector = nil
   241  	}
   242  	//if in.TemplateRef != nil {
   243  	//	out.TemplateRef = new(api.ObjectReference)
   244  	//	if err := Convert_v1_ObjectReference_To_api_ObjectReference(in.TemplateRef, out.TemplateRef, s); err != nil {
   245  	//		return err
   246  	//	}
   247  	//} else {
   248  	//	out.TemplateRef = nil
   249  	//}
   250  	if in.Template != nil {
   251  		out.Template = new(api.PodTemplateSpec)
   252  		if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil {
   253  			return err
   254  		}
   255  	} else {
   256  		out.Template = nil
   257  	}
   258  	return nil
   259  }
   260  
   261  // The following two PodSpec conversions are done here to support ServiceAccount
   262  // as an alias for ServiceAccountName.
   263  func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error {
   264  	if in.Volumes != nil {
   265  		out.Volumes = make([]Volume, len(in.Volumes))
   266  		for i := range in.Volumes {
   267  			if err := Convert_api_Volume_To_v1_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil {
   268  				return err
   269  			}
   270  		}
   271  	} else {
   272  		out.Volumes = nil
   273  	}
   274  	if in.Containers != nil {
   275  		out.Containers = make([]Container, len(in.Containers))
   276  		for i := range in.Containers {
   277  			if err := Convert_api_Container_To_v1_Container(&in.Containers[i], &out.Containers[i], s); err != nil {
   278  				return err
   279  			}
   280  		}
   281  	} else {
   282  		out.Containers = nil
   283  	}
   284  	out.RestartPolicy = RestartPolicy(in.RestartPolicy)
   285  	if in.TerminationGracePeriodSeconds != nil {
   286  		out.TerminationGracePeriodSeconds = new(int64)
   287  		*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
   288  	} else {
   289  		out.TerminationGracePeriodSeconds = nil
   290  	}
   291  	if in.ActiveDeadlineSeconds != nil {
   292  		out.ActiveDeadlineSeconds = new(int64)
   293  		*out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds
   294  	} else {
   295  		out.ActiveDeadlineSeconds = nil
   296  	}
   297  	out.DNSPolicy = DNSPolicy(in.DNSPolicy)
   298  	if in.NodeSelector != nil {
   299  		out.NodeSelector = make(map[string]string)
   300  		for key, val := range in.NodeSelector {
   301  			out.NodeSelector[key] = val
   302  		}
   303  	} else {
   304  		out.NodeSelector = nil
   305  	}
   306  	out.ServiceAccountName = in.ServiceAccountName
   307  	// DeprecatedServiceAccount is an alias for ServiceAccountName.
   308  	out.DeprecatedServiceAccount = in.ServiceAccountName
   309  	out.NodeName = in.NodeName
   310  	if in.SecurityContext != nil {
   311  		out.SecurityContext = new(PodSecurityContext)
   312  		if err := Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil {
   313  			return err
   314  		}
   315  
   316  		// the host namespace fields have to be handled here for backward compatibility
   317  		// with v1.0.0
   318  		out.HostPID = in.SecurityContext.HostPID
   319  		out.HostNetwork = in.SecurityContext.HostNetwork
   320  		out.HostIPC = in.SecurityContext.HostIPC
   321  	}
   322  	if in.ImagePullSecrets != nil {
   323  		out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets))
   324  		for i := range in.ImagePullSecrets {
   325  			if err := Convert_api_LocalObjectReference_To_v1_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil {
   326  				return err
   327  			}
   328  		}
   329  	} else {
   330  		out.ImagePullSecrets = nil
   331  	}
   332  	out.Hostname = in.Hostname
   333  	out.Subdomain = in.Subdomain
   334  	return nil
   335  }
   336  
   337  func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error {
   338  	SetDefaults_PodSpec(in)
   339  	if in.Volumes != nil {
   340  		out.Volumes = make([]api.Volume, len(in.Volumes))
   341  		for i := range in.Volumes {
   342  			if err := Convert_v1_Volume_To_api_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil {
   343  				return err
   344  			}
   345  		}
   346  	} else {
   347  		out.Volumes = nil
   348  	}
   349  	if in.Containers != nil {
   350  		out.Containers = make([]api.Container, len(in.Containers))
   351  		for i := range in.Containers {
   352  			if err := Convert_v1_Container_To_api_Container(&in.Containers[i], &out.Containers[i], s); err != nil {
   353  				return err
   354  			}
   355  		}
   356  	} else {
   357  		out.Containers = nil
   358  	}
   359  	out.RestartPolicy = api.RestartPolicy(in.RestartPolicy)
   360  	if in.TerminationGracePeriodSeconds != nil {
   361  		out.TerminationGracePeriodSeconds = new(int64)
   362  		*out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds
   363  	} else {
   364  		out.TerminationGracePeriodSeconds = nil
   365  	}
   366  	if in.ActiveDeadlineSeconds != nil {
   367  		out.ActiveDeadlineSeconds = new(int64)
   368  		*out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds
   369  	} else {
   370  		out.ActiveDeadlineSeconds = nil
   371  	}
   372  	out.DNSPolicy = api.DNSPolicy(in.DNSPolicy)
   373  	if in.NodeSelector != nil {
   374  		out.NodeSelector = make(map[string]string)
   375  		for key, val := range in.NodeSelector {
   376  			out.NodeSelector[key] = val
   377  		}
   378  	} else {
   379  		out.NodeSelector = nil
   380  	}
   381  	// We support DeprecatedServiceAccount as an alias for ServiceAccountName.
   382  	// If both are specified, ServiceAccountName (the new field) wins.
   383  	out.ServiceAccountName = in.ServiceAccountName
   384  	if in.ServiceAccountName == "" {
   385  		out.ServiceAccountName = in.DeprecatedServiceAccount
   386  	}
   387  	out.NodeName = in.NodeName
   388  	if in.SecurityContext != nil {
   389  		out.SecurityContext = new(api.PodSecurityContext)
   390  		if err := Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil {
   391  			return err
   392  		}
   393  	}
   394  
   395  	// the host namespace fields have to be handled specially for backward compatibility
   396  	// with v1.0.0
   397  	if out.SecurityContext == nil {
   398  		out.SecurityContext = new(api.PodSecurityContext)
   399  	}
   400  	out.SecurityContext.HostNetwork = in.HostNetwork
   401  	out.SecurityContext.HostPID = in.HostPID
   402  	out.SecurityContext.HostIPC = in.HostIPC
   403  	if in.ImagePullSecrets != nil {
   404  		out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets))
   405  		for i := range in.ImagePullSecrets {
   406  			if err := Convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil {
   407  				return err
   408  			}
   409  		}
   410  	} else {
   411  		out.ImagePullSecrets = nil
   412  	}
   413  	out.Hostname = in.Hostname
   414  	out.Subdomain = in.Subdomain
   415  	return nil
   416  }
   417  
   418  func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error {
   419  	if err := autoConvert_api_Pod_To_v1_Pod(in, out, s); err != nil {
   420  		return err
   421  	}
   422  	// We need to reset certain fields for mirror pods from pre-v1.1 kubelet
   423  	// (#15960).
   424  	// TODO: Remove this code after we drop support for v1.0 kubelets.
   425  	if value, ok := in.Annotations[mirrorAnnotationKey]; ok && value == mirrorAnnotationValue_1_0 {
   426  		// Reset the TerminationGracePeriodSeconds.
   427  		out.Spec.TerminationGracePeriodSeconds = nil
   428  		// Reset the resource requests.
   429  		for i := range out.Spec.Containers {
   430  			out.Spec.Containers[i].Resources.Requests = nil
   431  		}
   432  	}
   433  	return nil
   434  }
   435  
   436  func Convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error {
   437  	return autoConvert_v1_Pod_To_api_Pod(in, out, s)
   438  }
   439  
   440  func Convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error {
   441  	if err := autoConvert_api_ServiceSpec_To_v1_ServiceSpec(in, out, s); err != nil {
   442  		return err
   443  	}
   444  	// Publish both externalIPs and deprecatedPublicIPs fields in v1.
   445  	for _, ip := range in.ExternalIPs {
   446  		out.DeprecatedPublicIPs = append(out.DeprecatedPublicIPs, ip)
   447  	}
   448  	return nil
   449  }
   450  
   451  func Convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error {
   452  	if err := autoConvert_v1_ServiceSpec_To_api_ServiceSpec(in, out, s); err != nil {
   453  		return err
   454  	}
   455  	// Prefer the legacy deprecatedPublicIPs field, if provided.
   456  	if len(in.DeprecatedPublicIPs) > 0 {
   457  		out.ExternalIPs = nil
   458  		for _, ip := range in.DeprecatedPublicIPs {
   459  			out.ExternalIPs = append(out.ExternalIPs, ip)
   460  		}
   461  	}
   462  	return nil
   463  }
   464  
   465  func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *PodSecurityContext, s conversion.Scope) error {
   466  	out.SupplementalGroups = in.SupplementalGroups
   467  	if in.SELinuxOptions != nil {
   468  		out.SELinuxOptions = new(SELinuxOptions)
   469  		if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
   470  			return err
   471  		}
   472  	} else {
   473  		out.SELinuxOptions = nil
   474  	}
   475  	if in.RunAsUser != nil {
   476  		out.RunAsUser = new(int64)
   477  		*out.RunAsUser = *in.RunAsUser
   478  	} else {
   479  		out.RunAsUser = nil
   480  	}
   481  	if in.RunAsNonRoot != nil {
   482  		out.RunAsNonRoot = new(bool)
   483  		*out.RunAsNonRoot = *in.RunAsNonRoot
   484  	} else {
   485  		out.RunAsNonRoot = nil
   486  	}
   487  	if in.FSGroup != nil {
   488  		out.FSGroup = new(int64)
   489  		*out.FSGroup = *in.FSGroup
   490  	} else {
   491  		out.FSGroup = nil
   492  	}
   493  	return nil
   494  }
   495  
   496  func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
   497  	out.SupplementalGroups = in.SupplementalGroups
   498  	if in.SELinuxOptions != nil {
   499  		out.SELinuxOptions = new(api.SELinuxOptions)
   500  		if err := Convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
   501  			return err
   502  		}
   503  	} else {
   504  		out.SELinuxOptions = nil
   505  	}
   506  	if in.RunAsUser != nil {
   507  		out.RunAsUser = new(int64)
   508  		*out.RunAsUser = *in.RunAsUser
   509  	} else {
   510  		out.RunAsUser = nil
   511  	}
   512  	if in.RunAsNonRoot != nil {
   513  		out.RunAsNonRoot = new(bool)
   514  		*out.RunAsNonRoot = *in.RunAsNonRoot
   515  	} else {
   516  		out.RunAsNonRoot = nil
   517  	}
   518  	if in.FSGroup != nil {
   519  		out.FSGroup = new(int64)
   520  		*out.FSGroup = *in.FSGroup
   521  	} else {
   522  		out.FSGroup = nil
   523  	}
   524  	return nil
   525  }
   526  
   527  func Convert_v1_ResourceList_To_api_ResourceList(in *ResourceList, out *api.ResourceList, s conversion.Scope) error {
   528  	if *in == nil {
   529  		return nil
   530  	}
   531  
   532  	converted := make(api.ResourceList)
   533  	for key, val := range *in {
   534  		value := val.Copy()
   535  
   536  		// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
   537  		// In the future, we should instead reject values that need rounding.
   538  		const milliScale = 3
   539  		value.Amount.Round(value.Amount, milliScale, inf.RoundUp)
   540  
   541  		converted[api.ResourceName(key)] = *value
   542  	}
   543  
   544  	*out = converted
   545  	return nil
   546  }