Skip to content

Commit

Permalink
controlapi: Allow duplicate published ports when they use different p…
Browse files Browse the repository at this point in the history
…rotocols

Fix controlapi to allow duplicate published ports as long as different
protocols are in use. This is a 1.12.2 regression.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
  • Loading branch information
aaronlehmann committed Oct 13, 2016
1 parent a8e2bb9 commit db8be0b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
12 changes: 9 additions & 3 deletions manager/controlapi/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,19 @@ func validateEndpointSpec(epSpec *api.EndpointSpec) error {
return grpc.Errorf(codes.InvalidArgument, "EndpointSpec: ports can't be used with dnsrr mode")
}

portSet := make(map[uint32]struct{})
type portSpec struct {
publishedPort uint32
protocol api.PortConfig_Protocol
}

portSet := make(map[portSpec]struct{})
for _, port := range epSpec.Ports {
if _, ok := portSet[port.PublishedPort]; ok {
portSpec := portSpec{publishedPort: port.PublishedPort, protocol: port.Protocol}
if _, ok := portSet[portSpec]; ok {
return grpc.Errorf(codes.InvalidArgument, "EndpointSpec: duplicate published ports provided")
}

portSet[port.PublishedPort] = struct{}{}
portSet[portSpec] = struct{}{}
}

return nil
Expand Down
16 changes: 16 additions & 0 deletions manager/controlapi/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,22 @@ func TestCreateService(t *testing.T) {
}}
_, err = ts.Client.CreateService(context.Background(), &api.CreateServiceRequest{Spec: spec4})
assert.NoError(t, err)

// ensure no port conflict when different protocols are used
spec = createSpec("name6", "image", 1)
spec.Endpoint = &api.EndpointSpec{Ports: []*api.PortConfig{
{PublishedPort: uint32(9100), TargetPort: uint32(9100), Protocol: api.PortConfig_Protocol(api.ProtocolTCP)},
}}
r, err = ts.Client.CreateService(context.Background(), &api.CreateServiceRequest{Spec: spec})
assert.NoError(t, err)
assert.NotEmpty(t, r.Service.ID)

spec2 = createSpec("name7", "image", 1)
spec2.Endpoint = &api.EndpointSpec{Ports: []*api.PortConfig{
{PublishedPort: uint32(9100), TargetPort: uint32(9100), Protocol: api.PortConfig_Protocol(api.ProtocolUDP)},
}}
_, err = ts.Client.CreateService(context.Background(), &api.CreateServiceRequest{Spec: spec2})
assert.NoError(t, err)
}

func TestGetService(t *testing.T) {
Expand Down

0 comments on commit db8be0b

Please sign in to comment.