Change:
Kubernetes will create replication controller and pods in case of port spec error, e.g. will create 'myNginx'. A following correct spec will fail:
/cc

Discussion:
return nil } <del> func portsFromString(spec string) []api.Port { </del> <ins> func portsFromString(spec string) ([]api.Port, error) { </ins> if spec == "" { <del> return []api.Port{} </del> <ins> return []api.Port{}, nil </ins> } parts := strings.Split(spec, ",") var result []api.Port

pieces := strings.Split(part, ":") if len(pieces) < 1 || len(pieces) > 2 { glog.Infof("Bad port spec: %s", part) <del> continue </del> <ins> return nil, fmt.Errorf("Bad port spec: %s", part) </ins> } host := 0 container := 0

container, err = strconv.Atoi(pieces[0]) if err != nil { glog.Errorf("Container port is not integer: %s %v", pieces[0], err) <del> continue </del> <ins> return nil, err </ins> } } else { host, err = strconv.Atoi(pieces[0]) if err != nil { glog.Errorf("Host port is not integer: %s %v", pieces[0], err) <del> continue </del> <ins> return nil, err </ins> } container, err = strconv.Atoi(pieces[1]) if err != nil { glog.Errorf("Container port is not integer: %s %v", pieces[1], err) <del> continue </del> <ins> return nil, err </ins> } } if container < 1 { glog.Errorf("Container port is not valid: %d", container) <del> continue </del> <ins> return nil, err </ins> } result = append(result, api.Port{ContainerPort: container, HostPort: host}) } <del> return result </del> <ins> return result, nil </ins> } // RunController creates a new replication controller named 'name' which creates 'replicas' pods running 'image'.

if servicePort > 0 && !util.IsDNSLabel(name) { return fmt.Errorf("Service creation requested, but an invalid name for a service was provided (%s). Service names must be valid DNS labels.", name) } <ins> ports, err := portsFromString(portSpec) if err != nil { return err } </ins> controller := &api.ReplicationController{ JSONBase: api.JSONBase{ ID: name,

{ Name:  strings.ToLower(name), Image: image, <del> Ports: portsFromString(portSpec), </del> <ins> Ports: ports, </ins> }, }, },

} } <ins> func TestRunControllerWithWrongArgs(t *testing.T) { fakeClient := client.Fake{} name := "name" image := "foo/bar" replicas := 3 err := RunController(api.NewDefaultContext(), image, name, replicas, &fakeClient, "8080:", -1) if err == nil { t.Errorf("Unexpected non-error: %#v", fakeClient.Actions) } RunController(api.NewDefaultContext(), image, name, replicas, &fakeClient, "8080:80", -1) if len(fakeClient.Actions) != 1 || fakeClient.Actions[0].Action != "create-controller" { t.Errorf("Unexpected actions: %#v", fakeClient.Actions) } controller := fakeClient.Actions[0].Value.(*api.ReplicationController) if controller.ID != name || controller.DesiredState.Replicas != replicas || controller.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image != image { t.Errorf("Unexpected controller: %#v", controller) } } </ins> func TestRunControllerWithService(t *testing.T) { fakeClient := client.Fake{} name := "name"

} func TestMakePorts(t *testing.T) { <del> var testCases = []struct { </del> <ins> var successTestCases = []struct { </ins> spec  string ports []api.Port }{

[]api.Port{}, }, } <del> for _, tt := range testCases { ports := portsFromString(tt.spec) </del> <ins> for _, tt := range successTestCases { ports, err := portsFromString(tt.spec) </ins> if !reflect.DeepEqual(ports, tt.ports) { t.Errorf("Expected %#v, got %#v", tt.ports, ports) } <ins> if err != nil { t.Errorf("Unexpected error: %v", err) } } var failTestCases = []struct { spec string }{ {"8080:"}, {":80"}, {":"}, } for _, tt := range failTestCases { _, err := portsFromString(tt.spec) if err == nil { t.Errorf("Unexpected non-error") } </ins> } }