From 78a9bba276e2cd657bcdee3206a662a7647c1fd6 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Sat, 27 Sep 2014 16:24:26 -0700 Subject: [PATCH] pkg/types/flags: introduce flags package I want to use the Addrs type in another experimental proxy that I am implementing. Pull it out into a separate package. --- main.go | 89 ++----------------------- pkg/flags/addrs.go | 51 ++++++++++++++ main_test.go => pkg/flags/addrs_test.go | 25 +------ pkg/flags/proxy.go | 39 +++++++++++ pkg/flags/proxy_test.go | 28 ++++++++ test | 2 +- 6 files changed, 127 insertions(+), 107 deletions(-) create mode 100644 pkg/flags/addrs.go rename main_test.go => pkg/flags/addrs_test.go (65%) create mode 100644 pkg/flags/proxy.go create mode 100644 pkg/flags/proxy_test.go diff --git a/main.go b/main.go index 94c12130c..14b811f7d 100644 --- a/main.go +++ b/main.go @@ -1,21 +1,19 @@ package main import ( - "errors" "flag" "fmt" "log" - "net" "net/http" "os" "path" - "strconv" "strings" "time" "github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver/etcdhttp" "github.com/coreos/etcd/pkg" + flagtypes "github.com/coreos/etcd/pkg/flags" "github.com/coreos/etcd/pkg/transport" "github.com/coreos/etcd/proxy" "github.com/coreos/etcd/raft" @@ -28,10 +26,6 @@ const ( // the owner can make/remove files inside the directory privateDirMode = 0700 - proxyFlagValueOff = "off" - proxyFlagValueReadonly = "readonly" - proxyFlagValueOn = "on" - version = "0.5.0-alpha" ) @@ -44,15 +38,9 @@ var ( printVersion = flag.Bool("version", false, "Print the version and exit") cluster = &etcdserver.Cluster{} - addrs = &Addrs{} + addrs = &flagtypes.Addrs{} cors = &pkg.CORSInfo{} - proxyFlag = new(ProxyFlag) - - proxyFlagValues = []string{ - proxyFlagValueOff, - proxyFlagValueReadonly, - proxyFlagValueOn, - } + proxyFlag = new(flagtypes.Proxy) clientTLSInfo = transport.TLSInfo{} peerTLSInfo = transport.TLSInfo{} @@ -80,10 +68,10 @@ func init() { flag.Var(cluster, "bootstrap-config", "Initial cluster configuration for bootstrapping") flag.Var(addrs, "bind-addr", "List of HTTP service addresses (e.g., '127.0.0.1:4001,10.0.0.1:8080')") flag.Var(cors, "cors", "Comma-separated white list of origins for CORS (cross-origin resource sharing).") - flag.Var(proxyFlag, "proxy", fmt.Sprintf("Valid values include %s", strings.Join(proxyFlagValues, ", "))) + flag.Var(proxyFlag, "proxy", fmt.Sprintf("Valid values include %s", strings.Join(flagtypes.ProxyValues, ", "))) cluster.Set("default=localhost:8080") addrs.Set("127.0.0.1:4001") - proxyFlag.Set(proxyFlagValueOff) + proxyFlag.Set(flagtypes.ProxyValueOff) flag.StringVar(&clientTLSInfo.CAFile, "ca-file", "", "Path to the client server TLS CA file.") flag.StringVar(&clientTLSInfo.CertFile, "cert-file", "", "Path to the client server TLS cert file.") @@ -109,7 +97,7 @@ func main() { pkg.SetFlagsFromEnv(flag.CommandLine) - if string(*proxyFlag) == proxyFlagValueOff { + if string(*proxyFlag) == flagtypes.ProxyValueOff { startEtcd() } else { startProxy() @@ -257,7 +245,7 @@ func startProxy() { Info: cors, } - if string(*proxyFlag) == proxyFlagValueReadonly { + if string(*proxyFlag) == flagtypes.ProxyValueReadonly { ph = proxy.NewReadonlyHandler(ph) } @@ -275,66 +263,3 @@ func startProxy() { }() } } - -// 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 -} - -// ProxyFlag implements the flag.Value interface. -type ProxyFlag string - -// Set verifies the argument to be a valid member of proxyFlagValues -// before setting the underlying flag value. -func (pf *ProxyFlag) Set(s string) error { - for _, v := range proxyFlagValues { - if s == v { - *pf = ProxyFlag(s) - return nil - } - } - - return errors.New("invalid value") -} - -func (pf *ProxyFlag) String() string { - return string(*pf) -} diff --git a/pkg/flags/addrs.go b/pkg/flags/addrs.go new file mode 100644 index 000000000..b9892831a --- /dev/null +++ b/pkg/flags/addrs.go @@ -0,0 +1,51 @@ +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/main_test.go b/pkg/flags/addrs_test.go similarity index 65% rename from main_test.go rename to pkg/flags/addrs_test.go index 46aa848d9..092a5504d 100644 --- a/main_test.go +++ b/pkg/flags/addrs_test.go @@ -1,32 +1,9 @@ -package main +package flags import ( "testing" ) -func TestProxyFlagSet(t *testing.T) { - tests := []struct { - val string - pass bool - }{ - // known values - {"on", true}, - {"off", true}, - - // unrecognized values - {"foo", false}, - {"", false}, - } - - for i, tt := range tests { - pf := new(ProxyFlag) - err := pf.Set(tt.val) - if tt.pass != (err == nil) { - t.Errorf("#%d: want pass=%t, but got err=%v", i, tt.pass, err) - } - } -} - func TestBadValidateAddr(t *testing.T) { tests := []string{ // bad IP specification diff --git a/pkg/flags/proxy.go b/pkg/flags/proxy.go new file mode 100644 index 000000000..095831658 --- /dev/null +++ b/pkg/flags/proxy.go @@ -0,0 +1,39 @@ +package flags + +import ( + "errors" +) + +const ( + ProxyValueOff = "off" + ProxyValueReadonly = "readonly" + ProxyValueOn = "on" +) + +var ( + ProxyValues = []string{ + ProxyValueOff, + ProxyValueReadonly, + ProxyValueOn, + } +) + +// ProxyFlag implements the flag.Value interface. +type Proxy string + +// Set verifies the argument to be a valid member of proxyFlagValues +// before setting the underlying flag value. +func (pf *Proxy) Set(s string) error { + for _, v := range ProxyValues { + if s == v { + *pf = Proxy(s) + return nil + } + } + + return errors.New("invalid value") +} + +func (pf *Proxy) String() string { + return string(*pf) +} diff --git a/pkg/flags/proxy_test.go b/pkg/flags/proxy_test.go new file mode 100644 index 000000000..ca1dc25db --- /dev/null +++ b/pkg/flags/proxy_test.go @@ -0,0 +1,28 @@ +package flags + +import ( + "testing" +) + +func TestProxySet(t *testing.T) { + tests := []struct { + val string + pass bool + }{ + // known values + {"on", true}, + {"off", true}, + + // unrecognized values + {"foo", false}, + {"", false}, + } + + for i, tt := range tests { + pf := new(Proxy) + err := pf.Set(tt.val) + if tt.pass != (err == nil) { + t.Errorf("#%d: want pass=%t, but got err=%v", i, tt.pass, err) + } + } +} diff --git a/test b/test index da8c9577a..52bc71326 100755 --- a/test +++ b/test @@ -15,7 +15,7 @@ COVER=${COVER:-"-cover"} source ./build # Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt. -TESTABLE_AND_FORMATTABLE="client etcdserver etcdserver/etcdhttp etcdserver/etcdserverpb pkg pkg/transport proxy raft snap store wait wal" +TESTABLE_AND_FORMATTABLE="client etcdserver etcdserver/etcdhttp etcdserver/etcdserverpb pkg pkg/flags pkg/transport proxy raft snap store wait wal" TESTABLE="$TESTABLE_AND_FORMATTABLE ./" FORMATTABLE="$TESTABLE_AND_FORMATTABLE *.go"