diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 5be259af2..9a2429f6f 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -276,6 +276,9 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, store ipn.StateStor if err != nil { return nil, err } + if sds, ok := store.(ipn.StateStoreDialerSetter); ok { + sds.SetDialer(dialer.SystemDial) + } hi := hostinfo.New() logf.JSON(1, "Hostinfo", hi) diff --git a/ipn/store.go b/ipn/store.go index 33bc391cf..ee5a238a7 100644 --- a/ipn/store.go +++ b/ipn/store.go @@ -4,8 +4,10 @@ package ipn import ( + "context" "errors" "fmt" + "net" "strconv" ) @@ -72,6 +74,12 @@ type StateStore interface { WriteState(id StateKey, bs []byte) error } +// StateStoreDialerSetter is an optional interface that StateStores +// can implement to allow the caller to set a custom dialer. +type StateStoreDialerSetter interface { + SetDialer(d func(ctx context.Context, network, address string) (net.Conn, error)) +} + // ReadStoreInt reads an integer from a StateStore. func ReadStoreInt(store StateStore, id StateKey) (int64, error) { v, err := store.ReadState(id) diff --git a/ipn/store/kubestore/store_kube.go b/ipn/store/kubestore/store_kube.go index b82d041ff..65c73c1bd 100644 --- a/ipn/store/kubestore/store_kube.go +++ b/ipn/store/kubestore/store_kube.go @@ -7,6 +7,7 @@ package kubestore import ( "context" + "net" "strings" "time" @@ -33,6 +34,10 @@ func New(_ logger.Logf, secretName string) (*Store, error) { }, nil } +func (s *Store) SetDialer(d func(ctx context.Context, network, address string) (net.Conn, error)) { + s.client.SetDialer(d) +} + func (s *Store) String() string { return "kube.Store" } // ReadState implements the StateStore interface. diff --git a/kube/client.go b/kube/client.go index 020a8776e..ef62b74ce 100644 --- a/kube/client.go +++ b/kube/client.go @@ -15,6 +15,7 @@ import ( "fmt" "io" "log" + "net" "net/http" "net/url" "os" @@ -90,6 +91,12 @@ func (c *Client) SetURL(url string) { c.url = url } +// SetDialer sets the dialer to use when establishing a connection +// to the Kubernetes API server. +func (c *Client) SetDialer(dialer func(ctx context.Context, network, addr string) (net.Conn, error)) { + c.client.Transport.(*http.Transport).DialContext = dialer +} + func (c *Client) expireToken() { c.mu.Lock() defer c.mu.Unlock()