mirror of https://github.com/docker/cli.git
Merge pull request #2972 from thaJeztah/ipv6_port_join
Use net.JoinHostPort() to fix formatting with IPv6 addresses
This commit is contained in:
commit
1142740996
|
@ -3,6 +3,7 @@ package container
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -61,7 +62,7 @@ func runPort(dockerCli command.Cli, opts *portOptions) error {
|
||||||
}
|
}
|
||||||
if frontends, exists := c.NetworkSettings.Ports[newP]; exists && frontends != nil {
|
if frontends, exists := c.NetworkSettings.Ports[newP]; exists && frontends != nil {
|
||||||
for _, frontend := range frontends {
|
for _, frontend := range frontends {
|
||||||
fmt.Fprintf(dockerCli.Out(), "%s:%s\n", frontend.HostIP, frontend.HostPort)
|
fmt.Fprintln(dockerCli.Out(), net.JoinHostPort(frontend.HostIP, frontend.HostPort))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -70,7 +71,7 @@ func runPort(dockerCli command.Cli, opts *portOptions) error {
|
||||||
|
|
||||||
for from, frontends := range c.NetworkSettings.Ports {
|
for from, frontends := range c.NetworkSettings.Ports {
|
||||||
for _, frontend := range frontends {
|
for _, frontend := range frontends {
|
||||||
fmt.Fprintf(dockerCli.Out(), "%s -> %s:%s\n", from, frontend.HostIP, frontend.HostPort)
|
fmt.Fprintf(dockerCli.Out(), "%s -> %s\n", from, net.JoinHostPort(frontend.HostIP, frontend.HostPort))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/cli/internal/test"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/go-connections/nat"
|
||||||
|
"gotest.tools/v3/assert"
|
||||||
|
"gotest.tools/v3/golden"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewPortCommandOutput(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
ips []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "container-port-ipv4",
|
||||||
|
ips: []string{"0.0.0.0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "container-port-ipv6",
|
||||||
|
ips: []string{"::"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "container-port-ipv6-and-ipv4",
|
||||||
|
ips: []string{"::", "0.0.0.0"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
|
inspectFunc: func(string) (types.ContainerJSON, error) {
|
||||||
|
ci := types.ContainerJSON{NetworkSettings: &types.NetworkSettings{}}
|
||||||
|
ci.NetworkSettings.Ports = nat.PortMap{
|
||||||
|
"80/tcp": make([]nat.PortBinding, len(tc.ips)),
|
||||||
|
}
|
||||||
|
for i, ip := range tc.ips {
|
||||||
|
ci.NetworkSettings.Ports["80/tcp"][i] = nat.PortBinding{
|
||||||
|
HostIP: ip, HostPort: "3456",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ci, nil
|
||||||
|
},
|
||||||
|
}, test.EnableContentTrust)
|
||||||
|
cmd := NewPortCommand(cli)
|
||||||
|
cmd.SetErr(ioutil.Discard)
|
||||||
|
cmd.SetArgs([]string{"some_container", "80"})
|
||||||
|
err := cmd.Execute()
|
||||||
|
assert.NilError(t, err)
|
||||||
|
golden.Assert(t, cli.OutBuffer().String(), tc.name+".golden")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
0.0.0.0:3456
|
|
@ -0,0 +1,2 @@
|
||||||
|
[::]:3456
|
||||||
|
0.0.0.0:3456
|
|
@ -0,0 +1 @@
|
||||||
|
[::]:3456
|
|
@ -3,6 +3,7 @@ package opts
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -148,8 +149,8 @@ func ConvertPortToPortConfig(
|
||||||
ports := []swarm.PortConfig{}
|
ports := []swarm.PortConfig{}
|
||||||
|
|
||||||
for _, binding := range portBindings[port] {
|
for _, binding := range portBindings[port] {
|
||||||
if binding.HostIP != "" && binding.HostIP != "0.0.0.0" {
|
if p := net.ParseIP(binding.HostIP); p != nil && !p.IsUnspecified() {
|
||||||
logrus.Warnf("ignoring IP-address (%s:%s:%s) service will listen on '0.0.0.0'", binding.HostIP, binding.HostPort, port)
|
logrus.Warnf("ignoring IP-address (%s:%s) service will listen on '0.0.0.0'", net.JoinHostPort(binding.HostIP, binding.HostPort), port)
|
||||||
}
|
}
|
||||||
|
|
||||||
startHostPort, endHostPort, err := nat.ParsePortRange(binding.HostPort)
|
startHostPort, endHostPort, err := nat.ParsePortRange(binding.HostPort)
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package opts
|
package opts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/go-connections/nat"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -316,6 +320,46 @@ func TestPortOptInvalidSimpleSyntax(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConvertPortToPortConfigWithIP(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
value string
|
||||||
|
expectedWarning string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
value: "0.0.0.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "::",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "192.168.1.5",
|
||||||
|
expectedWarning: `ignoring IP-address (192.168.1.5:2345:80/tcp) service will listen on '0.0.0.0'`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "::2",
|
||||||
|
expectedWarning: `ignoring IP-address ([::2]:2345:80/tcp) service will listen on '0.0.0.0'`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var b bytes.Buffer
|
||||||
|
logrus.SetOutput(&b)
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.value, func(t *testing.T) {
|
||||||
|
_, err := ConvertPortToPortConfig("80/tcp", map[nat.Port][]nat.PortBinding{
|
||||||
|
"80/tcp": {{HostIP: tc.value, HostPort: "2345"}},
|
||||||
|
})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
if tc.expectedWarning == "" {
|
||||||
|
assert.Equal(t, b.String(), "")
|
||||||
|
} else {
|
||||||
|
assert.Assert(t, is.Contains(b.String(), tc.expectedWarning))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
logrus.SetOutput(os.Stderr)
|
||||||
|
}
|
||||||
|
|
||||||
func assertContains(t *testing.T, portConfigs []swarm.PortConfig, expected swarm.PortConfig) {
|
func assertContains(t *testing.T, portConfigs []swarm.PortConfig, expected swarm.PortConfig) {
|
||||||
var contains = false
|
var contains = false
|
||||||
for _, portConfig := range portConfigs {
|
for _, portConfig := range portConfigs {
|
||||||
|
|
Loading…
Reference in New Issue