netutil: add url comparison without resolver to URLStringsEqual
If one of the nodes in the cluster has lost a dns record, restarting the second node will break it. This PR makes an attempt to add a comparison without using a resolver, which allows to protect cluster from dns errors and does not break the current logic of comparing urls in the URLStringsEqual function. You can read more in the issue #7798 Fixes #7798 Signed-off-by: Prasad Chandrasekaran <prasadc@vmware.com>
This commit is contained in:
parent
07c7a98371
commit
25ef9b6f46
@ -174,21 +174,13 @@ func URLStringsEqual(ctx context.Context, lg *zap.Logger, a []string, b []string
|
|||||||
if len(a) != len(b) {
|
if len(a) != len(b) {
|
||||||
return false, fmt.Errorf("len(%q) != len(%q)", a, b)
|
return false, fmt.Errorf("len(%q) != len(%q)", a, b)
|
||||||
}
|
}
|
||||||
urlsA := make([]url.URL, 0)
|
urlsA, err := stringsToURLs(a)
|
||||||
for _, str := range a {
|
|
||||||
u, err := url.Parse(str)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("failed to parse %q", str)
|
return false, err
|
||||||
}
|
}
|
||||||
urlsA = append(urlsA, *u)
|
urlsB, err := stringsToURLs(b)
|
||||||
}
|
|
||||||
urlsB := make([]url.URL, 0)
|
|
||||||
for _, str := range b {
|
|
||||||
u, err := url.Parse(str)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("failed to parse %q", str)
|
return false, err
|
||||||
}
|
|
||||||
urlsB = append(urlsB, *u)
|
|
||||||
}
|
}
|
||||||
return urlsEqual(ctx, lg, urlsA, urlsB)
|
return urlsEqual(ctx, lg, urlsA, urlsB)
|
||||||
}
|
}
|
||||||
@ -201,6 +193,18 @@ func urlsToStrings(us []url.URL) []string {
|
|||||||
return rs
|
return rs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stringsToURLs(us []string) ([]url.URL, error) {
|
||||||
|
urls := make([]url.URL, 0, len(us))
|
||||||
|
for _, str := range us {
|
||||||
|
u, err := url.Parse(str)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse %q", str)
|
||||||
|
}
|
||||||
|
urls = append(urls, *u)
|
||||||
|
}
|
||||||
|
return urls, nil
|
||||||
|
}
|
||||||
|
|
||||||
func IsNetworkTimeoutError(err error) bool {
|
func IsNetworkTimeoutError(err error) bool {
|
||||||
nerr, ok := err.(net.Error)
|
nerr, ok := err.(net.Error)
|
||||||
return ok && nerr.Timeout()
|
return ok && nerr.Timeout()
|
||||||
|
@ -17,6 +17,7 @@ package netutil
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -292,11 +293,33 @@ func TestURLsEqual(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func TestURLStringsEqual(t *testing.T) {
|
func TestURLStringsEqual(t *testing.T) {
|
||||||
result, err := URLStringsEqual(context.TODO(), zap.NewExample(), []string{"http://127.0.0.1:8080"}, []string{"http://127.0.0.1:8080"})
|
defer func() { resolveTCPAddr = resolveTCPAddrDefault }()
|
||||||
|
errOnResolve := func(ctx context.Context, addr string) (*net.TCPAddr, error) {
|
||||||
|
return nil, fmt.Errorf("unexpected attempt to resolve: %q", addr)
|
||||||
|
}
|
||||||
|
cases := []struct {
|
||||||
|
urlsA []string
|
||||||
|
urlsB []string
|
||||||
|
resolver func(ctx context.Context, addr string) (*net.TCPAddr, error)
|
||||||
|
}{
|
||||||
|
{[]string{"http://127.0.0.1:8080"}, []string{"http://127.0.0.1:8080"}, resolveTCPAddrDefault},
|
||||||
|
{[]string{
|
||||||
|
"http://host1:8080",
|
||||||
|
"http://host2:8080",
|
||||||
|
}, []string{
|
||||||
|
"http://host1:8080",
|
||||||
|
"http://host2:8080",
|
||||||
|
}, errOnResolve},
|
||||||
|
}
|
||||||
|
for idx, c := range cases {
|
||||||
|
t.Logf("TestURLStringsEqual, case #%d", idx)
|
||||||
|
resolveTCPAddr = c.resolver
|
||||||
|
result, err := URLStringsEqual(context.TODO(), zap.NewExample(), c.urlsA, c.urlsB)
|
||||||
if !result {
|
if !result {
|
||||||
t.Errorf("unexpected result %v", result)
|
t.Errorf("unexpected result %v", result)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error %v", err)
|
t.Errorf("unexpected error %v", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user