Пример #1
0
func fakeDeploymentConfig(name string, containers ...containerDesc) *deployapi.DeploymentConfig {
	specContainers := []kapi.Container{}
	for _, c := range containers {
		container := kapi.Container{
			Name: c.name,
		}

		container.Ports = []kapi.ContainerPort{}
		for _, p := range c.ports {
			container.Ports = append(container.Ports, kapi.ContainerPort{
				Name:          fmt.Sprintf("port-%d-%s", p.port, p.protocol),
				ContainerPort: p.port,
				Protocol:      kapi.Protocol(p.protocol),
			})
		}

		specContainers = append(specContainers, container)
	}
	return &deployapi.DeploymentConfig{
		ObjectMeta: kapi.ObjectMeta{
			Name: name,
		},
		Template: deployapi.DeploymentTemplate{
			ControllerTemplate: kapi.ReplicationControllerSpec{
				Replicas: 1,
				Selector: map[string]string{"name": "test"},
				Template: &kapi.PodTemplateSpec{
					Spec: kapi.PodSpec{
						Containers: specContainers,
					},
				},
			},
		},
	}
}
func replicationControllerSpecFromService(s pmxadapter.Service) api.ReplicationController {
	ports := make([]api.Port, len(s.Ports))
	for i, p := range s.Ports {
		ports[i].HostPort = int(p.HostPort)
		ports[i].ContainerPort = int(p.ContainerPort)
		ports[i].Protocol = api.Protocol(p.Protocol)
	}

	env := make([]api.EnvVar, len(s.Environment))
	for i, e := range s.Environment {
		env[i].Name = e.Variable
		env[i].Value = e.Value
	}

	safeName := sanitizeServiceName(s.Name)
	commands := make([]string, 0)
	if s.Command != "" {
		commands = append(commands, s.Command)
	}

	replicas := s.Deployment.Count
	// The adapter seems to be in charge of adjusting missing replica count from
	// the JSON. The UI doesn't allow selection of 0 replicas, so this shouldn't
	// screw things up in the current state.
	if replicas == 0 {
		replicas = 1
	}

	return api.ReplicationController{
		ObjectMeta: api.ObjectMeta{
			Name: safeName,
		},
		Spec: api.ReplicationControllerSpec{
			Replicas: replicas,
			Selector: map[string]string{"service-name": safeName},
			Template: &api.PodTemplateSpec{
				ObjectMeta: api.ObjectMeta{
					Labels: map[string]string{
						"service-name": safeName,
						"panamax":      "panamax",
					},
				},
				Spec: api.PodSpec{
					Containers: []api.Container{
						{
							Name:    safeName,
							Image:   s.Source,
							Command: commands,
							Ports:   ports,
							Env:     env,
						},
					},
				},
			},
		},
	}
}
Пример #3
0
func (ServiceGenerator) Generate(params map[string]string) (runtime.Object, error) {
	selectorString, found := params["selector"]
	if !found || len(selectorString) == 0 {
		return nil, fmt.Errorf("'selector' is a required parameter.")
	}
	selector := ParseLabels(selectorString)
	name, found := params["name"]
	if !found {
		return nil, fmt.Errorf("'name' is a required parameter.")
	}
	portString, found := params["port"]
	if !found {
		return nil, fmt.Errorf("'port' is a required parameter.")
	}
	port, err := strconv.Atoi(portString)
	if err != nil {
		return nil, err
	}
	service := api.Service{
		ObjectMeta: api.ObjectMeta{
			Name: name,
		},
		Spec: api.ServiceSpec{
			Port:     port,
			Protocol: api.Protocol(params["protocol"]),
			Selector: selector,
		},
	}
	containerPort, found := params["container-port"]
	if found && len(containerPort) > 0 {
		if cPort, err := strconv.Atoi(containerPort); err != nil {
			service.Spec.ContainerPort = util.NewIntOrStringFromString(containerPort)
		} else {
			service.Spec.ContainerPort = util.NewIntOrStringFromInt(cPort)
		}
	} else {
		service.Spec.ContainerPort = util.NewIntOrStringFromInt(port)
	}
	if params["create-external-load-balancer"] == "true" {
		service.Spec.CreateExternalLoadBalancer = true
	}
	if len(params["public-ip"]) != 0 {
		service.Spec.PublicIPs = []string{params["public-ip"]}
	}
	return &service, nil
}
func kServiceByNameAndPort(name string, toServiceName string, p pmxadapter.Port) api.Service {
	return api.Service{
		ObjectMeta: api.ObjectMeta{
			Name:   name,
			Labels: map[string]string{"service-name": toServiceName},
		},
		Spec: api.ServiceSpec{
			// I'm unaware of any wildcard selector, we don't have a name for the
			// overarching application being started, and I can't specifically
			// target only certain RCs because we don't know if a Service exists
			// solely to allow external access. Shrug.
			Selector:      map[string]string{"panamax": "panamax"},
			Port:          int(p.HostPort),
			ContainerPort: util.NewIntOrStringFromInt(int(p.ContainerPort)),
			Protocol:      api.Protocol(p.Protocol),
			PublicIPs:     PublicIPs,
		},
	}
}
Пример #5
0
func expectedService(name string, ports ...portDesc) *kapi.Service {
	servicePorts := []kapi.ServicePort{}
	for _, p := range ports {
		servicePorts = append(servicePorts, kapi.ServicePort{
			Name:       fmt.Sprintf("port-%d-%s", p.port, p.protocol),
			Port:       p.port,
			Protocol:   kapi.Protocol(p.protocol),
			TargetPort: kutil.NewIntOrStringFromInt(p.port),
		})
	}

	return &kapi.Service{
		ObjectMeta: kapi.ObjectMeta{
			Name: name,
		},
		Spec: kapi.ServiceSpec{
			Selector: map[string]string{"name": "test"},
			Ports:    servicePorts,
		},
	}
}
Пример #6
0
func init() {
	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)
		},

		// Convert all to the new PodCondition constants
		func(in *newer.PodCondition, out *PodStatus, s conversion.Scope) error {
			switch *in {
			case "":
				*out = ""
			case newer.PodPending:
				*out = PodWaiting
			case newer.PodRunning:
				*out = PodRunning
			case newer.PodSucceeded:
				*out = PodTerminated
			case newer.PodFailed:
				*out = PodTerminated
			default:
				return errors.New("The string provided is not a valid PodCondition constant value")
			}

			return nil
		},

		func(in *PodStatus, out *newer.PodCondition, 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 PodFailed
				*out = newer.PodFailed
			default:
				return errors.New("The string provided is not a valid PodCondition 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
			}
			if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil {
				return err
			}

			if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil {
				return err
			}
			if err := s.Convert(&in.CurrentState, &out.CurrentState, 0); err != nil {
				return err
			}

			if err := s.Convert(&in.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, &out.DesiredState, 0); err != nil {
				return err
			}
			if err := s.Convert(&in.CurrentState, &out.CurrentState, 0); err != nil {
				return err
			}

			if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 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.DesiredState, &out.DesiredState, 0); err != nil {
				return err
			}
			if err := s.Convert(&in.CurrentState, &out.CurrentState, 0); err != nil {
				return err
			}
			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.DesiredState, 0); err != nil {
				return err
			}
			if err := s.Convert(&in.CurrentState, &out.CurrentState, 0); err != nil {
				return err
			}
			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.ContainerPort = in.Spec.ContainerPort
			out.PortalIP = in.Spec.PortalIP
			out.ProxyPort = in.Spec.ProxyPort

			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.ContainerPort = in.ContainerPort
			out.Spec.PortalIP = in.PortalIP
			out.Spec.ProxyPort = in.ProxyPort

			return nil
		},

		func(in *newer.Binding, out *Binding, 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.PodID = in.PodID
			out.Host = in.Host

			return nil
		},
		func(in *Binding, out *newer.Binding, 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.PodID = in.PodID
			out.Host = in.Host

			return nil
		},

		func(in *newer.Status, out *Status, 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.Code = in.Code
			out.Message = in.Message
			out.Reason = StatusReason(in.Reason)
			out.Status = in.Status
			return s.Convert(&in.Details, &out.Details, 0)
		},
		func(in *Status, out *newer.Status, 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.Code = in.Code
			out.Message = in.Message
			out.Reason = newer.StatusReason(in.Reason)
			out.Status = in.Status
			return s.Convert(&in.Details, &out.Details, 0)
		},

		func(in *newer.Minion, 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.Labels, &out.Labels, 0); err != nil {
				return err
			}

			out.HostIP = in.HostIP
			return s.Convert(&in.NodeResources, &out.NodeResources, 0)
		},
		func(in *Minion, out *newer.Minion, 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.HostIP = in.HostIP
			return s.Convert(&in.NodeResources, &out.NodeResources, 0)
		},

		func(in *newer.BoundPod, out *BoundPod, 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
			}

			return s.Convert(&in.Spec, &out.Spec, 0)
		},
		func(in *BoundPod, out *newer.BoundPod, 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
			}

			return s.Convert(&in.Spec, &out.Spec, 0)
		},

		func(in *newer.BoundPods, out *BoundPods, 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.Host = in.Host
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *BoundPods, out *newer.BoundPods, 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.Host = in.Host
			return s.Convert(&in.Items, &out.Items, 0)
		},

		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
			}

			return s.Convert(&in.Endpoints, &out.Endpoints, 0)
		},
		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
			}

			return s.Convert(&in.Endpoints, &out.Endpoints, 0)
		},

		func(in *newer.ServerOp, out *ServerOp, 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
			}
			return nil
		},
		func(in *ServerOp, out *newer.ServerOp, 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
			}
			return nil
		},

		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.Message = in.Message
			out.Reason = in.Reason
			out.Source = in.Source
			out.Status = in.Status
			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.Message = in.Message
			out.Reason = in.Reason
			out.Source = in.Source
			out.Status = in.Status
			out.Timestamp = in.Timestamp
			return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0)
		},

		// Convert all the standard lists
		func(in *newer.PodList, out *PodList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *PodList, out *newer.PodList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},

		func(in *newer.ReplicationControllerList, out *ReplicationControllerList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *ReplicationControllerList, out *newer.ReplicationControllerList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},

		func(in *newer.ServiceList, out *ServiceList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *ServiceList, out *newer.ServiceList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},

		func(in *newer.EndpointsList, out *EndpointsList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *EndpointsList, out *newer.EndpointsList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},

		func(in *newer.EventList, out *EventList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *EventList, out *newer.EventList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},

		func(in *newer.MinionList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *MinionList, out *newer.MinionList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},

		func(in *newer.ServerOpList, out *ServerOpList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *ServerOpList, out *newer.ServerOpList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},

		func(in *newer.ContainerManifestList, out *ContainerManifestList, 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
			}
			return s.Convert(&in.Items, &out.Items, 0)
		},
		func(in *ContainerManifestList, out *newer.ContainerManifestList, 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
			}
			return s.Convert(&in.Items, &out.Items, 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.ID = in.Name
			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
		},
	)
}
Пример #7
0
// DeployableContainer sets up a container for the image ready for deployment
func (r *ImageRef) DeployableContainer() (container *kapi.Container, triggers []deployapi.DeploymentTriggerPolicy, err error) {
	name, ok := r.SuggestName()
	if !ok {
		return nil, nil, fmt.Errorf("unable to suggest a container name for the image %q", r.String())
	}
	if r.AsImageStream {
		tag := r.Tag
		if len(tag) == 0 {
			tag = imageapi.DefaultImageTag
		}
		imageChangeParams := &deployapi.DeploymentTriggerImageChangeParams{
			Automatic:      true,
			ContainerNames: []string{name},
			Tag:            tag,
		}
		if r.Stream != nil {
			imageChangeParams.From = kapi.ObjectReference{
				Kind:      "ImageStream",
				Name:      r.Stream.Name,
				Namespace: r.Stream.Namespace,
			}
		} else {
			imageChangeParams.From = kapi.ObjectReference{
				Kind: "ImageStream",
				Name: r.Name,
			}
		}
		triggers = []deployapi.DeploymentTriggerPolicy{
			{
				Type:              deployapi.DeploymentTriggerOnImageChange,
				ImageChangeParams: imageChangeParams,
			},
		}
	}

	container = &kapi.Container{
		Name:  name,
		Image: r.String(),
	}

	// If imageInfo present, append ports
	if r.Info != nil && r.Info.Config != nil {
		ports := []string{}
		// ExposedPorts can consist of multiple space-separated ports
		for exposed := range r.Info.Config.ExposedPorts {
			ports = append(ports, strings.Split(exposed, " ")...)
		}

		for _, sp := range ports {
			p := docker.Port(sp)
			port, err := strconv.Atoi(p.Port())
			if err != nil {
				return nil, nil, fmt.Errorf("failed to parse port %q: %v", p.Port(), err)
			}

			container.Ports = append(container.Ports, kapi.ContainerPort{
				ContainerPort: port,
				Protocol:      kapi.Protocol(strings.ToUpper(p.Proto())),
			})
		}

		// Create volume mounts with names based on container name
		maxDigits := len(fmt.Sprintf("%d", len(r.Info.Config.Volumes)))
		baseName := namer.GetName(container.Name, volumeNameInfix, util.LabelValueMaxLength-maxDigits-1)
		i := 1
		for volume := range r.Info.Config.Volumes {
			r.HasEmptyDir = true
			container.VolumeMounts = append(container.VolumeMounts, kapi.VolumeMount{
				Name:      fmt.Sprintf("%s-%d", baseName, i),
				ReadOnly:  false,
				MountPath: volume,
			})
			i++
		}
		// TODO: Append environment variables
	}

	return container, triggers, nil

}
Пример #8
0
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)
	}
}
Пример #9
0
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)
	}
}
Пример #10
0
// DeployableContainer sets up a container for the image ready for deployment
func (r *ImageRef) DeployableContainer() (container *kapi.Container, triggers []deployapi.DeploymentTriggerPolicy, err error) {
	name, ok := r.SuggestName()
	if !ok {
		return nil, nil, fmt.Errorf("unable to suggest a container name for the image %q", r.String())
	}
	if r.AsImageStream {
		tag := r.Tag
		if len(tag) == 0 {
			tag = imageapi.DefaultImageTag
		}
		imageChangeParams := &deployapi.DeploymentTriggerImageChangeParams{
			Automatic:      true,
			ContainerNames: []string{name},
			Tag:            tag,
		}
		if r.Stream != nil {
			imageChangeParams.From = kapi.ObjectReference{
				Kind:      "ImageStream",
				Name:      r.Stream.Name,
				Namespace: r.Stream.Namespace,
			}
		} else {
			imageChangeParams.From = kapi.ObjectReference{
				Kind: "ImageStream",
				Name: r.Name,
			}
		}
		triggers = []deployapi.DeploymentTriggerPolicy{
			{
				Type:              deployapi.DeploymentTriggerOnImageChange,
				ImageChangeParams: imageChangeParams,
			},
		}
	}

	container = &kapi.Container{
		Name:  name,
		Image: r.String(),
	}

	// If imageInfo present, append ports
	if r.Info != nil {
		ports := []string{}
		// ExposedPorts can consist of multiple space-separated ports
		for exposed := range r.Info.Config.ExposedPorts {
			ports = append(ports, strings.Split(exposed, " ")...)
		}

		for _, sp := range ports {
			p := docker.Port(sp)
			port, err := strconv.Atoi(p.Port())
			if err != nil {
				return nil, nil, fmt.Errorf("failed to parse port %q: %v", p.Port(), err)
			}
			container.Ports = append(container.Ports, kapi.ContainerPort{
				Name:          strings.Join([]string{name, p.Proto(), p.Port()}, "-"),
				ContainerPort: port,
				Protocol:      kapi.Protocol(strings.ToUpper(p.Proto())),
			})
		}
		// TODO: Append volume information and environment variables
	}

	return container, triggers, 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)
	}
}
Пример #12
0
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")

	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)
		},

		// 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 = PodTerminated
			case newer.PodFailed:
				*out = PodTerminated
			default:
				return errors.New("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
			default:
				return errors.New("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
			}
			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
			}
			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.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 errors.New("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
			}
			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
			}
			if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 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.NetworkMode = in.NetworkMode
			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.NetworkMode = in.NetworkMode
			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.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.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
			}
			return nil
		},
		func(in *PodState, out *newer.PodSpec, s conversion.Scope) error {
			if err := s.Convert(&in.Manifest, &out, 0); err != nil {
				return err
			}
			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

			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

			return nil
		},

		func(in *newer.Minion, 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.Spec.VMs, &out.VMs, 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.Minion, 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.VMs, &out.Spec.VMs, 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.ID = in.Name
			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
		},
	)
}
Пример #13
0
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")
	newer.Scheme.AddStructFieldConversion(newer.Endpoints{}, "Endpoints", Endpoints{}, "Endpoints")

	// 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.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 *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.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 *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.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
		},
		// 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 newer.Container.
		// Fields 'CPU' and 'Memory' are not present in the internal newer.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.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
			}
			if err := s.Convert(&in.Conditions, &out.Conditions, 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
			}
			if err := s.Convert(&in.Conditions, &out.Conditions, 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.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.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
		},
		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.TargetPort
			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.TargetPort = 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
			}
			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 == newer.NodeLegacyHostIP {
					out.HostIP = address.Address
				}
			}
			out.PodCIDR = in.Spec.PodCIDR
			out.ExternalID = in.Spec.ExternalID
			out.Unschedulable = in.Spec.Unschedulable
			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
			}
			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 != "" {
				newer.AddToNodeAddresses(&out.Status.Addresses,
					newer.NodeAddress{Type: newer.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.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.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 *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
			}
			if err := s.Convert(&in.Labels, &out.Labels, 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
			}
			if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 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 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 *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
		},

		func(in *newer.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 *newer.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 *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
			}
			if err := s.Convert(&in.NFS, &out.NFS, 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
			}
			if err := s.Convert(&in.NFS, &out.NFS, 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.RestartPolicy, out *RestartPolicy, s conversion.Scope) error {
			switch *in {
			case newer.RestartPolicyAlways:
				*out = RestartPolicy{Always: &RestartPolicyAlways{}}
			case newer.RestartPolicyNever:
				*out = RestartPolicy{Never: &RestartPolicyNever{}}
			case newer.RestartPolicyOnFailure:
				*out = RestartPolicy{OnFailure: &RestartPolicyOnFailure{}}
			default:
				*out = RestartPolicy{}
			}
			return nil
		},
		func(in *RestartPolicy, out *newer.RestartPolicy, s conversion.Scope) error {
			switch {
			case in.Always != nil:
				*out = newer.RestartPolicyAlways
			case in.Never != nil:
				*out = newer.RestartPolicyNever
			case in.OnFailure != nil:
				*out = newer.RestartPolicyOnFailure
			default:
				*out = ""
			}
			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]
				hostPort := net.JoinHostPort(ep.IP, strconv.Itoa(ep.Port))
				out.Endpoints = append(out.Endpoints, hostPort)
				if ep.TargetRef != nil {
					target := EndpointObjectReference{
						Endpoint: hostPort,
					}
					if err := s.Convert(ep.TargetRef, &target.ObjectReference, 0); err != nil {
						return err
					}
					out.TargetRefs = append(out.TargetRefs, target)
				}
			}
			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
				for j := range in.TargetRefs {
					if in.TargetRefs[j].Endpoint != in.Endpoints[i] {
						continue
					}
					ep.TargetRef = &newer.ObjectReference{}
					if err := s.Convert(&in.TargetRefs[j], ep.TargetRef, 0); err != nil {
						return err
					}
				}
			}
			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
		},
		func(in *Binding, out *newer.Binding, s conversion.Scope) error {
			if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil {
				return err
			}
			out.Target = newer.ObjectReference{
				Name: in.Host,
			}
			out.Name = in.PodID
			return nil
		},
		func(in *newer.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
		},
	)
	if err != nil {
		// If one of the conversion functions is malformed, detect it immediately.
		panic(err)
	}

	// Add field conversion funcs.
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "pods",
		func(label, value string) (string, string, error) {
			switch label {
			case "name":
				return "name", value, nil
			case "DesiredState.Host":
				return "spec.host", value, nil
			case "DesiredState.Status":
				podStatus := PodStatus(value)
				var internalValue newer.PodPhase
				newer.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 = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "events",
		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)
	}
}
Пример #14
0
func TestImageRefDeployableContainerPorts(t *testing.T) {
	tests := []struct {
		name          string
		inputPorts    map[string]struct{}
		expectedPorts map[int]string
		expectError   bool
	}{
		{
			name: "tcp implied, individual ports",
			inputPorts: map[string]struct{}{
				"123": {},
				"456": {},
			},
			expectedPorts: map[int]string{
				123: "TCP",
				456: "TCP",
			},
			expectError: false,
		},
		{
			name: "tcp implied, multiple ports",
			inputPorts: map[string]struct{}{
				"123 456":  {},
				"678 1123": {},
			},
			expectedPorts: map[int]string{
				123:  "TCP",
				678:  "TCP",
				456:  "TCP",
				1123: "TCP",
			},
			expectError: false,
		},
		{
			name: "tcp and udp, individual ports",
			inputPorts: map[string]struct{}{
				"123/tcp": {},
				"456/udp": {},
			},
			expectedPorts: map[int]string{
				123: "TCP",
				456: "UDP",
			},
			expectError: false,
		},
		{
			name: "tcp implied, multiple ports",
			inputPorts: map[string]struct{}{
				"123/tcp 456/udp":  {},
				"678/udp 1123/tcp": {},
			},
			expectedPorts: map[int]string{
				123:  "TCP",
				456:  "UDP",
				678:  "UDP",
				1123: "TCP",
			},
			expectError: false,
		},
		{
			name: "invalid format",
			inputPorts: map[string]struct{}{
				"123/tcp abc": {},
			},
			expectedPorts: map[int]string{},
			expectError:   true,
		},
	}
	for _, test := range tests {
		imageRef := &ImageRef{
			DockerImageReference: imageapi.DockerImageReference{
				Namespace: "test",
				Name:      "image",
				Tag:       imageapi.DefaultImageTag,
			},
			Info: &imageapi.DockerImage{
				Config: imageapi.DockerConfig{
					ExposedPorts: test.inputPorts,
				},
			},
		}
		container, _, err := imageRef.DeployableContainer()
		if err != nil && !test.expectError {
			t.Errorf("%s: unexpected error: %v", test.name, err)
			continue
		}
		if err == nil && test.expectError {
			t.Errorf("%s: got no error and expected an error", test.name)
			continue
		}
		if test.expectError {
			continue
		}
		remaining := test.expectedPorts
		for _, port := range container.Ports {
			proto, ok := remaining[port.ContainerPort]
			if !ok {
				t.Errorf("%s: got unexpected port: %v", test.name, port)
				continue
			}
			if kapi.Protocol(proto) != port.Protocol {
				t.Errorf("%s: got unexpected protocol %s for port %v", test.name, port.Protocol, port)
			}
			delete(remaining, port.ContainerPort)
		}
		if len(remaining) > 0 {
			t.Errorf("%s: did not find expected ports: %#v", test.name, remaining)
		}
	}
}
Пример #15
0
func (ServiceGenerator) Generate(params map[string]string) (runtime.Object, error) {
	selectorString, found := params["selector"]
	if !found || len(selectorString) == 0 {
		return nil, fmt.Errorf("'selector' is a required parameter.")
	}
	selector, err := ParseLabels(selectorString)
	if err != nil {
		return nil, err
	}

	labelsString, found := params["labels"]
	var labels map[string]string
	if found && len(labelsString) > 0 {
		labels, err = ParseLabels(labelsString)
		if err != nil {
			return nil, err
		}
	}

	name, found := params["name"]
	if !found {
		return nil, fmt.Errorf("'name' is a required parameter.")
	}
	portString, found := params["port"]
	if !found {
		return nil, fmt.Errorf("'port' is a required parameter.")
	}
	port, err := strconv.Atoi(portString)
	if err != nil {
		return nil, err
	}
	service := api.Service{
		ObjectMeta: api.ObjectMeta{
			Name:   name,
			Labels: labels,
		},
		Spec: api.ServiceSpec{
			Selector: selector,
			Ports: []api.ServicePort{
				{
					Name:     "default",
					Port:     port,
					Protocol: api.Protocol(params["protocol"]),
				},
			},
		},
	}
	targetPort, found := params["target-port"]
	if !found {
		targetPort, found = params["container-port"]
	}
	if found && len(targetPort) > 0 {
		if portNum, err := strconv.Atoi(targetPort); err != nil {
			service.Spec.Ports[0].TargetPort = util.NewIntOrStringFromString(targetPort)
		} else {
			service.Spec.Ports[0].TargetPort = util.NewIntOrStringFromInt(portNum)
		}
	} else {
		service.Spec.Ports[0].TargetPort = util.NewIntOrStringFromInt(port)
	}
	if params["create-external-load-balancer"] == "true" {
		service.Spec.CreateExternalLoadBalancer = true
	}
	if len(params["public-ip"]) != 0 {
		service.Spec.PublicIPs = []string{params["public-ip"]}
	}
	return &service, nil
}
Пример #16
0
func TestRunExposeService(t *testing.T) {
	tests := []struct {
		name     string
		args     []string
		ns       string
		calls    map[string]string
		input    runtime.Object
		flags    map[string]string
		output   runtime.Object
		expected string
		status   int
	}{
		{
			name: "expose-service-from-service",
			args: []string{"service", "baz"},
			ns:   "test",
			calls: map[string]string{
				"GET":  "/namespaces/test/services/baz",
				"POST": "/namespaces/test/services",
			},
			input: &api.Service{
				ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
				TypeMeta:   api.TypeMeta{Kind: "Service", APIVersion: "v1"},
				Spec: api.ServiceSpec{
					Selector: map[string]string{"app": "go"},
				},
			},
			flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test"},
			output: &api.Service{
				ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "12", Labels: map[string]string{"svc": "test"}},
				TypeMeta:   api.TypeMeta{Kind: "Service", APIVersion: "v1"},
				Spec: api.ServiceSpec{
					Ports: []api.ServicePort{
						{
							Name:     "default",
							Protocol: api.Protocol("UDP"),
							Port:     14,
						},
					},
					Selector: map[string]string{"func": "stream"},
				},
			},
			status: 200,
		},
		{
			name: "no-name-passed-from-the-cli",
			args: []string{"service", "mayor"},
			ns:   "default",
			calls: map[string]string{
				"GET":  "/namespaces/default/services/mayor",
				"POST": "/namespaces/default/services",
			},
			input: &api.Service{
				ObjectMeta: api.ObjectMeta{Name: "mayor", Namespace: "default", ResourceVersion: "12"},
				TypeMeta:   api.TypeMeta{Kind: "Service", APIVersion: "v1"},
				Spec: api.ServiceSpec{
					Selector: map[string]string{"run": "this"},
				},
			},
			// No --name flag specified below. Service will use the rc's name passed via the 'default-name' parameter
			flags: map[string]string{"selector": "run=this", "port": "80", "labels": "runas=amayor"},
			output: &api.Service{
				ObjectMeta: api.ObjectMeta{Name: "mayor", Namespace: "default", ResourceVersion: "12", Labels: map[string]string{"runas": "amayor"}},
				TypeMeta:   api.TypeMeta{Kind: "Service", APIVersion: "v1"},
				Spec: api.ServiceSpec{
					Ports: []api.ServicePort{
						{
							Name:     "default",
							Protocol: api.Protocol("TCP"),
							Port:     80,
						},
					},
					Selector: map[string]string{"run": "this"},
				},
			},
			status: 200,
		},
		{
			name: "expose-external-service",
			args: []string{"service", "baz"},
			ns:   "test",
			calls: map[string]string{
				"GET":  "/namespaces/test/services/baz",
				"POST": "/namespaces/test/services",
			},
			input: &api.Service{
				ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
				TypeMeta:   api.TypeMeta{Kind: "Service", APIVersion: "v1"},
				Spec: api.ServiceSpec{
					Selector: map[string]string{"app": "go"},
				},
			},
			flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "create-external-load-balancer": "true"},
			output: &api.Service{
				ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "12", Labels: map[string]string{"svc": "test"}},
				TypeMeta:   api.TypeMeta{Kind: "Service", APIVersion: "v1"},
				Spec: api.ServiceSpec{
					Ports: []api.ServicePort{
						{
							Name:       "default",
							Protocol:   api.Protocol("UDP"),
							Port:       14,
							TargetPort: util.NewIntOrStringFromInt(14),
						},
					},
					Selector: map[string]string{"func": "stream"},
					Type:     api.ServiceTypeLoadBalancer,
				},
			},
			status: 200,
		},
	}

	for _, test := range tests {
		f, tf, codec := NewAPIFactory()
		tf.Printer = &testPrinter{}
		tf.Client = &client.FakeRESTClient{
			Codec: codec,
			Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
				switch p, m := req.URL.Path, req.Method; {
				case p == test.calls[m] && m == "GET":
					return &http.Response{StatusCode: test.status, Body: objBody(codec, test.input)}, nil
				case p == test.calls[m] && m == "POST":
					return &http.Response{StatusCode: test.status, Body: objBody(codec, test.output)}, nil
				default:
					t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
					return nil, nil
				}
			}),
		}
		tf.Namespace = test.ns
		buf := bytes.NewBuffer([]byte{})

		cmd := NewCmdExposeService(f, buf)
		cmd.SetOutput(buf)
		for flag, value := range test.flags {
			cmd.Flags().Set(flag, value)
		}
		cmd.Run(cmd, test.args)

		if len(test.expected) > 0 {
			out := buf.String()
			if !strings.Contains(out, test.expected) {
				t.Errorf("%s: unexpected output: %s", test.name, out)
			}
		}
	}
}
Пример #17
0
func generate(params map[string]string) (runtime.Object, error) {
	selectorString, found := params["selector"]
	if !found || len(selectorString) == 0 {
		return nil, fmt.Errorf("'selector' is a required parameter.")
	}
	selector, err := ParseLabels(selectorString)
	if err != nil {
		return nil, err
	}

	labelsString, found := params["labels"]
	var labels map[string]string
	if found && len(labelsString) > 0 {
		labels, err = ParseLabels(labelsString)
		if err != nil {
			return nil, err
		}
	}

	name, found := params["name"]
	if !found || len(name) == 0 {
		name, found = params["default-name"]
		if !found || len(name) == 0 {
			return nil, fmt.Errorf("'name' is a required parameter.")
		}
	}
	portString, found := params["port"]
	if !found {
		return nil, fmt.Errorf("'port' is a required parameter.")
	}
	port, err := strconv.Atoi(portString)
	if err != nil {
		return nil, err
	}
	servicePortName, found := params["port-name"]
	if !found {
		// Leave the port unnamed.
		servicePortName = ""
	}
	service := api.Service{
		ObjectMeta: api.ObjectMeta{
			Name:   name,
			Labels: labels,
		},
		Spec: api.ServiceSpec{
			Selector: selector,
			Ports: []api.ServicePort{
				{
					Name:     servicePortName,
					Port:     port,
					Protocol: api.Protocol(params["protocol"]),
				},
			},
		},
	}
	targetPort, found := params["target-port"]
	if !found {
		targetPort, found = params["container-port"]
	}
	if found && len(targetPort) > 0 {
		if portNum, err := strconv.Atoi(targetPort); err != nil {
			service.Spec.Ports[0].TargetPort = util.NewIntOrStringFromString(targetPort)
		} else {
			service.Spec.Ports[0].TargetPort = util.NewIntOrStringFromInt(portNum)
		}
	} else {
		service.Spec.Ports[0].TargetPort = util.NewIntOrStringFromInt(port)
	}
	if params["create-external-load-balancer"] == "true" {
		service.Spec.Type = api.ServiceTypeLoadBalancer
	}
	if len(params["public-ip"]) != 0 {
		service.Spec.DeprecatedPublicIPs = []string{params["public-ip"]}
	}
	if len(params["type"]) != 0 {
		service.Spec.Type = api.ServiceType(params["type"])
	}
	if len(params["session-affinity"]) != 0 {
		switch api.ServiceAffinity(params["session-affinity"]) {
		case api.ServiceAffinityNone:
			service.Spec.SessionAffinity = api.ServiceAffinityNone
		case api.ServiceAffinityClientIP:
			service.Spec.SessionAffinity = api.ServiceAffinityClientIP
		default:
			return nil, fmt.Errorf("unknown session affinity: %s", params["session-affinity"])
		}
	}
	return &service, nil
}