nat: introduce String method on PortMapping#111
Conversation
nat/nat.go
Outdated
| } | ||
|
|
||
| func (p *PortMapping) String() string { | ||
| return fmt.Sprintf("%s:%s:%s", p.Binding.HostIP, p.Binding.HostPort, p.Port) |
There was a problem hiding this comment.
We should use net.JoinHostPort() here, to account for IPv6 addresses; https://pkg.go.dev/net#JoinHostPort
e.g.;
| return fmt.Sprintf("%s:%s:%s", p.Binding.HostIP, p.Binding.HostPort, p.Port) | |
| return net.JoinHostPort(p.Binding.HostIP, p.Binding.HostPort+":"+p.Port.Port()) |
But I need to have a closer look, as there's many possible formats (ports mapped here can also have the protocol (e.g. 80/tcp), which may have to be taken into account here.
And of course we also have PortMap (which is a list of mapped ports) 😞
There was a problem hiding this comment.
Oh, I guess HostPort doesn't have the scheme, so maybe that part is not an issue
There was a problem hiding this comment.
Do we know if HostIP defaults to 0.0.0.0 (or :: IPv6)? 🤔
008e7cc to
a314a9d
Compare
7f68fd5 to
a2b6795
Compare
|
I rebased, and pushed some changes;
diff --git a/nat/nat.go b/nat/nat.go
index 5b53382..6c80825 100644
--- a/nat/nat.go
+++ b/nat/nat.go
@@ -151,7 +151,7 @@ type PortMapping struct {
}
func (p *PortMapping) String() string {
- return net.JoinHostPort(p.Binding.HostIP, fmt.Sprintf("%s:%s", p.Binding.HostPort, p.Port))
+ return net.JoinHostPort(p.Binding.HostIP, p.Binding.HostPort+":"+string(p.Port))
}
func splitParts(rawport string) (string, string, string) {
diff --git a/nat/nat_test.go b/nat/nat_test.go
index 3497643..571bf9e 100644
--- a/nat/nat_test.go
+++ b/nat/nat_test.go
@@ -699,14 +699,50 @@ func TestParseNetworkOptsSctp(t *testing.T) {
}
func TestStringer(t *testing.T) {
- spec := "192.168.1.100:8080:6000/udp"
- mappings, err := ParsePortSpec(spec)
- if err != nil {
- t.Fatal(err)
+ tests := []struct {
+ doc string
+ in string
+ expected string
+ }{
+ {
+ doc: "no host mapping",
+ in: ":8080:6000/tcp",
+ expected: ":8080:6000/tcp",
+ },
+ {
+ doc: "no proto",
+ in: "192.168.1.100:8080:6000",
+ expected: "192.168.1.100:8080:6000/tcp",
+ },
+ {
+ doc: "ipv4 mapping",
+ in: "192.168.1.100:8080:6000/udp",
+ expected: "192.168.1.100:8080:6000/udp",
+ },
+ {
+ doc: "ipv6 mapping",
+ in: "[::1]:8080:6000/udp",
+ expected: "[::1]:8080:6000/udp",
+ },
+ {
+ doc: "ipv6 legacy mapping",
+ in: "::1:8080:6000/udp",
+ expected: "[::1]:8080:6000/udp",
+ },
}
- for _, m := range mappings {
- if m.String() != spec {
- t.Fail()
- }
+ for _, tc := range tests {
+ t.Run(tc.doc, func(t *testing.T) {
+ mappings, err := ParsePortSpec(tc.in)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(mappings) != 1 {
+ // All tests produce a single mapping
+ t.Fatalf("Expected 1 got %d", len(mappings))
+ }
+ if actual := mappings[0].String(); actual != tc.expected {
+ t.Errorf("Expected %s got %s", tc.expected, actual)
+ }
+ })
}
}
--
2.44.0 |
| } | ||
| } | ||
|
|
||
| func TestStringer(t *testing.T) { |
There was a problem hiding this comment.
Maybe worth adding an in with a missing port, just to check it doesn't come out as a zero or something.
For maximum evil, perhaps ::::80 -> [::]::80/tcp?
There was a problem hiding this comment.
OK; added some evil permutations 👍
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
a2b6795 to
d630407
Compare
This introduce
PortMapping.String()for (some) symmetry withParsePortSpec