Update storageos api dependency to 0.3.4
This commit is contained in:
27
vendor/github.com/storageos/go-api/netutil/BUILD
generated
vendored
Normal file
27
vendor/github.com/storageos/go-api/netutil/BUILD
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"errors.go",
|
||||
"multidialer.go",
|
||||
"parsers.go",
|
||||
],
|
||||
importpath = "github.com/storageos/go-api/netutil",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/github.com/storageos/go-api/serror:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
26
vendor/github.com/storageos/go-api/netutil/errors.go
generated
vendored
Normal file
26
vendor/github.com/storageos/go-api/netutil/errors.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/storageos/go-api/serror"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func errAllFailed(addrs []string) error {
|
||||
msg := fmt.Sprintf("failed to dial all known cluster members, (%s)", strings.Join(addrs, ","))
|
||||
help := "ensure that the value of $STORAGEOS_HOST (or the -H flag) is correct, and that there are healthy StorageOS nodes in this cluster"
|
||||
|
||||
return serror.NewTypedStorageOSError(serror.APIUncontactable, nil, msg, help)
|
||||
}
|
||||
|
||||
func newInvalidNodeError(err error) error {
|
||||
msg := fmt.Sprintf("invalid node format: %s", err)
|
||||
help := "please check the format of $STORAGEOS_HOST (or the -H flag) complies with the StorageOS JOIN format"
|
||||
|
||||
return serror.NewTypedStorageOSError(serror.InvalidHostConfig, err, msg, help)
|
||||
}
|
||||
|
||||
var errNoAddresses = errors.New("the MultiDialer instance has not been initialised with client addresses")
|
||||
var errUnsupportedScheme = errors.New("unsupported URL scheme")
|
||||
var errInvalidPortNumber = errors.New("invalid port number")
|
109
vendor/github.com/storageos/go-api/netutil/multidialer.go
generated
vendored
Normal file
109
vendor/github.com/storageos/go-api/netutil/multidialer.go
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
var DefaultDialPort = "5705"
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
// Dialer is an interface that matches *net.Dialer. The intention is to allow either the stdlib
|
||||
// dialer or a custom implementation to be passed to the MultiDialer constructor. This also makes
|
||||
// the component easier to test.
|
||||
type Dialer interface {
|
||||
DialContext(context.Context, string, string) (net.Conn, error)
|
||||
}
|
||||
|
||||
// MultiDialer is a custom net Dialer (to be used in a net.Transport field) that attemps to dial
|
||||
// out to any (potentialy many) of a set of pre-defined addresses. The intended use of this
|
||||
// function is to extend the functionality of the stdlib http.Client to transparently support
|
||||
// requests to any member of a given storageos cluster.
|
||||
type MultiDialer struct {
|
||||
Addresses []string
|
||||
Dialer *net.Dialer
|
||||
}
|
||||
|
||||
// NewMultiDialer returns a new MultiDialer instance, configured to dial out to the given set of
|
||||
// nodes. Nodes can be provided using a URL format (e.g. http://google.com:80), or a host-port pair
|
||||
// (e.g. localhost:4567).
|
||||
//
|
||||
// If a port number is omitted, the value of DefaultDialPort is used.
|
||||
// Given hostnames are resolved to IP addresses, and IP addresses are used verbatim.
|
||||
//
|
||||
// If called with a non-nil dialer, the MultiDialer instance will use this for internall dial
|
||||
// requests. If this value is nil, the function will initialise one with sane defaults.
|
||||
func NewMultiDialer(nodes []string, dialer *net.Dialer) (*MultiDialer, error) {
|
||||
// If a dialer is not provided, initialise one with sane defaults
|
||||
if dialer == nil {
|
||||
dialer = &net.Dialer{
|
||||
Timeout: 5 * time.Second,
|
||||
KeepAlive: 5 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
addrs, err := addrsFromNodes(nodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &MultiDialer{
|
||||
Addresses: addrs,
|
||||
Dialer: dialer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DialContext will dial each of the MultiDialer's internal addresses in a random order until one
|
||||
// successfully returns a connection, it has run out of addresses (returning ErrAllFailed), or the
|
||||
// given context has been closed.
|
||||
//
|
||||
// Due to the intrinsic behaviour of this function, any address passed to this function will be
|
||||
// ignored.
|
||||
func (m *MultiDialer) DialContext(ctx context.Context, network, ignoredAddress string) (net.Conn, error) {
|
||||
if len(m.Addresses) == 0 {
|
||||
return nil, newInvalidNodeError(errNoAddresses)
|
||||
}
|
||||
|
||||
// Shuffle a copy of the addresses (for even load balancing)
|
||||
addrs := make([]string, len(m.Addresses))
|
||||
copy(addrs, m.Addresses)
|
||||
|
||||
// Fisher–Yates shuffle algorithm
|
||||
for i := len(addrs) - 1; i > 0; i-- {
|
||||
j := rand.Intn(i + 1)
|
||||
addrs[i], addrs[j] = addrs[j], addrs[i]
|
||||
}
|
||||
|
||||
// Try to dial each of these addresses in turn, or return on closed context
|
||||
for _, addr := range addrs {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
|
||||
default:
|
||||
// Create new child context for a single dial
|
||||
dctx, cancel := context.WithTimeout(ctx, time.Second)
|
||||
defer cancel()
|
||||
|
||||
conn, err := m.Dialer.DialContext(dctx, network, addr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
}
|
||||
|
||||
// We failed to dail all of the addresses we have
|
||||
return nil, errAllFailed(m.Addresses)
|
||||
}
|
||||
|
||||
// Dial returns the result of a call to m.DialContext passing in the background context
|
||||
func (m *MultiDialer) Dial(network, addr string) (net.Conn, error) {
|
||||
return m.DialContext(context.Background(), network, addr)
|
||||
}
|
142
vendor/github.com/storageos/go-api/netutil/parsers.go
generated
vendored
Normal file
142
vendor/github.com/storageos/go-api/netutil/parsers.go
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// addrsFromNodes takes a list of node hosts and attempts to return a list of hosts in ip:port
|
||||
// format along with any error encountered.
|
||||
//
|
||||
// The function accepts node hosts in URL, ip, ip:port, resolvable-name and resolvable-name:port
|
||||
// formats and will append the default port value if needed.
|
||||
func addrsFromNodes(nodes []string) ([]string, error) {
|
||||
var addrs []string
|
||||
|
||||
for _, n := range nodes {
|
||||
switch {
|
||||
// Assume that the node is provided as a URL
|
||||
case strings.Contains(n, "://"):
|
||||
newAddrs, err := parseURL(n)
|
||||
if err != nil {
|
||||
return nil, newInvalidNodeError(err)
|
||||
}
|
||||
|
||||
addrs = append(addrs, newAddrs...)
|
||||
|
||||
// Assume the node is in hostname:port or ip:port format
|
||||
case strings.Contains(n, ":"):
|
||||
newAddrs, err := parseHostPort(n)
|
||||
if err != nil {
|
||||
return nil, newInvalidNodeError(err)
|
||||
}
|
||||
|
||||
addrs = append(addrs, newAddrs...)
|
||||
|
||||
// Assume hostname or ip
|
||||
default:
|
||||
newAddrs, err := parseHost(n)
|
||||
if err != nil {
|
||||
return nil, newInvalidNodeError(err)
|
||||
}
|
||||
|
||||
addrs = append(addrs, newAddrs...)
|
||||
}
|
||||
}
|
||||
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
func validPort(port string) bool {
|
||||
intPort, err := strconv.Atoi(port)
|
||||
|
||||
return (err == nil) &&
|
||||
(intPort > 0) &&
|
||||
(intPort <= 65535)
|
||||
}
|
||||
|
||||
// parseURL takes a valid URL and verifies that it is using a correct scheme, has a resolvable
|
||||
// address (or is an IP) and has a valid port (or adds the default if the port is omitted). The
|
||||
// function then returns a list of addresses in ip:port format along with any error encountered.
|
||||
//
|
||||
// The function may return multiple addresses depending on the dns answer received when resolving
|
||||
// the host.
|
||||
func parseURL(node string) ([]string, error) {
|
||||
url, err := url.Parse(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify a valid scheme
|
||||
switch url.Scheme {
|
||||
case "tcp", "http", "https":
|
||||
host, port, err := net.SplitHostPort(url.Host)
|
||||
if err != nil {
|
||||
// We could be here as there is no port, lets try one last time with default port added
|
||||
host, port, err = net.SplitHostPort(url.Host + ":" + DefaultDialPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if !validPort(port) {
|
||||
return nil, errInvalidPortNumber
|
||||
}
|
||||
|
||||
// LookupHost works for IP addr too
|
||||
addrs, err := net.LookupHost(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, a := range addrs {
|
||||
addrs[i] = a + ":" + port
|
||||
}
|
||||
|
||||
return addrs, nil
|
||||
|
||||
default:
|
||||
return nil, errUnsupportedScheme
|
||||
}
|
||||
}
|
||||
|
||||
// parseHostPort takes a string in host:port format and checks it has a resolvable address (or is
|
||||
// an IP) and a valid port (or adds the default if the port is omitted). The function then returns
|
||||
// a list of addresses in ip:port format along with any error encountered.
|
||||
//
|
||||
// The function may return multiple addresses depending on the dns answer received when resolving
|
||||
// the host.
|
||||
func parseHostPort(node string) ([]string, error) {
|
||||
host, port, err := net.SplitHostPort(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !validPort(port) {
|
||||
return nil, errInvalidPortNumber
|
||||
}
|
||||
|
||||
// LookupHost works for IP addr too
|
||||
addrs, err := net.LookupHost(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, a := range addrs {
|
||||
addrs[i] = a + ":" + port
|
||||
}
|
||||
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
// parseHostPort takes a hostname string and checks it is resolvable to an address (or is already
|
||||
// an IP) The function then returns a list of addresses in ip:port format (where port is the
|
||||
// default port) along with any error encountered.
|
||||
//
|
||||
// The function may return multiple addresses depending on the dns answer received when resolving
|
||||
// the host.
|
||||
func parseHost(node string) ([]string, error) {
|
||||
return parseHostPort(node + ":" + DefaultDialPort)
|
||||
}
|
Reference in New Issue
Block a user