diff --git a/etcdmain/config.go b/etcdmain/config.go index 5f0d0909e..3d987b766 100644 --- a/etcdmain/config.go +++ b/etcdmain/config.go @@ -258,14 +258,6 @@ func NewConfig() *config { fs.IntVar(&cfg.autoCompactionRetention, "auto-compaction-retention", 0, "Auto compaction retention for mvcc key value store in hour. 0 means disable auto compaction.") - // backwards-compatibility with v0.4.6 - fs.Var(&flags.IPAddressPort{}, "addr", "DEPRECATED: Use --advertise-client-urls instead.") - fs.Var(&flags.IPAddressPort{}, "bind-addr", "DEPRECATED: Use --listen-client-urls instead.") - fs.Var(&flags.IPAddressPort{}, "peer-addr", "DEPRECATED: Use --initial-advertise-peer-urls instead.") - fs.Var(&flags.IPAddressPort{}, "peer-bind-addr", "DEPRECATED: Use --listen-peer-urls instead.") - fs.Var(&flags.DeprecatedFlag{Name: "peers"}, "peers", "DEPRECATED: Use --initial-cluster instead.") - fs.Var(&flags.DeprecatedFlag{Name: "peers-file"}, "peers-file", "DEPRECATED: Use --initial-cluster instead.") - // pprof profiler via HTTP fs.BoolVar(&cfg.enablePprof, "enable-pprof", false, "Enable runtime profiling data via HTTP server. Address is at client URL + \"/debug/pprof\"") @@ -315,25 +307,10 @@ func (cfg *config) configFromCmdLine() error { plog.Fatalf("%v", err) } - flags.SetBindAddrFromAddr(cfg.FlagSet, "peer-bind-addr", "peer-addr") - flags.SetBindAddrFromAddr(cfg.FlagSet, "bind-addr", "addr") - - cfg.lpurls, err = flags.URLsFromFlags(cfg.FlagSet, "listen-peer-urls", "peer-bind-addr", cfg.peerTLSInfo) - if err != nil { - return err - } - cfg.apurls, err = flags.URLsFromFlags(cfg.FlagSet, "initial-advertise-peer-urls", "peer-addr", cfg.peerTLSInfo) - if err != nil { - return err - } - cfg.lcurls, err = flags.URLsFromFlags(cfg.FlagSet, "listen-client-urls", "bind-addr", cfg.clientTLSInfo) - if err != nil { - return err - } - cfg.acurls, err = flags.URLsFromFlags(cfg.FlagSet, "advertise-client-urls", "addr", cfg.clientTLSInfo) - if err != nil { - return err - } + cfg.lpurls = flags.URLsFromFlag(cfg.FlagSet, "listen-peer-urls") + cfg.apurls = flags.URLsFromFlag(cfg.FlagSet, "initial-advertise-peer-urls") + cfg.lcurls = flags.URLsFromFlag(cfg.FlagSet, "listen-client-urls") + cfg.acurls = flags.URLsFromFlag(cfg.FlagSet, "advertise-client-urls") return cfg.validateConfig(func(field string) bool { return flags.IsSet(cfg.FlagSet, field) diff --git a/etcdmain/config_test.go b/etcdmain/config_test.go index 7837c0961..e9c58bc1b 100644 --- a/etcdmain/config_test.go +++ b/etcdmain/config_test.go @@ -209,35 +209,6 @@ func TestConfigFileOtherFields(t *testing.T) { validateOtherFlags(t, cfg) } -func TestConfigParsingV1Flags(t *testing.T) { - args := []string{ - "-peer-addr=127.0.0.1:2380", - "-addr=127.0.0.1:2379", - } - wcfg := NewConfig() - wcfg.lpurls = []url.URL{{Scheme: "http", Host: "[::]:2380"}} - wcfg.apurls = []url.URL{{Scheme: "http", Host: "127.0.0.1:2380"}} - wcfg.lcurls = []url.URL{{Scheme: "http", Host: "[::]:2379"}} - wcfg.acurls = []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}} - - cfg := NewConfig() - if err := cfg.Parse(args); err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(cfg.lpurls, wcfg.lpurls) { - t.Errorf("listen peer urls = %+v, want %+v", cfg.lpurls, wcfg.lpurls) - } - if !reflect.DeepEqual(cfg.apurls, wcfg.apurls) { - t.Errorf("advertise peer urls = %+v, want %+v", cfg.apurls, wcfg.apurls) - } - if !reflect.DeepEqual(cfg.lcurls, wcfg.lcurls) { - t.Errorf("listen client urls = %+v, want %+v", cfg.lcurls, wcfg.lcurls) - } - if !reflect.DeepEqual(cfg.acurls, wcfg.acurls) { - t.Errorf("advertise client urls = %+v, want %+v", cfg.acurls, wcfg.acurls) - } -} - func TestConfigParsingConflictClusteringFlags(t *testing.T) { conflictArgs := [][]string{ { diff --git a/pkg/flags/flag.go b/pkg/flags/flag.go index 7c888b9f8..4b844736f 100644 --- a/pkg/flags/flag.go +++ b/pkg/flags/flag.go @@ -22,7 +22,6 @@ import ( "os" "strings" - "github.com/coreos/etcd/pkg/transport" "github.com/coreos/pkg/capnslog" "github.com/spf13/pflag" ) @@ -148,54 +147,9 @@ func setFlagFromEnv(fs flagSetter, prefix, fname string, usedEnvKey, alreadySet return nil } -// SetBindAddrFromAddr sets the value of bindAddr flag from the value -// of addr flag. Both flags' Value must be of type IPAddressPort. If the -// bindAddr flag is set and the addr flag is unset, it will set bindAddr to -// [::]:port of addr. Otherwise, it keeps the original values. -func SetBindAddrFromAddr(fs *flag.FlagSet, bindAddrFlagName, addrFlagName string) { - if IsSet(fs, bindAddrFlagName) || !IsSet(fs, addrFlagName) { - return - } - addr := *fs.Lookup(addrFlagName).Value.(*IPAddressPort) - addr.IP = "::" - if err := fs.Set(bindAddrFlagName, addr.String()); err != nil { - plog.Panicf("unexpected flags set error: %v", err) - } -} - -// URLsFromFlags decides what URLs should be using two different flags -// as datasources. The first flag's Value must be of type URLs, while -// the second must be of type IPAddressPort. If both of these flags -// are set, an error will be returned. If only the first flag is set, -// the underlying url.URL objects will be returned unmodified. If the -// second flag happens to be set, the underlying IPAddressPort will be -// converted to a url.URL and returned. The Scheme of the returned -// url.URL will be http unless the provided TLSInfo object is non-empty. -// If neither of the flags have been explicitly set, the default value -// of the first flag will be returned unmodified. -func URLsFromFlags(fs *flag.FlagSet, urlsFlagName string, addrFlagName string, tlsInfo transport.TLSInfo) ([]url.URL, error) { - visited := make(map[string]struct{}) - fs.Visit(func(f *flag.Flag) { - visited[f.Name] = struct{}{} - }) - - _, urlsFlagIsSet := visited[urlsFlagName] - _, addrFlagIsSet := visited[addrFlagName] - - if addrFlagIsSet { - if urlsFlagIsSet { - return nil, fmt.Errorf("Set only one of flags -%s and -%s", urlsFlagName, addrFlagName) - } - - addr := *fs.Lookup(addrFlagName).Value.(*IPAddressPort) - addrURL := url.URL{Scheme: "http", Host: addr.String()} - if !tlsInfo.Empty() { - addrURL.Scheme = "https" - } - return []url.URL{addrURL}, nil - } - - return []url.URL(*fs.Lookup(urlsFlagName).Value.(*URLsValue)), nil +// URLsFromFlag returns a slices from url got from the flag. +func URLsFromFlag(fs *flag.FlagSet, urlsFlagName string) []url.URL { + return []url.URL(*fs.Lookup(urlsFlagName).Value.(*URLsValue)) } func IsSet(fs *flag.FlagSet, name string) bool { diff --git a/pkg/flags/flag_test.go b/pkg/flags/flag_test.go index c89d742e1..726bc4182 100644 --- a/pkg/flags/flag_test.go +++ b/pkg/flags/flag_test.go @@ -16,12 +16,8 @@ package flags import ( "flag" - "net/url" "os" - "reflect" "testing" - - "github.com/coreos/etcd/pkg/transport" ) func TestSetFlagsFromEnv(t *testing.T) { @@ -80,133 +76,3 @@ func TestSetFlagsFromEnvBad(t *testing.T) { t.Errorf("err=nil, want != nil") } } - -func TestSetBindAddrFromAddr(t *testing.T) { - tests := []struct { - args []string - waddr *IPAddressPort - }{ - // no flags set - { - args: []string{}, - waddr: &IPAddressPort{}, - }, - // addr flag set - { - args: []string{"-addr=192.0.3.17:2379"}, - waddr: &IPAddressPort{IP: "::", Port: 2379}, - }, - // bindAddr flag set - { - args: []string{"-bind-addr=127.0.0.1:2379"}, - waddr: &IPAddressPort{IP: "127.0.0.1", Port: 2379}, - }, - // both addr flags set - { - args: []string{"-bind-addr=127.0.0.1:2379", "-addr=192.0.3.17:2379"}, - waddr: &IPAddressPort{IP: "127.0.0.1", Port: 2379}, - }, - // both addr flags set, IPv6 - { - args: []string{"-bind-addr=[2001:db8::4:9]:2379", "-addr=[2001:db8::4:f0]:2379"}, - waddr: &IPAddressPort{IP: "2001:db8::4:9", Port: 2379}, - }, - } - for i, tt := range tests { - fs := flag.NewFlagSet("test", flag.PanicOnError) - fs.Var(&IPAddressPort{}, "addr", "") - bindAddr := &IPAddressPort{} - fs.Var(bindAddr, "bind-addr", "") - if err := fs.Parse(tt.args); err != nil { - t.Errorf("#%d: failed to parse flags: %v", i, err) - continue - } - SetBindAddrFromAddr(fs, "bind-addr", "addr") - - if !reflect.DeepEqual(bindAddr, tt.waddr) { - t.Errorf("#%d: bindAddr = %+v, want %+v", i, bindAddr, tt.waddr) - } - } -} - -func TestURLsFromFlags(t *testing.T) { - tests := []struct { - args []string - tlsInfo transport.TLSInfo - wantURLs []url.URL - wantFail bool - }{ - // use -urls default when no flags defined - { - args: []string{}, - tlsInfo: transport.TLSInfo{}, - wantURLs: []url.URL{ - {Scheme: "http", Host: "127.0.0.1:2379"}, - }, - wantFail: false, - }, - - // explicitly setting -urls should carry through - { - args: []string{"-urls=https://192.0.3.17:2930,http://127.0.0.1:1024"}, - tlsInfo: transport.TLSInfo{}, - wantURLs: []url.URL{ - {Scheme: "http", Host: "127.0.0.1:1024"}, - {Scheme: "https", Host: "192.0.3.17:2930"}, - }, - wantFail: false, - }, - - // explicitly setting -addr should carry through - { - args: []string{"-addr=192.0.2.3:1024"}, - tlsInfo: transport.TLSInfo{}, - wantURLs: []url.URL{ - {Scheme: "http", Host: "192.0.2.3:1024"}, - }, - wantFail: false, - }, - - // scheme prepended to -addr should be https if TLSInfo non-empty - { - args: []string{"-addr=192.0.2.3:1024"}, - tlsInfo: transport.TLSInfo{ - CertFile: "/tmp/foo", - KeyFile: "/tmp/bar", - }, - wantURLs: []url.URL{ - {Scheme: "https", Host: "192.0.2.3:1024"}, - }, - wantFail: false, - }, - - // explicitly setting both -urls and -addr should fail - { - args: []string{"-urls=https://127.0.0.1:1024", "-addr=192.0.2.3:1024"}, - tlsInfo: transport.TLSInfo{}, - wantURLs: nil, - wantFail: true, - }, - } - - for i, tt := range tests { - fs := flag.NewFlagSet("test", flag.PanicOnError) - fs.Var(NewURLsValue("http://127.0.0.1:2379"), "urls", "") - fs.Var(&IPAddressPort{}, "addr", "") - - if err := fs.Parse(tt.args); err != nil { - t.Errorf("#%d: failed to parse flags: %v", i, err) - continue - } - - gotURLs, err := URLsFromFlags(fs, "urls", "addr", tt.tlsInfo) - if tt.wantFail != (err != nil) { - t.Errorf("#%d: wantFail=%t, got err=%v", i, tt.wantFail, err) - continue - } - - if !reflect.DeepEqual(tt.wantURLs, gotURLs) { - t.Errorf("#%d: incorrect URLs\nwant=%#v\ngot=%#v", i, tt.wantURLs, gotURLs) - } - } -} diff --git a/pkg/flags/ipaddressport.go b/pkg/flags/ipaddressport.go deleted file mode 100644 index c4d62c255..000000000 --- a/pkg/flags/ipaddressport.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package flags - -import ( - "errors" - "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) - - host, portStr, err := net.SplitHostPort(arg) - if err != nil { - return err - } - - if net.ParseIP(host) == nil { - return errors.New("bad IP in address specification") - } - - port, err := strconv.Atoi(portStr) - if err != nil { - return errors.New("bad port in address specification") - } - - a.IP = host - a.Port = port - - return nil -} - -func (a *IPAddressPort) String() string { - return net.JoinHostPort(a.IP, strconv.Itoa(a.Port)) -} diff --git a/pkg/flags/ipaddressport_test.go b/pkg/flags/ipaddressport_test.go deleted file mode 100644 index 0bb60ef9c..000000000 --- a/pkg/flags/ipaddressport_test.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2015 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package flags - -import ( - "testing" -) - -func TestIPAddressPortSet(t *testing.T) { - pass := []string{ - "1.2.3.4:8080", - "10.1.1.1:80", - "[2001:db8::1]:8080", - } - - fail := []string{ - // bad IP specification - ":2379", - "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", - "2001:db8::1", - "2001:db8::1:1", - } - - 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) - } - } -} - -func TestIPAddressPortString(t *testing.T) { - addresses := []string{ - "[2001:db8::1:1234]:2379", - "127.0.0.1:2379", - } - for i, tt := range addresses { - f := &IPAddressPort{} - if err := f.Set(tt); err != nil { - t.Errorf("#%d: unexpected error: %v", i, err) - } - - want := tt - got := f.String() - if want != got { - t.Errorf("#%d: IPAddressPort.String() value should be %q, got %q", i, want, got) - } - } -}