Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proxy udp #1273

Merged
merged 7 commits into from
Sep 12, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ type Port struct {
HostPort int `yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
// Required: This must be a valid port number, 0 < x < 65536.
ContainerPort int `yaml:"containerPort" json:"containerPort"`
// Optional: Defaults to "TCP".
// Optional: Supports "TCP" and "UDP". Defaults to "TCP".
Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`
// Optional: What host IP to bind the external port to.
HostIP string `yaml:"hostIP,omitempty" json:"hostIP,omitempty"`
Expand Down Expand Up @@ -389,7 +389,11 @@ func (*ServiceList) IsAnAPIObject() {}
// will answer requests sent through the proxy.
type Service struct {
JSONBase `json:",inline" yaml:",inline"`
Port int `json:"port,omitempty" yaml:"port,omitempty"`

// Required.
Port int `json:"port" yaml:"port"`
// Optional: Supports "TCP" and "UDP". Defaults to "TCP".
Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`

// This service's labels.
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
Expand Down
8 changes: 6 additions & 2 deletions pkg/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ type Port struct {
HostPort int `yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
// Required: This must be a valid port number, 0 < x < 65536.
ContainerPort int `yaml:"containerPort" json:"containerPort"`
// Optional: Defaults to "TCP".
// Optional: Supports "TCP" and "UDP". Defaults to "TCP".
Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`
// Optional: What host IP to bind the external port to.
HostIP string `yaml:"hostIP,omitempty" json:"hostIP,omitempty"`
Expand Down Expand Up @@ -401,7 +401,11 @@ func (*ServiceList) IsAnAPIObject() {}
// will answer requests sent through the proxy.
type Service struct {
JSONBase `json:",inline" yaml:",inline"`
Port int `json:"port,omitempty" yaml:"port,omitempty"`

// Required.
Port int `json:"port" yaml:"port"`
// Optional: Supports "TCP" and "UDP". Defaults to "TCP".
Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`

// This service's labels.
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
Expand Down
5 changes: 5 additions & 0 deletions pkg/api/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ func ValidateService(service *api.Service) errs.ErrorList {
if !util.IsValidPortNum(service.Port) {
allErrs = append(allErrs, errs.NewFieldInvalid("Service.Port", service.Port))
}
if len(service.Protocol) == 0 {
service.Protocol = "TCP"
} else if !supportedPortProtocols.Has(strings.ToUpper(service.Protocol)) {
allErrs = append(allErrs, errs.NewFieldNotSupported("protocol", service.Protocol))
}
if labels.Set(service.Selector).AsSelector().Empty() {
allErrs = append(allErrs, errs.NewFieldRequired("selector", service.Selector))
}
Expand Down
138 changes: 103 additions & 35 deletions pkg/api/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,50 +365,118 @@ func TestValidatePod(t *testing.T) {
}

func TestValidateService(t *testing.T) {
// This test should fail because the port number is invalid i.e.
// the Port field has a default value of 0.
errs := ValidateService(&api.Service{
JSONBase: api.JSONBase{ID: "foo"},
Selector: map[string]string{
"foo": "bar",
testCases := []struct {
name string
svc api.Service
numErrs int
}{
{
name: "missing id",
svc: api.Service{
Port: 8675,
Selector: map[string]string{"foo": "bar"},
},
// Should fail because the ID is missing.
numErrs: 1,
},
})
if len(errs) != 1 {
t.Errorf("Unexpected error list: %#v", errs)
}

errs = ValidateService(&api.Service{
Port: 6502,
JSONBase: api.JSONBase{ID: "foo"},
Selector: map[string]string{
"foo": "bar",
{
name: "invalid id",
svc: api.Service{
JSONBase: api.JSONBase{ID: "123abc"},
Port: 8675,
Selector: map[string]string{"foo": "bar"},
},
// Should fail because the ID is invalid.
numErrs: 1,
},
{
name: "missing port",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
Selector: map[string]string{"foo": "bar"},
},
// Should fail because the port number is missing/invalid.
numErrs: 1,
},
{
name: "invalid port",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
Port: 65536,
Selector: map[string]string{"foo": "bar"},
},
// Should fail because the port number is invalid.
numErrs: 1,
},
{
name: "invalid protocol",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
Port: 8675,
Protocol: "INVALID",
Selector: map[string]string{"foo": "bar"},
},
// Should fail because the protocol is invalid.
numErrs: 1,
},
{
name: "missing selector",
svc: api.Service{
JSONBase: api.JSONBase{ID: "foo"},
Port: 8675,
},
// Should fail because the selector is missing.
numErrs: 1,
},
{
name: "valid 1",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
Port: 1,
Protocol: "TCP",
Selector: map[string]string{"foo": "bar"},
},
numErrs: 0,
},
{
name: "valid 2",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
Port: 65535,
Protocol: "UDP",
Selector: map[string]string{"foo": "bar"},
},
numErrs: 0,
},
{
name: "valid 3",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
Port: 80,
Selector: map[string]string{"foo": "bar"},
},
numErrs: 0,
},
})
if len(errs) != 0 {
t.Errorf("Unexpected non-zero error list: %#v", errs)
}

errs = ValidateService(&api.Service{
Port: 6502,
Selector: map[string]string{
"foo": "bar",
},
})
if len(errs) != 1 {
t.Errorf("Unexpected error list: %#v", errs)
for _, tc := range testCases {
errs := ValidateService(&tc.svc)
if len(errs) != tc.numErrs {
t.Errorf("Unexpected error list for case %q: %+v", tc.name, errs)
}
}

errs = ValidateService(&api.Service{
svc := api.Service{
Port: 6502,
JSONBase: api.JSONBase{ID: "foo"},
})
if len(errs) != 1 {
t.Errorf("Unexpected error list: %#v", errs)
Selector: map[string]string{"foo": "bar"},
}

errs = ValidateService(&api.Service{})
if len(errs) != 3 {
t.Errorf("Unexpected error list: %#v", errs)
errs := ValidateService(&svc)
if len(errs) != 0 {
t.Errorf("Unexpected non-zero error list: %#v", errs)
}
if svc.Protocol != "TCP" {
t.Errorf("Expected default protocol of 'TCP': %#v", errs)
}
}

Expand Down