Browse code

Move ParseDockerDaemonHost to opts/ package.

This function was only being used from a single place opts/opts.go. This
change moves it from a incohesive package (parsers) to the single place it
is used.

Also made a bunch of the helper methods private because they are not used
by any external modules.

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2015/12/16 10:53:17
Showing 6 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,146 @@
0
+package opts
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+	"net/url"
6
+	"runtime"
7
+	"strconv"
8
+	"strings"
9
+)
10
+
11
+var (
12
+	// DefaultHTTPPort Default HTTP Port used if only the protocol is provided to -H flag e.g. docker daemon -H tcp://
13
+	// TODO Windows. DefaultHTTPPort is only used on Windows if a -H parameter
14
+	// is not supplied. A better longer term solution would be to use a named
15
+	// pipe as the default on the Windows daemon.
16
+	// These are the IANA registered port numbers for use with Docker
17
+	// see http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=docker
18
+	DefaultHTTPPort = 2375 // Default HTTP Port
19
+	// DefaultTLSHTTPPort Default HTTP Port used when TLS enabled
20
+	DefaultTLSHTTPPort = 2376 // Default TLS encrypted HTTP Port
21
+	// DefaultUnixSocket Path for the unix socket.
22
+	// Docker daemon by default always listens on the default unix socket
23
+	DefaultUnixSocket = "/var/run/docker.sock"
24
+	// DefaultTCPHost constant defines the default host string used by docker on Windows
25
+	DefaultTCPHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort)
26
+	// DefaultTLSHost constant defines the default host string used by docker for TLS sockets
27
+	DefaultTLSHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultTLSHTTPPort)
28
+)
29
+
30
+// ValidateHost validates that the specified string is a valid host and returns it.
31
+func ValidateHost(val string) (string, error) {
32
+	_, err := parseDockerDaemonHost(DefaultTCPHost, DefaultTLSHost, DefaultUnixSocket, "", val)
33
+	if err != nil {
34
+		return val, err
35
+	}
36
+	// Note: unlike most flag validators, we don't return the mutated value here
37
+	//       we need to know what the user entered later (using ParseHost) to adjust for tls
38
+	return val, nil
39
+}
40
+
41
+// ParseHost and set defaults for a Daemon host string
42
+func ParseHost(defaultHost, val string) (string, error) {
43
+	host, err := parseDockerDaemonHost(DefaultTCPHost, DefaultTLSHost, DefaultUnixSocket, defaultHost, val)
44
+	if err != nil {
45
+		return val, err
46
+	}
47
+	return host, nil
48
+}
49
+
50
+// parseDockerDaemonHost parses the specified address and returns an address that will be used as the host.
51
+// Depending of the address specified, will use the defaultTCPAddr or defaultUnixAddr
52
+// defaultUnixAddr must be a absolute file path (no `unix://` prefix)
53
+// defaultTCPAddr must be the full `tcp://host:port` form
54
+func parseDockerDaemonHost(defaultTCPAddr, defaultTLSHost, defaultUnixAddr, defaultAddr, addr string) (string, error) {
55
+	addr = strings.TrimSpace(addr)
56
+	if addr == "" {
57
+		if defaultAddr == defaultTLSHost {
58
+			return defaultTLSHost, nil
59
+		}
60
+		if runtime.GOOS != "windows" {
61
+			return fmt.Sprintf("unix://%s", defaultUnixAddr), nil
62
+		}
63
+		return defaultTCPAddr, nil
64
+	}
65
+	addrParts := strings.Split(addr, "://")
66
+	if len(addrParts) == 1 {
67
+		addrParts = []string{"tcp", addrParts[0]}
68
+	}
69
+
70
+	switch addrParts[0] {
71
+	case "tcp":
72
+		return parseTCPAddr(addrParts[1], defaultTCPAddr)
73
+	case "unix":
74
+		return parseUnixAddr(addrParts[1], defaultUnixAddr)
75
+	case "fd":
76
+		return addr, nil
77
+	default:
78
+		return "", fmt.Errorf("Invalid bind address format: %s", addr)
79
+	}
80
+}
81
+
82
+// parseUnixAddr parses and validates that the specified address is a valid UNIX
83
+// socket address. It returns a formatted UNIX socket address, either using the
84
+// address parsed from addr, or the contents of defaultAddr if addr is a blank
85
+// string.
86
+func parseUnixAddr(addr string, defaultAddr string) (string, error) {
87
+	addr = strings.TrimPrefix(addr, "unix://")
88
+	if strings.Contains(addr, "://") {
89
+		return "", fmt.Errorf("Invalid proto, expected unix: %s", addr)
90
+	}
91
+	if addr == "" {
92
+		addr = defaultAddr
93
+	}
94
+	return fmt.Sprintf("unix://%s", addr), nil
95
+}
96
+
97
+// parseTCPAddr parses and validates that the specified address is a valid TCP
98
+// address. It returns a formatted TCP address, either using the address parsed
99
+// from tryAddr, or the contents of defaultAddr if tryAddr is a blank string.
100
+// tryAddr is expected to have already been Trim()'d
101
+// defaultAddr must be in the full `tcp://host:port` form
102
+func parseTCPAddr(tryAddr string, defaultAddr string) (string, error) {
103
+	if tryAddr == "" || tryAddr == "tcp://" {
104
+		return defaultAddr, nil
105
+	}
106
+	addr := strings.TrimPrefix(tryAddr, "tcp://")
107
+	if strings.Contains(addr, "://") || addr == "" {
108
+		return "", fmt.Errorf("Invalid proto, expected tcp: %s", tryAddr)
109
+	}
110
+
111
+	defaultAddr = strings.TrimPrefix(defaultAddr, "tcp://")
112
+	defaultHost, defaultPort, err := net.SplitHostPort(defaultAddr)
113
+	if err != nil {
114
+		return "", err
115
+	}
116
+	// url.Parse fails for trailing colon on IPv6 brackets on Go 1.5, but
117
+	// not 1.4. See https://github.com/golang/go/issues/12200 and
118
+	// https://github.com/golang/go/issues/6530.
119
+	if strings.HasSuffix(addr, "]:") {
120
+		addr += defaultPort
121
+	}
122
+
123
+	u, err := url.Parse("tcp://" + addr)
124
+	if err != nil {
125
+		return "", err
126
+	}
127
+
128
+	host, port, err := net.SplitHostPort(u.Host)
129
+	if err != nil {
130
+		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
131
+	}
132
+
133
+	if host == "" {
134
+		host = defaultHost
135
+	}
136
+	if port == "" {
137
+		port = defaultPort
138
+	}
139
+	p, err := strconv.Atoi(port)
140
+	if err != nil && p == 0 {
141
+		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
142
+	}
143
+
144
+	return fmt.Sprintf("tcp://%s%s", net.JoinHostPort(host, port), u.Path), nil
145
+}
0 146
new file mode 100644
... ...
@@ -0,0 +1,164 @@
0
+package opts
1
+
2
+import (
3
+	"runtime"
4
+	"testing"
5
+)
6
+
7
+func TestParseHost(t *testing.T) {
8
+	invalid := map[string]string{
9
+		"anything":              "Invalid bind address format: anything",
10
+		"something with spaces": "Invalid bind address format: something with spaces",
11
+		"://":                "Invalid bind address format: ://",
12
+		"unknown://":         "Invalid bind address format: unknown://",
13
+		"tcp://:port":        "Invalid bind address format: :port",
14
+		"tcp://invalid":      "Invalid bind address format: invalid",
15
+		"tcp://invalid:port": "Invalid bind address format: invalid:port",
16
+	}
17
+	const defaultHTTPHost = "tcp://127.0.0.1:2375"
18
+	var defaultHOST = "unix:///var/run/docker.sock"
19
+
20
+	if runtime.GOOS == "windows" {
21
+		defaultHOST = defaultHTTPHost
22
+	}
23
+	valid := map[string]string{
24
+		"":                         defaultHOST,
25
+		"fd://":                    "fd://",
26
+		"fd://something":           "fd://something",
27
+		"tcp://host:":              "tcp://host:2375",
28
+		"tcp://":                   "tcp://localhost:2375",
29
+		"tcp://:2375":              "tcp://localhost:2375", // default ip address
30
+		"tcp://:2376":              "tcp://localhost:2376", // default ip address
31
+		"tcp://0.0.0.0:8080":       "tcp://0.0.0.0:8080",
32
+		"tcp://192.168.0.0:12000":  "tcp://192.168.0.0:12000",
33
+		"tcp://192.168:8080":       "tcp://192.168:8080",
34
+		"tcp://0.0.0.0:1234567890": "tcp://0.0.0.0:1234567890", // yeah it's valid :P
35
+		"tcp://docker.com:2375":    "tcp://docker.com:2375",
36
+		"unix://":                  "unix:///var/run/docker.sock", // default unix:// value
37
+		"unix://path/to/socket":    "unix://path/to/socket",
38
+	}
39
+
40
+	for value, errorMessage := range invalid {
41
+		if _, err := ParseHost(defaultHTTPHost, value); err == nil || err.Error() != errorMessage {
42
+			t.Fatalf("Expected an error for %v with [%v], got [%v]", value, errorMessage, err)
43
+		}
44
+	}
45
+	for value, expected := range valid {
46
+		if actual, err := ParseHost(defaultHTTPHost, value); err != nil || actual != expected {
47
+			t.Fatalf("Expected for %v [%v], got [%v, %v]", value, expected, actual, err)
48
+		}
49
+	}
50
+}
51
+
52
+func TestParseDockerDaemonHost(t *testing.T) {
53
+	var (
54
+		defaultHTTPHost  = "tcp://localhost:2375"
55
+		defaultHTTPSHost = "tcp://localhost:2376"
56
+		defaultUnix      = "/var/run/docker.sock"
57
+		defaultHOST      = "unix:///var/run/docker.sock"
58
+	)
59
+	if runtime.GOOS == "windows" {
60
+		defaultHOST = defaultHTTPHost
61
+	}
62
+	invalids := map[string]string{
63
+		"0.0.0.0":                       "Invalid bind address format: 0.0.0.0",
64
+		"tcp:a.b.c.d":                   "Invalid bind address format: tcp:a.b.c.d",
65
+		"tcp:a.b.c.d/path":              "Invalid bind address format: tcp:a.b.c.d/path",
66
+		"udp://127.0.0.1":               "Invalid bind address format: udp://127.0.0.1",
67
+		"udp://127.0.0.1:2375":          "Invalid bind address format: udp://127.0.0.1:2375",
68
+		"tcp://unix:///run/docker.sock": "Invalid bind address format: unix",
69
+		"tcp":  "Invalid bind address format: tcp",
70
+		"unix": "Invalid bind address format: unix",
71
+		"fd":   "Invalid bind address format: fd",
72
+	}
73
+	valids := map[string]string{
74
+		"0.0.0.1:":                    "tcp://0.0.0.1:2375",
75
+		"0.0.0.1:5555":                "tcp://0.0.0.1:5555",
76
+		"0.0.0.1:5555/path":           "tcp://0.0.0.1:5555/path",
77
+		"[::1]:":                      "tcp://[::1]:2375",
78
+		"[::1]:5555/path":             "tcp://[::1]:5555/path",
79
+		"[0:0:0:0:0:0:0:1]:":          "tcp://[0:0:0:0:0:0:0:1]:2375",
80
+		"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
81
+		":6666":                   "tcp://localhost:6666",
82
+		":6666/path":              "tcp://localhost:6666/path",
83
+		"":                        defaultHOST,
84
+		" ":                       defaultHOST,
85
+		"  ":                      defaultHOST,
86
+		"tcp://":                  defaultHTTPHost,
87
+		"tcp://:7777":             "tcp://localhost:7777",
88
+		"tcp://:7777/path":        "tcp://localhost:7777/path",
89
+		" tcp://:7777/path ":      "tcp://localhost:7777/path",
90
+		"unix:///run/docker.sock": "unix:///run/docker.sock",
91
+		"unix://":                 "unix:///var/run/docker.sock",
92
+		"fd://":                   "fd://",
93
+		"fd://something":          "fd://something",
94
+		"localhost:":              "tcp://localhost:2375",
95
+		"localhost:5555":          "tcp://localhost:5555",
96
+		"localhost:5555/path":     "tcp://localhost:5555/path",
97
+	}
98
+	for invalidAddr, expectedError := range invalids {
99
+		if addr, err := parseDockerDaemonHost(defaultHTTPHost, defaultHTTPSHost, defaultUnix, "", invalidAddr); err == nil || err.Error() != expectedError {
100
+			t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
101
+		}
102
+	}
103
+	for validAddr, expectedAddr := range valids {
104
+		if addr, err := parseDockerDaemonHost(defaultHTTPHost, defaultHTTPSHost, defaultUnix, "", validAddr); err != nil || addr != expectedAddr {
105
+			t.Errorf("%v -> expected %v, got (%v) addr (%v)", validAddr, expectedAddr, err, addr)
106
+		}
107
+	}
108
+}
109
+
110
+func TestParseTCP(t *testing.T) {
111
+	var (
112
+		defaultHTTPHost = "tcp://127.0.0.1:2376"
113
+	)
114
+	invalids := map[string]string{
115
+		"0.0.0.0":              "Invalid bind address format: 0.0.0.0",
116
+		"tcp:a.b.c.d":          "Invalid bind address format: tcp:a.b.c.d",
117
+		"tcp:a.b.c.d/path":     "Invalid bind address format: tcp:a.b.c.d/path",
118
+		"udp://127.0.0.1":      "Invalid proto, expected tcp: udp://127.0.0.1",
119
+		"udp://127.0.0.1:2375": "Invalid proto, expected tcp: udp://127.0.0.1:2375",
120
+	}
121
+	valids := map[string]string{
122
+		"":                            defaultHTTPHost,
123
+		"tcp://":                      defaultHTTPHost,
124
+		"0.0.0.1:":                    "tcp://0.0.0.1:2376",
125
+		"0.0.0.1:5555":                "tcp://0.0.0.1:5555",
126
+		"0.0.0.1:5555/path":           "tcp://0.0.0.1:5555/path",
127
+		":6666":                       "tcp://127.0.0.1:6666",
128
+		":6666/path":                  "tcp://127.0.0.1:6666/path",
129
+		"tcp://:7777":                 "tcp://127.0.0.1:7777",
130
+		"tcp://:7777/path":            "tcp://127.0.0.1:7777/path",
131
+		"[::1]:":                      "tcp://[::1]:2376",
132
+		"[::1]:5555":                  "tcp://[::1]:5555",
133
+		"[::1]:5555/path":             "tcp://[::1]:5555/path",
134
+		"[0:0:0:0:0:0:0:1]:":          "tcp://[0:0:0:0:0:0:0:1]:2376",
135
+		"[0:0:0:0:0:0:0:1]:5555":      "tcp://[0:0:0:0:0:0:0:1]:5555",
136
+		"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
137
+		"localhost:":                  "tcp://localhost:2376",
138
+		"localhost:5555":              "tcp://localhost:5555",
139
+		"localhost:5555/path":         "tcp://localhost:5555/path",
140
+	}
141
+	for invalidAddr, expectedError := range invalids {
142
+		if addr, err := parseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || err.Error() != expectedError {
143
+			t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
144
+		}
145
+	}
146
+	for validAddr, expectedAddr := range valids {
147
+		if addr, err := parseTCPAddr(validAddr, defaultHTTPHost); err != nil || addr != expectedAddr {
148
+			t.Errorf("%v -> expected %v, got %v and addr %v", validAddr, expectedAddr, err, addr)
149
+		}
150
+	}
151
+}
152
+
153
+func TestParseInvalidUnixAddrInvalid(t *testing.T) {
154
+	if _, err := parseUnixAddr("tcp://127.0.0.1", "unix:///var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
155
+		t.Fatalf("Expected an error, got %v", err)
156
+	}
157
+	if _, err := parseUnixAddr("unix://tcp://127.0.0.1", "/var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
158
+		t.Fatalf("Expected an error, got %v", err)
159
+	}
160
+	if v, err := parseUnixAddr("", "/var/run/docker.sock"); err != nil || v != "unix:///var/run/docker.sock" {
161
+		t.Fatalf("Expected an %v, got %v", v, "unix:///var/run/docker.sock")
162
+	}
163
+}
... ...
@@ -17,22 +17,6 @@ import (
17 17
 var (
18 18
 	alphaRegexp  = regexp.MustCompile(`[a-zA-Z]`)
19 19
 	domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
20
-	// DefaultHTTPPort Default HTTP Port used if only the protocol is provided to -H flag e.g. docker daemon -H tcp://
21
-	// TODO Windows. DefaultHTTPPort is only used on Windows if a -H parameter
22
-	// is not supplied. A better longer term solution would be to use a named
23
-	// pipe as the default on the Windows daemon.
24
-	// These are the IANA registered port numbers for use with Docker
25
-	// see http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=docker
26
-	DefaultHTTPPort = 2375 // Default HTTP Port
27
-	// DefaultTLSHTTPPort Default HTTP Port used when TLS enabled
28
-	DefaultTLSHTTPPort = 2376 // Default TLS encrypted HTTP Port
29
-	// DefaultUnixSocket Path for the unix socket.
30
-	// Docker daemon by default always listens on the default unix socket
31
-	DefaultUnixSocket = "/var/run/docker.sock"
32
-	// DefaultTCPHost constant defines the default host string used by docker on Windows
33
-	DefaultTCPHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort)
34
-	// DefaultTLSHost constant defines the default host string used by docker for TLS sockets
35
-	DefaultTLSHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultTLSHTTPPort)
36 20
 )
37 21
 
38 22
 // ListOpts holds a list of values and a validation function.
... ...
@@ -391,26 +375,6 @@ func ValidateLabel(val string) (string, error) {
391 391
 	return val, nil
392 392
 }
393 393
 
394
-// ValidateHost validates that the specified string is a valid host and returns it.
395
-func ValidateHost(val string) (string, error) {
396
-	_, err := parsers.ParseDockerDaemonHost(DefaultTCPHost, DefaultTLSHost, DefaultUnixSocket, "", val)
397
-	if err != nil {
398
-		return val, err
399
-	}
400
-	// Note: unlike most flag validators, we don't return the mutated value here
401
-	//       we need to know what the user entered later (using ParseHost) to adjust for tls
402
-	return val, nil
403
-}
404
-
405
-// ParseHost and set defaults for a Daemon host string
406
-func ParseHost(defaultHost, val string) (string, error) {
407
-	host, err := parsers.ParseDockerDaemonHost(DefaultTCPHost, DefaultTLSHost, DefaultUnixSocket, defaultHost, val)
408
-	if err != nil {
409
-		return val, err
410
-	}
411
-	return host, nil
412
-}
413
-
414 394
 func doesEnvExist(name string) bool {
415 395
 	for _, entry := range os.Environ() {
416 396
 		parts := strings.SplitN(entry, "=", 2)
... ...
@@ -3,7 +3,6 @@ package opts
3 3
 import (
4 4
 	"fmt"
5 5
 	"os"
6
-	"runtime"
7 6
 	"strings"
8 7
 	"testing"
9 8
 )
... ...
@@ -372,51 +371,6 @@ func TestValidateLabel(t *testing.T) {
372 372
 	}
373 373
 }
374 374
 
375
-func TestParseHost(t *testing.T) {
376
-	invalid := map[string]string{
377
-		"anything":              "Invalid bind address format: anything",
378
-		"something with spaces": "Invalid bind address format: something with spaces",
379
-		"://":                "Invalid bind address format: ://",
380
-		"unknown://":         "Invalid bind address format: unknown://",
381
-		"tcp://:port":        "Invalid bind address format: :port",
382
-		"tcp://invalid":      "Invalid bind address format: invalid",
383
-		"tcp://invalid:port": "Invalid bind address format: invalid:port",
384
-	}
385
-	const defaultHTTPHost = "tcp://127.0.0.1:2375"
386
-	var defaultHOST = "unix:///var/run/docker.sock"
387
-
388
-	if runtime.GOOS == "windows" {
389
-		defaultHOST = defaultHTTPHost
390
-	}
391
-	valid := map[string]string{
392
-		"":                         defaultHOST,
393
-		"fd://":                    "fd://",
394
-		"fd://something":           "fd://something",
395
-		"tcp://host:":              "tcp://host:2375",
396
-		"tcp://":                   "tcp://localhost:2375",
397
-		"tcp://:2375":              "tcp://localhost:2375", // default ip address
398
-		"tcp://:2376":              "tcp://localhost:2376", // default ip address
399
-		"tcp://0.0.0.0:8080":       "tcp://0.0.0.0:8080",
400
-		"tcp://192.168.0.0:12000":  "tcp://192.168.0.0:12000",
401
-		"tcp://192.168:8080":       "tcp://192.168:8080",
402
-		"tcp://0.0.0.0:1234567890": "tcp://0.0.0.0:1234567890", // yeah it's valid :P
403
-		"tcp://docker.com:2375":    "tcp://docker.com:2375",
404
-		"unix://":                  "unix:///var/run/docker.sock", // default unix:// value
405
-		"unix://path/to/socket":    "unix://path/to/socket",
406
-	}
407
-
408
-	for value, errorMessage := range invalid {
409
-		if _, err := ParseHost(defaultHTTPHost, value); err == nil || err.Error() != errorMessage {
410
-			t.Fatalf("Expected an error for %v with [%v], got [%v]", value, errorMessage, err)
411
-		}
412
-	}
413
-	for value, expected := range valid {
414
-		if actual, err := ParseHost(defaultHTTPHost, value); err != nil || actual != expected {
415
-			t.Fatalf("Expected for %v [%v], got [%v, %v]", value, expected, actual, err)
416
-		}
417
-	}
418
-}
419
-
420 375
 func logOptsValidator(val string) (string, error) {
421 376
 	allowedKeys := map[string]string{"max-size": "1", "max-file": "2"}
422 377
 	vals := strings.Split(val, "=")
... ...
@@ -5,111 +5,11 @@ package parsers
5 5
 
6 6
 import (
7 7
 	"fmt"
8
-	"net"
9
-	"net/url"
10 8
 	"path"
11
-	"runtime"
12 9
 	"strconv"
13 10
 	"strings"
14 11
 )
15 12
 
16
-// ParseDockerDaemonHost parses the specified address and returns an address that will be used as the host.
17
-// Depending of the address specified, will use the defaultTCPAddr or defaultUnixAddr
18
-// defaultUnixAddr must be a absolute file path (no `unix://` prefix)
19
-// defaultTCPAddr must be the full `tcp://host:port` form
20
-func ParseDockerDaemonHost(defaultTCPAddr, defaultTLSHost, defaultUnixAddr, defaultAddr, addr string) (string, error) {
21
-	addr = strings.TrimSpace(addr)
22
-	if addr == "" {
23
-		if defaultAddr == defaultTLSHost {
24
-			return defaultTLSHost, nil
25
-		}
26
-		if runtime.GOOS != "windows" {
27
-			return fmt.Sprintf("unix://%s", defaultUnixAddr), nil
28
-		}
29
-		return defaultTCPAddr, nil
30
-	}
31
-	addrParts := strings.Split(addr, "://")
32
-	if len(addrParts) == 1 {
33
-		addrParts = []string{"tcp", addrParts[0]}
34
-	}
35
-
36
-	switch addrParts[0] {
37
-	case "tcp":
38
-		return ParseTCPAddr(addrParts[1], defaultTCPAddr)
39
-	case "unix":
40
-		return ParseUnixAddr(addrParts[1], defaultUnixAddr)
41
-	case "fd":
42
-		return addr, nil
43
-	default:
44
-		return "", fmt.Errorf("Invalid bind address format: %s", addr)
45
-	}
46
-}
47
-
48
-// ParseUnixAddr parses and validates that the specified address is a valid UNIX
49
-// socket address. It returns a formatted UNIX socket address, either using the
50
-// address parsed from addr, or the contents of defaultAddr if addr is a blank
51
-// string.
52
-func ParseUnixAddr(addr string, defaultAddr string) (string, error) {
53
-	addr = strings.TrimPrefix(addr, "unix://")
54
-	if strings.Contains(addr, "://") {
55
-		return "", fmt.Errorf("Invalid proto, expected unix: %s", addr)
56
-	}
57
-	if addr == "" {
58
-		addr = defaultAddr
59
-	}
60
-	return fmt.Sprintf("unix://%s", addr), nil
61
-}
62
-
63
-// ParseTCPAddr parses and validates that the specified address is a valid TCP
64
-// address. It returns a formatted TCP address, either using the address parsed
65
-// from tryAddr, or the contents of defaultAddr if tryAddr is a blank string.
66
-// tryAddr is expected to have already been Trim()'d
67
-// defaultAddr must be in the full `tcp://host:port` form
68
-func ParseTCPAddr(tryAddr string, defaultAddr string) (string, error) {
69
-	if tryAddr == "" || tryAddr == "tcp://" {
70
-		return defaultAddr, nil
71
-	}
72
-	addr := strings.TrimPrefix(tryAddr, "tcp://")
73
-	if strings.Contains(addr, "://") || addr == "" {
74
-		return "", fmt.Errorf("Invalid proto, expected tcp: %s", tryAddr)
75
-	}
76
-
77
-	defaultAddr = strings.TrimPrefix(defaultAddr, "tcp://")
78
-	defaultHost, defaultPort, err := net.SplitHostPort(defaultAddr)
79
-	if err != nil {
80
-		return "", err
81
-	}
82
-	// url.Parse fails for trailing colon on IPv6 brackets on Go 1.5, but
83
-	// not 1.4. See https://github.com/golang/go/issues/12200 and
84
-	// https://github.com/golang/go/issues/6530.
85
-	if strings.HasSuffix(addr, "]:") {
86
-		addr += defaultPort
87
-	}
88
-
89
-	u, err := url.Parse("tcp://" + addr)
90
-	if err != nil {
91
-		return "", err
92
-	}
93
-
94
-	host, port, err := net.SplitHostPort(u.Host)
95
-	if err != nil {
96
-		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
97
-	}
98
-
99
-	if host == "" {
100
-		host = defaultHost
101
-	}
102
-	if port == "" {
103
-		port = defaultPort
104
-	}
105
-	p, err := strconv.Atoi(port)
106
-	if err != nil && p == 0 {
107
-		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
108
-	}
109
-
110
-	return fmt.Sprintf("tcp://%s%s", net.JoinHostPort(host, port), u.Path), nil
111
-}
112
-
113 13
 // PartParser parses and validates the specified string (data) using the specified template
114 14
 // e.g. ip:public:private -> 192.168.0.1:80:8000
115 15
 func PartParser(template, data string) (map[string]string, error) {
... ...
@@ -2,124 +2,10 @@ package parsers
2 2
 
3 3
 import (
4 4
 	"reflect"
5
-	"runtime"
6 5
 	"strings"
7 6
 	"testing"
8 7
 )
9 8
 
10
-func TestParseDockerDaemonHost(t *testing.T) {
11
-	var (
12
-		defaultHTTPHost  = "tcp://localhost:2375"
13
-		defaultHTTPSHost = "tcp://localhost:2376"
14
-		defaultUnix      = "/var/run/docker.sock"
15
-		defaultHOST      = "unix:///var/run/docker.sock"
16
-	)
17
-	if runtime.GOOS == "windows" {
18
-		defaultHOST = defaultHTTPHost
19
-	}
20
-	invalids := map[string]string{
21
-		"0.0.0.0":                       "Invalid bind address format: 0.0.0.0",
22
-		"tcp:a.b.c.d":                   "Invalid bind address format: tcp:a.b.c.d",
23
-		"tcp:a.b.c.d/path":              "Invalid bind address format: tcp:a.b.c.d/path",
24
-		"udp://127.0.0.1":               "Invalid bind address format: udp://127.0.0.1",
25
-		"udp://127.0.0.1:2375":          "Invalid bind address format: udp://127.0.0.1:2375",
26
-		"tcp://unix:///run/docker.sock": "Invalid bind address format: unix",
27
-		"tcp":  "Invalid bind address format: tcp",
28
-		"unix": "Invalid bind address format: unix",
29
-		"fd":   "Invalid bind address format: fd",
30
-	}
31
-	valids := map[string]string{
32
-		"0.0.0.1:":                    "tcp://0.0.0.1:2375",
33
-		"0.0.0.1:5555":                "tcp://0.0.0.1:5555",
34
-		"0.0.0.1:5555/path":           "tcp://0.0.0.1:5555/path",
35
-		"[::1]:":                      "tcp://[::1]:2375",
36
-		"[::1]:5555/path":             "tcp://[::1]:5555/path",
37
-		"[0:0:0:0:0:0:0:1]:":          "tcp://[0:0:0:0:0:0:0:1]:2375",
38
-		"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
39
-		":6666":                   "tcp://localhost:6666",
40
-		":6666/path":              "tcp://localhost:6666/path",
41
-		"":                        defaultHOST,
42
-		" ":                       defaultHOST,
43
-		"  ":                      defaultHOST,
44
-		"tcp://":                  defaultHTTPHost,
45
-		"tcp://:7777":             "tcp://localhost:7777",
46
-		"tcp://:7777/path":        "tcp://localhost:7777/path",
47
-		" tcp://:7777/path ":      "tcp://localhost:7777/path",
48
-		"unix:///run/docker.sock": "unix:///run/docker.sock",
49
-		"unix://":                 "unix:///var/run/docker.sock",
50
-		"fd://":                   "fd://",
51
-		"fd://something":          "fd://something",
52
-		"localhost:":              "tcp://localhost:2375",
53
-		"localhost:5555":          "tcp://localhost:5555",
54
-		"localhost:5555/path":     "tcp://localhost:5555/path",
55
-	}
56
-	for invalidAddr, expectedError := range invalids {
57
-		if addr, err := ParseDockerDaemonHost(defaultHTTPHost, defaultHTTPSHost, defaultUnix, "", invalidAddr); err == nil || err.Error() != expectedError {
58
-			t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
59
-		}
60
-	}
61
-	for validAddr, expectedAddr := range valids {
62
-		if addr, err := ParseDockerDaemonHost(defaultHTTPHost, defaultHTTPSHost, defaultUnix, "", validAddr); err != nil || addr != expectedAddr {
63
-			t.Errorf("%v -> expected %v, got (%v) addr (%v)", validAddr, expectedAddr, err, addr)
64
-		}
65
-	}
66
-}
67
-
68
-func TestParseTCP(t *testing.T) {
69
-	var (
70
-		defaultHTTPHost = "tcp://127.0.0.1:2376"
71
-	)
72
-	invalids := map[string]string{
73
-		"0.0.0.0":              "Invalid bind address format: 0.0.0.0",
74
-		"tcp:a.b.c.d":          "Invalid bind address format: tcp:a.b.c.d",
75
-		"tcp:a.b.c.d/path":     "Invalid bind address format: tcp:a.b.c.d/path",
76
-		"udp://127.0.0.1":      "Invalid proto, expected tcp: udp://127.0.0.1",
77
-		"udp://127.0.0.1:2375": "Invalid proto, expected tcp: udp://127.0.0.1:2375",
78
-	}
79
-	valids := map[string]string{
80
-		"":                            defaultHTTPHost,
81
-		"tcp://":                      defaultHTTPHost,
82
-		"0.0.0.1:":                    "tcp://0.0.0.1:2376",
83
-		"0.0.0.1:5555":                "tcp://0.0.0.1:5555",
84
-		"0.0.0.1:5555/path":           "tcp://0.0.0.1:5555/path",
85
-		":6666":                       "tcp://127.0.0.1:6666",
86
-		":6666/path":                  "tcp://127.0.0.1:6666/path",
87
-		"tcp://:7777":                 "tcp://127.0.0.1:7777",
88
-		"tcp://:7777/path":            "tcp://127.0.0.1:7777/path",
89
-		"[::1]:":                      "tcp://[::1]:2376",
90
-		"[::1]:5555":                  "tcp://[::1]:5555",
91
-		"[::1]:5555/path":             "tcp://[::1]:5555/path",
92
-		"[0:0:0:0:0:0:0:1]:":          "tcp://[0:0:0:0:0:0:0:1]:2376",
93
-		"[0:0:0:0:0:0:0:1]:5555":      "tcp://[0:0:0:0:0:0:0:1]:5555",
94
-		"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
95
-		"localhost:":                  "tcp://localhost:2376",
96
-		"localhost:5555":              "tcp://localhost:5555",
97
-		"localhost:5555/path":         "tcp://localhost:5555/path",
98
-	}
99
-	for invalidAddr, expectedError := range invalids {
100
-		if addr, err := ParseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || err.Error() != expectedError {
101
-			t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
102
-		}
103
-	}
104
-	for validAddr, expectedAddr := range valids {
105
-		if addr, err := ParseTCPAddr(validAddr, defaultHTTPHost); err != nil || addr != expectedAddr {
106
-			t.Errorf("%v -> expected %v, got %v and addr %v", validAddr, expectedAddr, err, addr)
107
-		}
108
-	}
109
-}
110
-
111
-func TestParseInvalidUnixAddrInvalid(t *testing.T) {
112
-	if _, err := ParseUnixAddr("tcp://127.0.0.1", "unix:///var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
113
-		t.Fatalf("Expected an error, got %v", err)
114
-	}
115
-	if _, err := ParseUnixAddr("unix://tcp://127.0.0.1", "/var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
116
-		t.Fatalf("Expected an error, got %v", err)
117
-	}
118
-	if v, err := ParseUnixAddr("", "/var/run/docker.sock"); err != nil || v != "unix:///var/run/docker.sock" {
119
-		t.Fatalf("Expected an %v, got %v", v, "unix:///var/run/docker.sock")
120
-	}
121
-}
122
-
123 9
 func TestParseKeyValueOpt(t *testing.T) {
124 10
 	invalids := map[string]string{
125 11
 		"":    "Unable to parse key/value option: ",