func TestGetResources(t *testing.T) { instances := make([]ec2.Instance, 3) instances[0].PrivateDNSName = "m3.medium" instances[0].InstanceType = "m3.medium" instances[0].State.Name = "running" instances[1].PrivateDNSName = "r3.8xlarge" instances[1].InstanceType = "r3.8xlarge" instances[1].State.Name = "running" instances[2].PrivateDNSName = "unknown.type" instances[2].InstanceType = "unknown.type" instances[2].State.Name = "running" aws1 := mockInstancesResp(instances) res1, err1 := aws1.GetNodeResources("m3.medium") if err1 != nil { t.Errorf("Should not error when instance type found: %v", err1) } e1 := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(int64(3.0*1000), resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(int64(3.75*1024*1024*1024), resource.BinarySI), }, } if !reflect.DeepEqual(e1, res1) { t.Errorf("Expected %v, got %v", e1, res1) } res2, err2 := aws1.GetNodeResources("r3.8xlarge") if err2 != nil { t.Errorf("Should not error when instance type found: %v", err2) } e2 := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(int64(104.0*1000), resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(int64(244.0*1024*1024*1024), resource.BinarySI), }, } if !reflect.DeepEqual(e2, res2) { t.Errorf("Expected %v, got %v", e2, res2) } res3, err3 := aws1.GetNodeResources("unknown.type") if err3 != nil { t.Errorf("Should not error when unknown instance type") } if res3 != nil { t.Errorf("Should return nil resources when unknown instance type") } }
func TestCreateGetCloudNodesWithSpec(t *testing.T) { resourceList := api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(1000, resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(3000, resource.DecimalSI), } table := []struct { fakeCloud *fake_cloud.FakeCloud machines []string expectedNodes *api.NodeList }{ { fakeCloud: &fake_cloud.FakeCloud{}, expectedNodes: &api.NodeList{}, }, { fakeCloud: &fake_cloud.FakeCloud{ Machines: []string{"node0"}, NodeResources: &api.NodeResources{Capacity: resourceList}, }, expectedNodes: &api.NodeList{ Items: []api.Node{ { ObjectMeta: api.ObjectMeta{Name: "node0"}, Spec: api.NodeSpec{Capacity: resourceList}, }, }, }, }, { fakeCloud: &fake_cloud.FakeCloud{ Machines: []string{"node0", "node1"}, NodeResources: &api.NodeResources{Capacity: resourceList}, }, expectedNodes: &api.NodeList{ Items: []api.Node{ { ObjectMeta: api.ObjectMeta{Name: "node0"}, Spec: api.NodeSpec{Capacity: resourceList}, }, { ObjectMeta: api.ObjectMeta{Name: "node1"}, Spec: api.NodeSpec{Capacity: resourceList}, }, }, }, }, } for _, item := range table { nodeController := NewNodeController(item.fakeCloud, ".*", nil, &api.NodeResources{}, nil, nil, 10, time.Minute) nodes, err := nodeController.GetCloudNodesWithSpec() if err != nil { t.Errorf("unexpected error: %v", err) } if !reflect.DeepEqual(item.expectedNodes, nodes) { t.Errorf("expected node list %+v, got %+v", item.expectedNodes, nodes) } } }
// PodCPU computes total cpu usage of a pod func PodCPU(pod *api.Pod) *resource.Quantity { val := int64(0) for j := range pod.Spec.Containers { val = val + pod.Spec.Containers[j].Resources.Limits.Cpu().MilliValue() } return resource.NewMilliQuantity(int64(val), resource.DecimalSI) }
// Builds an api.NodeResources // cpu is in ecus, memory is in GiB // We pass the family in so that we could provide more info (e.g. GPU or not) func makeNodeResources(family string, cpu float64, memory float64) (*api.NodeResources, error) { return &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(int64(cpu*1000), resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(int64(memory*1024*1024*1024), resource.BinarySI), }, }, nil }
func makeResources(milliCPU int64, memory int64) api.NodeResources { return api.NodeResources{ Capacity: api.ResourceList{ "cpu": *resource.NewMilliQuantity(milliCPU, resource.DecimalSI), "memory": *resource.NewQuantity(memory, resource.BinarySI), }, } }
// cpu is in cores, memory is in GiB func makeResources(cpu float64, memory float64) *api.NodeResources { return &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(int64(cpu*1000), resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(int64(memory*1024*1024*1024), resource.BinarySI), }, } }
func makeResources(milliCPU int64, memory int64, pods int64) api.NodeResources { return api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(milliCPU, resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(memory, resource.BinarySI), api.ResourcePods: *resource.NewQuantity(pods, resource.DecimalSI), }, } }
func makeMinion(node string, milliCPU, memory int64) api.Node { return api.Node{ ObjectMeta: api.ObjectMeta{Name: node}, Status: api.NodeStatus{ Capacity: api.ResourceList{ "cpu": *resource.NewMilliQuantity(milliCPU, resource.DecimalSI), "memory": *resource.NewQuantity(memory, resource.BinarySI), }, }, } }
func CapacityFromMachineInfo(info *cadvisorApi.MachineInfo) api.ResourceList { c := api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity( int64(info.NumCores*1000), resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity( info.MemoryCapacity, resource.BinarySI), } return c }
func makeMinion(node string, milliCPU, memory int64) api.Node { return api.Node{ ObjectMeta: api.ObjectMeta{Name: node}, Spec: api.NodeSpec{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(milliCPU, resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(memory, resource.BinarySI), }, }, } }
// Run runs the CMServer. This should never exit. func (s *CMServer) Run(_ []string) error { s.verifyMinionFlags() if len(s.ClientConfig.Host) == 0 { glog.Fatal("usage: controller-manager --master <master>") } kubeClient, err := client.New(&s.ClientConfig) if err != nil { glog.Fatalf("Invalid API configuration: %v", err) } go func() { if s.EnableProfiling { mux := http.NewServeMux() mux.HandleFunc("/debug/pprof/", pprof.Index) mux.HandleFunc("/debug/pprof/profile", pprof.Profile) mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) } http.ListenAndServe(net.JoinHostPort(s.Address.String(), strconv.Itoa(s.Port)), nil) }() endpoints := service.NewEndpointController(kubeClient) go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10) controllerManager := replicationControllerPkg.NewReplicationManager(kubeClient) controllerManager.Run(replicationControllerPkg.DefaultSyncPeriod) kubeletClient, err := client.NewKubeletClient(&s.KubeletConfig) if err != nil { glog.Fatalf("Failure to start kubelet client: %v", err) } cloud := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile) nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(s.NodeMilliCPU, resource.DecimalSI), api.ResourceMemory: s.NodeMemory, }, } nodeController := nodeControllerPkg.NewNodeController(cloud, s.MinionRegexp, s.MachineList, nodeResources, kubeClient, kubeletClient, s.RegisterRetryCount, s.PodEvictionTimeout) nodeController.Run(s.NodeSyncPeriod, s.SyncNodeList, s.SyncNodeStatus) resourceQuotaManager := resourcequota.NewResourceQuotaManager(kubeClient) resourceQuotaManager.Run(s.ResourceQuotaSyncPeriod) select {} return nil }
func (cm *containerManagerImpl) SystemContainersLimit() api.ResourceList { cpuLimit := int64(0) // Sum up resources of all external containers. for _, cont := range cm.systemContainers { cpuLimit += cont.cpuMillicores } return api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity( cpuLimit, resource.DecimalSI), } }
func newResourcePod(usage ...resourceRequest) api.Pod { containers := []api.Container{} for _, req := range usage { containers = append(containers, api.Container{ Memory: *resource.NewQuantity(req.memory, resource.BinarySI), CPU: *resource.NewMilliQuantity(req.milliCPU, resource.DecimalSI), }) } return api.Pod{ Spec: api.PodSpec{ Containers: containers, }, } }
func ExampleFormat() { memorySize := resource.NewQuantity(5*1024*1024*1024, resource.BinarySI) fmt.Printf("memorySize = %v\n", memorySize) diskSize := resource.NewQuantity(5*1000*1000*1000, resource.DecimalSI) fmt.Printf("diskSize = %v\n", diskSize) cores := resource.NewMilliQuantity(5300, resource.DecimalSI) fmt.Printf("cores = %v\n", cores) // Output: // memorySize = 5Gi // diskSize = 5G // cores = 5300m }
// Instances returns an implementation of Instances for OpenStack. func (os *OpenStack) Instances() (cloudprovider.Instances, bool) { glog.V(4).Info("openstack.Instances() called") if err := openstack.Authenticate(os.provider, os.authOpts); err != nil { glog.Warningf("Failed to reauthenticate: %v", err) return nil, false } compute, err := openstack.NewComputeV2(os.provider, gophercloud.EndpointOpts{ Region: os.region, }) if err != nil { glog.Warningf("Failed to find compute endpoint: %v", err) return nil, false } pager := flavors.ListDetail(compute, nil) flavor_to_resource := make(map[string]*api.NodeResources) err = pager.EachPage(func(page pagination.Page) (bool, error) { flavorList, err := flavors.ExtractFlavors(page) if err != nil { return false, err } for _, flavor := range flavorList { rsrc := api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewQuantity(int64(flavor.VCPUs), resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(int64(flavor.RAM)*MiB, resource.BinarySI), "openstack.org/disk": *resource.NewQuantity(int64(flavor.Disk)*GB, resource.DecimalSI), "openstack.org/rxTxFactor": *resource.NewMilliQuantity(int64(flavor.RxTxFactor)*1000, resource.DecimalSI), "openstack.org/swap": *resource.NewQuantity(int64(flavor.Swap)*MiB, resource.BinarySI), }, } flavor_to_resource[flavor.ID] = &rsrc } return true, nil }) if err != nil { glog.Warningf("Failed to find compute flavors: %v", err) return nil, false } glog.V(3).Infof("Found %v compute flavors", len(flavor_to_resource)) glog.V(1).Info("Claiming to support Instances") return &Instances{compute, flavor_to_resource}, true }
// RunControllerManager starts a controller func RunControllerManager(machineList []string, cl *client.Client, nodeMilliCPU, nodeMemory int64) { nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(nodeMilliCPU, resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(nodeMemory, resource.BinarySI), }, } nodeController := nodeControllerPkg.NewNodeController(nil, "", machineList, nodeResources, cl) nodeController.Run(10 * time.Second) endpoints := service.NewEndpointController(cl) go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10) controllerManager := controller.NewReplicationManager(cl) controllerManager.Run(10 * time.Second) }
// RunControllerManager starts a controller func runControllerManager(machineList []string, cl *client.Client, nodeMilliCPU, nodeMemory int64) { nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(nodeMilliCPU, resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(nodeMemory, resource.BinarySI), }, } kubeClient := &client.HTTPKubeletClient{Client: http.DefaultClient, Port: ports.KubeletPort} nodeController := nodeControllerPkg.NewNodeController(nil, "", machineList, nodeResources, cl, kubeClient, 10, 5*time.Minute) nodeController.Run(10*time.Second, true, true) endpoints := service.NewEndpointController(cl) go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10) controllerManager := controller.NewReplicationManager(cl) controllerManager.Run(controller.DefaultSyncPeriod) }
func newResourcePod(usage ...resourceRequest) *api.Pod { containers := []api.Container{} for _, req := range usage { containers = append(containers, api.Container{ Resources: api.ResourceRequirements{ Limits: api.ResourceList{ "cpu": *resource.NewMilliQuantity(req.milliCPU, resource.DecimalSI), "memory": *resource.NewQuantity(req.memory, resource.BinarySI), }, }, }) } return &api.Pod{ Spec: api.PodSpec{ Containers: containers, }, } }
// RunControllerManager starts a controller func runControllerManager(machineList []string, cl *client.Client, nodeMilliCPU, nodeMemory int64) { nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(nodeMilliCPU, resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(nodeMemory, resource.BinarySI), }, } nodeController := nodecontroller.NewNodeController( nil, "", machineList, nodeResources, cl, 10, 5*time.Minute, util.NewTokenBucketRateLimiter(*deletingPodsQps, *deletingPodsBurst), 40*time.Second, 60*time.Second, 5*time.Second, "") nodeController.Run(10*time.Second, true) serviceController := servicecontroller.New(nil, cl, "kubernetes") if err := serviceController.Run(); err != nil { glog.Warningf("Running without a service controller: %v", err) } endpoints := service.NewEndpointController(cl) go endpoints.Run(5, util.NeverStop) controllerManager := controller.NewReplicationManager(cl) controllerManager.Run(controller.DefaultSyncPeriod) }
func main() { flag.Parse() util.InitLogs() defer util.FlushLogs() verflag.PrintAndExitIfRequested() verifyMinionFlags() if len(clientConfig.Host) == 0 { glog.Fatal("usage: controller-manager -master <master>") } kubeClient, err := client.New(clientConfig) if err != nil { glog.Fatalf("Invalid API configuration: %v", err) } go http.ListenAndServe(net.JoinHostPort(address.String(), strconv.Itoa(*port)), nil) endpoints := service.NewEndpointController(kubeClient) go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10) controllerManager := replicationControllerPkg.NewReplicationManager(kubeClient) controllerManager.Run(10 * time.Second) cloud := cloudprovider.InitCloudProvider(*cloudProvider, *cloudConfigFile) nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(*nodeMilliCPU, resource.DecimalSI), api.ResourceMemory: *nodeMemory, }, } nodeController := nodeControllerPkg.NewNodeController(cloud, *minionRegexp, machineList, nodeResources, kubeClient) nodeController.Run(10 * time.Second) select {} }
// PodLimitFunc enforces resource requirements enumerated by the pod against // the specified LimitRange. The pod may be modified to apply default resource // requirements if not specified, and enumerated on the LimitRange func PodLimitFunc(limitRange *api.LimitRange, pod *api.Pod) error { defaultResources := defaultContainerResourceRequirements(limitRange) mergePodResourceRequirements(pod, &defaultResources) podCPU := int64(0) podMem := int64(0) minContainerCPU := int64(0) minContainerMem := int64(0) maxContainerCPU := int64(0) maxContainerMem := int64(0) for i := range pod.Spec.Containers { container := &pod.Spec.Containers[i] containerCPU := container.Resources.Limits.Cpu().MilliValue() containerMem := container.Resources.Limits.Memory().Value() if i == 0 { minContainerCPU = containerCPU minContainerMem = containerMem maxContainerCPU = containerCPU maxContainerMem = containerMem } podCPU = podCPU + container.Resources.Limits.Cpu().MilliValue() podMem = podMem + container.Resources.Limits.Memory().Value() minContainerCPU = Min(containerCPU, minContainerCPU) minContainerMem = Min(containerMem, minContainerMem) maxContainerCPU = Max(containerCPU, maxContainerCPU) maxContainerMem = Max(containerMem, maxContainerMem) } for i := range limitRange.Spec.Limits { limit := limitRange.Spec.Limits[i] for _, minOrMax := range []string{"Min", "Max"} { var rl api.ResourceList switch minOrMax { case "Min": rl = limit.Min case "Max": rl = limit.Max } for k, v := range rl { observed := int64(0) enforced := int64(0) var err error switch k { case api.ResourceMemory: enforced = v.Value() switch limit.Type { case api.LimitTypePod: observed = podMem err = fmt.Errorf("%simum memory usage per pod is %s", minOrMax, v.String()) case api.LimitTypeContainer: observed = maxContainerMem err = fmt.Errorf("%simum memory usage per container is %s", minOrMax, v.String()) } case api.ResourceCPU: enforced = v.MilliValue() switch limit.Type { case api.LimitTypePod: observed = podCPU err = fmt.Errorf("%simum CPU usage per pod is %s, but requested %s", minOrMax, v.String(), resource.NewMilliQuantity(observed, resource.DecimalSI)) case api.LimitTypeContainer: observed = maxContainerCPU err = fmt.Errorf("%simum CPU usage per container is %s", minOrMax, v.String()) } } switch minOrMax { case "Min": if observed < enforced { return err } case "Max": if observed > enforced { return err } } } } } return nil }
startPods(c, podsNeededForSaturation, ns, "overcommit", api.Pod{ TypeMeta: api.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ Name: "", Labels: map[string]string{"name": ""}, }, Spec: api.PodSpec{ Containers: []api.Container{ { Name: "", Image: "gcr.io/google_containers/pause:go", Resources: api.ResourceRequirements{ Limits: api.ResourceList{ "cpu": *resource.NewMilliQuantity(100, "DecimalSI"), }, }, }, }, }, }) podName := "additional-pod" _, err = c.Pods(ns).Create(&api.Pod{ TypeMeta: api.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ Name: podName, Labels: map[string]string{"name": "additional"},
// limitPodCPU sets DefaultContainerCPUs for the CPU limit of each container that // does not limit its CPU resource yet. limitPodCPU returns true iff at least one // container had no CPU limit set. func LimitPodCPU(pod *api.Pod, defaultLimit CPUShares) bool { defaultCPUQuantity := resource.NewMilliQuantity(int64(float64(defaultLimit)*1000.0), resource.DecimalSI) return limitPodResource(pod, api.ResourceCPU, *defaultCPUQuantity) }
// Run runs the CMServer. This should never exit. func (s *CMServer) Run(_ []string) error { s.verifyMinionFlags() if s.Kubeconfig == "" && s.Master == "" { glog.Warningf("Neither --kubeconfig nor --master was specified. Using default API client. This might not work.") } // This creates a client, first loading any specified kubeconfig // file, and then overriding the Master flag, if non-empty. kubeconfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( &clientcmd.ClientConfigLoadingRules{ExplicitPath: s.Kubeconfig}, &clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: s.Master}}).ClientConfig() if err != nil { return err } kubeconfig.QPS = 20.0 kubeconfig.Burst = 30 kubeClient, err := client.New(kubeconfig) if err != nil { glog.Fatalf("Invalid API configuration: %v", err) } go func() { mux := http.NewServeMux() healthz.InstallHandler(mux) if s.EnableProfiling { mux.HandleFunc("/debug/pprof/", pprof.Index) mux.HandleFunc("/debug/pprof/profile", pprof.Profile) mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) } mux.Handle("/metrics", prometheus.Handler()) server := &http.Server{ Addr: net.JoinHostPort(s.Address.String(), strconv.Itoa(s.Port)), Handler: mux, } glog.Fatal(server.ListenAndServe()) }() endpoints := service.NewEndpointController(kubeClient) go endpoints.Run(s.ConcurrentEndpointSyncs, util.NeverStop) controllerManager := replicationControllerPkg.NewReplicationManager(kubeClient) controllerManager.Run(replicationControllerPkg.DefaultSyncPeriod) cloud := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile) nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(s.NodeMilliCPU, resource.DecimalSI), api.ResourceMemory: s.NodeMemory, }, } if s.SyncNodeStatus { glog.Warning("DEPRECATION NOTICE: sync_node_status flag is being deprecated. It has no effect now and it will be removed in a future version.") } nodeController := nodecontroller.NewNodeController(cloud, s.MinionRegexp, s.MachineList, nodeResources, kubeClient, s.RegisterRetryCount, s.PodEvictionTimeout, util.NewTokenBucketRateLimiter(s.DeletingPodsQps, s.DeletingPodsBurst), s.NodeMonitorGracePeriod, s.NodeStartupGracePeriod, s.NodeMonitorPeriod, s.ClusterName) nodeController.Run(s.NodeSyncPeriod, s.SyncNodeList) serviceController := servicecontroller.New(cloud, kubeClient, s.ClusterName) if err := serviceController.Run(); err != nil { glog.Errorf("Failed to start service controller: %v", err) } resourceQuotaManager := resourcequota.NewResourceQuotaManager(kubeClient) resourceQuotaManager.Run(s.ResourceQuotaSyncPeriod) namespaceManager := namespace.NewNamespaceManager(kubeClient, s.NamespaceSyncPeriod) namespaceManager.Run() select {} return nil }
pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: name, Labels: map[string]string{ "name": "foo", "time": value, }, }, Spec: api.PodSpec{ Containers: []api.Container{ { Name: "nginx", Image: "gcr.io/google_containers/pause", Resources: api.ResourceRequirements{ Limits: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(10*1024*1024, resource.DecimalSI), }, }, }, }, }, } defer podClient.Delete(pod.Name, nil) _, err := podClient.Create(pod) if err != nil { Fail(fmt.Sprintf("Error creating a pod: %v", err)) } expectNoError(waitForPodRunning(c, pod.Name)) }) It("should be submitted and removed", func() {
func addConversionFuncs() { // Our TypeMeta was split into two different structs. api.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", api.TypeMeta{}, "TypeMeta") api.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", api.ObjectMeta{}, "ObjectMeta") api.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", api.ListMeta{}, "ListMeta") api.Scheme.AddStructFieldConversion(api.TypeMeta{}, "TypeMeta", TypeMeta{}, "TypeMeta") api.Scheme.AddStructFieldConversion(api.ObjectMeta{}, "ObjectMeta", TypeMeta{}, "TypeMeta") api.Scheme.AddStructFieldConversion(api.ListMeta{}, "ListMeta", TypeMeta{}, "TypeMeta") api.Scheme.AddStructFieldConversion(api.Endpoints{}, "Endpoints", Endpoints{}, "Endpoints") // TODO: scope this to a specific type once that becomes available and remove the Event conversion functions below // api.Scheme.AddStructFieldConversion(string(""), "Status", string(""), "Condition") // api.Scheme.AddStructFieldConversion(string(""), "Condition", string(""), "Status") err := api.Scheme.AddConversionFuncs( // TypeMeta must be split into two objects func(in *api.TypeMeta, out *TypeMeta, s conversion.Scope) error { out.Kind = in.Kind out.APIVersion = in.APIVersion return nil }, func(in *TypeMeta, out *api.TypeMeta, s conversion.Scope) error { out.Kind = in.Kind out.APIVersion = in.APIVersion return nil }, // ListMeta must be converted to TypeMeta func(in *api.ListMeta, out *TypeMeta, s conversion.Scope) error { out.SelfLink = in.SelfLink if len(in.ResourceVersion) > 0 { v, err := strconv.ParseUint(in.ResourceVersion, 10, 64) if err != nil { return err } out.ResourceVersion = v } return nil }, func(in *TypeMeta, out *api.ListMeta, s conversion.Scope) error { out.SelfLink = in.SelfLink if in.ResourceVersion != 0 { out.ResourceVersion = strconv.FormatUint(in.ResourceVersion, 10) } else { out.ResourceVersion = "" } return nil }, // ObjectMeta must be converted to TypeMeta func(in *api.ObjectMeta, out *TypeMeta, s conversion.Scope) error { out.Namespace = in.Namespace out.ID = in.Name out.GenerateName = in.GenerateName out.UID = in.UID out.CreationTimestamp = in.CreationTimestamp out.DeletionTimestamp = in.DeletionTimestamp out.SelfLink = in.SelfLink if len(in.ResourceVersion) > 0 { v, err := strconv.ParseUint(in.ResourceVersion, 10, 64) if err != nil { return err } out.ResourceVersion = v } return s.Convert(&in.Annotations, &out.Annotations, 0) }, func(in *TypeMeta, out *api.ObjectMeta, s conversion.Scope) error { out.Namespace = in.Namespace out.Name = in.ID out.GenerateName = in.GenerateName out.UID = in.UID out.CreationTimestamp = in.CreationTimestamp out.DeletionTimestamp = in.DeletionTimestamp out.SelfLink = in.SelfLink if in.ResourceVersion != 0 { out.ResourceVersion = strconv.FormatUint(in.ResourceVersion, 10) } else { out.ResourceVersion = "" } return s.Convert(&in.Annotations, &out.Annotations, 0) }, // Convert all to the new PodPhase constants func(in *api.PodPhase, out *PodStatus, s conversion.Scope) error { switch *in { case "": *out = "" case api.PodPending: *out = PodWaiting case api.PodRunning: *out = PodRunning case api.PodSucceeded: *out = PodSucceeded case api.PodFailed: *out = PodTerminated case api.PodUnknown: *out = PodUnknown default: return &api.ConversionError{ In: in, Out: out, Message: "The string provided is not a valid PodPhase constant value", } } return nil }, func(in *PodStatus, out *api.PodPhase, s conversion.Scope) error { switch *in { case "": *out = "" case PodWaiting: *out = api.PodPending case PodRunning: *out = api.PodRunning case PodTerminated: // Older API versions did not contain enough info to map to PodSucceeded *out = api.PodFailed case PodSucceeded: *out = api.PodSucceeded case PodUnknown: *out = api.PodUnknown default: return &api.ConversionError{ In: in, Out: out, Message: "The string provided is not a valid PodPhase constant value", } } return nil }, // Convert all the standard objects func(in *api.Pod, out *Pod, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } // TODO: Change this to use in.ObjectMeta.Labels. if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil { return err } out.DesiredState.Host = in.Spec.Host out.CurrentState.Host = in.Spec.Host out.ServiceAccount = in.Spec.ServiceAccount if err := s.Convert(&in.Status, &out.CurrentState, 0); err != nil { return err } if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { return err } return nil }, func(in *Pod, out *api.Pod, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil { return err } out.Spec.ServiceAccount = in.ServiceAccount out.Spec.Host = in.DesiredState.Host if err := s.Convert(&in.CurrentState, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { return err } return nil }, func(in *api.ReplicationController, out *ReplicationController, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.DesiredState, 0); err != nil { return err } out.CurrentState.Replicas = in.Status.Replicas return nil }, func(in *ReplicationController, out *api.ReplicationController, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.DesiredState, &out.Spec, 0); err != nil { return err } out.Status.Replicas = in.CurrentState.Replicas return nil }, func(in *api.ReplicationControllerSpec, out *ReplicationControllerState, s conversion.Scope) error { out.Replicas = in.Replicas if err := s.Convert(&in.Selector, &out.ReplicaSelector, 0); err != nil { return err } if in.TemplateRef != nil && in.Template == nil { return &api.ConversionError{ In: in, Out: out, Message: "objects with a template ref cannot be converted to older objects, must populate template", } } if in.Template != nil { if err := s.Convert(in.Template, &out.PodTemplate, 0); err != nil { return err } } return nil }, func(in *ReplicationControllerState, out *api.ReplicationControllerSpec, s conversion.Scope) error { out.Replicas = in.Replicas if err := s.Convert(&in.ReplicaSelector, &out.Selector, 0); err != nil { return err } out.Template = &api.PodTemplateSpec{} if err := s.Convert(&in.PodTemplate, out.Template, 0); err != nil { return err } return nil }, func(in *api.PodTemplateSpec, out *PodTemplate, s conversion.Scope) error { if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil { return err } out.DesiredState.Host = in.Spec.Host out.ServiceAccount = in.Spec.ServiceAccount if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta.Annotations, &out.Annotations, 0); err != nil { return err } return nil }, func(in *PodTemplate, out *api.PodTemplateSpec, s conversion.Scope) error { if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil { return err } out.Spec.Host = in.DesiredState.Host out.Spec.ServiceAccount = in.ServiceAccount if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } if err := s.Convert(&in.Annotations, &out.ObjectMeta.Annotations, 0); err != nil { return err } return nil }, // Converts internal Container to v1beta2.Container. // Fields 'CPU' and 'Memory' are not present in the internal Container object. // Hence the need for a custom conversion function. func(in *api.Container, out *Container, s conversion.Scope) error { if err := s.Convert(&in.Name, &out.Name, 0); err != nil { return err } if err := s.Convert(&in.Image, &out.Image, 0); err != nil { return err } if err := s.Convert(&in.Command, &out.Entrypoint, 0); err != nil { return err } if err := s.Convert(&in.Args, &out.Command, 0); err != nil { return err } if err := s.Convert(&in.WorkingDir, &out.WorkingDir, 0); err != nil { return err } if err := s.Convert(&in.Ports, &out.Ports, 0); err != nil { return err } if err := s.Convert(&in.Env, &out.Env, 0); err != nil { return err } if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { return err } if err := s.Convert(in.Resources.Limits.Cpu(), &out.CPU, 0); err != nil { return err } if err := s.Convert(in.Resources.Limits.Memory(), &out.Memory, 0); err != nil { return err } if err := s.Convert(&in.VolumeMounts, &out.VolumeMounts, 0); err != nil { return err } if err := s.Convert(&in.LivenessProbe, &out.LivenessProbe, 0); err != nil { return err } if err := s.Convert(&in.ReadinessProbe, &out.ReadinessProbe, 0); err != nil { return err } if err := s.Convert(&in.Lifecycle, &out.Lifecycle, 0); err != nil { return err } if err := s.Convert(&in.TerminationMessagePath, &out.TerminationMessagePath, 0); err != nil { return err } if err := s.Convert(&in.ImagePullPolicy, &out.ImagePullPolicy, 0); err != nil { return err } if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil { return err } // now that we've converted set the container field from security context if out.SecurityContext != nil && out.SecurityContext.Privileged != nil { out.Privileged = *out.SecurityContext.Privileged } // now that we've converted set the container field from security context if out.SecurityContext != nil && out.SecurityContext.Capabilities != nil { out.Capabilities = *out.SecurityContext.Capabilities } return nil }, // Internal API does not support CPU to be specified via an explicit field. // Hence it must be stored in Container.Resources. func(in *int, out *api.ResourceList, s conversion.Scope) error { if *in == 0 { return nil } quantity := resource.Quantity{} if err := s.Convert(in, &quantity, 0); err != nil { return err } (*out)[api.ResourceCPU] = quantity return nil }, // Internal API does not support Memory to be specified via an explicit field. // Hence it must be stored in Container.Resources. func(in *int64, out *api.ResourceList, s conversion.Scope) error { if *in == 0 { return nil } quantity := resource.Quantity{} if err := s.Convert(in, &quantity, 0); err != nil { return err } (*out)[api.ResourceMemory] = quantity return nil }, // Converts v1beta2.Container to internal api.Container. // Fields 'CPU' and 'Memory' are not present in the internal api.Container object. // Hence the need for a custom conversion function. func(in *Container, out *api.Container, s conversion.Scope) error { if err := s.Convert(&in.Name, &out.Name, 0); err != nil { return err } if err := s.Convert(&in.Image, &out.Image, 0); err != nil { return err } if err := s.Convert(&in.Command, &out.Args, 0); err != nil { return err } if err := s.Convert(&in.Entrypoint, &out.Command, 0); err != nil { return err } if err := s.Convert(&in.WorkingDir, &out.WorkingDir, 0); err != nil { return err } if err := s.Convert(&in.Ports, &out.Ports, 0); err != nil { return err } if err := s.Convert(&in.Env, &out.Env, 0); err != nil { return err } if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { return err } if err := s.Convert(&in.CPU, &out.Resources.Limits, 0); err != nil { return err } if err := s.Convert(&in.Memory, &out.Resources.Limits, 0); err != nil { return err } if err := s.Convert(&in.VolumeMounts, &out.VolumeMounts, 0); err != nil { return err } if err := s.Convert(&in.LivenessProbe, &out.LivenessProbe, 0); err != nil { return err } if err := s.Convert(&in.ReadinessProbe, &out.ReadinessProbe, 0); err != nil { return err } if err := s.Convert(&in.Lifecycle, &out.Lifecycle, 0); err != nil { return err } if err := s.Convert(&in.TerminationMessagePath, &out.TerminationMessagePath, 0); err != nil { return err } if err := s.Convert(&in.ImagePullPolicy, &out.ImagePullPolicy, 0); err != nil { return err } if in.SecurityContext != nil { if in.SecurityContext.Capabilities != nil { if !reflect.DeepEqual(in.SecurityContext.Capabilities.Add, in.Capabilities.Add) || !reflect.DeepEqual(in.SecurityContext.Capabilities.Drop, in.Capabilities.Drop) { return fmt.Errorf("container capability settings do not match security context settings, cannot convert") } } if in.SecurityContext.Privileged != nil { if in.Privileged != *in.SecurityContext.Privileged { return fmt.Errorf("container privileged settings do not match security context settings, cannot convert") } } } if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil { return err } return nil }, func(in *api.PodSpec, out *ContainerManifest, s conversion.Scope) error { if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil { return err } if err := s.Convert(&in.Containers, &out.Containers, 0); err != nil { return err } if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil { return err } if err := s.Convert(&in.ImagePullSecrets, &out.ImagePullSecrets, 0); err != nil { return err } if in.TerminationGracePeriodSeconds != nil { out.TerminationGracePeriodSeconds = new(int64) *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds } if in.ActiveDeadlineSeconds != nil { out.ActiveDeadlineSeconds = new(int64) *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds } out.DNSPolicy = DNSPolicy(in.DNSPolicy) out.Version = "v1beta2" out.HostNetwork = in.HostNetwork return nil }, func(in *ContainerManifest, out *api.PodSpec, s conversion.Scope) error { if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil { return err } if err := s.Convert(&in.Containers, &out.Containers, 0); err != nil { return err } if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil { return err } if err := s.Convert(&in.ImagePullSecrets, &out.ImagePullSecrets, 0); err != nil { return err } if in.TerminationGracePeriodSeconds != nil { out.TerminationGracePeriodSeconds = new(int64) *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds } if in.ActiveDeadlineSeconds != nil { out.ActiveDeadlineSeconds = new(int64) *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds } out.DNSPolicy = api.DNSPolicy(in.DNSPolicy) out.HostNetwork = in.HostNetwork return nil }, func(in *api.PodStatus, out *PodState, s conversion.Scope) error { if err := s.Convert(&in.Phase, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.ContainerStatuses, &out.Info, 0); err != nil { return err } if err := s.Convert(&in.Conditions, &out.Conditions, 0); err != nil { return err } out.Message = in.Message out.HostIP = in.HostIP out.PodIP = in.PodIP return nil }, func(in *PodState, out *api.PodStatus, s conversion.Scope) error { if err := s.Convert(&in.Status, &out.Phase, 0); err != nil { return err } if err := s.Convert(&in.Info, &out.ContainerStatuses, 0); err != nil { return err } if err := s.Convert(&in.Conditions, &out.Conditions, 0); err != nil { return err } out.Message = in.Message out.HostIP = in.HostIP out.PodIP = in.PodIP return nil }, func(in *[]api.ContainerStatus, out *PodInfo, s conversion.Scope) error { *out = make(map[string]ContainerStatus) for _, st := range *in { v := ContainerStatus{} if err := s.Convert(&st, &v, 0); err != nil { return err } (*out)[st.Name] = v } return nil }, func(in *PodInfo, out *[]api.ContainerStatus, s conversion.Scope) error { for k, v := range *in { st := api.ContainerStatus{} if err := s.Convert(&v, &st, 0); err != nil { return err } st.Name = k *out = append(*out, st) } return nil }, func(in *api.ContainerStatus, out *ContainerStatus, s conversion.Scope) error { if err := s.Convert(&in.State, &out.State, 0); err != nil { return err } if err := s.Convert(&in.LastTerminationState, &out.LastTerminationState, 0); err != nil { return err } if err := s.Convert(&in.Ready, &out.Ready, 0); err != nil { return err } if err := s.Convert(&in.RestartCount, &out.RestartCount, 0); err != nil { return err } if err := s.Convert(&in.Image, &out.Image, 0); err != nil { return err } if err := s.Convert(&in.ImageID, &out.ImageID, 0); err != nil { return err } if err := s.Convert(&in.ContainerID, &out.ContainerID, 0); err != nil { return err } return nil }, func(in *ContainerStatus, out *api.ContainerStatus, s conversion.Scope) error { if err := s.Convert(&in.State, &out.State, 0); err != nil { return err } if err := s.Convert(&in.LastTerminationState, &out.LastTerminationState, 0); err != nil { return err } if err := s.Convert(&in.Ready, &out.Ready, 0); err != nil { return err } if err := s.Convert(&in.RestartCount, &out.RestartCount, 0); err != nil { return err } if err := s.Convert(&in.Image, &out.Image, 0); err != nil { return err } if err := s.Convert(&in.ImageID, &out.ImageID, 0); err != nil { return err } if err := s.Convert(&in.ContainerID, &out.ContainerID, 0); err != nil { return err } return nil }, func(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.State, 0); err != nil { return err } return nil }, func(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.State, &out.Status, 0); err != nil { return err } return nil }, func(in *api.PodSpec, out *PodState, s conversion.Scope) error { if err := s.Convert(&in, &out.Manifest, 0); err != nil { return err } out.Host = in.Host return nil }, func(in *PodState, out *api.PodSpec, s conversion.Scope) error { if err := s.Convert(&in.Manifest, &out, 0); err != nil { return err } out.Host = in.Host return nil }, func(in *api.Service, out *Service, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } // Produce legacy fields. out.Protocol = ProtocolTCP if len(in.Spec.Ports) > 0 { out.PortName = in.Spec.Ports[0].Name out.Port = in.Spec.Ports[0].Port out.Protocol = Protocol(in.Spec.Ports[0].Protocol) out.ContainerPort = in.Spec.Ports[0].TargetPort } // Copy modern fields. for i := range in.Spec.Ports { out.Ports = append(out.Ports, ServicePort{ Name: in.Spec.Ports[i].Name, Port: in.Spec.Ports[i].Port, Protocol: Protocol(in.Spec.Ports[i].Protocol), ContainerPort: in.Spec.Ports[i].TargetPort, NodePort: in.Spec.Ports[i].NodePort, }) } if err := s.Convert(&in.Spec.Selector, &out.Selector, 0); err != nil { return err } out.PublicIPs = in.Spec.DeprecatedPublicIPs out.PortalIP = in.Spec.PortalIP if err := s.Convert(&in.Spec.SessionAffinity, &out.SessionAffinity, 0); err != nil { return err } if err := s.Convert(&in.Status.LoadBalancer, &out.LoadBalancerStatus, 0); err != nil { return err } if err := s.Convert(&in.Spec.Type, &out.Type, 0); err != nil { return err } out.CreateExternalLoadBalancer = in.Spec.Type == api.ServiceTypeLoadBalancer return nil }, func(in *Service, out *api.Service, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if len(in.Ports) == 0 && in.Port != 0 { // Use legacy fields to produce modern fields. out.Spec.Ports = append(out.Spec.Ports, api.ServicePort{ Name: in.PortName, Port: in.Port, Protocol: api.Protocol(in.Protocol), TargetPort: in.ContainerPort, }) } else { // Use modern fields, ignore legacy. for i := range in.Ports { out.Spec.Ports = append(out.Spec.Ports, api.ServicePort{ Name: in.Ports[i].Name, Port: in.Ports[i].Port, Protocol: api.Protocol(in.Ports[i].Protocol), TargetPort: in.Ports[i].ContainerPort, NodePort: in.Ports[i].NodePort, }) } } if err := s.Convert(&in.Selector, &out.Spec.Selector, 0); err != nil { return err } out.Spec.DeprecatedPublicIPs = in.PublicIPs out.Spec.PortalIP = in.PortalIP if err := s.Convert(&in.SessionAffinity, &out.Spec.SessionAffinity, 0); err != nil { return err } if err := s.Convert(&in.LoadBalancerStatus, &out.Status.LoadBalancer, 0); err != nil { return err } typeIn := in.Type if typeIn == "" { if in.CreateExternalLoadBalancer { typeIn = ServiceTypeLoadBalancer } else { typeIn = ServiceTypeClusterIP } } if err := s.Convert(&typeIn, &out.Spec.Type, 0); err != nil { return err } return nil }, func(in *api.Node, out *Minion, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Status.Phase, &out.Status.Phase, 0); err != nil { return err } if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil { return err } if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil { return err } for _, address := range in.Status.Addresses { if address.Type == api.NodeLegacyHostIP { out.HostIP = address.Address } } out.PodCIDR = in.Spec.PodCIDR out.ExternalID = in.Spec.ExternalID out.Unschedulable = in.Spec.Unschedulable return s.Convert(&in.Status.Capacity, &out.NodeResources.Capacity, 0) }, func(in *Minion, out *api.Node, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } if err := s.Convert(&in.Status.Phase, &out.Status.Phase, 0); err != nil { return err } if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil { return err } if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil { return err } if in.HostIP != "" { api.AddToNodeAddresses(&out.Status.Addresses, api.NodeAddress{Type: api.NodeLegacyHostIP, Address: in.HostIP}) } out.Spec.PodCIDR = in.PodCIDR out.Spec.ExternalID = in.ExternalID out.Spec.Unschedulable = in.Unschedulable return s.Convert(&in.NodeResources.Capacity, &out.Status.Capacity, 0) }, func(in *api.LimitRange, out *LimitRange, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } return nil }, func(in *LimitRange, out *api.LimitRange, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } return nil }, func(in *Namespace, out *api.Namespace, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } return nil }, func(in *api.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { *out = LimitRangeSpec{} out.Limits = make([]LimitRangeItem, len(in.Limits), len(in.Limits)) for i := range in.Limits { if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil { return err } } return nil }, func(in *LimitRangeSpec, out *api.LimitRangeSpec, s conversion.Scope) error { *out = api.LimitRangeSpec{} out.Limits = make([]api.LimitRangeItem, len(in.Limits), len(in.Limits)) for i := range in.Limits { if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil { return err } } return nil }, func(in *api.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { *out = LimitRangeItem{} out.Type = LimitType(in.Type) if err := s.Convert(&in.Max, &out.Max, 0); err != nil { return err } if err := s.Convert(&in.Min, &out.Min, 0); err != nil { return err } if err := s.Convert(&in.Default, &out.Default, 0); err != nil { return err } return nil }, func(in *LimitRangeItem, out *api.LimitRangeItem, s conversion.Scope) error { *out = api.LimitRangeItem{} out.Type = api.LimitType(in.Type) if err := s.Convert(&in.Max, &out.Max, 0); err != nil { return err } if err := s.Convert(&in.Min, &out.Min, 0); err != nil { return err } if err := s.Convert(&in.Default, &out.Default, 0); err != nil { return err } return nil }, func(in *api.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } return nil }, func(in *ResourceQuota, out *api.ResourceQuota, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } return nil }, func(in *api.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { *out = ResourceQuotaSpec{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { return err } return nil }, func(in *ResourceQuotaSpec, out *api.ResourceQuotaSpec, s conversion.Scope) error { *out = api.ResourceQuotaSpec{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { return err } return nil }, func(in *api.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { *out = ResourceQuotaStatus{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { return err } if err := s.Convert(&in.Used, &out.Used, 0); err != nil { return err } return nil }, func(in *ResourceQuotaStatus, out *api.ResourceQuotaStatus, s conversion.Scope) error { *out = api.ResourceQuotaStatus{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { return err } if err := s.Convert(&in.Used, &out.Used, 0); err != nil { return err } return nil }, // Object ID <-> Name // TODO: amend the conversion package to allow overriding specific fields. func(in *ObjectReference, out *api.ObjectReference, s conversion.Scope) error { out.Kind = in.Kind out.Namespace = in.Namespace out.Name = in.ID out.UID = in.UID out.APIVersion = in.APIVersion out.ResourceVersion = in.ResourceVersion out.FieldPath = in.FieldPath return nil }, func(in *api.ObjectReference, out *ObjectReference, s conversion.Scope) error { out.Kind = in.Kind out.Namespace = in.Namespace out.ID = in.Name out.UID = in.UID out.APIVersion = in.APIVersion out.ResourceVersion = in.ResourceVersion out.FieldPath = in.FieldPath return nil }, // Event Status <-> Condition // Event Source <-> Source.Component // Event Host <-> Source.Host // TODO: remove this when it becomes possible to specify a field name conversion on a specific type func(in *api.Event, out *Event, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } out.Reason = in.Reason out.Message = in.Message out.Source = in.Source.Component out.Host = in.Source.Host out.Timestamp = in.FirstTimestamp out.FirstTimestamp = in.FirstTimestamp out.LastTimestamp = in.LastTimestamp out.Count = in.Count return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, func(in *Event, out *api.Event, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } out.Reason = in.Reason out.Message = in.Message out.Source.Component = in.Source out.Source.Host = in.Host if in.FirstTimestamp.IsZero() { // Assume this is an old event that does not specify FirstTimestamp/LastTimestamp/Count out.FirstTimestamp = in.Timestamp out.LastTimestamp = in.Timestamp out.Count = 1 } else { out.FirstTimestamp = in.FirstTimestamp out.LastTimestamp = in.LastTimestamp out.Count = in.Count } return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, // This is triggered for the Memory field of Container. func(in *int64, out *resource.Quantity, s conversion.Scope) error { out.Set(*in) out.Format = resource.BinarySI return nil }, func(in *resource.Quantity, out *int64, s conversion.Scope) error { *out = in.Value() return nil }, // This is triggered by the CPU field of Container. // Note that if we add other int/Quantity conversions my // simple hack (int64=Value(), int=MilliValue()) here won't work. func(in *int, out *resource.Quantity, s conversion.Scope) error { out.SetMilli(int64(*in)) out.Format = resource.DecimalSI return nil }, func(in *resource.Quantity, out *int, s conversion.Scope) error { *out = int(in.MilliValue()) return nil }, // Convert resource lists. func(in *ResourceList, out *api.ResourceList, s conversion.Scope) error { *out = api.ResourceList{} for k, v := range *in { fv, err := strconv.ParseFloat(v.String(), 64) if err != nil { return &api.ConversionError{ In: in, Out: out, Message: fmt.Sprintf("value '%v' of '%v': %v", v, k, err), } } if k == ResourceCPU { (*out)[api.ResourceCPU] = *resource.NewMilliQuantity(int64(fv*1000), resource.DecimalSI) } else { (*out)[api.ResourceName(k)] = *resource.NewQuantity(int64(fv), resource.BinarySI) } } return nil }, func(in *api.ResourceList, out *ResourceList, s conversion.Scope) error { *out = ResourceList{} for k, v := range *in { if k == api.ResourceCPU { (*out)[ResourceCPU] = util.NewIntOrStringFromString(fmt.Sprintf("%v", float64(v.MilliValue())/1000)) } else { (*out)[ResourceName(k)] = util.NewIntOrStringFromInt(int(v.Value())) } } return nil }, func(in *api.Volume, out *Volume, s conversion.Scope) error { if err := s.Convert(&in.VolumeSource, &out.Source, 0); err != nil { return err } out.Name = in.Name return nil }, func(in *Volume, out *api.Volume, s conversion.Scope) error { if err := s.Convert(&in.Source, &out.VolumeSource, 0); err != nil { return err } out.Name = in.Name return nil }, func(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { if err := s.Convert(&in.EmptyDir, &out.EmptyDir, 0); err != nil { return err } if err := s.Convert(&in.GitRepo, &out.GitRepo, 0); err != nil { return err } if err := s.Convert(&in.ISCSI, &out.ISCSI, 0); err != nil { return err } if err := s.Convert(&in.GCEPersistentDisk, &out.GCEPersistentDisk, 0); err != nil { return err } if err := s.Convert(&in.AWSElasticBlockStore, &out.AWSElasticBlockStore, 0); err != nil { return err } if err := s.Convert(&in.HostPath, &out.HostDir, 0); err != nil { return err } if err := s.Convert(&in.Secret, &out.Secret, 0); err != nil { return err } if err := s.Convert(&in.NFS, &out.NFS, 0); err != nil { return err } if err := s.Convert(&in.Glusterfs, &out.Glusterfs, 0); err != nil { return err } if err := s.Convert(&in.PersistentVolumeClaimVolumeSource, &out.PersistentVolumeClaimVolumeSource, 0); err != nil { return err } if err := s.Convert(&in.RBD, &out.RBD, 0); err != nil { return err } return nil }, func(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { if err := s.Convert(&in.EmptyDir, &out.EmptyDir, 0); err != nil { return err } if err := s.Convert(&in.GitRepo, &out.GitRepo, 0); err != nil { return err } if err := s.Convert(&in.GCEPersistentDisk, &out.GCEPersistentDisk, 0); err != nil { return err } if err := s.Convert(&in.AWSElasticBlockStore, &out.AWSElasticBlockStore, 0); err != nil { return err } if err := s.Convert(&in.ISCSI, &out.ISCSI, 0); err != nil { return err } if err := s.Convert(&in.HostDir, &out.HostPath, 0); err != nil { return err } if err := s.Convert(&in.Secret, &out.Secret, 0); err != nil { return err } if err := s.Convert(&in.NFS, &out.NFS, 0); err != nil { return err } if err := s.Convert(&in.PersistentVolumeClaimVolumeSource, &out.PersistentVolumeClaimVolumeSource, 0); err != nil { return err } if err := s.Convert(&in.Glusterfs, &out.Glusterfs, 0); err != nil { return err } if err := s.Convert(&in.RBD, &out.RBD, 0); err != nil { return err } return nil }, func(in *api.PullPolicy, out *PullPolicy, s conversion.Scope) error { switch *in { case api.PullAlways: *out = PullAlways case api.PullNever: *out = PullNever case api.PullIfNotPresent: *out = PullIfNotPresent case "": *out = "" default: // Let unknown values through - they will get caught by validation *out = PullPolicy(*in) } return nil }, func(in *PullPolicy, out *api.PullPolicy, s conversion.Scope) error { switch *in { case PullAlways: *out = api.PullAlways case PullNever: *out = api.PullNever case PullIfNotPresent: *out = api.PullIfNotPresent case "": *out = "" default: // Let unknown values through - they will get caught by validation *out = api.PullPolicy(*in) } return nil }, func(in *api.RestartPolicy, out *RestartPolicy, s conversion.Scope) error { switch *in { case api.RestartPolicyAlways: *out = RestartPolicy{Always: &RestartPolicyAlways{}} case api.RestartPolicyNever: *out = RestartPolicy{Never: &RestartPolicyNever{}} case api.RestartPolicyOnFailure: *out = RestartPolicy{OnFailure: &RestartPolicyOnFailure{}} default: *out = RestartPolicy{} } return nil }, func(in *RestartPolicy, out *api.RestartPolicy, s conversion.Scope) error { switch { case in.Always != nil: *out = api.RestartPolicyAlways case in.Never != nil: *out = api.RestartPolicyNever case in.OnFailure != nil: *out = api.RestartPolicyOnFailure default: *out = "" } return nil }, func(in *api.Probe, out *LivenessProbe, s conversion.Scope) error { if err := s.Convert(&in.Exec, &out.Exec, 0); err != nil { return err } if err := s.Convert(&in.HTTPGet, &out.HTTPGet, 0); err != nil { return err } if err := s.Convert(&in.TCPSocket, &out.TCPSocket, 0); err != nil { return err } out.InitialDelaySeconds = in.InitialDelaySeconds out.TimeoutSeconds = in.TimeoutSeconds return nil }, func(in *LivenessProbe, out *api.Probe, s conversion.Scope) error { if err := s.Convert(&in.Exec, &out.Exec, 0); err != nil { return err } if err := s.Convert(&in.HTTPGet, &out.HTTPGet, 0); err != nil { return err } if err := s.Convert(&in.TCPSocket, &out.TCPSocket, 0); err != nil { return err } out.InitialDelaySeconds = in.InitialDelaySeconds out.TimeoutSeconds = in.TimeoutSeconds return nil }, func(in *api.Endpoints, out *Endpoints, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Subsets, &out.Subsets, 0); err != nil { return err } // Produce back-compat fields. firstPortName := "" if len(in.Subsets) > 0 { if len(in.Subsets[0].Ports) > 0 { if err := s.Convert(&in.Subsets[0].Ports[0].Protocol, &out.Protocol, 0); err != nil { return err } firstPortName = in.Subsets[0].Ports[0].Name } } else { out.Protocol = ProtocolTCP } for i := range in.Subsets { ss := &in.Subsets[i] for j := range ss.Ports { ssp := &ss.Ports[j] if ssp.Name != firstPortName { continue } for k := range ss.Addresses { ssa := &ss.Addresses[k] hostPort := net.JoinHostPort(ssa.IP, strconv.Itoa(ssp.Port)) out.Endpoints = append(out.Endpoints, hostPort) if ssa.TargetRef != nil { target := EndpointObjectReference{ Endpoint: hostPort, } if err := s.Convert(ssa.TargetRef, &target.ObjectReference, 0); err != nil { return err } out.TargetRefs = append(out.TargetRefs, target) } } } } return nil }, func(in *Endpoints, out *api.Endpoints, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Subsets, &out.Subsets, 0); err != nil { return err } // Back-compat fields are handled in the defaulting phase. return nil }, func(in *api.NodeCondition, out *NodeCondition, s conversion.Scope) error { if err := s.Convert(&in.Type, &out.Kind, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.LastHeartbeatTime, &out.LastProbeTime, 0); err != nil { return err } if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { return err } if err := s.Convert(&in.Reason, &out.Reason, 0); err != nil { return err } if err := s.Convert(&in.Message, &out.Message, 0); err != nil { return err } return nil }, func(in *NodeCondition, out *api.NodeCondition, s conversion.Scope) error { if err := s.Convert(&in.Kind, &out.Type, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.LastProbeTime, &out.LastHeartbeatTime, 0); err != nil { return err } if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { return err } if err := s.Convert(&in.Reason, &out.Reason, 0); err != nil { return err } if err := s.Convert(&in.Message, &out.Message, 0); err != nil { return err } return nil }, func(in *api.NodeConditionType, out *NodeConditionKind, s conversion.Scope) error { switch *in { case api.NodeReady: *out = NodeReady break case "": *out = "" default: *out = NodeConditionKind(*in) break } return nil }, func(in *NodeConditionKind, out *api.NodeConditionType, s conversion.Scope) error { switch *in { case NodeReady: *out = api.NodeReady break case "": *out = "" default: *out = api.NodeConditionType(*in) break } return nil }, func(in *api.ConditionStatus, out *ConditionStatus, s conversion.Scope) error { switch *in { case api.ConditionTrue: *out = ConditionFull break case api.ConditionFalse: *out = ConditionNone break default: *out = ConditionStatus(*in) break } return nil }, func(in *ConditionStatus, out *api.ConditionStatus, s conversion.Scope) error { switch *in { case ConditionFull: *out = api.ConditionTrue break case ConditionNone: *out = api.ConditionFalse break default: *out = api.ConditionStatus(*in) break } return nil }, func(in *api.PodCondition, out *PodCondition, s conversion.Scope) error { if err := s.Convert(&in.Type, &out.Kind, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } return nil }, func(in *PodCondition, out *api.PodCondition, s conversion.Scope) error { if err := s.Convert(&in.Kind, &out.Type, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } return nil }, func(in *api.PodConditionType, out *PodConditionKind, s conversion.Scope) error { switch *in { case api.PodReady: *out = PodReady break case "": *out = "" default: *out = PodConditionKind(*in) break } return nil }, func(in *PodConditionKind, out *api.PodConditionType, s conversion.Scope) error { switch *in { case PodReady: *out = api.PodReady break case "": *out = "" default: *out = api.PodConditionType(*in) break } return nil }, func(in *Binding, out *api.Binding, s conversion.Scope) error { if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { return err } out.Target = api.ObjectReference{ Name: in.Host, } out.Name = in.PodID return nil }, func(in *api.Binding, out *Binding, s conversion.Scope) error { if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { return err } out.Host = in.Target.Name out.PodID = in.Name return nil }, func(in *api.SecretVolumeSource, out *SecretVolumeSource, s conversion.Scope) error { out.Target.ID = in.SecretName return nil }, func(in *SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { out.SecretName = in.Target.ID return nil }, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } // Add field conversion funcs. err = api.Scheme.AddFieldLabelConversionFunc("v1beta2", "Pod", func(label, value string) (string, string, error) { switch label { case "name": return "metadata.name", value, nil case "DesiredState.Host": return "spec.host", value, nil case "DesiredState.Status": podStatus := PodStatus(value) var internalValue api.PodPhase api.Scheme.Convert(&podStatus, &internalValue) return "status.phase", string(internalValue), nil default: return "", "", fmt.Errorf("field label not supported: %s", label) } }) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } err = api.Scheme.AddFieldLabelConversionFunc("v1beta2", "Node", func(label, value string) (string, string, error) { switch label { case "name": return "metadata.name", value, nil case "unschedulable": return "spec.unschedulable", value, nil default: return "", "", fmt.Errorf("field label not supported: %s", label) } }) if err != nil { // if one of the conversion functions is malformed, detect it immediately. panic(err) } err = api.Scheme.AddFieldLabelConversionFunc("v1beta2", "ReplicationController", func(label, value string) (string, string, error) { switch label { case "name": return "metadata.name", value, nil case "currentState.replicas": return "status.replicas", value, nil default: return "", "", fmt.Errorf("field label not supported: %s", label) } }) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } err = api.Scheme.AddFieldLabelConversionFunc("v1beta2", "Event", func(label, value string) (string, string, error) { switch label { case "involvedObject.kind", "involvedObject.namespace", "involvedObject.uid", "involvedObject.apiVersion", "involvedObject.resourceVersion", "involvedObject.fieldPath", "reason", "source": return label, value, nil case "involvedObject.id": return "involvedObject.name", value, nil default: return "", "", fmt.Errorf("field label not supported: %s", label) } }) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } err = api.Scheme.AddFieldLabelConversionFunc("v1beta2", "Namespace", func(label, value string) (string, string, error) { switch label { case "status.phase": return label, value, nil default: return "", "", fmt.Errorf("field label not supported: %s", label) } }) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } err = api.Scheme.AddFieldLabelConversionFunc("v1beta2", "Secret", func(label, value string) (string, string, error) { switch label { case "type": return label, value, nil default: return "", "", fmt.Errorf("field label not supported: %s", label) } }) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } err = api.Scheme.AddFieldLabelConversionFunc("v1beta2", "ServiceAccount", func(label, value string) (string, string, error) { switch label { case "name": return "metadata.name", value, nil default: return "", "", fmt.Errorf("field label not supported: %s", label) } }) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } }
func TestGetResources(t *testing.T) { var instance0 ec2.Instance var instance1 ec2.Instance var instance2 ec2.Instance //0 instance0.PrivateDNSName = aws.String("m3.medium") instance0.InstanceType = aws.String("m3.medium") state0 := ec2.InstanceState{ Name: aws.String("running"), } instance0.State = &state0 //1 instance1.PrivateDNSName = aws.String("r3.8xlarge") instance1.InstanceType = aws.String("r3.8xlarge") state1 := ec2.InstanceState{ Name: aws.String("running"), } instance1.State = &state1 //2 instance2.PrivateDNSName = aws.String("unknown.type") instance2.InstanceType = aws.String("unknown.type") state2 := ec2.InstanceState{ Name: aws.String("running"), } instance2.State = &state2 instances := []*ec2.Instance{&instance0, &instance1, &instance2} aws1 := mockInstancesResp(instances) res1, err1 := aws1.GetNodeResources("m3.medium") if err1 != nil { t.Errorf("Should not error when instance type found: %v", err1) } e1 := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(int64(3.0*1000), resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(int64(3.75*1024*1024*1024), resource.BinarySI), }, } if !reflect.DeepEqual(e1, res1) { t.Errorf("Expected %v, got %v", e1, res1) } res2, err2 := aws1.GetNodeResources("r3.8xlarge") if err2 != nil { t.Errorf("Should not error when instance type found: %v", err2) } e2 := &api.NodeResources{ Capacity: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(int64(104.0*1000), resource.DecimalSI), api.ResourceMemory: *resource.NewQuantity(int64(244.0*1024*1024*1024), resource.BinarySI), }, } if !reflect.DeepEqual(e2, res2) { t.Errorf("Expected %v, got %v", e2, res2) } res3, err3 := aws1.GetNodeResources("unknown.type") if err3 != nil { t.Errorf("Should not error when unknown instance type") } if res3 != nil { t.Errorf("Should return nil resources when unknown instance type") } }
func init() { // Our TypeMeta was split into two different structs. newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.ObjectMeta{}, "ObjectMeta") newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.ListMeta{}, "ListMeta") newer.Scheme.AddStructFieldConversion(newer.TypeMeta{}, "TypeMeta", TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(newer.ObjectMeta{}, "ObjectMeta", TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(newer.ListMeta{}, "ListMeta", TypeMeta{}, "TypeMeta") // TODO: scope this to a specific type once that becomes available and remove the Event conversion functions below // newer.Scheme.AddStructFieldConversion(string(""), "Status", string(""), "Condition") // newer.Scheme.AddStructFieldConversion(string(""), "Condition", string(""), "Status") err := newer.Scheme.AddConversionFuncs( // TypeMeta must be split into two objects func(in *newer.TypeMeta, out *TypeMeta, s conversion.Scope) error { out.Kind = in.Kind out.APIVersion = in.APIVersion return nil }, func(in *TypeMeta, out *newer.TypeMeta, s conversion.Scope) error { out.Kind = in.Kind out.APIVersion = in.APIVersion return nil }, // ListMeta must be converted to TypeMeta func(in *newer.ListMeta, out *TypeMeta, s conversion.Scope) error { out.SelfLink = in.SelfLink if len(in.ResourceVersion) > 0 { v, err := strconv.ParseUint(in.ResourceVersion, 10, 64) if err != nil { return err } out.ResourceVersion = v } return nil }, func(in *TypeMeta, out *newer.ListMeta, s conversion.Scope) error { out.SelfLink = in.SelfLink if in.ResourceVersion != 0 { out.ResourceVersion = strconv.FormatUint(in.ResourceVersion, 10) } else { out.ResourceVersion = "" } return nil }, // ObjectMeta must be converted to TypeMeta func(in *newer.ObjectMeta, out *TypeMeta, s conversion.Scope) error { out.Namespace = in.Namespace out.ID = in.Name out.UID = in.UID out.CreationTimestamp = in.CreationTimestamp out.SelfLink = in.SelfLink if len(in.ResourceVersion) > 0 { v, err := strconv.ParseUint(in.ResourceVersion, 10, 64) if err != nil { return err } out.ResourceVersion = v } return s.Convert(&in.Annotations, &out.Annotations, 0) }, func(in *TypeMeta, out *newer.ObjectMeta, s conversion.Scope) error { out.Namespace = in.Namespace out.Name = in.ID out.UID = in.UID out.CreationTimestamp = in.CreationTimestamp out.SelfLink = in.SelfLink if in.ResourceVersion != 0 { out.ResourceVersion = strconv.FormatUint(in.ResourceVersion, 10) } else { out.ResourceVersion = "" } return s.Convert(&in.Annotations, &out.Annotations, 0) }, // EnvVar's Key is deprecated in favor of Name. func(in *newer.EnvVar, out *EnvVar, s conversion.Scope) error { out.Value = in.Value out.Key = in.Name out.Name = in.Name return nil }, func(in *EnvVar, out *newer.EnvVar, s conversion.Scope) error { out.Value = in.Value if in.Name != "" { out.Name = in.Name } else { out.Name = in.Key } return nil }, // Path & MountType are deprecated. func(in *newer.VolumeMount, out *VolumeMount, s conversion.Scope) error { out.Name = in.Name out.ReadOnly = in.ReadOnly out.MountPath = in.MountPath out.Path = in.MountPath out.MountType = "" // MountType is ignored. return nil }, func(in *VolumeMount, out *newer.VolumeMount, s conversion.Scope) error { out.Name = in.Name out.ReadOnly = in.ReadOnly if in.MountPath == "" { out.MountPath = in.Path } else { out.MountPath = in.MountPath } return nil }, // MinionList.Items had a wrong name in v1beta1 func(in *newer.NodeList, out *MinionList, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ListMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Items, &out.Items, 0); err != nil { return err } out.Minions = out.Items return nil }, func(in *MinionList, out *newer.NodeList, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ListMeta, 0); err != nil { return err } if len(in.Items) == 0 { if err := s.Convert(&in.Minions, &out.Items, 0); err != nil { return err } } else { if err := s.Convert(&in.Items, &out.Items, 0); err != nil { return err } } return nil }, func(in *newer.PodStatus, out *PodState, s conversion.Scope) error { if err := s.Convert(&in.Phase, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.Info, &out.Info, 0); err != nil { return err } out.Message = in.Message out.Host = in.Host out.HostIP = in.HostIP out.PodIP = in.PodIP return nil }, func(in *PodState, out *newer.PodStatus, s conversion.Scope) error { if err := s.Convert(&in.Status, &out.Phase, 0); err != nil { return err } if err := s.Convert(&in.Info, &out.Info, 0); err != nil { return err } out.Message = in.Message out.Host = in.Host out.HostIP = in.HostIP out.PodIP = in.PodIP return nil }, func(in *newer.PodSpec, out *PodState, s conversion.Scope) error { if err := s.Convert(&in, &out.Manifest, 0); err != nil { return err } out.Host = in.Host return nil }, func(in *PodState, out *newer.PodSpec, s conversion.Scope) error { if err := s.Convert(&in.Manifest, &out, 0); err != nil { return err } out.Host = in.Host return nil }, // Convert all to the new PodPhase constants func(in *newer.PodPhase, out *PodStatus, s conversion.Scope) error { switch *in { case "": *out = "" case newer.PodPending: *out = PodWaiting case newer.PodRunning: *out = PodRunning case newer.PodSucceeded: *out = PodSucceeded case newer.PodFailed: *out = PodTerminated case newer.PodUnknown: *out = PodUnknown default: return &newer.ConversionError{ In: in, Out: out, Message: "The string provided is not a valid PodPhase constant value", } } return nil }, func(in *PodStatus, out *newer.PodPhase, s conversion.Scope) error { switch *in { case "": *out = "" case PodWaiting: *out = newer.PodPending case PodRunning: *out = newer.PodRunning case PodTerminated: // Older API versions did not contain enough info to map to PodSucceeded *out = newer.PodFailed case PodSucceeded: *out = newer.PodSucceeded case PodUnknown: *out = newer.PodUnknown default: return &newer.ConversionError{ In: in, Out: out, Message: "The string provided is not a valid PodPhase constant value", } } return nil }, // Convert all the standard objects func(in *newer.Pod, out *Pod, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } // TODO: Change this to use in.ObjectMeta.Labels. if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil { return err } out.DesiredState.Host = in.Spec.Host if err := s.Convert(&in.Status, &out.CurrentState, 0); err != nil { return err } if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { return err } return nil }, func(in *Pod, out *newer.Pod, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil { return err } out.Spec.Host = in.DesiredState.Host if err := s.Convert(&in.CurrentState, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { return err } return nil }, func(in *newer.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.State, 0); err != nil { return err } return nil }, func(in *PodStatusResult, out *newer.PodStatusResult, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.State, &out.Status, 0); err != nil { return err } return nil }, func(in *newer.ReplicationController, out *ReplicationController, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.DesiredState, 0); err != nil { return err } out.CurrentState.Replicas = in.Status.Replicas return nil }, func(in *ReplicationController, out *newer.ReplicationController, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.DesiredState, &out.Spec, 0); err != nil { return err } out.Status.Replicas = in.CurrentState.Replicas return nil }, func(in *newer.ReplicationControllerSpec, out *ReplicationControllerState, s conversion.Scope) error { out.Replicas = in.Replicas if err := s.Convert(&in.Selector, &out.ReplicaSelector, 0); err != nil { return err } if in.TemplateRef != nil && in.Template == nil { return &newer.ConversionError{ In: in, Out: out, Message: "objects with a template ref cannot be converted to older objects, must populate template", } } if in.Template != nil { if err := s.Convert(in.Template, &out.PodTemplate, 0); err != nil { return err } } return nil }, func(in *ReplicationControllerState, out *newer.ReplicationControllerSpec, s conversion.Scope) error { out.Replicas = in.Replicas if err := s.Convert(&in.ReplicaSelector, &out.Selector, 0); err != nil { return err } out.Template = &newer.PodTemplateSpec{} if err := s.Convert(&in.PodTemplate, out.Template, 0); err != nil { return err } return nil }, func(in *newer.PodTemplateSpec, out *PodTemplate, s conversion.Scope) error { if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil { return err } out.DesiredState.Host = in.Spec.Host if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil { return err } return nil }, func(in *PodTemplate, out *newer.PodTemplateSpec, s conversion.Scope) error { if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil { return err } out.Spec.Host = in.DesiredState.Host if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } return nil }, func(in *newer.PodSpec, out *BoundPod, s conversion.Scope) error { if err := s.Convert(&in, &out.Spec, 0); err != nil { return err } return nil }, func(in *BoundPod, out *newer.PodSpec, s conversion.Scope) error { if err := s.Convert(&in.Spec, &out, 0); err != nil { return err } return nil }, func(in *newer.PodSpec, out *ContainerManifest, s conversion.Scope) error { if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil { return err } if err := s.Convert(&in.Containers, &out.Containers, 0); err != nil { return err } if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil { return err } out.DNSPolicy = DNSPolicy(in.DNSPolicy) out.Version = "v1beta2" return nil }, func(in *ContainerManifest, out *newer.PodSpec, s conversion.Scope) error { if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil { return err } if err := s.Convert(&in.Containers, &out.Containers, 0); err != nil { return err } if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil { return err } out.DNSPolicy = newer.DNSPolicy(in.DNSPolicy) return nil }, func(in *newer.Service, out *Service, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } out.Port = in.Spec.Port out.Protocol = Protocol(in.Spec.Protocol) if err := s.Convert(&in.Spec.Selector, &out.Selector, 0); err != nil { return err } out.CreateExternalLoadBalancer = in.Spec.CreateExternalLoadBalancer out.PublicIPs = in.Spec.PublicIPs out.ContainerPort = in.Spec.ContainerPort out.PortalIP = in.Spec.PortalIP out.ProxyPort = in.Spec.ProxyPort if err := s.Convert(&in.Spec.SessionAffinity, &out.SessionAffinity, 0); err != nil { return err } return nil }, func(in *Service, out *newer.Service, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } out.Spec.Port = in.Port out.Spec.Protocol = newer.Protocol(in.Protocol) if err := s.Convert(&in.Selector, &out.Spec.Selector, 0); err != nil { return err } out.Spec.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer out.Spec.PublicIPs = in.PublicIPs out.Spec.ContainerPort = in.ContainerPort out.Spec.PortalIP = in.PortalIP out.Spec.ProxyPort = in.ProxyPort if err := s.Convert(&in.SessionAffinity, &out.Spec.SessionAffinity, 0); err != nil { return err } return nil }, func(in *newer.Node, out *Minion, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Status.Phase, &out.Status.Phase, 0); err != nil { return err } if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } out.HostIP = in.Status.HostIP return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0) }, func(in *Minion, out *newer.Node, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } if err := s.Convert(&in.Status.Phase, &out.Status.Phase, 0); err != nil { return err } if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } out.Status.HostIP = in.HostIP return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0) }, // Object ID <-> Name // TODO: amend the conversion package to allow overriding specific fields. func(in *ObjectReference, out *newer.ObjectReference, s conversion.Scope) error { out.Kind = in.Kind out.Namespace = in.Namespace out.Name = in.ID out.UID = in.UID out.APIVersion = in.APIVersion out.ResourceVersion = in.ResourceVersion out.FieldPath = in.FieldPath return nil }, func(in *newer.ObjectReference, out *ObjectReference, s conversion.Scope) error { out.Kind = in.Kind out.Namespace = in.Namespace out.ID = in.Name out.UID = in.UID out.APIVersion = in.APIVersion out.ResourceVersion = in.ResourceVersion out.FieldPath = in.FieldPath return nil }, // Event Source <-> Source.Component // Event Host <-> Source.Host // TODO: remove this when it becomes possible to specify a field name conversion on a specific type func(in *newer.Event, out *Event, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } out.Reason = in.Reason out.Message = in.Message out.Source = in.Source.Component out.Host = in.Source.Host out.Timestamp = in.Timestamp return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, func(in *Event, out *newer.Event, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } out.Reason = in.Reason out.Message = in.Message out.Source.Component = in.Source out.Source.Host = in.Host out.Timestamp = in.Timestamp return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, // This is triggered for the Memory field of Container. func(in *int64, out *resource.Quantity, s conversion.Scope) error { out.Set(*in) out.Format = resource.BinarySI return nil }, func(in *resource.Quantity, out *int64, s conversion.Scope) error { *out = in.Value() return nil }, // This is triggered by the CPU field of Container. // Note that if we add other int/Quantity conversions my // simple hack (int64=Value(), int=MilliValue()) here won't work. func(in *int, out *resource.Quantity, s conversion.Scope) error { out.SetMilli(int64(*in)) out.Format = resource.DecimalSI return nil }, func(in *resource.Quantity, out *int, s conversion.Scope) error { *out = int(in.MilliValue()) return nil }, // Convert resource lists. func(in *ResourceList, out *newer.ResourceList, s conversion.Scope) error { *out = newer.ResourceList{} for k, v := range *in { fv, err := strconv.ParseFloat(v.String(), 64) if err != nil { return &newer.ConversionError{ In: in, Out: out, Message: fmt.Sprintf("value '%v' of '%v': %v", v, k, err), } } if k == ResourceCPU { (*out)[newer.ResourceCPU] = *resource.NewMilliQuantity(int64(fv*1000), resource.DecimalSI) } else { (*out)[newer.ResourceName(k)] = *resource.NewQuantity(int64(fv), resource.BinarySI) } } return nil }, func(in *newer.ResourceList, out *ResourceList, s conversion.Scope) error { *out = ResourceList{} for k, v := range *in { if k == newer.ResourceCPU { (*out)[ResourceCPU] = util.NewIntOrStringFromString(fmt.Sprintf("%v", float64(v.MilliValue())/1000)) } else { (*out)[ResourceName(k)] = util.NewIntOrStringFromInt(int(v.Value())) } } return nil }, // VolumeSource's HostDir is deprecated in favor of HostPath. // TODO: It would be great if I could just map field names to // convert or else maybe say "convert all members of this // struct" and then fix up only the stuff that changed. func(in *newer.VolumeSource, out *VolumeSource, s conversion.Scope) error { if err := s.Convert(&in.EmptyDir, &out.EmptyDir, 0); err != nil { return err } if err := s.Convert(&in.GitRepo, &out.GitRepo, 0); err != nil { return err } if err := s.Convert(&in.GCEPersistentDisk, &out.GCEPersistentDisk, 0); err != nil { return err } if err := s.Convert(&in.HostPath, &out.HostDir, 0); err != nil { return err } return nil }, func(in *VolumeSource, out *newer.VolumeSource, s conversion.Scope) error { if err := s.Convert(&in.EmptyDir, &out.EmptyDir, 0); err != nil { return err } if err := s.Convert(&in.GitRepo, &out.GitRepo, 0); err != nil { return err } if err := s.Convert(&in.GCEPersistentDisk, &out.GCEPersistentDisk, 0); err != nil { return err } if err := s.Convert(&in.HostDir, &out.HostPath, 0); err != nil { return err } return nil }, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } }
// IncrementUsage updates the supplied ResourceQuotaStatus object based on the incoming operation // Return true if the usage must be recorded prior to admitting the new resource // Return an error if the operation should not pass admission control func IncrementUsage(a admission.Attributes, status *api.ResourceQuotaStatus, client client.Interface) (bool, error) { dirty := false set := map[api.ResourceName]bool{} for k := range status.Hard { set[k] = true } obj := a.GetObject() // handle max counts for each kind of resource (pods, services, replicationControllers, etc.) if a.GetOperation() == admission.Create { resourceName := resourceToResourceName[a.GetResource()] hard, hardFound := status.Hard[resourceName] if hardFound { used, usedFound := status.Used[resourceName] if !usedFound { return false, fmt.Errorf("Quota usage stats are not yet known, unable to admit resource until an accurate count is completed.") } if used.Value() >= hard.Value() { return false, fmt.Errorf("Limited to %s %s", hard.String(), resourceName) } else { status.Used[resourceName] = *resource.NewQuantity(used.Value()+int64(1), resource.DecimalSI) dirty = true } } } // handle memory/cpu constraints, and any diff of usage based on memory/cpu on updates if a.GetResource() == "pods" && (set[api.ResourceMemory] || set[api.ResourceCPU]) { pod := obj.(*api.Pod) deltaCPU := resourcequotacontroller.PodCPU(pod) deltaMemory := resourcequotacontroller.PodMemory(pod) // if this is an update, we need to find the delta cpu/memory usage from previous state if a.GetOperation() == admission.Update { oldPod, err := client.Pods(a.GetNamespace()).Get(pod.Name) if err != nil { return false, err } oldCPU := resourcequotacontroller.PodCPU(oldPod) oldMemory := resourcequotacontroller.PodMemory(oldPod) deltaCPU = resource.NewMilliQuantity(deltaCPU.MilliValue()-oldCPU.MilliValue(), resource.DecimalSI) deltaMemory = resource.NewQuantity(deltaMemory.Value()-oldMemory.Value(), resource.DecimalSI) } hardMem, hardMemFound := status.Hard[api.ResourceMemory] if hardMemFound { if set[api.ResourceMemory] && resourcequotacontroller.IsPodMemoryUnbounded(pod) { return false, fmt.Errorf("Limited to %s memory, but pod has no specified memory limit", hardMem.String()) } used, usedFound := status.Used[api.ResourceMemory] if !usedFound { return false, fmt.Errorf("Quota usage stats are not yet known, unable to admit resource until an accurate count is completed.") } if used.Value()+deltaMemory.Value() > hardMem.Value() { return false, fmt.Errorf("Limited to %s memory", hardMem.String()) } else { status.Used[api.ResourceMemory] = *resource.NewQuantity(used.Value()+deltaMemory.Value(), resource.DecimalSI) dirty = true } } hardCPU, hardCPUFound := status.Hard[api.ResourceCPU] if hardCPUFound { if set[api.ResourceCPU] && resourcequotacontroller.IsPodCPUUnbounded(pod) { return false, fmt.Errorf("Limited to %s CPU, but pod has no specified cpu limit", hardCPU.String()) } used, usedFound := status.Used[api.ResourceCPU] if !usedFound { return false, fmt.Errorf("Quota usage stats are not yet known, unable to admit resource until an accurate count is completed.") } if used.MilliValue()+deltaCPU.MilliValue() > hardCPU.MilliValue() { return false, fmt.Errorf("Limited to %s CPU", hardCPU.String()) } else { status.Used[api.ResourceCPU] = *resource.NewMilliQuantity(used.MilliValue()+deltaCPU.MilliValue(), resource.DecimalSI) dirty = true } } } return dirty, nil }
func init() { // Our TypeMeta was split into two different structs. newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.ObjectMeta{}, "ObjectMeta") newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.ListMeta{}, "ListMeta") newer.Scheme.AddStructFieldConversion(newer.TypeMeta{}, "TypeMeta", TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(newer.ObjectMeta{}, "ObjectMeta", TypeMeta{}, "TypeMeta") newer.Scheme.AddStructFieldConversion(newer.ListMeta{}, "ListMeta", TypeMeta{}, "TypeMeta") // TODO: scope this to a specific type once that becomes available and remove the Event conversion functions below // newer.Scheme.AddStructFieldConversion(string(""), "Status", string(""), "Condition") // newer.Scheme.AddStructFieldConversion(string(""), "Condition", string(""), "Status") err := newer.Scheme.AddConversionFuncs( // TypeMeta must be split into two objects func(in *newer.TypeMeta, out *TypeMeta, s conversion.Scope) error { out.Kind = in.Kind out.APIVersion = in.APIVersion return nil }, func(in *TypeMeta, out *newer.TypeMeta, s conversion.Scope) error { out.Kind = in.Kind out.APIVersion = in.APIVersion return nil }, // ListMeta must be converted to TypeMeta func(in *newer.ListMeta, out *TypeMeta, s conversion.Scope) error { out.SelfLink = in.SelfLink if len(in.ResourceVersion) > 0 { v, err := strconv.ParseUint(in.ResourceVersion, 10, 64) if err != nil { return err } out.ResourceVersion = v } return nil }, func(in *TypeMeta, out *newer.ListMeta, s conversion.Scope) error { out.SelfLink = in.SelfLink if in.ResourceVersion != 0 { out.ResourceVersion = strconv.FormatUint(in.ResourceVersion, 10) } else { out.ResourceVersion = "" } return nil }, // ObjectMeta must be converted to TypeMeta func(in *newer.ObjectMeta, out *TypeMeta, s conversion.Scope) error { out.Namespace = in.Namespace out.ID = in.Name out.GenerateName = in.GenerateName out.UID = in.UID out.CreationTimestamp = in.CreationTimestamp out.SelfLink = in.SelfLink if len(in.ResourceVersion) > 0 { v, err := strconv.ParseUint(in.ResourceVersion, 10, 64) if err != nil { return err } out.ResourceVersion = v } return s.Convert(&in.Annotations, &out.Annotations, 0) }, func(in *TypeMeta, out *newer.ObjectMeta, s conversion.Scope) error { out.Namespace = in.Namespace out.Name = in.ID out.GenerateName = in.GenerateName out.UID = in.UID out.CreationTimestamp = in.CreationTimestamp out.SelfLink = in.SelfLink if in.ResourceVersion != 0 { out.ResourceVersion = strconv.FormatUint(in.ResourceVersion, 10) } else { out.ResourceVersion = "" } return s.Convert(&in.Annotations, &out.Annotations, 0) }, // EnvVar's Key is deprecated in favor of Name. func(in *newer.EnvVar, out *EnvVar, s conversion.Scope) error { out.Value = in.Value out.Key = in.Name out.Name = in.Name return nil }, func(in *EnvVar, out *newer.EnvVar, s conversion.Scope) error { out.Value = in.Value if in.Name != "" { out.Name = in.Name } else { out.Name = in.Key } return nil }, // Path & MountType are deprecated. func(in *newer.VolumeMount, out *VolumeMount, s conversion.Scope) error { out.Name = in.Name out.ReadOnly = in.ReadOnly out.MountPath = in.MountPath out.Path = in.MountPath out.MountType = "" // MountType is ignored. return nil }, func(in *VolumeMount, out *newer.VolumeMount, s conversion.Scope) error { out.Name = in.Name out.ReadOnly = in.ReadOnly if in.MountPath == "" { out.MountPath = in.Path } else { out.MountPath = in.MountPath } return nil }, // MinionList.Items had a wrong name in v1beta1 func(in *newer.NodeList, out *MinionList, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ListMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Items, &out.Items, 0); err != nil { return err } out.Minions = out.Items return nil }, func(in *MinionList, out *newer.NodeList, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ListMeta, 0); err != nil { return err } if len(in.Items) == 0 { if err := s.Convert(&in.Minions, &out.Items, 0); err != nil { return err } } else { if err := s.Convert(&in.Items, &out.Items, 0); err != nil { return err } } return nil }, func(in *newer.PodStatus, out *PodState, s conversion.Scope) error { if err := s.Convert(&in.Phase, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.Conditions, &out.Conditions, 0); err != nil { return err } if err := s.Convert(&in.Info, &out.Info, 0); err != nil { return err } out.Message = in.Message out.Host = in.Host out.HostIP = in.HostIP out.PodIP = in.PodIP return nil }, func(in *PodState, out *newer.PodStatus, s conversion.Scope) error { if err := s.Convert(&in.Status, &out.Phase, 0); err != nil { return err } if err := s.Convert(&in.Conditions, &out.Conditions, 0); err != nil { return err } if err := s.Convert(&in.Info, &out.Info, 0); err != nil { return err } out.Message = in.Message out.Host = in.Host out.HostIP = in.HostIP out.PodIP = in.PodIP return nil }, func(in *newer.PodSpec, out *PodState, s conversion.Scope) error { if err := s.Convert(&in, &out.Manifest, 0); err != nil { return err } out.Host = in.Host return nil }, func(in *PodState, out *newer.PodSpec, s conversion.Scope) error { if err := s.Convert(&in.Manifest, &out, 0); err != nil { return err } out.Host = in.Host return nil }, // Convert all to the new PodPhase constants func(in *newer.PodPhase, out *PodStatus, s conversion.Scope) error { switch *in { case "": *out = "" case newer.PodPending: *out = PodWaiting case newer.PodRunning: *out = PodRunning case newer.PodSucceeded: *out = PodSucceeded case newer.PodFailed: *out = PodTerminated case newer.PodUnknown: *out = PodUnknown default: return &newer.ConversionError{ In: in, Out: out, Message: "The string provided is not a valid PodPhase constant value", } } return nil }, func(in *PodStatus, out *newer.PodPhase, s conversion.Scope) error { switch *in { case "": *out = "" case PodWaiting: *out = newer.PodPending case PodRunning: *out = newer.PodRunning case PodTerminated: // Older API versions did not contain enough info to map to PodSucceeded *out = newer.PodFailed case PodSucceeded: *out = newer.PodSucceeded case PodUnknown: *out = newer.PodUnknown default: return &newer.ConversionError{ In: in, Out: out, Message: "The string provided is not a valid PodPhase constant value", } } return nil }, // Convert all the standard objects func(in *newer.Pod, out *Pod, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } // TODO: Change this to use in.ObjectMeta.Labels. if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil { return err } out.DesiredState.Host = in.Spec.Host if err := s.Convert(&in.Status, &out.CurrentState, 0); err != nil { return err } if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { return err } return nil }, func(in *Pod, out *newer.Pod, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil { return err } out.Spec.Host = in.DesiredState.Host if err := s.Convert(&in.CurrentState, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { return err } return nil }, func(in *newer.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.State, 0); err != nil { return err } return nil }, func(in *PodStatusResult, out *newer.PodStatusResult, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.State, &out.Status, 0); err != nil { return err } return nil }, func(in *newer.ReplicationController, out *ReplicationController, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.DesiredState, 0); err != nil { return err } out.CurrentState.Replicas = in.Status.Replicas return nil }, func(in *ReplicationController, out *newer.ReplicationController, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.DesiredState, &out.Spec, 0); err != nil { return err } out.Status.Replicas = in.CurrentState.Replicas return nil }, func(in *newer.ReplicationControllerSpec, out *ReplicationControllerState, s conversion.Scope) error { out.Replicas = in.Replicas if err := s.Convert(&in.Selector, &out.ReplicaSelector, 0); err != nil { return err } if in.TemplateRef != nil && in.Template == nil { return &newer.ConversionError{ In: in, Out: out, Message: "objects with a template ref cannot be converted to older objects, must populate template", } } if in.Template != nil { if err := s.Convert(in.Template, &out.PodTemplate, 0); err != nil { return err } } return nil }, func(in *ReplicationControllerState, out *newer.ReplicationControllerSpec, s conversion.Scope) error { out.Replicas = in.Replicas if err := s.Convert(&in.ReplicaSelector, &out.Selector, 0); err != nil { return err } out.Template = &newer.PodTemplateSpec{} if err := s.Convert(&in.PodTemplate, out.Template, 0); err != nil { return err } return nil }, func(in *newer.PodTemplateSpec, out *PodTemplate, s conversion.Scope) error { if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil { return err } out.DesiredState.Host = in.Spec.Host if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta.Annotations, &out.Annotations, 0); err != nil { return err } return nil }, func(in *PodTemplate, out *newer.PodTemplateSpec, s conversion.Scope) error { if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil { return err } out.Spec.Host = in.DesiredState.Host if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } if err := s.Convert(&in.Annotations, &out.ObjectMeta.Annotations, 0); err != nil { return err } return nil }, func(in *newer.PodSpec, out *BoundPod, s conversion.Scope) error { if err := s.Convert(&in, &out.Spec, 0); err != nil { return err } return nil }, func(in *BoundPod, out *newer.PodSpec, s conversion.Scope) error { if err := s.Convert(&in.Spec, &out, 0); err != nil { return err } return nil }, // Converts internal Container to v1beta1.Container. // Fields 'CPU' and 'Memory' are not present in the internal Container object. // Hence the need for a custom conversion function. func(in *newer.Container, out *Container, s conversion.Scope) error { if err := s.Convert(&in.Name, &out.Name, 0); err != nil { return err } if err := s.Convert(&in.Image, &out.Image, 0); err != nil { return err } if err := s.Convert(&in.Command, &out.Command, 0); err != nil { return err } if err := s.Convert(&in.WorkingDir, &out.WorkingDir, 0); err != nil { return err } if err := s.Convert(&in.Ports, &out.Ports, 0); err != nil { return err } if err := s.Convert(&in.Env, &out.Env, 0); err != nil { return err } if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { return err } if err := s.Convert(in.Resources.Limits.Cpu(), &out.CPU, 0); err != nil { return err } if err := s.Convert(in.Resources.Limits.Memory(), &out.Memory, 0); err != nil { return err } if err := s.Convert(&in.VolumeMounts, &out.VolumeMounts, 0); err != nil { return err } if err := s.Convert(&in.LivenessProbe, &out.LivenessProbe, 0); err != nil { return err } if err := s.Convert(&in.ReadinessProbe, &out.ReadinessProbe, 0); err != nil { return err } if err := s.Convert(&in.Lifecycle, &out.Lifecycle, 0); err != nil { return err } if err := s.Convert(&in.TerminationMessagePath, &out.TerminationMessagePath, 0); err != nil { return err } if err := s.Convert(&in.Privileged, &out.Privileged, 0); err != nil { return err } if err := s.Convert(&in.ImagePullPolicy, &out.ImagePullPolicy, 0); err != nil { return err } if err := s.Convert(&in.Capabilities, &out.Capabilities, 0); err != nil { return err } return nil }, // Internal API does not support CPU to be specified via an explicit field. // Hence it must be stored in Container.Resources. func(in *int, out *newer.ResourceList, s conversion.Scope) error { if *in <= 0 { return nil } quantity := resource.Quantity{} if err := s.Convert(in, &quantity, 0); err != nil { return err } (*out)[newer.ResourceCPU] = quantity return nil }, // Internal API does not support Memory to be specified via an explicit field. // Hence it must be stored in Container.Resources. func(in *int64, out *newer.ResourceList, s conversion.Scope) error { if *in <= 0 { return nil } quantity := resource.Quantity{} if err := s.Convert(in, &quantity, 0); err != nil { return err } (*out)[newer.ResourceMemory] = quantity return nil }, // Converts v1beta1.Container to internal Container. // Fields 'CPU' and 'Memory' are not present in the internal Container object. // Hence the need for a custom conversion function. func(in *Container, out *newer.Container, s conversion.Scope) error { if err := s.Convert(&in.Name, &out.Name, 0); err != nil { return err } if err := s.Convert(&in.Image, &out.Image, 0); err != nil { return err } if err := s.Convert(&in.Command, &out.Command, 0); err != nil { return err } if err := s.Convert(&in.WorkingDir, &out.WorkingDir, 0); err != nil { return err } if err := s.Convert(&in.Ports, &out.Ports, 0); err != nil { return err } if err := s.Convert(&in.Env, &out.Env, 0); err != nil { return err } if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { return err } if err := s.Convert(&in.CPU, &out.Resources.Limits, 0); err != nil { return err } if err := s.Convert(&in.Memory, &out.Resources.Limits, 0); err != nil { return err } if err := s.Convert(&in.VolumeMounts, &out.VolumeMounts, 0); err != nil { return err } if err := s.Convert(&in.LivenessProbe, &out.LivenessProbe, 0); err != nil { return err } if err := s.Convert(&in.ReadinessProbe, &out.ReadinessProbe, 0); err != nil { return err } if err := s.Convert(&in.Lifecycle, &out.Lifecycle, 0); err != nil { return err } if err := s.Convert(&in.TerminationMessagePath, &out.TerminationMessagePath, 0); err != nil { return err } if err := s.Convert(&in.Privileged, &out.Privileged, 0); err != nil { return err } if err := s.Convert(&in.ImagePullPolicy, &out.ImagePullPolicy, 0); err != nil { return err } if err := s.Convert(&in.Capabilities, &out.Capabilities, 0); err != nil { return err } return nil }, func(in *newer.PodSpec, out *ContainerManifest, s conversion.Scope) error { if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil { return err } if err := s.Convert(&in.Containers, &out.Containers, 0); err != nil { return err } if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil { return err } out.DNSPolicy = DNSPolicy(in.DNSPolicy) out.Version = "v1beta2" return nil }, func(in *ContainerManifest, out *newer.PodSpec, s conversion.Scope) error { if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil { return err } if err := s.Convert(&in.Containers, &out.Containers, 0); err != nil { return err } if err := s.Convert(&in.RestartPolicy, &out.RestartPolicy, 0); err != nil { return err } out.DNSPolicy = newer.DNSPolicy(in.DNSPolicy) return nil }, func(in *newer.Service, out *Service, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } out.Port = in.Spec.Port out.Protocol = Protocol(in.Spec.Protocol) if err := s.Convert(&in.Spec.Selector, &out.Selector, 0); err != nil { return err } out.CreateExternalLoadBalancer = in.Spec.CreateExternalLoadBalancer out.PublicIPs = in.Spec.PublicIPs out.ContainerPort = in.Spec.ContainerPort out.PortalIP = in.Spec.PortalIP if err := s.Convert(&in.Spec.SessionAffinity, &out.SessionAffinity, 0); err != nil { return err } return nil }, func(in *Service, out *newer.Service, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } out.Spec.Port = in.Port out.Spec.Protocol = newer.Protocol(in.Protocol) if err := s.Convert(&in.Selector, &out.Spec.Selector, 0); err != nil { return err } out.Spec.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer out.Spec.PublicIPs = in.PublicIPs out.Spec.ContainerPort = in.ContainerPort out.Spec.PortalIP = in.PortalIP if err := s.Convert(&in.SessionAffinity, &out.Spec.SessionAffinity, 0); err != nil { return err } return nil }, func(in *newer.Node, out *Minion, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil { return err } if err := s.Convert(&in.Status.Phase, &out.Status.Phase, 0); err != nil { return err } if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } out.HostIP = in.Status.HostIP out.PodCIDR = in.Spec.PodCIDR out.ExternalID = in.Spec.ExternalID return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0) }, func(in *Minion, out *newer.Node, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } if err := s.Convert(&in.Status.Phase, &out.Status.Phase, 0); err != nil { return err } if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } out.Status.HostIP = in.HostIP out.Spec.PodCIDR = in.PodCIDR out.Spec.ExternalID = in.ExternalID return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0) }, func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } return nil }, func(in *LimitRange, out *newer.LimitRange, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } return nil }, func(in *Namespace, out *newer.Namespace, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } return nil }, func(in *newer.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { *out = LimitRangeSpec{} out.Limits = make([]LimitRangeItem, len(in.Limits), len(in.Limits)) for i := range in.Limits { if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil { return err } } return nil }, func(in *LimitRangeSpec, out *newer.LimitRangeSpec, s conversion.Scope) error { *out = newer.LimitRangeSpec{} out.Limits = make([]newer.LimitRangeItem, len(in.Limits), len(in.Limits)) for i := range in.Limits { if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil { return err } } return nil }, func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { *out = LimitRangeItem{} out.Type = LimitType(in.Type) if err := s.Convert(&in.Max, &out.Max, 0); err != nil { return err } if err := s.Convert(&in.Min, &out.Min, 0); err != nil { return err } return nil }, func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error { *out = newer.LimitRangeItem{} out.Type = newer.LimitType(in.Type) if err := s.Convert(&in.Max, &out.Max, 0); err != nil { return err } if err := s.Convert(&in.Min, &out.Min, 0); err != nil { return err } return nil }, func(in *newer.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } return nil }, func(in *ResourceQuota, out *newer.ResourceQuota, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } return nil }, func(in *newer.ResourceQuotaUsage, out *ResourceQuotaUsage, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } return nil }, func(in *ResourceQuotaUsage, out *newer.ResourceQuotaUsage, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } return nil }, func(in *newer.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { *out = ResourceQuotaSpec{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { return err } return nil }, func(in *ResourceQuotaSpec, out *newer.ResourceQuotaSpec, s conversion.Scope) error { *out = newer.ResourceQuotaSpec{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { return err } return nil }, func(in *newer.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { *out = ResourceQuotaStatus{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { return err } if err := s.Convert(&in.Used, &out.Used, 0); err != nil { return err } return nil }, func(in *ResourceQuotaStatus, out *newer.ResourceQuotaStatus, s conversion.Scope) error { *out = newer.ResourceQuotaStatus{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { return err } if err := s.Convert(&in.Used, &out.Used, 0); err != nil { return err } return nil }, // Object ID <-> Name // TODO: amend the conversion package to allow overriding specific fields. func(in *ObjectReference, out *newer.ObjectReference, s conversion.Scope) error { out.Kind = in.Kind out.Namespace = in.Namespace out.Name = in.ID out.UID = in.UID out.APIVersion = in.APIVersion out.ResourceVersion = in.ResourceVersion out.FieldPath = in.FieldPath return nil }, func(in *newer.ObjectReference, out *ObjectReference, s conversion.Scope) error { out.Kind = in.Kind out.Namespace = in.Namespace out.ID = in.Name out.UID = in.UID out.APIVersion = in.APIVersion out.ResourceVersion = in.ResourceVersion out.FieldPath = in.FieldPath return nil }, // Event Source <-> Source.Component // Event Host <-> Source.Host // TODO: remove this when it becomes possible to specify a field name conversion on a specific type func(in *newer.Event, out *Event, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } out.Reason = in.Reason out.Message = in.Message out.Source = in.Source.Component out.Host = in.Source.Host out.Timestamp = in.FirstTimestamp out.FirstTimestamp = in.FirstTimestamp out.LastTimestamp = in.LastTimestamp out.Count = in.Count return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, func(in *Event, out *newer.Event, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } out.Reason = in.Reason out.Message = in.Message out.Source.Component = in.Source out.Source.Host = in.Host if in.FirstTimestamp.IsZero() { // Assume this is an old event that does not specify FirstTimestamp/LastTimestamp/Count out.FirstTimestamp = in.Timestamp out.LastTimestamp = in.Timestamp out.Count = 1 } else { out.FirstTimestamp = in.FirstTimestamp out.LastTimestamp = in.LastTimestamp out.Count = in.Count } return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, // This is triggered for the Memory field of Container. func(in *int64, out *resource.Quantity, s conversion.Scope) error { out.Set(*in) out.Format = resource.BinarySI return nil }, func(in *resource.Quantity, out *int64, s conversion.Scope) error { *out = in.Value() return nil }, // This is triggered by the CPU field of Container. // Note that if we add other int/Quantity conversions my // simple hack (int64=Value(), int=MilliValue()) here won't work. func(in *int, out *resource.Quantity, s conversion.Scope) error { out.SetMilli(int64(*in)) out.Format = resource.DecimalSI return nil }, func(in *resource.Quantity, out *int, s conversion.Scope) error { *out = int(in.MilliValue()) return nil }, // Convert resource lists. func(in *ResourceList, out *newer.ResourceList, s conversion.Scope) error { *out = newer.ResourceList{} for k, v := range *in { fv, err := strconv.ParseFloat(v.String(), 64) if err != nil { return &newer.ConversionError{ In: in, Out: out, Message: fmt.Sprintf("value '%v' of '%v': %v", v, k, err), } } if k == ResourceCPU { (*out)[newer.ResourceCPU] = *resource.NewMilliQuantity(int64(fv*1000), resource.DecimalSI) } else { (*out)[newer.ResourceName(k)] = *resource.NewQuantity(int64(fv), resource.BinarySI) } } return nil }, func(in *newer.ResourceList, out *ResourceList, s conversion.Scope) error { *out = ResourceList{} for k, v := range *in { if k == newer.ResourceCPU { (*out)[ResourceCPU] = util.NewIntOrStringFromString(fmt.Sprintf("%v", float64(v.MilliValue())/1000)) } else { (*out)[ResourceName(k)] = util.NewIntOrStringFromInt(int(v.Value())) } } return nil }, // VolumeSource's HostDir is deprecated in favor of HostPath. // TODO: It would be great if I could just map field names to // convert or else maybe say "convert all members of this // struct" and then fix up only the stuff that changed. func(in *newer.VolumeSource, out *VolumeSource, s conversion.Scope) error { if err := s.Convert(&in.EmptyDir, &out.EmptyDir, 0); err != nil { return err } if err := s.Convert(&in.GitRepo, &out.GitRepo, 0); err != nil { return err } if err := s.Convert(&in.GCEPersistentDisk, &out.GCEPersistentDisk, 0); err != nil { return err } if err := s.Convert(&in.HostPath, &out.HostDir, 0); err != nil { return err } if err := s.Convert(&in.Secret, &out.Secret, 0); err != nil { return err } return nil }, func(in *VolumeSource, out *newer.VolumeSource, s conversion.Scope) error { if err := s.Convert(&in.EmptyDir, &out.EmptyDir, 0); err != nil { return err } if err := s.Convert(&in.GitRepo, &out.GitRepo, 0); err != nil { return err } if err := s.Convert(&in.GCEPersistentDisk, &out.GCEPersistentDisk, 0); err != nil { return err } if err := s.Convert(&in.HostDir, &out.HostPath, 0); err != nil { return err } if err := s.Convert(&in.Secret, &out.Secret, 0); err != nil { return err } return nil }, func(in *newer.PullPolicy, out *PullPolicy, s conversion.Scope) error { switch *in { case newer.PullAlways: *out = PullAlways case newer.PullNever: *out = PullNever case newer.PullIfNotPresent: *out = PullIfNotPresent case "": *out = "" default: // Let unknown values through - they will get caught by validation *out = PullPolicy(*in) } return nil }, func(in *PullPolicy, out *newer.PullPolicy, s conversion.Scope) error { switch *in { case PullAlways: *out = newer.PullAlways case PullNever: *out = newer.PullNever case PullIfNotPresent: *out = newer.PullIfNotPresent case "": *out = "" default: // Let unknown values through - they will get caught by validation *out = newer.PullPolicy(*in) } return nil }, func(in *newer.Probe, out *LivenessProbe, s conversion.Scope) error { if err := s.Convert(&in.Exec, &out.Exec, 0); err != nil { return err } if err := s.Convert(&in.HTTPGet, &out.HTTPGet, 0); err != nil { return err } if err := s.Convert(&in.TCPSocket, &out.TCPSocket, 0); err != nil { return err } out.InitialDelaySeconds = in.InitialDelaySeconds out.TimeoutSeconds = in.TimeoutSeconds return nil }, func(in *LivenessProbe, out *newer.Probe, s conversion.Scope) error { if err := s.Convert(&in.Exec, &out.Exec, 0); err != nil { return err } if err := s.Convert(&in.HTTPGet, &out.HTTPGet, 0); err != nil { return err } if err := s.Convert(&in.TCPSocket, &out.TCPSocket, 0); err != nil { return err } out.InitialDelaySeconds = in.InitialDelaySeconds out.TimeoutSeconds = in.TimeoutSeconds return nil }, func(in *newer.Endpoints, out *Endpoints, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.Protocol, &out.Protocol, 0); err != nil { return err } for i := range in.Endpoints { ep := &in.Endpoints[i] out.Endpoints = append(out.Endpoints, net.JoinHostPort(ep.IP, strconv.Itoa(ep.Port))) } return nil }, func(in *Endpoints, out *newer.Endpoints, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { return err } if err := s.Convert(&in.Protocol, &out.Protocol, 0); err != nil { return err } for i := range in.Endpoints { out.Endpoints = append(out.Endpoints, newer.Endpoint{}) ep := &out.Endpoints[i] host, port, err := net.SplitHostPort(in.Endpoints[i]) if err != nil { return err } ep.IP = host pn, err := strconv.Atoi(port) if err != nil { return err } ep.Port = pn } return nil }, func(in *newer.NodeCondition, out *NodeCondition, s conversion.Scope) error { if err := s.Convert(&in.Type, &out.Kind, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { return err } if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { return err } if err := s.Convert(&in.Reason, &out.Reason, 0); err != nil { return err } if err := s.Convert(&in.Message, &out.Message, 0); err != nil { return err } return nil }, func(in *NodeCondition, out *newer.NodeCondition, s conversion.Scope) error { if err := s.Convert(&in.Kind, &out.Type, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { return err } if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { return err } if err := s.Convert(&in.Reason, &out.Reason, 0); err != nil { return err } if err := s.Convert(&in.Message, &out.Message, 0); err != nil { return err } return nil }, func(in *newer.NodeConditionType, out *NodeConditionKind, s conversion.Scope) error { switch *in { case newer.NodeReachable: *out = NodeReachable break case newer.NodeReady: *out = NodeReady break case "": *out = "" default: *out = NodeConditionKind(*in) break } return nil }, func(in *NodeConditionKind, out *newer.NodeConditionType, s conversion.Scope) error { switch *in { case NodeReachable: *out = newer.NodeReachable break case NodeReady: *out = newer.NodeReady break case "": *out = "" default: *out = newer.NodeConditionType(*in) break } return nil }, func(in *newer.PodCondition, out *PodCondition, s conversion.Scope) error { if err := s.Convert(&in.Type, &out.Kind, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } return nil }, func(in *PodCondition, out *newer.PodCondition, s conversion.Scope) error { if err := s.Convert(&in.Kind, &out.Type, 0); err != nil { return err } if err := s.Convert(&in.Status, &out.Status, 0); err != nil { return err } return nil }, func(in *newer.PodConditionType, out *PodConditionKind, s conversion.Scope) error { switch *in { case newer.PodReady: *out = PodReady break case "": *out = "" default: *out = PodConditionKind(*in) break } return nil }, func(in *PodConditionKind, out *newer.PodConditionType, s conversion.Scope) error { switch *in { case PodReady: *out = newer.PodReady break case "": *out = "" default: *out = newer.PodConditionType(*in) break } return nil }, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } }