@@ -5,37 +5,58 @@ import (
55 "errors"
66 "fmt"
77 "net"
8+ "net/netip"
89 "strconv"
910 "strings"
11+
12+ "github.com/moby/moby/api/types/network"
1013)
1114
1215// PortBinding represents a binding between a Host IP address and a Host Port
13- type PortBinding struct {
14- // HostIP is the host IP Address
15- HostIP string `json:"HostIp"`
16- // HostPort is the host port number
17- HostPort string
18- }
16+ //
17+ // Deprecated: Use [network.PortBinding] instead.
18+ type PortBinding = network.PortBinding
1919
2020// PortMap is a collection of PortBinding indexed by Port
21- type PortMap map [Port ][]PortBinding
21+ //
22+ // Deprecated: Use [network.PortMap] instead.
23+ type PortMap = network.PortMap
2224
2325// PortSet is a collection of structs indexed by Port
24- type PortSet map [Port ]struct {}
26+ //
27+ // Deprecated: Use [network.PortSet] instead.
28+ type PortSet = network.PortSet
2529
2630// Port is a string containing port number and protocol in the format "80/tcp"
27- type Port string
31+ //
32+ // Deprecated: Use [network.Port] or [network.PortRange] accordingly instead.
33+ type Port struct {
34+ network.PortRange
35+ }
2836
2937// NewPort creates a new instance of a Port given a protocol and port number or port range
3038func NewPort (proto , portOrRange string ) (Port , error ) {
31- start , end , err := parsePortRange (portOrRange )
39+ pr , err := network . ParsePortRange (portOrRange + "/" + proto )
3240 if err != nil {
33- return "" , err
41+ return Port {} , err
3442 }
35- if start == end {
36- return Port (fmt .Sprintf ("%d/%s" , start , proto )), nil
37- }
38- return Port (fmt .Sprintf ("%d-%d/%s" , start , end , proto )), nil
43+ return Port {pr }, nil
44+ }
45+
46+ // Port returns the port number of a Port
47+ func (p Port ) Port () string {
48+ return fmt .Sprintf ("%d" , p .Start ())
49+ }
50+
51+ // Int returns the port number of a Port as an int. It assumes [Port]
52+ // is valid, and returns 0 otherwise.
53+ func (p Port ) Int () int {
54+ return int (p .Start ())
55+ }
56+
57+ // Range returns the start/end port numbers of a Port range as ints
58+ func (p Port ) Range () (int , int , error ) {
59+ return int (p .Start ()), int (p .End ()), nil
3960}
4061
4162// ParsePort parses the port number string and returns an int
@@ -59,39 +80,6 @@ func ParsePortRangeToInt(rawPort string) (startPort, endPort int, _ error) {
5980 return parsePortRange (rawPort )
6081}
6182
62- // Proto returns the protocol of a Port
63- func (p Port ) Proto () string {
64- _ , proto , _ := strings .Cut (string (p ), "/" )
65- if proto == "" {
66- proto = "tcp"
67- }
68- return proto
69- }
70-
71- // Port returns the port number of a Port
72- func (p Port ) Port () string {
73- port , _ , _ := strings .Cut (string (p ), "/" )
74- return port
75- }
76-
77- // Int returns the port number of a Port as an int. It assumes [Port]
78- // is valid, and returns 0 otherwise.
79- func (p Port ) Int () int {
80- // We don't need to check for an error because we're going to
81- // assume that any error would have been found, and reported, in [NewPort]
82- port , _ := parsePortNumber (p .Port ())
83- return port
84- }
85-
86- // Range returns the start/end port numbers of a Port range as ints
87- func (p Port ) Range () (int , int , error ) {
88- portRange := p .Port ()
89- if portRange == "" {
90- return 0 , 0 , nil
91- }
92- return parsePortRange (portRange )
93- }
94-
9583// SplitProtoPort splits a port(range) and protocol, formatted as "<portnum>/[<proto>]"
9684// "<startport-endport>/[<proto>]". It returns an empty string for both if
9785// no port(range) is provided. If a port(range) is provided, but no protocol,
@@ -150,7 +138,13 @@ type PortMapping struct {
150138}
151139
152140func (p * PortMapping ) String () string {
153- return net .JoinHostPort (p .Binding .HostIP , p .Binding .HostPort + ":" + string (p .Port ))
141+ var host string
142+
143+ if p .Binding .HostIP != netip .IPv4Unspecified () {
144+ host = p .Binding .HostIP .String ()
145+ }
146+
147+ return net .JoinHostPort (host , p .Binding .HostPort + ":" + p .Port .String ())
154148}
155149
156150func splitParts (rawport string ) (hostIP , hostPort , containerPort string ) {
@@ -228,9 +222,28 @@ func ParsePortSpec(rawPort string) ([]PortMapping, error) {
228222 hPort += "-" + strconv .Itoa (endHostPort )
229223 }
230224 }
225+ port , err := network .ParsePortRange (fmt .Sprintf ("%d/%s" , startPort + i , proto ))
226+ if err != nil {
227+ return nil , err
228+ }
229+
230+ var addr netip.Addr
231+ if strings .Count (ip , ":" ) >= 2 {
232+ addr = netip .IPv6Unspecified ()
233+ } else {
234+ addr = netip .IPv4Unspecified ()
235+ }
236+
237+ if ip != "" {
238+ addr , err = netip .ParseAddr (ip )
239+ if err != nil {
240+ return nil , err
241+ }
242+ }
243+
231244 ports = append (ports , PortMapping {
232- Port : Port ( strconv . Itoa ( startPort + i ) + "/" + proto ) ,
233- Binding : PortBinding {HostIP : ip , HostPort : hPort },
245+ Port : Port { port } ,
246+ Binding : PortBinding {HostIP : addr , HostPort : hPort },
234247 })
235248 }
236249 return ports , nil
0 commit comments