فهرست منبع

Revert "Revert "Treat URLs have same IP address as same""

This reverts commit 3153e635d5799f1ff8715fd4b7c07e0283820acd.

Conflicts:
	etcdserver/config.go
Yicheng Qin 10 سال پیش
والد
کامیت
8ea3d157c5
4فایلهای تغییر یافته به همراه157 افزوده شده و 4 حذف شده
  1. 3 2
      etcdserver/cluster.go
  2. 3 2
      etcdserver/config.go
  3. 46 0
      pkg/netutil/netutil.go
  4. 105 0
      pkg/netutil/netutil_test.go

+ 3 - 2
etcdserver/cluster.go

@@ -21,12 +21,12 @@ import (
 	"encoding/json"
 	"fmt"
 	"path"
-	"reflect"
 	"sort"
 	"strings"
 	"sync"
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/go-semver/semver"
+	"github.com/coreos/etcd/pkg/netutil"
 	"github.com/coreos/etcd/pkg/types"
 	"github.com/coreos/etcd/raft"
 	"github.com/coreos/etcd/raft/raftpb"
@@ -424,7 +424,8 @@ func ValidateClusterAndAssignIDs(local *cluster, existing *cluster) error {
 	sort.Sort(MembersByPeerURLs(lms))
 
 	for i := range ems {
-		if !reflect.DeepEqual(ems[i].PeerURLs, lms[i].PeerURLs) {
+		// TODO: Remove URLStringsEqual after improvement of using hostnames #2150 #2123
+		if !netutil.URLStringsEqual(ems[i].PeerURLs, lms[i].PeerURLs) {
 			return fmt.Errorf("unmatched member while checking PeerURLs")
 		}
 		lms[i].ID = ems[i].ID

+ 3 - 2
etcdserver/config.go

@@ -18,10 +18,10 @@ import (
 	"fmt"
 	"net/http"
 	"path"
-	"reflect"
 	"sort"
 	"time"
 
+	"github.com/coreos/etcd/pkg/netutil"
 	"github.com/coreos/etcd/pkg/types"
 )
 
@@ -92,11 +92,12 @@ func (c *ServerConfig) verifyLocalMember(strict bool) error {
 	}
 
 	// Advertised peer URLs must match those in the cluster peer list
+	// TODO: Remove URLStringsEqual after improvement of using hostnames #2150 #2123
 	apurls := c.PeerURLs.StringSlice()
 	sort.Strings(apurls)
 	urls.Sort()
 	if strict {
-		if !reflect.DeepEqual(apurls, urls.StringSlice()) {
+		if !netutil.URLStringsEqual(apurls, urls.StringSlice()) {
 			return fmt.Errorf("advertise URLs of %q do not match in --initial-advertise-peer-urls %s and --initial-cluster %s", c.Name, apurls, urls.StringSlice())
 		}
 	}

+ 46 - 0
pkg/netutil/netutil.go

@@ -19,6 +19,7 @@ import (
 	"net"
 	"net/http"
 	"net/url"
+	"reflect"
 	"strings"
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/pkg/capnslog"
@@ -60,6 +61,51 @@ func ResolveTCPAddrs(urls ...[]url.URL) error {
 	return nil
 }
 
+// URLsEqual checks equality of url.URLS between two arrays.
+// This check pass even if an URL is in hostname and opposite is in IP address.
+func URLsEqual(a []url.URL, b []url.URL) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, urlA := range a {
+		urlB := b[i]
+
+		if !reflect.DeepEqual(urlA, urlB) {
+			urls := []url.URL{urlA, urlB}
+			ResolveTCPAddrs(urls)
+			if !reflect.DeepEqual(urls[0], urls[1]) {
+				return false
+			}
+		}
+	}
+
+	return true
+}
+
+func URLStringsEqual(a []string, b []string) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	urlsA := make([]url.URL, len(a))
+	for _, str := range a {
+		u, err := url.Parse(str)
+		if err != nil {
+			return false
+		}
+		urlsA = append(urlsA, *u)
+	}
+	urlsB := make([]url.URL, len(b))
+	for _, str := range b {
+		u, err := url.Parse(str)
+		if err != nil {
+			return false
+		}
+		urlsB = append(urlsB, *u)
+	}
+
+	return URLsEqual(urlsA, urlsB)
+}
+
 // BasicAuth returns the username and password provided in the request's
 // Authorization header, if the request uses HTTP Basic Authentication.
 // See RFC 2617, Section 2.

+ 105 - 0
pkg/netutil/netutil_test.go

@@ -136,3 +136,108 @@ func TestResolveTCPAddrs(t *testing.T) {
 		}
 	}
 }
+
+func TestURLsEqual(t *testing.T) {
+	defer func() { resolveTCPAddr = net.ResolveTCPAddr }()
+	resolveTCPAddr = func(network, addr string) (*net.TCPAddr, error) {
+		host, port, err := net.SplitHostPort(addr)
+		if host != "example.com" {
+			return nil, errors.New("cannot resolve host.")
+		}
+		i, err := strconv.Atoi(port)
+		if err != nil {
+			return nil, err
+		}
+		return &net.TCPAddr{IP: net.ParseIP("10.0.10.1"), Port: i, Zone: ""}, nil
+	}
+
+	tests := []struct {
+		a      []url.URL
+		b      []url.URL
+		expect bool
+	}{
+		{
+			a:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}},
+			b:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}},
+			expect: true,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "example.com:2379"}},
+			b:      []url.URL{{Scheme: "http", Host: "10.0.10.1:2379"}},
+			expect: true,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			b:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: true,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "example.com:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			b:      []url.URL{{Scheme: "http", Host: "example.com:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: true,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "10.0.10.1:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			b:      []url.URL{{Scheme: "http", Host: "example.com:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: true,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}},
+			b:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: false,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "example.com:2380"}},
+			b:      []url.URL{{Scheme: "http", Host: "10.0.10.1:2379"}},
+			expect: false,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}},
+			b:      []url.URL{{Scheme: "http", Host: "10.0.0.1:2379"}},
+			expect: false,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "example.com:2379"}},
+			b:      []url.URL{{Scheme: "http", Host: "10.0.0.1:2379"}},
+			expect: false,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			b:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2380"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: false,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "example.com:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			b:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2380"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: false,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "127.0.0.1:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			b:      []url.URL{{Scheme: "http", Host: "10.0.0.1:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: false,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "example.com:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			b:      []url.URL{{Scheme: "http", Host: "10.0.0.1:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: false,
+		},
+		{
+			a:      []url.URL{{Scheme: "http", Host: "10.0.0.1:2379"}},
+			b:      []url.URL{{Scheme: "http", Host: "10.0.0.1:2379"}, {Scheme: "http", Host: "127.0.0.1:2380"}},
+			expect: false,
+		},
+	}
+
+	for _, test := range tests {
+		result := URLsEqual(test.a, test.b)
+		if result != test.expect {
+			t.Errorf("a:%v b:%v, expected %v but %v", test.a, test.b, test.expect, result)
+		}
+	}
+}
+func TestURLStringsEqual(t *testing.T) {
+	result := URLStringsEqual([]string{"http://127.0.0.1:8080"}, []string{"http://127.0.0.1:8080"})
+	if !result {
+		t.Errorf("unexpected result %v", result)
+	}
+}