1/* 2Copyright 2015 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package v1 18 19import ( 20 "encoding/json" 21 "fmt" 22 "reflect" 23 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/conversion" 26 "k8s.io/apimachinery/pkg/runtime" 27 "k8s.io/apimachinery/pkg/util/validation/field" 28 "k8s.io/client-go/pkg/api" 29 "k8s.io/client-go/pkg/apis/extensions" 30) 31 32// This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are 33// converted the most in the cluster. 34// TODO: generate one of these for every external API group - this is to prove the impact 35func addFastPathConversionFuncs(scheme *runtime.Scheme) error { 36 scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) { 37 switch a := objA.(type) { 38 case *Pod: 39 switch b := objB.(type) { 40 case *api.Pod: 41 return true, Convert_v1_Pod_To_api_Pod(a, b, s) 42 } 43 case *api.Pod: 44 switch b := objB.(type) { 45 case *Pod: 46 return true, Convert_api_Pod_To_v1_Pod(a, b, s) 47 } 48 49 case *Event: 50 switch b := objB.(type) { 51 case *api.Event: 52 return true, Convert_v1_Event_To_api_Event(a, b, s) 53 } 54 case *api.Event: 55 switch b := objB.(type) { 56 case *Event: 57 return true, Convert_api_Event_To_v1_Event(a, b, s) 58 } 59 60 case *ReplicationController: 61 switch b := objB.(type) { 62 case *api.ReplicationController: 63 return true, Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s) 64 } 65 case *api.ReplicationController: 66 switch b := objB.(type) { 67 case *ReplicationController: 68 return true, Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s) 69 } 70 71 case *Node: 72 switch b := objB.(type) { 73 case *api.Node: 74 return true, Convert_v1_Node_To_api_Node(a, b, s) 75 } 76 case *api.Node: 77 switch b := objB.(type) { 78 case *Node: 79 return true, Convert_api_Node_To_v1_Node(a, b, s) 80 } 81 82 case *Namespace: 83 switch b := objB.(type) { 84 case *api.Namespace: 85 return true, Convert_v1_Namespace_To_api_Namespace(a, b, s) 86 } 87 case *api.Namespace: 88 switch b := objB.(type) { 89 case *Namespace: 90 return true, Convert_api_Namespace_To_v1_Namespace(a, b, s) 91 } 92 93 case *Service: 94 switch b := objB.(type) { 95 case *api.Service: 96 return true, Convert_v1_Service_To_api_Service(a, b, s) 97 } 98 case *api.Service: 99 switch b := objB.(type) { 100 case *Service: 101 return true, Convert_api_Service_To_v1_Service(a, b, s) 102 } 103 104 case *Endpoints: 105 switch b := objB.(type) { 106 case *api.Endpoints: 107 return true, Convert_v1_Endpoints_To_api_Endpoints(a, b, s) 108 } 109 case *api.Endpoints: 110 switch b := objB.(type) { 111 case *Endpoints: 112 return true, Convert_api_Endpoints_To_v1_Endpoints(a, b, s) 113 } 114 115 case *metav1.WatchEvent: 116 switch b := objB.(type) { 117 case *metav1.InternalEvent: 118 return true, metav1.Convert_versioned_Event_to_versioned_InternalEvent(a, b, s) 119 } 120 case *metav1.InternalEvent: 121 switch b := objB.(type) { 122 case *metav1.WatchEvent: 123 return true, metav1.Convert_versioned_InternalEvent_to_versioned_Event(a, b, s) 124 } 125 } 126 return false, nil 127 }) 128 return nil 129} 130 131func addConversionFuncs(scheme *runtime.Scheme) error { 132 // Add non-generated conversion functions 133 err := scheme.AddConversionFuncs( 134 Convert_api_Pod_To_v1_Pod, 135 Convert_api_PodSpec_To_v1_PodSpec, 136 Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec, 137 Convert_api_ServiceSpec_To_v1_ServiceSpec, 138 Convert_v1_Pod_To_api_Pod, 139 Convert_v1_PodSpec_To_api_PodSpec, 140 Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec, 141 Convert_v1_Secret_To_api_Secret, 142 Convert_v1_ServiceSpec_To_api_ServiceSpec, 143 Convert_v1_ResourceList_To_api_ResourceList, 144 Convert_v1_ReplicationController_to_extensions_ReplicaSet, 145 Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec, 146 Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus, 147 Convert_extensions_ReplicaSet_to_v1_ReplicationController, 148 Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec, 149 Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus, 150 ) 151 if err != nil { 152 return err 153 } 154 155 // Add field label conversions for kinds having selectable nothing but ObjectMeta fields. 156 for _, k := range []string{ 157 "Endpoints", 158 "ResourceQuota", 159 "PersistentVolumeClaim", 160 "Service", 161 "ServiceAccount", 162 "ConfigMap", 163 } { 164 kind := k // don't close over range variables 165 err = scheme.AddFieldLabelConversionFunc("v1", kind, 166 func(label, value string) (string, string, error) { 167 switch label { 168 case "metadata.namespace", 169 "metadata.name": 170 return label, value, nil 171 default: 172 return "", "", fmt.Errorf("field label %q not supported for %q", label, kind) 173 } 174 }, 175 ) 176 if err != nil { 177 return err 178 } 179 } 180 181 // Add field conversion funcs. 182 err = scheme.AddFieldLabelConversionFunc("v1", "Pod", 183 func(label, value string) (string, string, error) { 184 switch label { 185 case "metadata.annotations", 186 "metadata.labels", 187 "metadata.name", 188 "metadata.namespace", 189 "spec.nodeName", 190 "spec.restartPolicy", 191 "spec.serviceAccountName", 192 "status.phase", 193 "status.podIP": 194 return label, value, nil 195 // This is for backwards compatibility with old v1 clients which send spec.host 196 case "spec.host": 197 return "spec.nodeName", value, nil 198 default: 199 return "", "", fmt.Errorf("field label not supported: %s", label) 200 } 201 }, 202 ) 203 if err != nil { 204 return err 205 } 206 err = scheme.AddFieldLabelConversionFunc("v1", "Node", 207 func(label, value string) (string, string, error) { 208 switch label { 209 case "metadata.name": 210 return label, value, nil 211 case "spec.unschedulable": 212 return label, value, nil 213 default: 214 return "", "", fmt.Errorf("field label not supported: %s", label) 215 } 216 }, 217 ) 218 if err != nil { 219 return err 220 } 221 err = scheme.AddFieldLabelConversionFunc("v1", "ReplicationController", 222 func(label, value string) (string, string, error) { 223 switch label { 224 case "metadata.name", 225 "metadata.namespace", 226 "status.replicas": 227 return label, value, nil 228 default: 229 return "", "", fmt.Errorf("field label not supported: %s", label) 230 } 231 }) 232 if err != nil { 233 return err 234 } 235 err = scheme.AddFieldLabelConversionFunc("v1", "PersistentVolume", 236 func(label, value string) (string, string, error) { 237 switch label { 238 case "metadata.name": 239 return label, value, nil 240 default: 241 return "", "", fmt.Errorf("field label not supported: %s", label) 242 } 243 }, 244 ) 245 if err != nil { 246 return err 247 } 248 if err := AddFieldLabelConversionsForEvent(scheme); err != nil { 249 return err 250 } 251 if err := AddFieldLabelConversionsForNamespace(scheme); err != nil { 252 return err 253 } 254 if err := AddFieldLabelConversionsForSecret(scheme); err != nil { 255 return err 256 } 257 return nil 258} 259 260func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *ReplicationController, out *extensions.ReplicaSet, s conversion.Scope) error { 261 out.ObjectMeta = in.ObjectMeta 262 if err := Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil { 263 return err 264 } 265 if err := Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil { 266 return err 267 } 268 return nil 269} 270 271func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error { 272 out.Replicas = *in.Replicas 273 if in.Selector != nil { 274 metav1.Convert_map_to_unversioned_LabelSelector(&in.Selector, out.Selector, s) 275 } 276 if in.Template != nil { 277 if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, &out.Template, s); err != nil { 278 return err 279 } 280 } 281 return nil 282} 283 284func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *ReplicationControllerStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error { 285 out.Replicas = in.Replicas 286 out.FullyLabeledReplicas = in.FullyLabeledReplicas 287 out.ReadyReplicas = in.ReadyReplicas 288 out.AvailableReplicas = in.AvailableReplicas 289 out.ObservedGeneration = in.ObservedGeneration 290 return nil 291} 292 293func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.ReplicaSet, out *ReplicationController, s conversion.Scope) error { 294 out.ObjectMeta = in.ObjectMeta 295 if err := Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil { 296 fieldErr, ok := err.(*field.Error) 297 if !ok { 298 return err 299 } 300 if out.Annotations == nil { 301 out.Annotations = make(map[string]string) 302 } 303 out.Annotations[api.NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String() 304 } 305 if err := Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil { 306 return err 307 } 308 return nil 309} 310 311func Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(in *extensions.ReplicaSetSpec, out *ReplicationControllerSpec, s conversion.Scope) error { 312 out.Replicas = new(int32) 313 *out.Replicas = in.Replicas 314 out.MinReadySeconds = in.MinReadySeconds 315 var invalidErr error 316 if in.Selector != nil { 317 invalidErr = metav1.Convert_unversioned_LabelSelector_to_map(in.Selector, &out.Selector, s) 318 } 319 out.Template = new(PodTemplateSpec) 320 if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, out.Template, s); err != nil { 321 return err 322 } 323 return invalidErr 324} 325 326func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *extensions.ReplicaSetStatus, out *ReplicationControllerStatus, s conversion.Scope) error { 327 out.Replicas = in.Replicas 328 out.FullyLabeledReplicas = in.FullyLabeledReplicas 329 out.ReadyReplicas = in.ReadyReplicas 330 out.AvailableReplicas = in.AvailableReplicas 331 out.ObservedGeneration = in.ObservedGeneration 332 return nil 333} 334 335func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *ReplicationControllerSpec, s conversion.Scope) error { 336 out.Replicas = &in.Replicas 337 out.MinReadySeconds = in.MinReadySeconds 338 out.Selector = in.Selector 339 if in.Template != nil { 340 out.Template = new(PodTemplateSpec) 341 if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { 342 return err 343 } 344 } else { 345 out.Template = nil 346 } 347 return nil 348} 349 350func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error { 351 if in.Replicas != nil { 352 out.Replicas = *in.Replicas 353 } 354 out.MinReadySeconds = in.MinReadySeconds 355 out.Selector = in.Selector 356 if in.Template != nil { 357 out.Template = new(api.PodTemplateSpec) 358 if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { 359 return err 360 } 361 } else { 362 out.Template = nil 363 } 364 return nil 365} 366 367func Convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { 368 if err := autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in, out, s); err != nil { 369 return err 370 } 371 372 if old := out.Annotations; old != nil { 373 out.Annotations = make(map[string]string, len(old)) 374 for k, v := range old { 375 out.Annotations[k] = v 376 } 377 } 378 if len(out.Status.InitContainerStatuses) > 0 { 379 if out.Annotations == nil { 380 out.Annotations = make(map[string]string) 381 } 382 value, err := json.Marshal(out.Status.InitContainerStatuses) 383 if err != nil { 384 return err 385 } 386 out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value) 387 out.Annotations[PodInitContainerStatusesBetaAnnotationKey] = string(value) 388 } else { 389 delete(out.Annotations, PodInitContainerStatusesAnnotationKey) 390 delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey) 391 } 392 return nil 393} 394 395func Convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { 396 // TODO: sometime after we move init container to stable, remove these conversions 397 // If there is a beta annotation, copy to alpha key. 398 // See commit log for PR #31026 for why we do this. 399 if valueBeta, okBeta := in.Annotations[PodInitContainerStatusesBetaAnnotationKey]; okBeta { 400 in.Annotations[PodInitContainerStatusesAnnotationKey] = valueBeta 401 } 402 // Move the annotation to the internal repr. field 403 if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok { 404 var values []ContainerStatus 405 if err := json.Unmarshal([]byte(value), &values); err != nil { 406 return err 407 } 408 // Conversion from external to internal version exists more to 409 // satisfy the needs of the decoder than it does to be a general 410 // purpose tool. And Decode always creates an intermediate object 411 // to decode to. Thus the caller of UnsafeConvertToVersion is 412 // taking responsibility to ensure mutation of in is not exposed 413 // back to the caller. 414 in.Status.InitContainerStatuses = values 415 } 416 417 if err := autoConvert_v1_PodStatusResult_To_api_PodStatusResult(in, out, s); err != nil { 418 return err 419 } 420 if len(out.Annotations) > 0 { 421 old := out.Annotations 422 out.Annotations = make(map[string]string, len(old)) 423 for k, v := range old { 424 out.Annotations[k] = v 425 } 426 delete(out.Annotations, PodInitContainerStatusesAnnotationKey) 427 delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey) 428 } 429 return nil 430} 431 432func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { 433 if err := autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s); err != nil { 434 return err 435 } 436 437 // TODO: sometime after we move init container to stable, remove these conversions. 438 if old := out.Annotations; old != nil { 439 out.Annotations = make(map[string]string, len(old)) 440 for k, v := range old { 441 out.Annotations[k] = v 442 } 443 } 444 if len(out.Spec.InitContainers) > 0 { 445 if out.Annotations == nil { 446 out.Annotations = make(map[string]string) 447 } 448 value, err := json.Marshal(out.Spec.InitContainers) 449 if err != nil { 450 return err 451 } 452 out.Annotations[PodInitContainersAnnotationKey] = string(value) 453 out.Annotations[PodInitContainersBetaAnnotationKey] = string(value) 454 } else { 455 delete(out.Annotations, PodInitContainersAnnotationKey) 456 delete(out.Annotations, PodInitContainersBetaAnnotationKey) 457 } 458 return nil 459} 460 461func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { 462 // TODO: sometime after we move init container to stable, remove these conversions 463 // If there is a beta annotation, copy to alpha key. 464 // See commit log for PR #31026 for why we do this. 465 if valueBeta, okBeta := in.Annotations[PodInitContainersBetaAnnotationKey]; okBeta { 466 in.Annotations[PodInitContainersAnnotationKey] = valueBeta 467 } 468 // Move the annotation to the internal repr. field 469 if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok { 470 var values []Container 471 if err := json.Unmarshal([]byte(value), &values); err != nil { 472 return err 473 } 474 // Conversion from external to internal version exists more to 475 // satisfy the needs of the decoder than it does to be a general 476 // purpose tool. And Decode always creates an intermediate object 477 // to decode to. Thus the caller of UnsafeConvertToVersion is 478 // taking responsibility to ensure mutation of in is not exposed 479 // back to the caller. 480 in.Spec.InitContainers = values 481 482 // Call defaulters explicitly until annotations are removed 483 for i := range in.Spec.InitContainers { 484 c := &in.Spec.InitContainers[i] 485 SetDefaults_Container(c) 486 } 487 } 488 489 if err := autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s); err != nil { 490 return err 491 } 492 if len(out.Annotations) > 0 { 493 old := out.Annotations 494 out.Annotations = make(map[string]string, len(old)) 495 for k, v := range old { 496 out.Annotations[k] = v 497 } 498 delete(out.Annotations, PodInitContainersAnnotationKey) 499 delete(out.Annotations, PodInitContainersBetaAnnotationKey) 500 } 501 return nil 502} 503 504// The following two PodSpec conversions are done here to support ServiceAccount 505// as an alias for ServiceAccountName. 506func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error { 507 if err := autoConvert_api_PodSpec_To_v1_PodSpec(in, out, s); err != nil { 508 return err 509 } 510 511 // DeprecatedServiceAccount is an alias for ServiceAccountName. 512 out.DeprecatedServiceAccount = in.ServiceAccountName 513 514 if in.SecurityContext != nil { 515 // the host namespace fields have to be handled here for backward compatibility 516 // with v1.0.0 517 out.HostPID = in.SecurityContext.HostPID 518 out.HostNetwork = in.SecurityContext.HostNetwork 519 out.HostIPC = in.SecurityContext.HostIPC 520 } 521 522 return nil 523} 524 525func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error { 526 if err := autoConvert_v1_PodSpec_To_api_PodSpec(in, out, s); err != nil { 527 return err 528 } 529 530 // We support DeprecatedServiceAccount as an alias for ServiceAccountName. 531 // If both are specified, ServiceAccountName (the new field) wins. 532 if in.ServiceAccountName == "" { 533 out.ServiceAccountName = in.DeprecatedServiceAccount 534 } 535 536 // the host namespace fields have to be handled specially for backward compatibility 537 // with v1.0.0 538 if out.SecurityContext == nil { 539 out.SecurityContext = new(api.PodSecurityContext) 540 } 541 out.SecurityContext.HostNetwork = in.HostNetwork 542 out.SecurityContext.HostPID = in.HostPID 543 out.SecurityContext.HostIPC = in.HostIPC 544 545 return nil 546} 547 548func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error { 549 if err := autoConvert_api_Pod_To_v1_Pod(in, out, s); err != nil { 550 return err 551 } 552 553 // TODO: sometime after we move init container to stable, remove these conversions 554 if len(out.Spec.InitContainers) > 0 || len(out.Status.InitContainerStatuses) > 0 { 555 old := out.Annotations 556 out.Annotations = make(map[string]string, len(old)) 557 for k, v := range old { 558 out.Annotations[k] = v 559 } 560 delete(out.Annotations, PodInitContainersAnnotationKey) 561 delete(out.Annotations, PodInitContainersBetaAnnotationKey) 562 delete(out.Annotations, PodInitContainerStatusesAnnotationKey) 563 delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey) 564 } 565 if len(out.Spec.InitContainers) > 0 { 566 value, err := json.Marshal(out.Spec.InitContainers) 567 if err != nil { 568 return err 569 } 570 out.Annotations[PodInitContainersAnnotationKey] = string(value) 571 out.Annotations[PodInitContainersBetaAnnotationKey] = string(value) 572 } 573 if len(out.Status.InitContainerStatuses) > 0 { 574 value, err := json.Marshal(out.Status.InitContainerStatuses) 575 if err != nil { 576 return err 577 } 578 out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value) 579 out.Annotations[PodInitContainerStatusesBetaAnnotationKey] = string(value) 580 } 581 582 return nil 583} 584 585func Convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { 586 // If there is a beta annotation, copy to alpha key. 587 // See commit log for PR #31026 for why we do this. 588 if valueBeta, okBeta := in.Annotations[PodInitContainersBetaAnnotationKey]; okBeta { 589 in.Annotations[PodInitContainersAnnotationKey] = valueBeta 590 } 591 // TODO: sometime after we move init container to stable, remove these conversions 592 // Move the annotation to the internal repr. field 593 if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok { 594 var values []Container 595 if err := json.Unmarshal([]byte(value), &values); err != nil { 596 return err 597 } 598 // Conversion from external to internal version exists more to 599 // satisfy the needs of the decoder than it does to be a general 600 // purpose tool. And Decode always creates an intermediate object 601 // to decode to. Thus the caller of UnsafeConvertToVersion is 602 // taking responsibility to ensure mutation of in is not exposed 603 // back to the caller. 604 in.Spec.InitContainers = values 605 // Call defaulters explicitly until annotations are removed 606 for i := range in.Spec.InitContainers { 607 c := &in.Spec.InitContainers[i] 608 SetDefaults_Container(c) 609 } 610 } 611 // If there is a beta annotation, copy to alpha key. 612 // See commit log for PR #31026 for why we do this. 613 if valueBeta, okBeta := in.Annotations[PodInitContainerStatusesBetaAnnotationKey]; okBeta { 614 in.Annotations[PodInitContainerStatusesAnnotationKey] = valueBeta 615 } 616 if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok { 617 var values []ContainerStatus 618 if err := json.Unmarshal([]byte(value), &values); err != nil { 619 return err 620 } 621 // Conversion from external to internal version exists more to 622 // satisfy the needs of the decoder than it does to be a general 623 // purpose tool. And Decode always creates an intermediate object 624 // to decode to. Thus the caller of UnsafeConvertToVersion is 625 // taking responsibility to ensure mutation of in is not exposed 626 // back to the caller. 627 in.Status.InitContainerStatuses = values 628 } 629 630 if err := autoConvert_v1_Pod_To_api_Pod(in, out, s); err != nil { 631 return err 632 } 633 if len(out.Annotations) > 0 { 634 old := out.Annotations 635 out.Annotations = make(map[string]string, len(old)) 636 for k, v := range old { 637 out.Annotations[k] = v 638 } 639 delete(out.Annotations, PodInitContainersAnnotationKey) 640 delete(out.Annotations, PodInitContainersBetaAnnotationKey) 641 delete(out.Annotations, PodInitContainerStatusesAnnotationKey) 642 delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey) 643 } 644 return nil 645} 646 647func Convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error { 648 if err := autoConvert_api_ServiceSpec_To_v1_ServiceSpec(in, out, s); err != nil { 649 return err 650 } 651 // Publish both externalIPs and deprecatedPublicIPs fields in v1. 652 out.DeprecatedPublicIPs = in.ExternalIPs 653 return nil 654} 655 656func Convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error { 657 if err := autoConvert_v1_Secret_To_api_Secret(in, out, s); err != nil { 658 return err 659 } 660 661 // StringData overwrites Data 662 if len(in.StringData) > 0 { 663 if out.Data == nil { 664 out.Data = map[string][]byte{} 665 } 666 for k, v := range in.StringData { 667 out.Data[k] = []byte(v) 668 } 669 } 670 671 return nil 672} 673 674func Convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error { 675 if err := autoConvert_v1_ServiceSpec_To_api_ServiceSpec(in, out, s); err != nil { 676 return err 677 } 678 // Prefer the legacy deprecatedPublicIPs field, if provided. 679 if len(in.DeprecatedPublicIPs) > 0 { 680 out.ExternalIPs = in.DeprecatedPublicIPs 681 } 682 return nil 683} 684 685func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *PodSecurityContext, s conversion.Scope) error { 686 out.SupplementalGroups = in.SupplementalGroups 687 if in.SELinuxOptions != nil { 688 out.SELinuxOptions = new(SELinuxOptions) 689 if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { 690 return err 691 } 692 } else { 693 out.SELinuxOptions = nil 694 } 695 out.RunAsUser = in.RunAsUser 696 out.RunAsNonRoot = in.RunAsNonRoot 697 out.FSGroup = in.FSGroup 698 return nil 699} 700 701func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error { 702 out.SupplementalGroups = in.SupplementalGroups 703 if in.SELinuxOptions != nil { 704 out.SELinuxOptions = new(api.SELinuxOptions) 705 if err := Convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { 706 return err 707 } 708 } else { 709 out.SELinuxOptions = nil 710 } 711 out.RunAsUser = in.RunAsUser 712 out.RunAsNonRoot = in.RunAsNonRoot 713 out.FSGroup = in.FSGroup 714 return nil 715} 716 717// +k8s:conversion-fn=copy-only 718func Convert_v1_ResourceList_To_api_ResourceList(in *ResourceList, out *api.ResourceList, s conversion.Scope) error { 719 if *in == nil { 720 return nil 721 } 722 if *out == nil { 723 *out = make(api.ResourceList, len(*in)) 724 } 725 for key, val := range *in { 726 // Moved to defaults 727 // TODO(#18538): We round up resource values to milli scale to maintain API compatibility. 728 // In the future, we should instead reject values that need rounding. 729 // const milliScale = -3 730 // val.RoundUp(milliScale) 731 732 (*out)[api.ResourceName(key)] = val 733 } 734 return nil 735} 736 737func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error { 738 return scheme.AddFieldLabelConversionFunc("v1", "Event", 739 func(label, value string) (string, string, error) { 740 switch label { 741 case "involvedObject.kind", 742 "involvedObject.namespace", 743 "involvedObject.name", 744 "involvedObject.uid", 745 "involvedObject.apiVersion", 746 "involvedObject.resourceVersion", 747 "involvedObject.fieldPath", 748 "reason", 749 "source", 750 "type", 751 "metadata.namespace", 752 "metadata.name": 753 return label, value, nil 754 default: 755 return "", "", fmt.Errorf("field label not supported: %s", label) 756 } 757 }) 758} 759 760func AddFieldLabelConversionsForNamespace(scheme *runtime.Scheme) error { 761 return scheme.AddFieldLabelConversionFunc("v1", "Namespace", 762 func(label, value string) (string, string, error) { 763 switch label { 764 case "status.phase", 765 "metadata.name": 766 return label, value, nil 767 default: 768 return "", "", fmt.Errorf("field label not supported: %s", label) 769 } 770 }) 771} 772 773func AddFieldLabelConversionsForSecret(scheme *runtime.Scheme) error { 774 return scheme.AddFieldLabelConversionFunc("v1", "Secret", 775 func(label, value string) (string, string, error) { 776 switch label { 777 case "type", 778 "metadata.namespace", 779 "metadata.name": 780 return label, value, nil 781 default: 782 return "", "", fmt.Errorf("field label not supported: %s", label) 783 } 784 }) 785} 786