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 }