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