mirror of https://github.com/k3s-io/k3s
Use networking to hold network related pkgs
Change names of unclear methods Use net as pkg name for shortpull/6/head
parent
33c72db59c
commit
936a11e775
|
@ -53,6 +53,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
"k8s.io/kubernetes/pkg/master"
|
"k8s.io/kubernetes/pkg/master"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
"k8s.io/kubernetes/pkg/volume/empty_dir"
|
"k8s.io/kubernetes/pkg/volume/empty_dir"
|
||||||
|
@ -153,7 +154,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
|
||||||
}
|
}
|
||||||
|
|
||||||
// The caller of master.New should guarantee pulicAddress is properly set
|
// The caller of master.New should guarantee pulicAddress is properly set
|
||||||
hostIP, err := util.ValidPublicAddrForMaster(publicAddress)
|
hostIP, err := utilnet.ChooseBindAddress(publicAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Unable to find suitable network address.error='%v' . "+
|
glog.Fatalf("Unable to find suitable network address.error='%v' . "+
|
||||||
"Fail to get a valid public address for master.", err)
|
"Fail to get a valid public address for master.", err)
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||||
"k8s.io/kubernetes/pkg/master/ports"
|
"k8s.io/kubernetes/pkg/master/ports"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
@ -76,7 +77,7 @@ type APIServer struct {
|
||||||
ServiceAccountKeyFile string
|
ServiceAccountKeyFile string
|
||||||
ServiceAccountLookup bool
|
ServiceAccountLookup bool
|
||||||
ServiceClusterIPRange net.IPNet // TODO: make this a list
|
ServiceClusterIPRange net.IPNet // TODO: make this a list
|
||||||
ServiceNodePortRange util.PortRange
|
ServiceNodePortRange utilnet.PortRange
|
||||||
StorageVersions string
|
StorageVersions string
|
||||||
TokenAuthFile string
|
TokenAuthFile string
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/storage"
|
"k8s.io/kubernetes/pkg/storage"
|
||||||
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewAPIServerCommand creates a *cobra.Command object with default parameters
|
// NewAPIServerCommand creates a *cobra.Command object with default parameters
|
||||||
|
@ -164,9 +164,9 @@ func Run(s *options.APIServer) error {
|
||||||
|
|
||||||
// If advertise-address is not specified, use bind-address. If bind-address
|
// If advertise-address is not specified, use bind-address. If bind-address
|
||||||
// is not usable (unset, 0.0.0.0, or loopback), we will use the host's default
|
// is not usable (unset, 0.0.0.0, or loopback), we will use the host's default
|
||||||
// interface as valid public addr for master (see: util#ValidPublicAddrForMaster)
|
// interface as valid public addr for master (see: util/net#ValidPublicAddrForMaster)
|
||||||
if s.AdvertiseAddress == nil || s.AdvertiseAddress.IsUnspecified() {
|
if s.AdvertiseAddress == nil || s.AdvertiseAddress.IsUnspecified() {
|
||||||
hostIP, err := util.ValidPublicAddrForMaster(s.BindAddress)
|
hostIP, err := utilnet.ChooseBindAddress(s.BindAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Unable to find suitable network address.error='%v' . "+
|
glog.Fatalf("Unable to find suitable network address.error='%v' . "+
|
||||||
"Try to set the AdvertiseAddress directly or provide a valid BindAddress to fix this.", err)
|
"Try to set the AdvertiseAddress directly or provide a valid BindAddress to fix this.", err)
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
@ -42,7 +42,7 @@ type ProxyServerConfig struct {
|
||||||
ResourceContainer string
|
ResourceContainer string
|
||||||
Master string
|
Master string
|
||||||
Kubeconfig string
|
Kubeconfig string
|
||||||
PortRange util.PortRange
|
PortRange utilnet.PortRange
|
||||||
HostnameOverride string
|
HostnameOverride string
|
||||||
ProxyMode string
|
ProxyMode string
|
||||||
IptablesSyncPeriod time.Duration
|
IptablesSyncPeriod time.Duration
|
||||||
|
|
|
@ -43,6 +43,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
"k8s.io/kubernetes/pkg/util/flushwriter"
|
"k8s.io/kubernetes/pkg/util/flushwriter"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/wsstream"
|
"k8s.io/kubernetes/pkg/util/wsstream"
|
||||||
"k8s.io/kubernetes/pkg/version"
|
"k8s.io/kubernetes/pkg/version"
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ func monitorFilter(action, resource string) restful.FilterFunction {
|
||||||
reqStart := time.Now()
|
reqStart := time.Now()
|
||||||
chain.ProcessFilter(req, res)
|
chain.ProcessFilter(req, res)
|
||||||
httpCode := res.StatusCode()
|
httpCode := res.StatusCode()
|
||||||
metrics.Monitor(&action, &resource, util.GetClient(req.Request), &httpCode, reqStart)
|
metrics.Monitor(&action, &resource, utilnet.GetHTTPClient(req.Request), &httpCode, reqStart)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/apiserver/metrics"
|
"k8s.io/kubernetes/pkg/apiserver/metrics"
|
||||||
"k8s.io/kubernetes/pkg/httplog"
|
"k8s.io/kubernetes/pkg/httplog"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
|
||||||
"k8s.io/kubernetes/pkg/util/httpstream"
|
"k8s.io/kubernetes/pkg/util/httpstream"
|
||||||
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
proxyutil "k8s.io/kubernetes/pkg/util/proxy"
|
proxyutil "k8s.io/kubernetes/pkg/util/proxy"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
@ -56,7 +56,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
var apiResource string
|
var apiResource string
|
||||||
var httpCode int
|
var httpCode int
|
||||||
reqStart := time.Now()
|
reqStart := time.Now()
|
||||||
defer metrics.Monitor(&verb, &apiResource, util.GetClient(req), &httpCode, reqStart)
|
defer metrics.Monitor(&verb, &apiResource, net.GetHTTPClient(req), &httpCode, reqStart)
|
||||||
|
|
||||||
requestInfo, err := r.requestInfoResolver.GetRequestInfo(req)
|
requestInfo, err := r.requestInfoResolver.GetRequestInfo(req)
|
||||||
if err != nil || !requestInfo.IsResourceRequest {
|
if err != nil || !requestInfo.IsResourceRequest {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/probe"
|
"k8s.io/kubernetes/pkg/probe"
|
||||||
httpprober "k8s.io/kubernetes/pkg/probe/http"
|
httpprober "k8s.io/kubernetes/pkg/probe/http"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func (server *Server) DoServerCheck(prober httpprober.HTTPProber) (probe.Result,
|
||||||
if server.EnableHTTPS {
|
if server.EnableHTTPS {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
}
|
}
|
||||||
url := util.FormatURL(scheme, server.Addr, server.Port, server.Path)
|
url := utilnet.FormatURL(scheme, server.Addr, server.Port, server.Path)
|
||||||
|
|
||||||
result, data, err := prober.Probe(url, probeTimeOut)
|
result, data, err := prober.Probe(url, probeTimeOut)
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
// chaosrt provides the ability to perform simulations of HTTP client failures
|
// chaosrt provides the ability to perform simulations of HTTP client failures
|
||||||
|
@ -88,7 +88,7 @@ func (rt *chaosrt) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
return rt.rt.RoundTrip(req)
|
return rt.rt.RoundTrip(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = util.RoundTripperWrapper(&chaosrt{})
|
var _ = net.RoundTripperWrapper(&chaosrt{})
|
||||||
|
|
||||||
func (rt *chaosrt) WrappedRoundTripper() http.RoundTripper {
|
func (rt *chaosrt) WrappedRoundTripper() http.RoundTripper {
|
||||||
return rt.rt
|
return rt.rt
|
||||||
|
|
|
@ -40,7 +40,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/fields"
|
"k8s.io/kubernetes/pkg/fields"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
"k8s.io/kubernetes/pkg/watch"
|
"k8s.io/kubernetes/pkg/watch"
|
||||||
watchjson "k8s.io/kubernetes/pkg/watch/json"
|
watchjson "k8s.io/kubernetes/pkg/watch/json"
|
||||||
|
@ -637,7 +637,7 @@ func (r *Request) Watch() (watch.Interface, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The watch stream mechanism handles many common partial data errors, so closed
|
// The watch stream mechanism handles many common partial data errors, so closed
|
||||||
// connections can be retried in many cases.
|
// connections can be retried in many cases.
|
||||||
if util.IsProbableEOF(err) {
|
if net.IsProbableEOF(err) {
|
||||||
return watch.NewEmptyWatch(), nil
|
return watch.NewEmptyWatch(), nil
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -18,7 +18,7 @@ package unversioned
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/watch"
|
"k8s.io/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ func (c *services) ProxyGet(scheme, name, port, path string, params map[string]s
|
||||||
Prefix("proxy").
|
Prefix("proxy").
|
||||||
Namespace(c.ns).
|
Namespace(c.ns).
|
||||||
Resource("services").
|
Resource("services").
|
||||||
Name(util.JoinSchemeNamePort(scheme, name, port)).
|
Name(net.JoinSchemeNamePort(scheme, name, port)).
|
||||||
Suffix(path)
|
Suffix(path)
|
||||||
for k, v := range params {
|
for k, v := range params {
|
||||||
request = request.Param(k, v)
|
request = request.Param(k, v)
|
||||||
|
|
|
@ -33,7 +33,7 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultClusterName = "mesos"
|
const defaultClusterName = "mesos"
|
||||||
|
@ -111,7 +111,7 @@ func newMesosClient(
|
||||||
md detector.Master,
|
md detector.Master,
|
||||||
mesosHttpClientTimeout, stateCacheTTL time.Duration) (*mesosClient, error) {
|
mesosHttpClientTimeout, stateCacheTTL time.Duration) (*mesosClient, error) {
|
||||||
|
|
||||||
tr := util.SetTransportDefaults(&http.Transport{})
|
tr := utilnet.SetTransportDefaults(&http.Transport{})
|
||||||
httpClient := &http.Client{
|
httpClient := &http.Client{
|
||||||
Transport: tr,
|
Transport: tr,
|
||||||
Timeout: mesosHttpClientTimeout,
|
Timeout: mesosHttpClientTimeout,
|
||||||
|
|
|
@ -43,6 +43,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/storage"
|
"k8s.io/kubernetes/pkg/storage"
|
||||||
"k8s.io/kubernetes/pkg/ui"
|
"k8s.io/kubernetes/pkg/ui"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
|
|
||||||
systemd "github.com/coreos/go-systemd/daemon"
|
systemd "github.com/coreos/go-systemd/daemon"
|
||||||
|
@ -212,7 +213,7 @@ type Config struct {
|
||||||
ServiceReadWriteIP net.IP
|
ServiceReadWriteIP net.IP
|
||||||
|
|
||||||
// The range of ports to be assigned to services with type=NodePort or greater
|
// The range of ports to be assigned to services with type=NodePort or greater
|
||||||
ServiceNodePortRange util.PortRange
|
ServiceNodePortRange utilnet.PortRange
|
||||||
|
|
||||||
// Used to customize default proxy dial/tls options
|
// Used to customize default proxy dial/tls options
|
||||||
ProxyDialer apiserver.ProxyDialerFunc
|
ProxyDialer apiserver.ProxyDialerFunc
|
||||||
|
@ -237,7 +238,7 @@ type Config struct {
|
||||||
type GenericAPIServer struct {
|
type GenericAPIServer struct {
|
||||||
// "Inputs", Copied from Config
|
// "Inputs", Copied from Config
|
||||||
ServiceClusterIPRange *net.IPNet
|
ServiceClusterIPRange *net.IPNet
|
||||||
ServiceNodePortRange util.PortRange
|
ServiceNodePortRange utilnet.PortRange
|
||||||
cacheTimeout time.Duration
|
cacheTimeout time.Duration
|
||||||
MinRequestTimeout time.Duration
|
MinRequestTimeout time.Duration
|
||||||
|
|
||||||
|
@ -319,7 +320,7 @@ func setDefaults(c *Config) {
|
||||||
// We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE)
|
// We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE)
|
||||||
// but then that breaks the strict nestedness of ServiceType.
|
// but then that breaks the strict nestedness of ServiceType.
|
||||||
// Review post-v1
|
// Review post-v1
|
||||||
defaultServiceNodePortRange := util.PortRange{Base: 30000, Size: 2768}
|
defaultServiceNodePortRange := utilnet.PortRange{Base: 30000, Size: 2768}
|
||||||
c.ServiceNodePortRange = defaultServiceNodePortRange
|
c.ServiceNodePortRange = defaultServiceNodePortRange
|
||||||
glog.Infof("Node port range unspecified. Defaulting to %v.", c.ServiceNodePortRange)
|
glog.Infof("Node port range unspecified. Defaulting to %v.", c.ServiceNodePortRange)
|
||||||
}
|
}
|
||||||
|
@ -454,7 +455,7 @@ func NewHandlerContainer(mux *http.ServeMux) *restful.Container {
|
||||||
func (s *GenericAPIServer) init(c *Config) {
|
func (s *GenericAPIServer) init(c *Config) {
|
||||||
|
|
||||||
if c.ProxyDialer != nil || c.ProxyTLSClientConfig != nil {
|
if c.ProxyDialer != nil || c.ProxyTLSClientConfig != nil {
|
||||||
s.ProxyTransport = util.SetTransportDefaults(&http.Transport{
|
s.ProxyTransport = utilnet.SetTransportDefaults(&http.Transport{
|
||||||
Dial: c.ProxyDialer,
|
Dial: c.ProxyDialer,
|
||||||
TLSClientConfig: c.ProxyTLSClientConfig,
|
TLSClientConfig: c.ProxyTLSClientConfig,
|
||||||
})
|
})
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
"k8s.io/kubernetes/pkg/apiserver"
|
"k8s.io/kubernetes/pkg/apiserver"
|
||||||
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -77,7 +77,7 @@ func TestNew(t *testing.T) {
|
||||||
assert.Equal(s.ServiceReadWriteIP, config.ServiceReadWriteIP)
|
assert.Equal(s.ServiceReadWriteIP, config.ServiceReadWriteIP)
|
||||||
|
|
||||||
// These functions should point to the same memory location
|
// These functions should point to the same memory location
|
||||||
serverDialer, _ := util.Dialer(s.ProxyTransport)
|
serverDialer, _ := utilnet.Dialer(s.ProxyTransport)
|
||||||
serverDialerFunc := fmt.Sprintf("%p", serverDialer)
|
serverDialerFunc := fmt.Sprintf("%p", serverDialer)
|
||||||
configDialerFunc := fmt.Sprintf("%p", config.ProxyDialer)
|
configDialerFunc := fmt.Sprintf("%p", config.ProxyDialer)
|
||||||
assert.Equal(serverDialerFunc, configDialerFunc)
|
assert.Equal(serverDialerFunc, configDialerFunc)
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
"k8s.io/kubernetes/pkg/client/transport"
|
"k8s.io/kubernetes/pkg/client/transport"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type KubeletClientConfig struct {
|
type KubeletClientConfig struct {
|
||||||
|
@ -71,7 +71,7 @@ func MakeTransport(config *KubeletClientConfig) (http.RoundTripper, error) {
|
||||||
|
|
||||||
rt := http.DefaultTransport
|
rt := http.DefaultTransport
|
||||||
if config.Dial != nil || tlsConfig != nil {
|
if config.Dial != nil || tlsConfig != nil {
|
||||||
rt = util.SetTransportDefaults(&http.Transport{
|
rt = utilnet.SetTransportDefaults(&http.Transport{
|
||||||
Dial: config.Dial,
|
Dial: config.Dial,
|
||||||
TLSClientConfig: tlsConfig,
|
TLSClientConfig: tlsConfig,
|
||||||
})
|
})
|
||||||
|
|
|
@ -73,6 +73,7 @@ import (
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
kubeio "k8s.io/kubernetes/pkg/util/io"
|
kubeio "k8s.io/kubernetes/pkg/util/io"
|
||||||
"k8s.io/kubernetes/pkg/util/mount"
|
"k8s.io/kubernetes/pkg/util/mount"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
||||||
"k8s.io/kubernetes/pkg/util/oom"
|
"k8s.io/kubernetes/pkg/util/oom"
|
||||||
"k8s.io/kubernetes/pkg/util/procfs"
|
"k8s.io/kubernetes/pkg/util/procfs"
|
||||||
|
@ -2677,7 +2678,7 @@ func (kl *Kubelet) setNodeAddress(node *api.Node) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(node.Status.Addresses) == 0 {
|
if len(node.Status.Addresses) == 0 {
|
||||||
ip, err := util.ChooseHostInterface()
|
ip, err := utilnet.ChooseHostInterface()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/endpoints"
|
"k8s.io/kubernetes/pkg/api/endpoints"
|
||||||
"k8s.io/kubernetes/pkg/api/errors"
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
|
@ -32,8 +33,7 @@ import (
|
||||||
portallocatorcontroller "k8s.io/kubernetes/pkg/registry/service/portallocator/controller"
|
portallocatorcontroller "k8s.io/kubernetes/pkg/registry/service/portallocator/controller"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"github.com/golang/glog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Controller is the controller manager for the core bootstrap Kubernetes controller
|
// Controller is the controller manager for the core bootstrap Kubernetes controller
|
||||||
|
@ -51,7 +51,7 @@ type Controller struct {
|
||||||
|
|
||||||
ServiceNodePortRegistry service.RangeRegistry
|
ServiceNodePortRegistry service.RangeRegistry
|
||||||
ServiceNodePortInterval time.Duration
|
ServiceNodePortInterval time.Duration
|
||||||
ServiceNodePortRange util.PortRange
|
ServiceNodePortRange utilnet.PortRange
|
||||||
|
|
||||||
EndpointRegistry endpoint.Registry
|
EndpointRegistry endpoint.Registry
|
||||||
EndpointInterval time.Duration
|
EndpointInterval time.Duration
|
||||||
|
|
|
@ -33,6 +33,8 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
apiutil "k8s.io/kubernetes/pkg/api/util"
|
apiutil "k8s.io/kubernetes/pkg/api/util"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/client"
|
"k8s.io/kubernetes/pkg/kubelet/client"
|
||||||
|
@ -44,7 +46,6 @@ import (
|
||||||
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
||||||
"k8s.io/kubernetes/pkg/storage/etcd/etcdtest"
|
"k8s.io/kubernetes/pkg/storage/etcd/etcdtest"
|
||||||
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
|
|
||||||
"github.com/emicklei/go-restful"
|
"github.com/emicklei/go-restful"
|
||||||
|
@ -110,7 +111,7 @@ func TestNew(t *testing.T) {
|
||||||
assert.Equal(master.ServiceReadWriteIP, config.ServiceReadWriteIP)
|
assert.Equal(master.ServiceReadWriteIP, config.ServiceReadWriteIP)
|
||||||
|
|
||||||
// These functions should point to the same memory location
|
// These functions should point to the same memory location
|
||||||
masterDialer, _ := util.Dialer(master.ProxyTransport)
|
masterDialer, _ := utilnet.Dialer(master.ProxyTransport)
|
||||||
masterDialerFunc := fmt.Sprintf("%p", masterDialer)
|
masterDialerFunc := fmt.Sprintf("%p", masterDialer)
|
||||||
configDialerFunc := fmt.Sprintf("%p", config.ProxyDialer)
|
configDialerFunc := fmt.Sprintf("%p", config.ProxyDialer)
|
||||||
assert.Equal(masterDialerFunc, configDialerFunc)
|
assert.Equal(masterDialerFunc, configDialerFunc)
|
||||||
|
@ -164,7 +165,7 @@ func TestNewBootstrapController(t *testing.T) {
|
||||||
master, etcdserver, _, assert := setUp(t)
|
master, etcdserver, _, assert := setUp(t)
|
||||||
defer etcdserver.Terminate(t)
|
defer etcdserver.Terminate(t)
|
||||||
|
|
||||||
portRange := util.PortRange{Base: 10, Size: 10}
|
portRange := utilnet.PortRange{Base: 10, Size: 10}
|
||||||
|
|
||||||
master.namespaceRegistry = namespace.NewRegistry(nil)
|
master.namespaceRegistry = namespace.NewRegistry(nil)
|
||||||
master.serviceRegistry = registrytest.NewServiceRegistry()
|
master.serviceRegistry = registrytest.NewServiceRegistry()
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -52,7 +53,7 @@ func (r *randomAllocator) Release(_ int) {
|
||||||
// newPortAllocator builds PortAllocator for a given PortRange. If the PortRange is empty
|
// newPortAllocator builds PortAllocator for a given PortRange. If the PortRange is empty
|
||||||
// then a random port allocator is returned; otherwise, a new range-based allocator
|
// then a random port allocator is returned; otherwise, a new range-based allocator
|
||||||
// is returned.
|
// is returned.
|
||||||
func newPortAllocator(r util.PortRange) PortAllocator {
|
func newPortAllocator(r net.PortRange) PortAllocator {
|
||||||
if r.Base == 0 {
|
if r.Base == 0 {
|
||||||
return &randomAllocator{}
|
return &randomAllocator{}
|
||||||
}
|
}
|
||||||
|
@ -66,14 +67,14 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type rangeAllocator struct {
|
type rangeAllocator struct {
|
||||||
util.PortRange
|
net.PortRange
|
||||||
ports chan int
|
ports chan int
|
||||||
used big.Int
|
used big.Int
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
rand *rand.Rand
|
rand *rand.Rand
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPortRangeAllocator(r util.PortRange) PortAllocator {
|
func newPortRangeAllocator(r net.PortRange) PortAllocator {
|
||||||
if r.Base == 0 || r.Size == 0 {
|
if r.Base == 0 || r.Size == 0 {
|
||||||
panic("illegal argument: may not specify an empty port range")
|
panic("illegal argument: may not specify an empty port range")
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRangeAllocatorEmpty(t *testing.T) {
|
func TestRangeAllocatorEmpty(t *testing.T) {
|
||||||
r := &util.PortRange{}
|
r := &net.PortRange{}
|
||||||
r.Set("0-0")
|
r.Set("0-0")
|
||||||
defer func() {
|
defer func() {
|
||||||
if rv := recover(); rv == nil {
|
if rv := recover(); rv == nil {
|
||||||
|
@ -35,7 +35,7 @@ func TestRangeAllocatorEmpty(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRangeAllocatorFullyAllocated(t *testing.T) {
|
func TestRangeAllocatorFullyAllocated(t *testing.T) {
|
||||||
r := &util.PortRange{}
|
r := &net.PortRange{}
|
||||||
r.Set("1-1")
|
r.Set("1-1")
|
||||||
a := newPortRangeAllocator(*r)
|
a := newPortRangeAllocator(*r)
|
||||||
p, err := a.AllocateNext()
|
p, err := a.AllocateNext()
|
||||||
|
@ -67,7 +67,7 @@ func TestRangeAllocatorFullyAllocated(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRangeAllocator_RandomishAllocation(t *testing.T) {
|
func TestRangeAllocator_RandomishAllocation(t *testing.T) {
|
||||||
r := &util.PortRange{}
|
r := &net.PortRange{}
|
||||||
r.Set("1-100")
|
r.Set("1-100")
|
||||||
a := newPortRangeAllocator(*r)
|
a := newPortRangeAllocator(*r)
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/proxy"
|
"k8s.io/kubernetes/pkg/proxy"
|
||||||
"k8s.io/kubernetes/pkg/types"
|
"k8s.io/kubernetes/pkg/types"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
"k8s.io/kubernetes/pkg/util/iptables"
|
"k8s.io/kubernetes/pkg/util/iptables"
|
||||||
)
|
)
|
||||||
|
@ -137,12 +139,12 @@ func IsProxyLocked(err error) bool {
|
||||||
// if iptables fails to update or acquire the initial lock. Once a proxier is
|
// if iptables fails to update or acquire the initial lock. Once a proxier is
|
||||||
// created, it will keep iptables up to date in the background and will not
|
// created, it will keep iptables up to date in the background and will not
|
||||||
// terminate if a particular iptables call fails.
|
// terminate if a particular iptables call fails.
|
||||||
func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, pr util.PortRange, syncPeriod, udpIdleTimeout time.Duration) (*Proxier, error) {
|
func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, pr utilnet.PortRange, syncPeriod, udpIdleTimeout time.Duration) (*Proxier, error) {
|
||||||
if listenIP.Equal(localhostIPv4) || listenIP.Equal(localhostIPv6) {
|
if listenIP.Equal(localhostIPv4) || listenIP.Equal(localhostIPv6) {
|
||||||
return nil, ErrProxyOnLocalhost
|
return nil, ErrProxyOnLocalhost
|
||||||
}
|
}
|
||||||
|
|
||||||
hostIP, err := util.ChooseHostInterface()
|
hostIP, err := utilnet.ChooseHostInterface()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to select a host interface: %v", err)
|
return nil, fmt.Errorf("failed to select a host interface: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -161,7 +163,7 @@ func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.In
|
||||||
func createProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, hostIP net.IP, proxyPorts PortAllocator, syncPeriod, udpIdleTimeout time.Duration) (*Proxier, error) {
|
func createProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, hostIP net.IP, proxyPorts PortAllocator, syncPeriod, udpIdleTimeout time.Duration) (*Proxier, error) {
|
||||||
// convenient to pass nil for tests..
|
// convenient to pass nil for tests..
|
||||||
if proxyPorts == nil {
|
if proxyPorts == nil {
|
||||||
proxyPorts = newPortAllocator(util.PortRange{})
|
proxyPorts = newPortAllocator(utilnet.PortRange{})
|
||||||
}
|
}
|
||||||
// Set up the iptables foundations we need.
|
// Set up the iptables foundations we need.
|
||||||
if err := iptablesInit(iptables); err != nil {
|
if err := iptablesInit(iptables); err != nil {
|
||||||
|
|
|
@ -26,8 +26,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api/errors"
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
|
||||||
"k8s.io/kubernetes/pkg/util/httpstream"
|
"k8s.io/kubernetes/pkg/util/httpstream"
|
||||||
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/proxy"
|
"k8s.io/kubernetes/pkg/util/proxy"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
@ -226,7 +226,7 @@ func (p *corsRemovingTransport) RoundTrip(req *http.Request) (*http.Response, er
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = util.RoundTripperWrapper(&corsRemovingTransport{})
|
var _ = net.RoundTripperWrapper(&corsRemovingTransport{})
|
||||||
|
|
||||||
func (rt *corsRemovingTransport) WrappedRoundTripper() http.RoundTripper {
|
func (rt *corsRemovingTransport) WrappedRoundTripper() http.RoundTripper {
|
||||||
return rt.RoundTripper
|
return rt.RoundTripper
|
||||||
|
|
|
@ -32,7 +32,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/master/ports"
|
"k8s.io/kubernetes/pkg/master/ports"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
||||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
@ -162,7 +162,7 @@ func MatchNode(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||||
|
|
||||||
// ResourceLocation returns an URL and transport which one can use to send traffic for the specified node.
|
// ResourceLocation returns an URL and transport which one can use to send traffic for the specified node.
|
||||||
func ResourceLocation(getter ResourceGetter, connection client.ConnectionInfoGetter, proxyTransport http.RoundTripper, ctx api.Context, id string) (*url.URL, http.RoundTripper, error) {
|
func ResourceLocation(getter ResourceGetter, connection client.ConnectionInfoGetter, proxyTransport http.RoundTripper, ctx api.Context, id string) (*url.URL, http.RoundTripper, error) {
|
||||||
schemeReq, name, portReq, valid := util.SplitSchemeNamePort(id)
|
schemeReq, name, portReq, valid := utilnet.SplitSchemeNamePort(id)
|
||||||
if !valid {
|
if !valid {
|
||||||
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid node request %q", id))
|
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid node request %q", id))
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ func getPod(getter ResourceGetter, ctx api.Context, name string) (*api.Pod, erro
|
||||||
func ResourceLocation(getter ResourceGetter, rt http.RoundTripper, ctx api.Context, id string) (*url.URL, http.RoundTripper, error) {
|
func ResourceLocation(getter ResourceGetter, rt http.RoundTripper, ctx api.Context, id string) (*url.URL, http.RoundTripper, error) {
|
||||||
// Allow ID as "podname" or "podname:port" or "scheme:podname:port".
|
// Allow ID as "podname" or "podname:port" or "scheme:podname:port".
|
||||||
// If port is not specified, try to use the first defined port on the pod.
|
// If port is not specified, try to use the first defined port on the pod.
|
||||||
scheme, name, port, valid := util.SplitSchemeNamePort(id)
|
scheme, name, port, valid := utilnet.SplitSchemeNamePort(id)
|
||||||
if !valid {
|
if !valid {
|
||||||
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid pod request %q", id))
|
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid pod request %q", id))
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/registry/service/allocator"
|
"k8s.io/kubernetes/pkg/registry/service/allocator"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
@ -43,7 +43,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type PortAllocator struct {
|
type PortAllocator struct {
|
||||||
portRange util.PortRange
|
portRange net.PortRange
|
||||||
|
|
||||||
alloc allocator.Interface
|
alloc allocator.Interface
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,8 @@ type PortAllocator struct {
|
||||||
// PortAllocator implements Interface and Snapshottable
|
// PortAllocator implements Interface and Snapshottable
|
||||||
var _ Interface = &PortAllocator{}
|
var _ Interface = &PortAllocator{}
|
||||||
|
|
||||||
// NewPortAllocatorCustom creates a PortAllocator over a util.PortRange, calling allocatorFactory to construct the backing store.
|
// NewPortAllocatorCustom creates a PortAllocator over a net.PortRange, calling allocatorFactory to construct the backing store.
|
||||||
func NewPortAllocatorCustom(pr util.PortRange, allocatorFactory allocator.AllocatorFactory) *PortAllocator {
|
func NewPortAllocatorCustom(pr net.PortRange, allocatorFactory allocator.AllocatorFactory) *PortAllocator {
|
||||||
max := pr.Size
|
max := pr.Size
|
||||||
rangeSpec := pr.String()
|
rangeSpec := pr.String()
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func NewPortAllocatorCustom(pr util.PortRange, allocatorFactory allocator.Alloca
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper that wraps NewAllocatorCIDRRange, for creating a range backed by an in-memory store.
|
// Helper that wraps NewAllocatorCIDRRange, for creating a range backed by an in-memory store.
|
||||||
func NewPortAllocator(pr util.PortRange) *PortAllocator {
|
func NewPortAllocator(pr net.PortRange) *PortAllocator {
|
||||||
return NewPortAllocatorCustom(pr, func(max int, rangeSpec string) allocator.Interface {
|
return NewPortAllocatorCustom(pr, func(max int, rangeSpec string) allocator.Interface {
|
||||||
return allocator.NewAllocationMap(max, rangeSpec)
|
return allocator.NewAllocationMap(max, rangeSpec)
|
||||||
})
|
})
|
||||||
|
@ -146,7 +146,7 @@ func (r *PortAllocator) Snapshot(dst *api.RangeAllocation) error {
|
||||||
|
|
||||||
// Restore restores the pool to the previously captured state. ErrMismatchedNetwork
|
// Restore restores the pool to the previously captured state. ErrMismatchedNetwork
|
||||||
// is returned if the provided port range doesn't exactly match the previous range.
|
// is returned if the provided port range doesn't exactly match the previous range.
|
||||||
func (r *PortAllocator) Restore(pr util.PortRange, data []byte) error {
|
func (r *PortAllocator) Restore(pr net.PortRange, data []byte) error {
|
||||||
if pr.String() != r.portRange.String() {
|
if pr.String() != r.portRange.String() {
|
||||||
return ErrMismatchedNetwork
|
return ErrMismatchedNetwork
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAllocate(t *testing.T) {
|
func TestAllocate(t *testing.T) {
|
||||||
pr, err := util.ParsePortRange("10000-10200")
|
pr, err := net.ParsePortRange("10000-10200")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ func TestAllocate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSnapshot(t *testing.T) {
|
func TestSnapshot(t *testing.T) {
|
||||||
pr, err := util.ParsePortRange("10000-10200")
|
pr, err := net.ParsePortRange("10000-10200")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ func TestSnapshot(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pr2, err := util.ParsePortRange(dst.Range)
|
pr2, err := net.ParsePortRange(dst.Range)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ func TestSnapshot(t *testing.T) {
|
||||||
t.Fatalf("mismatched networks: %s : %s", pr, pr2)
|
t.Fatalf("mismatched networks: %s : %s", pr, pr2)
|
||||||
}
|
}
|
||||||
|
|
||||||
otherPr, err := util.ParsePortRange("200-300")
|
otherPr, err := net.ParsePortRange("200-300")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,19 +24,20 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/registry/service"
|
"k8s.io/kubernetes/pkg/registry/service"
|
||||||
"k8s.io/kubernetes/pkg/registry/service/portallocator"
|
"k8s.io/kubernetes/pkg/registry/service/portallocator"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
// See ipallocator/controller/repair.go; this is a copy for ports.
|
// See ipallocator/controller/repair.go; this is a copy for ports.
|
||||||
type Repair struct {
|
type Repair struct {
|
||||||
interval time.Duration
|
interval time.Duration
|
||||||
registry service.Registry
|
registry service.Registry
|
||||||
portRange util.PortRange
|
portRange net.PortRange
|
||||||
alloc service.RangeRegistry
|
alloc service.RangeRegistry
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRepair creates a controller that periodically ensures that all ports are uniquely allocated across the cluster
|
// NewRepair creates a controller that periodically ensures that all ports are uniquely allocated across the cluster
|
||||||
// and generates informational warnings for a cluster that is not in sync.
|
// and generates informational warnings for a cluster that is not in sync.
|
||||||
func NewRepair(interval time.Duration, registry service.Registry, portRange util.PortRange, alloc service.RangeRegistry) *Repair {
|
func NewRepair(interval time.Duration, registry service.Registry, portRange net.PortRange, alloc service.RangeRegistry) *Repair {
|
||||||
return &Repair{
|
return &Repair{
|
||||||
interval: interval,
|
interval: interval,
|
||||||
registry: registry,
|
registry: registry,
|
||||||
|
|
|
@ -34,7 +34,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/registry/service/ipallocator"
|
"k8s.io/kubernetes/pkg/registry/service/ipallocator"
|
||||||
"k8s.io/kubernetes/pkg/registry/service/portallocator"
|
"k8s.io/kubernetes/pkg/registry/service/portallocator"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/pkg/watch"
|
"k8s.io/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
@ -287,7 +287,7 @@ var _ = rest.Redirector(&REST{})
|
||||||
// ResourceLocation returns a URL to which one can send traffic for the specified service.
|
// ResourceLocation returns a URL to which one can send traffic for the specified service.
|
||||||
func (rs *REST) ResourceLocation(ctx api.Context, id string) (*url.URL, http.RoundTripper, error) {
|
func (rs *REST) ResourceLocation(ctx api.Context, id string) (*url.URL, http.RoundTripper, error) {
|
||||||
// Allow ID as "svcname", "svcname:port", or "scheme:svcname:port".
|
// Allow ID as "svcname", "svcname:port", or "scheme:svcname:port".
|
||||||
svcScheme, svcName, portStr, valid := util.SplitSchemeNamePort(id)
|
svcScheme, svcName, portStr, valid := utilnet.SplitSchemeNamePort(id)
|
||||||
if !valid {
|
if !valid {
|
||||||
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid service request %q", id))
|
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid service request %q", id))
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,8 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||||
"k8s.io/kubernetes/pkg/registry/service/ipallocator"
|
"k8s.io/kubernetes/pkg/registry/service/ipallocator"
|
||||||
"k8s.io/kubernetes/pkg/registry/service/portallocator"
|
"k8s.io/kubernetes/pkg/registry/service/portallocator"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ func NewTestREST(t *testing.T, endpoints *api.EndpointsList) (*REST, *registryte
|
||||||
}
|
}
|
||||||
r := ipallocator.NewCIDRRange(makeIPNet(t))
|
r := ipallocator.NewCIDRRange(makeIPNet(t))
|
||||||
|
|
||||||
portRange := util.PortRange{Base: 30000, Size: 1000}
|
portRange := utilnet.PortRange{Base: 30000, Size: 1000}
|
||||||
portAllocator := portallocator.NewPortAllocator(portRange)
|
portAllocator := portallocator.NewPortAllocator(portRange)
|
||||||
|
|
||||||
storage := NewStorage(registry, endpointRegistry, r, portAllocator, nil)
|
storage := NewStorage(registry, endpointRegistry, r, portAllocator, nil)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package util
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
@ -111,3 +111,12 @@ func FormatURL(scheme string, host string, port int, path string) *url.URL {
|
||||||
Path: path,
|
Path: path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetHTTPClient(req *http.Request) string {
|
||||||
|
if userAgent, ok := req.Header["User-Agent"]; ok {
|
||||||
|
if len(userAgent) > 0 {
|
||||||
|
return userAgent[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
|
@ -0,0 +1,278 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
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 net
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Route struct {
|
||||||
|
Interface string
|
||||||
|
Destination net.IP
|
||||||
|
Gateway net.IP
|
||||||
|
// TODO: add more fields here if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRoutes(input io.Reader) ([]Route, error) {
|
||||||
|
routes := []Route{}
|
||||||
|
if input == nil {
|
||||||
|
return nil, fmt.Errorf("input is nil")
|
||||||
|
}
|
||||||
|
scanner := bufio.NewReader(input)
|
||||||
|
for {
|
||||||
|
line, err := scanner.ReadString('\n')
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
//ignore the headers in the route info
|
||||||
|
if strings.HasPrefix(line, "Iface") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
routes = append(routes, Route{})
|
||||||
|
route := &routes[len(routes)-1]
|
||||||
|
route.Interface = fields[0]
|
||||||
|
ip, err := parseIP(fields[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
route.Destination = ip
|
||||||
|
ip, err = parseIP(fields[2])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
route.Gateway = ip
|
||||||
|
}
|
||||||
|
return routes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseIP(str string) (net.IP, error) {
|
||||||
|
if str == "" {
|
||||||
|
return nil, fmt.Errorf("input is nil")
|
||||||
|
}
|
||||||
|
bytes, err := hex.DecodeString(str)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//TODO add ipv6 support
|
||||||
|
if len(bytes) != net.IPv4len {
|
||||||
|
return nil, fmt.Errorf("only IPv4 is supported")
|
||||||
|
}
|
||||||
|
bytes[0], bytes[1], bytes[2], bytes[3] = bytes[3], bytes[2], bytes[1], bytes[0]
|
||||||
|
return net.IP(bytes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isInterfaceUp(intf *net.Interface) bool {
|
||||||
|
if intf == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if intf.Flags&net.FlagUp != 0 {
|
||||||
|
glog.V(4).Infof("Interface %v is up", intf.Name)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//getFinalIP method receives all the IP addrs of a Interface
|
||||||
|
//and returns a nil if the address is Loopback, Ipv6, link-local or nil.
|
||||||
|
//It returns a valid IPv4 if an Ipv4 address is found in the array.
|
||||||
|
func getFinalIP(addrs []net.Addr) (net.IP, error) {
|
||||||
|
if len(addrs) > 0 {
|
||||||
|
for i := range addrs {
|
||||||
|
glog.V(4).Infof("Checking addr %s.", addrs[i].String())
|
||||||
|
ip, _, err := net.ParseCIDR(addrs[i].String())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//Only IPv4
|
||||||
|
//TODO : add IPv6 support
|
||||||
|
if ip.To4() != nil {
|
||||||
|
if !ip.IsLoopback() && !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
|
||||||
|
glog.V(4).Infof("IP found %v", ip)
|
||||||
|
return ip, nil
|
||||||
|
} else {
|
||||||
|
glog.V(4).Infof("Loopback/link-local found %v", ip)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glog.V(4).Infof("%v is not a valid IPv4 address", ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIPFromInterface(intfName string, nw networkInterfacer) (net.IP, error) {
|
||||||
|
intf, err := nw.InterfaceByName(intfName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isInterfaceUp(intf) {
|
||||||
|
addrs, err := nw.Addrs(intf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
glog.V(4).Infof("Interface %q has %d addresses :%v.", intfName, len(addrs), addrs)
|
||||||
|
finalIP, err := getFinalIP(addrs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if finalIP != nil {
|
||||||
|
glog.V(4).Infof("valid IPv4 address for interface %q found as %v.", intfName, finalIP)
|
||||||
|
return finalIP, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func flagsSet(flags net.Flags, test net.Flags) bool {
|
||||||
|
return flags&test != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func flagsClear(flags net.Flags, test net.Flags) bool {
|
||||||
|
return flags&test == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func chooseHostInterfaceNativeGo() (net.IP, error) {
|
||||||
|
intfs, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
i := 0
|
||||||
|
var ip net.IP
|
||||||
|
for i = range intfs {
|
||||||
|
if flagsSet(intfs[i].Flags, net.FlagUp) && flagsClear(intfs[i].Flags, net.FlagLoopback|net.FlagPointToPoint) {
|
||||||
|
addrs, err := intfs[i].Addrs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(addrs) > 0 {
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if addrIP, _, err := net.ParseCIDR(addr.String()); err == nil {
|
||||||
|
if addrIP.To4() != nil {
|
||||||
|
ip = addrIP.To4()
|
||||||
|
if !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ip != nil {
|
||||||
|
// This interface should suffice.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ip == nil {
|
||||||
|
return nil, fmt.Errorf("no acceptable interface from host")
|
||||||
|
}
|
||||||
|
glog.V(4).Infof("Choosing interface %s (IP %v) as default", intfs[i].Name, ip)
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//ChooseHostInterface is a method used fetch an IP for a daemon.
|
||||||
|
//It uses data from /proc/net/route file.
|
||||||
|
//For a node with no internet connection ,it returns error
|
||||||
|
//For a multi n/w interface node it returns the IP of the interface with gateway on it.
|
||||||
|
func ChooseHostInterface() (net.IP, error) {
|
||||||
|
inFile, err := os.Open("/proc/net/route")
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return chooseHostInterfaceNativeGo()
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer inFile.Close()
|
||||||
|
var nw networkInterfacer = networkInterface{}
|
||||||
|
return chooseHostInterfaceFromRoute(inFile, nw)
|
||||||
|
}
|
||||||
|
|
||||||
|
type networkInterfacer interface {
|
||||||
|
InterfaceByName(intfName string) (*net.Interface, error)
|
||||||
|
Addrs(intf *net.Interface) ([]net.Addr, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type networkInterface struct{}
|
||||||
|
|
||||||
|
func (_ networkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
|
||||||
|
intf, err := net.InterfaceByName(intfName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return intf, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ networkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||||
|
addrs, err := intf.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return addrs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func chooseHostInterfaceFromRoute(inFile io.Reader, nw networkInterfacer) (net.IP, error) {
|
||||||
|
routes, err := getRoutes(inFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
zero := net.IP{0, 0, 0, 0}
|
||||||
|
var finalIP net.IP
|
||||||
|
for i := range routes {
|
||||||
|
//find interface with gateway
|
||||||
|
if routes[i].Destination.Equal(zero) {
|
||||||
|
glog.V(4).Infof("Default route transits interface %q", routes[i].Interface)
|
||||||
|
finalIP, err := getIPFromInterface(routes[i].Interface, nw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if finalIP != nil {
|
||||||
|
glog.V(4).Infof("Choosing IP %v ", finalIP)
|
||||||
|
return finalIP, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glog.V(4).Infof("No valid IP found")
|
||||||
|
if finalIP == nil {
|
||||||
|
return nil, fmt.Errorf("Unable to select an IP.")
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If bind-address is usable, return it directly
|
||||||
|
// If bind-address is not usable (unset, 0.0.0.0, or loopback), we will use the host's default
|
||||||
|
// interface.
|
||||||
|
func ChooseBindAddress(bindAddress net.IP) (net.IP, error) {
|
||||||
|
if bindAddress == nil || bindAddress.IsUnspecified() || bindAddress.IsLoopback() {
|
||||||
|
hostIP, err := ChooseHostInterface()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bindAddress = hostIP
|
||||||
|
}
|
||||||
|
return bindAddress, nil
|
||||||
|
}
|
|
@ -0,0 +1,300 @@
|
||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
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 net
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const gatewayfirst = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
|
||||||
|
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
||||||
|
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
||||||
|
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||||
|
`
|
||||||
|
const gatewaylast = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
||||||
|
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||||
|
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
||||||
|
eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
|
||||||
|
`
|
||||||
|
const gatewaymiddle = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
||||||
|
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
||||||
|
eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
|
||||||
|
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||||
|
`
|
||||||
|
const noInternetConnection = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
||||||
|
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||||
|
`
|
||||||
|
const nothing = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
`
|
||||||
|
const gatewayfirstIpv6_1 = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
|
||||||
|
eth3 0000FE0AA1 00000000 0001 0 0 0 0080FFFF 0 0 0
|
||||||
|
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
||||||
|
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||||
|
`
|
||||||
|
const gatewayfirstIpv6_2 = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth3 00000000 0100FE0AA1 0003 0 0 1024 00000000 0 0 0
|
||||||
|
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
||||||
|
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
||||||
|
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||||
|
`
|
||||||
|
const route_Invalidhex = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth3 00000000 0100FE0AA 0003 0 0 1024 00000000 0 0 0
|
||||||
|
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
||||||
|
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
||||||
|
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||||
|
`
|
||||||
|
|
||||||
|
// Based on DigitalOcean COREOS
|
||||||
|
const gatewayfirstLinkLocal = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth0 00000000 0120372D 0001 0 0 0 00000000 0 0 0
|
||||||
|
eth0 00000000 00000000 0001 0 0 2048 00000000 0 0 0
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestGetRoutes(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
tcase string
|
||||||
|
route string
|
||||||
|
expected int
|
||||||
|
}{
|
||||||
|
{"gatewayfirst", gatewayfirst, 4},
|
||||||
|
{"gatewaymiddle", gatewaymiddle, 4},
|
||||||
|
{"gatewaylast", gatewaylast, 4},
|
||||||
|
{"nothing", nothing, 0},
|
||||||
|
{"gatewayfirstIpv6_1", gatewayfirstIpv6_1, 0},
|
||||||
|
{"gatewayfirstIpv6_2", gatewayfirstIpv6_2, 0},
|
||||||
|
{"route_Invalidhex", route_Invalidhex, 0},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
r := strings.NewReader(tc.route)
|
||||||
|
routes, err := getRoutes(r)
|
||||||
|
if len(routes) != tc.expected {
|
||||||
|
t.Errorf("case[%v]: expected %v, got %v .err : %v", tc.tcase, tc.expected, len(routes), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseIP(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
tcase string
|
||||||
|
ip string
|
||||||
|
success bool
|
||||||
|
expected net.IP
|
||||||
|
}{
|
||||||
|
{"empty", "", false, nil},
|
||||||
|
{"too short", "AA", false, nil},
|
||||||
|
{"too long", "0011223344", false, nil},
|
||||||
|
{"invalid", "invalid!", false, nil},
|
||||||
|
{"zero", "00000000", true, net.IP{0, 0, 0, 0}},
|
||||||
|
{"ffff", "FFFFFFFF", true, net.IP{0xff, 0xff, 0xff, 0xff}},
|
||||||
|
{"valid", "12345678", true, net.IP{120, 86, 52, 18}},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
ip, err := parseIP(tc.ip)
|
||||||
|
if !ip.Equal(tc.expected) {
|
||||||
|
t.Errorf("case[%v]: expected %q, got %q . err : %v", tc.tcase, tc.expected, ip, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsInterfaceUp(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
tcase string
|
||||||
|
intf net.Interface
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{"up", net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}, true},
|
||||||
|
{"down", net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: 0}, false},
|
||||||
|
{"nothing", net.Interface{}, false},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
it := isInterfaceUp(&tc.intf)
|
||||||
|
if it != tc.expected {
|
||||||
|
t.Errorf("case[%v]: expected %v, got %v .", tc.tcase, tc.expected, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type addrStruct struct{ val string }
|
||||||
|
|
||||||
|
func (a addrStruct) Network() string {
|
||||||
|
return a.val
|
||||||
|
}
|
||||||
|
func (a addrStruct) String() string {
|
||||||
|
return a.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFinalIP(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
tcase string
|
||||||
|
addr []net.Addr
|
||||||
|
expected net.IP
|
||||||
|
}{
|
||||||
|
{"ipv6", []net.Addr{addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}}, nil},
|
||||||
|
{"invalidCIDR", []net.Addr{addrStruct{val: "fe80::2f7:67fff:fe6e:2956/64"}}, nil},
|
||||||
|
{"loopback", []net.Addr{addrStruct{val: "127.0.0.1/24"}}, nil},
|
||||||
|
{"ip4", []net.Addr{addrStruct{val: "10.254.12.132/17"}}, net.ParseIP("10.254.12.132")},
|
||||||
|
|
||||||
|
{"nothing", []net.Addr{}, nil},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
ip, err := getFinalIP(tc.addr)
|
||||||
|
if !ip.Equal(tc.expected) {
|
||||||
|
t.Errorf("case[%v]: expected %v, got %v .err : %v", tc.tcase, tc.expected, ip, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddrs(t *testing.T) {
|
||||||
|
var nw networkInterfacer = validNetworkInterface{}
|
||||||
|
intf := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: 0}
|
||||||
|
addrs, err := nw.Addrs(&intf)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error got : %v", err)
|
||||||
|
}
|
||||||
|
if len(addrs) != 2 {
|
||||||
|
t.Errorf("expected addrs: 2 got null")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type validNetworkInterface struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ validNetworkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
|
||||||
|
c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
func (_ validNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||||
|
var ifat []net.Addr
|
||||||
|
ifat = []net.Addr{
|
||||||
|
addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}, addrStruct{val: "10.254.71.145/17"}}
|
||||||
|
return ifat, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type validNetworkInterfaceWithLinkLocal struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ validNetworkInterfaceWithLinkLocal) InterfaceByName(intfName string) (*net.Interface, error) {
|
||||||
|
c := net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: net.FlagUp}
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
func (_ validNetworkInterfaceWithLinkLocal) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||||
|
var ifat []net.Addr
|
||||||
|
ifat = []net.Addr{addrStruct{val: "169.254.162.166/16"}, addrStruct{val: "45.55.47.146/19"}}
|
||||||
|
return ifat, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type validNetworkInterfacewithIpv6Only struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ validNetworkInterfacewithIpv6Only) InterfaceByName(intfName string) (*net.Interface, error) {
|
||||||
|
c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
func (_ validNetworkInterfacewithIpv6Only) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||||
|
var ifat []net.Addr
|
||||||
|
ifat = []net.Addr{addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}}
|
||||||
|
return ifat, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type noNetworkInterface struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ noNetworkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
|
||||||
|
return nil, fmt.Errorf("unable get Interface")
|
||||||
|
}
|
||||||
|
func (_ noNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type networkInterfacewithNoAddrs struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ networkInterfacewithNoAddrs) InterfaceByName(intfName string) (*net.Interface, error) {
|
||||||
|
c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
func (_ networkInterfacewithNoAddrs) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||||
|
return nil, fmt.Errorf("unable get Addrs")
|
||||||
|
}
|
||||||
|
|
||||||
|
type networkInterfacewithIpv6addrs struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ networkInterfacewithIpv6addrs) InterfaceByName(intfName string) (*net.Interface, error) {
|
||||||
|
c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
func (_ networkInterfacewithIpv6addrs) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||||
|
var ifat []net.Addr
|
||||||
|
ifat = []net.Addr{addrStruct{val: "fe80::2f7:6ffff:fe6e:2956/64"}}
|
||||||
|
return ifat, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetIPFromInterface(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
tcase string
|
||||||
|
nwname string
|
||||||
|
nw networkInterfacer
|
||||||
|
expected net.IP
|
||||||
|
}{
|
||||||
|
{"valid", "eth3", validNetworkInterface{}, net.ParseIP("10.254.71.145")},
|
||||||
|
{"ipv6", "eth3", validNetworkInterfacewithIpv6Only{}, nil},
|
||||||
|
{"nothing", "eth3", noNetworkInterface{}, nil},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
ip, err := getIPFromInterface(tc.nwname, tc.nw)
|
||||||
|
if !ip.Equal(tc.expected) {
|
||||||
|
t.Errorf("case[%v]: expected %v, got %+v .err : %v", tc.tcase, tc.expected, ip, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChooseHostInterfaceFromRoute(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
tcase string
|
||||||
|
inFile io.Reader
|
||||||
|
nw networkInterfacer
|
||||||
|
expected net.IP
|
||||||
|
}{
|
||||||
|
{"valid_routefirst", strings.NewReader(gatewayfirst), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
|
||||||
|
{"valid_routelast", strings.NewReader(gatewaylast), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
|
||||||
|
{"valid_routemiddle", strings.NewReader(gatewaymiddle), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
|
||||||
|
{"valid_routemiddle_ipv6", strings.NewReader(gatewaymiddle), validNetworkInterfacewithIpv6Only{}, nil},
|
||||||
|
{"no internet connection", strings.NewReader(noInternetConnection), validNetworkInterface{}, nil},
|
||||||
|
{"no non-link-local ip", strings.NewReader(gatewayfirstLinkLocal), validNetworkInterfaceWithLinkLocal{}, net.ParseIP("45.55.47.146")},
|
||||||
|
{"no route", strings.NewReader(nothing), validNetworkInterface{}, nil},
|
||||||
|
{"no route file", nil, validNetworkInterface{}, nil},
|
||||||
|
{"no interfaces", nil, noNetworkInterface{}, nil},
|
||||||
|
{"no interface Addrs", strings.NewReader(gatewaymiddle), networkInterfacewithNoAddrs{}, nil},
|
||||||
|
{"Invalid Addrs", strings.NewReader(gatewaymiddle), networkInterfacewithIpv6addrs{}, nil},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
ip, err := chooseHostInterfaceFromRoute(tc.inFile, tc.nw)
|
||||||
|
if !ip.Equal(tc.expected) {
|
||||||
|
t.Errorf("case[%v]: expected %v, got %+v .err : %v", tc.tcase, tc.expected, ip, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package util
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package util
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package util
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package util
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -25,14 +25,14 @@ import (
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/util"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/third_party/golang/netutil"
|
"k8s.io/kubernetes/third_party/golang/netutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DialURL(url *url.URL, transport http.RoundTripper) (net.Conn, error) {
|
func DialURL(url *url.URL, transport http.RoundTripper) (net.Conn, error) {
|
||||||
dialAddr := netutil.CanonicalAddr(url)
|
dialAddr := netutil.CanonicalAddr(url)
|
||||||
|
|
||||||
dialer, _ := util.Dialer(transport)
|
dialer, _ := utilnet.Dialer(transport)
|
||||||
|
|
||||||
switch url.Scheme {
|
switch url.Scheme {
|
||||||
case "http":
|
case "http":
|
||||||
|
@ -45,7 +45,7 @@ func DialURL(url *url.URL, transport http.RoundTripper) (net.Conn, error) {
|
||||||
var tlsConfig *tls.Config
|
var tlsConfig *tls.Config
|
||||||
var tlsConn *tls.Conn
|
var tlsConn *tls.Conn
|
||||||
var err error
|
var err error
|
||||||
tlsConfig, _ = util.TLSClientConfig(transport)
|
tlsConfig, _ = utilnet.TLSClientConfig(transport)
|
||||||
|
|
||||||
if dialer != nil {
|
if dialer != nil {
|
||||||
// We have a dialer; use it to open the connection, then
|
// We have a dialer; use it to open the connection, then
|
||||||
|
|
|
@ -31,7 +31,7 @@ import (
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
"golang.org/x/net/html/atom"
|
"golang.org/x/net/html/atom"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
return t.rewriteResponse(req, resp)
|
return t.rewriteResponse(req, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = util.RoundTripperWrapper(&Transport{})
|
var _ = net.RoundTripperWrapper(&Transport{})
|
||||||
|
|
||||||
func (rt *Transport) WrappedRoundTripper() http.RoundTripper {
|
func (rt *Transport) WrappedRoundTripper() http.RoundTripper {
|
||||||
return rt.RoundTripper
|
return rt.RoundTripper
|
||||||
|
|
262
pkg/util/util.go
262
pkg/util/util.go
|
@ -17,13 +17,8 @@ limitations under the License.
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"math"
|
"math"
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -203,249 +198,6 @@ func AllPtrFieldsNil(obj interface{}) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
type Route struct {
|
|
||||||
Interface string
|
|
||||||
Destination net.IP
|
|
||||||
Gateway net.IP
|
|
||||||
// TODO: add more fields here if needed
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRoutes(input io.Reader) ([]Route, error) {
|
|
||||||
routes := []Route{}
|
|
||||||
if input == nil {
|
|
||||||
return nil, fmt.Errorf("input is nil")
|
|
||||||
}
|
|
||||||
scanner := bufio.NewReader(input)
|
|
||||||
for {
|
|
||||||
line, err := scanner.ReadString('\n')
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
//ignore the headers in the route info
|
|
||||||
if strings.HasPrefix(line, "Iface") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fields := strings.Fields(line)
|
|
||||||
routes = append(routes, Route{})
|
|
||||||
route := &routes[len(routes)-1]
|
|
||||||
route.Interface = fields[0]
|
|
||||||
ip, err := parseIP(fields[1])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
route.Destination = ip
|
|
||||||
ip, err = parseIP(fields[2])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
route.Gateway = ip
|
|
||||||
}
|
|
||||||
return routes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseIP(str string) (net.IP, error) {
|
|
||||||
if str == "" {
|
|
||||||
return nil, fmt.Errorf("input is nil")
|
|
||||||
}
|
|
||||||
bytes, err := hex.DecodeString(str)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//TODO add ipv6 support
|
|
||||||
if len(bytes) != net.IPv4len {
|
|
||||||
return nil, fmt.Errorf("only IPv4 is supported")
|
|
||||||
}
|
|
||||||
bytes[0], bytes[1], bytes[2], bytes[3] = bytes[3], bytes[2], bytes[1], bytes[0]
|
|
||||||
return net.IP(bytes), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isInterfaceUp(intf *net.Interface) bool {
|
|
||||||
if intf == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if intf.Flags&net.FlagUp != 0 {
|
|
||||||
glog.V(4).Infof("Interface %v is up", intf.Name)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
//getFinalIP method receives all the IP addrs of a Interface
|
|
||||||
//and returns a nil if the address is Loopback, Ipv6, link-local or nil.
|
|
||||||
//It returns a valid IPv4 if an Ipv4 address is found in the array.
|
|
||||||
func getFinalIP(addrs []net.Addr) (net.IP, error) {
|
|
||||||
if len(addrs) > 0 {
|
|
||||||
for i := range addrs {
|
|
||||||
glog.V(4).Infof("Checking addr %s.", addrs[i].String())
|
|
||||||
ip, _, err := net.ParseCIDR(addrs[i].String())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//Only IPv4
|
|
||||||
//TODO : add IPv6 support
|
|
||||||
if ip.To4() != nil {
|
|
||||||
if !ip.IsLoopback() && !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
|
|
||||||
glog.V(4).Infof("IP found %v", ip)
|
|
||||||
return ip, nil
|
|
||||||
} else {
|
|
||||||
glog.V(4).Infof("Loopback/link-local found %v", ip)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
glog.V(4).Infof("%v is not a valid IPv4 address", ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getIPFromInterface(intfName string, nw networkInterfacer) (net.IP, error) {
|
|
||||||
intf, err := nw.InterfaceByName(intfName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if isInterfaceUp(intf) {
|
|
||||||
addrs, err := nw.Addrs(intf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
glog.V(4).Infof("Interface %q has %d addresses :%v.", intfName, len(addrs), addrs)
|
|
||||||
finalIP, err := getFinalIP(addrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if finalIP != nil {
|
|
||||||
glog.V(4).Infof("valid IPv4 address for interface %q found as %v.", intfName, finalIP)
|
|
||||||
return finalIP, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func flagsSet(flags net.Flags, test net.Flags) bool {
|
|
||||||
return flags&test != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func flagsClear(flags net.Flags, test net.Flags) bool {
|
|
||||||
return flags&test == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func chooseHostInterfaceNativeGo() (net.IP, error) {
|
|
||||||
intfs, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
i := 0
|
|
||||||
var ip net.IP
|
|
||||||
for i = range intfs {
|
|
||||||
if flagsSet(intfs[i].Flags, net.FlagUp) && flagsClear(intfs[i].Flags, net.FlagLoopback|net.FlagPointToPoint) {
|
|
||||||
addrs, err := intfs[i].Addrs()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(addrs) > 0 {
|
|
||||||
for _, addr := range addrs {
|
|
||||||
if addrIP, _, err := net.ParseCIDR(addr.String()); err == nil {
|
|
||||||
if addrIP.To4() != nil {
|
|
||||||
ip = addrIP.To4()
|
|
||||||
if !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ip != nil {
|
|
||||||
// This interface should suffice.
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ip == nil {
|
|
||||||
return nil, fmt.Errorf("no acceptable interface from host")
|
|
||||||
}
|
|
||||||
glog.V(4).Infof("Choosing interface %s (IP %v) as default", intfs[i].Name, ip)
|
|
||||||
return ip, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//ChooseHostInterface is a method used fetch an IP for a daemon.
|
|
||||||
//It uses data from /proc/net/route file.
|
|
||||||
//For a node with no internet connection ,it returns error
|
|
||||||
//For a multi n/w interface node it returns the IP of the interface with gateway on it.
|
|
||||||
func ChooseHostInterface() (net.IP, error) {
|
|
||||||
inFile, err := os.Open("/proc/net/route")
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return chooseHostInterfaceNativeGo()
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer inFile.Close()
|
|
||||||
var nw networkInterfacer = networkInterface{}
|
|
||||||
return chooseHostInterfaceFromRoute(inFile, nw)
|
|
||||||
}
|
|
||||||
|
|
||||||
type networkInterfacer interface {
|
|
||||||
InterfaceByName(intfName string) (*net.Interface, error)
|
|
||||||
Addrs(intf *net.Interface) ([]net.Addr, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type networkInterface struct{}
|
|
||||||
|
|
||||||
func (_ networkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
|
|
||||||
intf, err := net.InterfaceByName(intfName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return intf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ networkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
|
||||||
addrs, err := intf.Addrs()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return addrs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func chooseHostInterfaceFromRoute(inFile io.Reader, nw networkInterfacer) (net.IP, error) {
|
|
||||||
routes, err := getRoutes(inFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
zero := net.IP{0, 0, 0, 0}
|
|
||||||
var finalIP net.IP
|
|
||||||
for i := range routes {
|
|
||||||
//find interface with gateway
|
|
||||||
if routes[i].Destination.Equal(zero) {
|
|
||||||
glog.V(4).Infof("Default route transits interface %q", routes[i].Interface)
|
|
||||||
finalIP, err := getIPFromInterface(routes[i].Interface, nw)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if finalIP != nil {
|
|
||||||
glog.V(4).Infof("Choosing IP %v ", finalIP)
|
|
||||||
return finalIP, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glog.V(4).Infof("No valid IP found")
|
|
||||||
if finalIP == nil {
|
|
||||||
return nil, fmt.Errorf("Unable to select an IP.")
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetClient(req *http.Request) string {
|
|
||||||
if userAgent, ok := req.Header["User-Agent"]; ok {
|
|
||||||
if len(userAgent) > 0 {
|
|
||||||
return userAgent[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
func FileExists(filename string) (bool, error) {
|
func FileExists(filename string) (bool, error) {
|
||||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -486,17 +238,3 @@ func ReadDirNoExit(dirname string) ([]os.FileInfo, []error, error) {
|
||||||
|
|
||||||
return list, errs, nil
|
return list, errs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If bind-address is usable, return it directly
|
|
||||||
// If bind-address is not usable (unset, 0.0.0.0, or loopback), we will use the host's default
|
|
||||||
// interface.
|
|
||||||
func ValidPublicAddrForMaster(bindAddress net.IP) (net.IP, error) {
|
|
||||||
if bindAddress == nil || bindAddress.IsUnspecified() || bindAddress.IsLoopback() {
|
|
||||||
hostIP, err := ChooseHostInterface()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
bindAddress = hostIP
|
|
||||||
}
|
|
||||||
return bindAddress, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,9 +18,6 @@ package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -182,278 +179,3 @@ func TestAllPtrFieldsNil(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const gatewayfirst = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
|
|
||||||
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
|
||||||
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
|
||||||
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
|
||||||
`
|
|
||||||
const gatewaylast = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
|
||||||
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
|
||||||
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
|
||||||
eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
|
|
||||||
`
|
|
||||||
const gatewaymiddle = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
|
||||||
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
|
||||||
eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
|
|
||||||
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
|
||||||
`
|
|
||||||
const noInternetConnection = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
|
||||||
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
|
||||||
`
|
|
||||||
const nothing = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
`
|
|
||||||
const gatewayfirstIpv6_1 = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
|
|
||||||
eth3 0000FE0AA1 00000000 0001 0 0 0 0080FFFF 0 0 0
|
|
||||||
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
|
||||||
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
|
||||||
`
|
|
||||||
const gatewayfirstIpv6_2 = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
eth3 00000000 0100FE0AA1 0003 0 0 1024 00000000 0 0 0
|
|
||||||
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
|
||||||
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
|
||||||
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
|
||||||
`
|
|
||||||
const route_Invalidhex = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
eth3 00000000 0100FE0AA 0003 0 0 1024 00000000 0 0 0
|
|
||||||
eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
|
|
||||||
docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
|
|
||||||
virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
|
||||||
`
|
|
||||||
|
|
||||||
// Based on DigitalOcean COREOS
|
|
||||||
const gatewayfirstLinkLocal = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
|
||||||
eth0 00000000 0120372D 0001 0 0 0 00000000 0 0 0
|
|
||||||
eth0 00000000 00000000 0001 0 0 2048 00000000 0 0 0
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestGetRoutes(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
tcase string
|
|
||||||
route string
|
|
||||||
expected int
|
|
||||||
}{
|
|
||||||
{"gatewayfirst", gatewayfirst, 4},
|
|
||||||
{"gatewaymiddle", gatewaymiddle, 4},
|
|
||||||
{"gatewaylast", gatewaylast, 4},
|
|
||||||
{"nothing", nothing, 0},
|
|
||||||
{"gatewayfirstIpv6_1", gatewayfirstIpv6_1, 0},
|
|
||||||
{"gatewayfirstIpv6_2", gatewayfirstIpv6_2, 0},
|
|
||||||
{"route_Invalidhex", route_Invalidhex, 0},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
r := strings.NewReader(tc.route)
|
|
||||||
routes, err := getRoutes(r)
|
|
||||||
if len(routes) != tc.expected {
|
|
||||||
t.Errorf("case[%v]: expected %v, got %v .err : %v", tc.tcase, tc.expected, len(routes), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseIP(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
tcase string
|
|
||||||
ip string
|
|
||||||
success bool
|
|
||||||
expected net.IP
|
|
||||||
}{
|
|
||||||
{"empty", "", false, nil},
|
|
||||||
{"too short", "AA", false, nil},
|
|
||||||
{"too long", "0011223344", false, nil},
|
|
||||||
{"invalid", "invalid!", false, nil},
|
|
||||||
{"zero", "00000000", true, net.IP{0, 0, 0, 0}},
|
|
||||||
{"ffff", "FFFFFFFF", true, net.IP{0xff, 0xff, 0xff, 0xff}},
|
|
||||||
{"valid", "12345678", true, net.IP{120, 86, 52, 18}},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
ip, err := parseIP(tc.ip)
|
|
||||||
if !ip.Equal(tc.expected) {
|
|
||||||
t.Errorf("case[%v]: expected %q, got %q . err : %v", tc.tcase, tc.expected, ip, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsInterfaceUp(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
tcase string
|
|
||||||
intf net.Interface
|
|
||||||
expected bool
|
|
||||||
}{
|
|
||||||
{"up", net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}, true},
|
|
||||||
{"down", net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: 0}, false},
|
|
||||||
{"nothing", net.Interface{}, false},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
it := isInterfaceUp(&tc.intf)
|
|
||||||
if it != tc.expected {
|
|
||||||
t.Errorf("case[%v]: expected %v, got %v .", tc.tcase, tc.expected, it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type addrStruct struct{ val string }
|
|
||||||
|
|
||||||
func (a addrStruct) Network() string {
|
|
||||||
return a.val
|
|
||||||
}
|
|
||||||
func (a addrStruct) String() string {
|
|
||||||
return a.val
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFinalIP(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
tcase string
|
|
||||||
addr []net.Addr
|
|
||||||
expected net.IP
|
|
||||||
}{
|
|
||||||
{"ipv6", []net.Addr{addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}}, nil},
|
|
||||||
{"invalidCIDR", []net.Addr{addrStruct{val: "fe80::2f7:67fff:fe6e:2956/64"}}, nil},
|
|
||||||
{"loopback", []net.Addr{addrStruct{val: "127.0.0.1/24"}}, nil},
|
|
||||||
{"ip4", []net.Addr{addrStruct{val: "10.254.12.132/17"}}, net.ParseIP("10.254.12.132")},
|
|
||||||
|
|
||||||
{"nothing", []net.Addr{}, nil},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
ip, err := getFinalIP(tc.addr)
|
|
||||||
if !ip.Equal(tc.expected) {
|
|
||||||
t.Errorf("case[%v]: expected %v, got %v .err : %v", tc.tcase, tc.expected, ip, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAddrs(t *testing.T) {
|
|
||||||
var nw networkInterfacer = validNetworkInterface{}
|
|
||||||
intf := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: 0}
|
|
||||||
addrs, err := nw.Addrs(&intf)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("expected no error got : %v", err)
|
|
||||||
}
|
|
||||||
if len(addrs) != 2 {
|
|
||||||
t.Errorf("expected addrs: 2 got null")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type validNetworkInterface struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ validNetworkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
|
|
||||||
c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
func (_ validNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
|
||||||
var ifat []net.Addr
|
|
||||||
ifat = []net.Addr{
|
|
||||||
addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}, addrStruct{val: "10.254.71.145/17"}}
|
|
||||||
return ifat, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type validNetworkInterfaceWithLinkLocal struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ validNetworkInterfaceWithLinkLocal) InterfaceByName(intfName string) (*net.Interface, error) {
|
|
||||||
c := net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: net.FlagUp}
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
func (_ validNetworkInterfaceWithLinkLocal) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
|
||||||
var ifat []net.Addr
|
|
||||||
ifat = []net.Addr{addrStruct{val: "169.254.162.166/16"}, addrStruct{val: "45.55.47.146/19"}}
|
|
||||||
return ifat, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type validNetworkInterfacewithIpv6Only struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ validNetworkInterfacewithIpv6Only) InterfaceByName(intfName string) (*net.Interface, error) {
|
|
||||||
c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
func (_ validNetworkInterfacewithIpv6Only) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
|
||||||
var ifat []net.Addr
|
|
||||||
ifat = []net.Addr{addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}}
|
|
||||||
return ifat, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type noNetworkInterface struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ noNetworkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
|
|
||||||
return nil, fmt.Errorf("unable get Interface")
|
|
||||||
}
|
|
||||||
func (_ noNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type networkInterfacewithNoAddrs struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ networkInterfacewithNoAddrs) InterfaceByName(intfName string) (*net.Interface, error) {
|
|
||||||
c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
func (_ networkInterfacewithNoAddrs) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
|
||||||
return nil, fmt.Errorf("unable get Addrs")
|
|
||||||
}
|
|
||||||
|
|
||||||
type networkInterfacewithIpv6addrs struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ networkInterfacewithIpv6addrs) InterfaceByName(intfName string) (*net.Interface, error) {
|
|
||||||
c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
func (_ networkInterfacewithIpv6addrs) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
|
||||||
var ifat []net.Addr
|
|
||||||
ifat = []net.Addr{addrStruct{val: "fe80::2f7:6ffff:fe6e:2956/64"}}
|
|
||||||
return ifat, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetIPFromInterface(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
tcase string
|
|
||||||
nwname string
|
|
||||||
nw networkInterfacer
|
|
||||||
expected net.IP
|
|
||||||
}{
|
|
||||||
{"valid", "eth3", validNetworkInterface{}, net.ParseIP("10.254.71.145")},
|
|
||||||
{"ipv6", "eth3", validNetworkInterfacewithIpv6Only{}, nil},
|
|
||||||
{"nothing", "eth3", noNetworkInterface{}, nil},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
ip, err := getIPFromInterface(tc.nwname, tc.nw)
|
|
||||||
if !ip.Equal(tc.expected) {
|
|
||||||
t.Errorf("case[%v]: expected %v, got %+v .err : %v", tc.tcase, tc.expected, ip, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChooseHostInterfaceFromRoute(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
tcase string
|
|
||||||
inFile io.Reader
|
|
||||||
nw networkInterfacer
|
|
||||||
expected net.IP
|
|
||||||
}{
|
|
||||||
{"valid_routefirst", strings.NewReader(gatewayfirst), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
|
|
||||||
{"valid_routelast", strings.NewReader(gatewaylast), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
|
|
||||||
{"valid_routemiddle", strings.NewReader(gatewaymiddle), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
|
|
||||||
{"valid_routemiddle_ipv6", strings.NewReader(gatewaymiddle), validNetworkInterfacewithIpv6Only{}, nil},
|
|
||||||
{"no internet connection", strings.NewReader(noInternetConnection), validNetworkInterface{}, nil},
|
|
||||||
{"no non-link-local ip", strings.NewReader(gatewayfirstLinkLocal), validNetworkInterfaceWithLinkLocal{}, net.ParseIP("45.55.47.146")},
|
|
||||||
{"no route", strings.NewReader(nothing), validNetworkInterface{}, nil},
|
|
||||||
{"no route file", nil, validNetworkInterface{}, nil},
|
|
||||||
{"no interfaces", nil, noNetworkInterface{}, nil},
|
|
||||||
{"no interface Addrs", strings.NewReader(gatewaymiddle), networkInterfacewithNoAddrs{}, nil},
|
|
||||||
{"Invalid Addrs", strings.NewReader(gatewaymiddle), networkInterfacewithIpv6addrs{}, nil},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
ip, err := chooseHostInterfaceFromRoute(tc.inFile, tc.nw)
|
|
||||||
if !ip.Equal(tc.expected) {
|
|
||||||
t.Errorf("case[%v]: expected %v, got %+v .err : %v", tc.tcase, tc.expected, ip, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Decoder allows StreamWatcher to watch any stream for which a Decoder can be written.
|
// Decoder allows StreamWatcher to watch any stream for which a Decoder can be written.
|
||||||
|
@ -102,7 +103,7 @@ func (sw *StreamWatcher) receive() {
|
||||||
glog.V(1).Infof("Unexpected EOF during watch stream event decoding: %v", err)
|
glog.V(1).Infof("Unexpected EOF during watch stream event decoding: %v", err)
|
||||||
default:
|
default:
|
||||||
msg := "Unable to decode an event from the watch stream: %v"
|
msg := "Unable to decode an event from the watch stream: %v"
|
||||||
if util.IsProbableEOF(err) {
|
if net.IsProbableEOF(err) {
|
||||||
glog.V(5).Infof(msg, err)
|
glog.V(5).Infof(msg, err)
|
||||||
} else {
|
} else {
|
||||||
glog.Errorf(msg, err)
|
glog.Errorf(msg, err)
|
||||||
|
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"k8s.io/kubernetes/pkg/auth/user"
|
"k8s.io/kubernetes/pkg/auth/user"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -72,7 +73,7 @@ func New(issuerURL, clientID, caFile, usernameClaim string) (*OIDCAuthenticator,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copied from http.DefaultTransport.
|
// Copied from http.DefaultTransport.
|
||||||
tr := util.SetTransportDefaults(&http.Transport{
|
tr := net.SetTransportDefaults(&http.Transport{
|
||||||
// According to golang's doc, if RootCAs is nil,
|
// According to golang's doc, if RootCAs is nil,
|
||||||
// TLS uses the host's root CA set.
|
// TLS uses the host's root CA set.
|
||||||
TLSClientConfig: &tls.Config{RootCAs: roots},
|
TLSClientConfig: &tls.Config{RootCAs: roots},
|
||||||
|
|
|
@ -27,8 +27,8 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
|
"k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
@ -133,13 +133,13 @@ func proxyContext(version string) {
|
||||||
|
|
||||||
// Try proxying through the service and directly to through the pod.
|
// Try proxying through the service and directly to through the pod.
|
||||||
svcProxyURL := func(scheme, port string) string {
|
svcProxyURL := func(scheme, port string) string {
|
||||||
return prefix + "/proxy/namespaces/" + f.Namespace.Name + "/services/" + util.JoinSchemeNamePort(scheme, service.Name, port)
|
return prefix + "/proxy/namespaces/" + f.Namespace.Name + "/services/" + net.JoinSchemeNamePort(scheme, service.Name, port)
|
||||||
}
|
}
|
||||||
podProxyURL := func(scheme, port string) string {
|
podProxyURL := func(scheme, port string) string {
|
||||||
return prefix + "/proxy/namespaces/" + f.Namespace.Name + "/pods/" + util.JoinSchemeNamePort(scheme, pods[0].Name, port)
|
return prefix + "/proxy/namespaces/" + f.Namespace.Name + "/pods/" + net.JoinSchemeNamePort(scheme, pods[0].Name, port)
|
||||||
}
|
}
|
||||||
subresourcePodProxyURL := func(scheme, port string) string {
|
subresourcePodProxyURL := func(scheme, port string) string {
|
||||||
return prefix + "/namespaces/" + f.Namespace.Name + "/pods/" + util.JoinSchemeNamePort(scheme, pods[0].Name, port) + "/proxy"
|
return prefix + "/namespaces/" + f.Namespace.Name + "/pods/" + net.JoinSchemeNamePort(scheme, pods[0].Name, port) + "/proxy"
|
||||||
}
|
}
|
||||||
expectations := map[string]string{
|
expectations := map[string]string{
|
||||||
svcProxyURL("", "portname1") + "/": "foo",
|
svcProxyURL("", "portname1") + "/": "foo",
|
||||||
|
|
|
@ -35,12 +35,13 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/types"
|
"k8s.io/kubernetes/pkg/types"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This should match whatever the default/configured range is
|
// This should match whatever the default/configured range is
|
||||||
var ServiceNodePortRange = util.PortRange{Base: 30000, Size: 2768}
|
var ServiceNodePortRange = utilnet.PortRange{Base: 30000, Size: 2768}
|
||||||
|
|
||||||
var _ = Describe("Services", func() {
|
var _ = Describe("Services", func() {
|
||||||
f := NewFramework("services")
|
f := NewFramework("services")
|
||||||
|
|
Loading…
Reference in New Issue