diff --git a/pkg/flags/addrs.go b/pkg/flags/addrs.go deleted file mode 100644 index b9892831a..000000000 --- a/pkg/flags/addrs.go +++ /dev/null @@ -1,51 +0,0 @@ -package flags - -import ( - "errors" - "net" - "strconv" - "strings" -) - -// Addrs implements the flag.Value interface to allow users to define multiple -// listen addresses on the command-line -type Addrs []string - -// Set parses a command line set of listen addresses, formatted like: -// 127.0.0.1:7001,10.1.1.2:80 -func (as *Addrs) Set(s string) error { - parsed := make([]string, 0) - for _, in := range strings.Split(s, ",") { - a := strings.TrimSpace(in) - if err := validateAddr(a); err != nil { - return err - } - parsed = append(parsed, a) - } - if len(parsed) == 0 { - return errors.New("no valid addresses given!") - } - *as = parsed - return nil -} - -func (as *Addrs) String() string { - return strings.Join(*as, ",") -} - -// validateAddr ensures that the provided string is a valid address. Valid -// addresses are of the form IP:port. -// Returns an error if the address is invalid, else nil. -func validateAddr(s string) error { - parts := strings.SplitN(s, ":", 2) - if len(parts) != 2 { - return errors.New("bad format in address specification") - } - if net.ParseIP(parts[0]) == nil { - return errors.New("bad IP in address specification") - } - if _, err := strconv.Atoi(parts[1]); err != nil { - return errors.New("bad port in address specification") - } - return nil -} diff --git a/pkg/flags/addrs_test.go b/pkg/flags/addrs_test.go deleted file mode 100644 index 092a5504d..000000000 --- a/pkg/flags/addrs_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package flags - -import ( - "testing" -) - -func TestBadValidateAddr(t *testing.T) { - tests := []string{ - // bad IP specification - ":4001", - "127.0:8080", - "123:456", - // bad port specification - "127.0.0.1:foo", - "127.0.0.1:", - // unix sockets not supported - "unix://", - "unix://tmp/etcd.sock", - // bad strings - "somewhere", - "234#$", - "file://foo/bar", - "http://hello", - } - for i, in := range tests { - if err := validateAddr(in); err == nil { - t.Errorf(`#%d: unexpected nil error for in=%q`, i, in) - } - } -} - -func TestValidateAddr(t *testing.T) { - tests := []string{ - "1.2.3.4:8080", - "10.1.1.1:80", - } - for i, in := range tests { - if err := validateAddr(in); err != nil { - t.Errorf("#%d: err=%v, want nil for in=%q", i, err, in) - } - } -} diff --git a/pkg/flags/ipaddressport.go b/pkg/flags/ipaddressport.go new file mode 100644 index 000000000..41ad15210 --- /dev/null +++ b/pkg/flags/ipaddressport.go @@ -0,0 +1,43 @@ +package flags + +import ( + "errors" + "fmt" + "net" + "strconv" + "strings" +) + +// IPAddressPort implements the flag.Value interface. The argument +// is validated as "ip:port". +type IPAddressPort struct { + IP string + Port int +} + +func (a *IPAddressPort) Set(arg string) error { + arg = strings.TrimSpace(arg) + + parts := strings.SplitN(arg, ":", 2) + if len(parts) != 2 { + return errors.New("bad format in address specification") + } + + if net.ParseIP(parts[0]) == nil { + return errors.New("bad IP in address specification") + } + + port, err := strconv.Atoi(parts[1]) + if err != nil { + return errors.New("bad port in address specification") + } + + a.IP = parts[0] + a.Port = port + + return nil +} + +func (a *IPAddressPort) String() string { + return fmt.Sprintf("%s:%d", a.IP, a.Port) +} diff --git a/pkg/flags/ipaddressport_test.go b/pkg/flags/ipaddressport_test.go new file mode 100644 index 000000000..d9d60f9b2 --- /dev/null +++ b/pkg/flags/ipaddressport_test.go @@ -0,0 +1,57 @@ +package flags + +import ( + "testing" +) + +func TestIPAddressPortSet(t *testing.T) { + pass := []string{ + "1.2.3.4:8080", + "10.1.1.1:80", + } + + fail := []string{ + // bad IP specification + ":4001", + "127.0:8080", + "123:456", + // bad port specification + "127.0.0.1:foo", + "127.0.0.1:", + // unix sockets not supported + "unix://", + "unix://tmp/etcd.sock", + // bad strings + "somewhere", + "234#$", + "file://foo/bar", + "http://hello", + } + + for i, tt := range pass { + f := &IPAddressPort{} + if err := f.Set(tt); err != nil { + t.Errorf("#%d: unexpected error from IPAddressPort.Set(%q): %v", i, tt, err) + } + } + + for i, tt := range fail { + f := &IPAddressPort{} + if err := f.Set(tt); err == nil { + t.Errorf("#%d: expected error from IPAddressPort.Set(%q)", i, tt, err) + } + } +} + +func TestIPAddressPortString(t *testing.T) { + f := &IPAddressPort{} + if err := f.Set("127.0.0.1:4001"); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + want := "127.0.0.1:4001" + got := f.String() + if want != got { + t.Fatalf("IPAddressPort.String() value should be %q, got %q", want, got) + } +}