From 9f5aa467b4ce14bb7c0450d538f4c9aeb274cd07 Mon Sep 17 00:00:00 2001 From: Josh Robson Chase Date: Thu, 30 Nov 2023 12:47:15 -0500 Subject: [PATCH] tunneldriver: use the ngrok-go provided forwarding mechanism --- go.mod | 2 +- go.sum | 2 + internal/mocks/conn.go | 149 ------------------------- internal/mocks/dialer.go | 50 --------- internal/mocks/gen.go | 7 -- internal/mocks/tunnel.go | 191 -------------------------------- pkg/tunneldriver/driver.go | 109 +++--------------- pkg/tunneldriver/driver_test.go | 52 --------- tools.go | 1 - 9 files changed, 18 insertions(+), 545 deletions(-) delete mode 100644 internal/mocks/conn.go delete mode 100644 internal/mocks/dialer.go delete mode 100644 internal/mocks/gen.go delete mode 100644 internal/mocks/tunnel.go delete mode 100644 pkg/tunneldriver/driver_test.go diff --git a/go.mod b/go.mod index e749ee76..7a9b0c4e 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/onsi/gomega v1.27.10 github.com/spf13/cobra v1.7.0 github.com/stretchr/testify v1.8.4 - golang.ngrok.com/ngrok v1.7.0 + golang.ngrok.com/ngrok v1.9.1 golang.org/x/exp v0.0.0-20231006140011-7918f672742d golang.org/x/sync v0.5.0 k8s.io/api v0.28.3 diff --git a/go.sum b/go.sum index af5ae9d7..92275a63 100644 --- a/go.sum +++ b/go.sum @@ -582,6 +582,8 @@ golang.ngrok.com/muxado/v2 v2.0.0 h1:bu9eIDhRdYNtIXNnqat/HyMeHYOAbUH55ebD7gTvW6c golang.ngrok.com/muxado/v2 v2.0.0/go.mod h1:wzxJYX4xiAtmwumzL+QsukVwFRXmPNv86vB8RPpOxyM= golang.ngrok.com/ngrok v1.7.0 h1:xwcr8QWue+ehgn54hdQwTya4B6A1qXg6+IRim6WINmA= golang.ngrok.com/ngrok v1.7.0/go.mod h1:ruVcXZ7Rre5O9oeqqa8uZCB3Xtkt2PoyjF3eW9b7t6A= +golang.ngrok.com/ngrok v1.9.1 h1:hZCZ7E0t4Jhf3m3AB7YZKSZKH5lEZ5Q6C+T2hlkt8jE= +golang.ngrok.com/ngrok v1.9.1/go.mod h1:DrWT2BcTdcnHMsP/bHEIP/Ebs0pN5VVYDpbZ3bWrwY4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/internal/mocks/conn.go b/internal/mocks/conn.go deleted file mode 100644 index f3343148..00000000 --- a/internal/mocks/conn.go +++ /dev/null @@ -1,149 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: net (interfaces: Conn) - -// Package mocks is a generated GoMock package. -package mocks - -import ( - gomock "github.com/golang/mock/gomock" - net "net" - reflect "reflect" - time "time" -) - -// MockConn is a mock of Conn interface -type MockConn struct { - ctrl *gomock.Controller - recorder *MockConnMockRecorder -} - -// MockConnMockRecorder is the mock recorder for MockConn -type MockConnMockRecorder struct { - mock *MockConn -} - -// NewMockConn creates a new mock instance -func NewMockConn(ctrl *gomock.Controller) *MockConn { - mock := &MockConn{ctrl: ctrl} - mock.recorder = &MockConnMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockConn) EXPECT() *MockConnMockRecorder { - return m.recorder -} - -// Close mocks base method -func (m *MockConn) Close() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close -func (mr *MockConnMockRecorder) Close() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockConn)(nil).Close)) -} - -// LocalAddr mocks base method -func (m *MockConn) LocalAddr() net.Addr { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LocalAddr") - ret0, _ := ret[0].(net.Addr) - return ret0 -} - -// LocalAddr indicates an expected call of LocalAddr -func (mr *MockConnMockRecorder) LocalAddr() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockConn)(nil).LocalAddr)) -} - -// Read mocks base method -func (m *MockConn) Read(arg0 []byte) (int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Read", arg0) - ret0, _ := ret[0].(int) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Read indicates an expected call of Read -func (mr *MockConnMockRecorder) Read(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockConn)(nil).Read), arg0) -} - -// RemoteAddr mocks base method -func (m *MockConn) RemoteAddr() net.Addr { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RemoteAddr") - ret0, _ := ret[0].(net.Addr) - return ret0 -} - -// RemoteAddr indicates an expected call of RemoteAddr -func (mr *MockConnMockRecorder) RemoteAddr() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockConn)(nil).RemoteAddr)) -} - -// SetDeadline mocks base method -func (m *MockConn) SetDeadline(arg0 time.Time) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDeadline", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetDeadline indicates an expected call of SetDeadline -func (mr *MockConnMockRecorder) SetDeadline(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockConn)(nil).SetDeadline), arg0) -} - -// SetReadDeadline mocks base method -func (m *MockConn) SetReadDeadline(arg0 time.Time) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetReadDeadline", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetReadDeadline indicates an expected call of SetReadDeadline -func (mr *MockConnMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockConn)(nil).SetReadDeadline), arg0) -} - -// SetWriteDeadline mocks base method -func (m *MockConn) SetWriteDeadline(arg0 time.Time) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetWriteDeadline", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetWriteDeadline indicates an expected call of SetWriteDeadline -func (mr *MockConnMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockConn)(nil).SetWriteDeadline), arg0) -} - -// Write mocks base method -func (m *MockConn) Write(arg0 []byte) (int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Write", arg0) - ret0, _ := ret[0].(int) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Write indicates an expected call of Write -func (mr *MockConnMockRecorder) Write(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockConn)(nil).Write), arg0) -} diff --git a/internal/mocks/dialer.go b/internal/mocks/dialer.go deleted file mode 100644 index 155f7c62..00000000 --- a/internal/mocks/dialer.go +++ /dev/null @@ -1,50 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ngrok/kubernetes-ingress-controller/pkg/tunneldriver (interfaces: Dialer) - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - gomock "github.com/golang/mock/gomock" - net "net" - reflect "reflect" -) - -// MockDialer is a mock of Dialer interface -type MockDialer struct { - ctrl *gomock.Controller - recorder *MockDialerMockRecorder -} - -// MockDialerMockRecorder is the mock recorder for MockDialer -type MockDialerMockRecorder struct { - mock *MockDialer -} - -// NewMockDialer creates a new mock instance -func NewMockDialer(ctrl *gomock.Controller) *MockDialer { - mock := &MockDialer{ctrl: ctrl} - mock.recorder = &MockDialerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockDialer) EXPECT() *MockDialerMockRecorder { - return m.recorder -} - -// DialContext mocks base method -func (m *MockDialer) DialContext(arg0 context.Context, arg1, arg2 string) (net.Conn, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DialContext", arg0, arg1, arg2) - ret0, _ := ret[0].(net.Conn) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DialContext indicates an expected call of DialContext -func (mr *MockDialerMockRecorder) DialContext(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DialContext", reflect.TypeOf((*MockDialer)(nil).DialContext), arg0, arg1, arg2) -} diff --git a/internal/mocks/gen.go b/internal/mocks/gen.go deleted file mode 100644 index 29a772ca..00000000 --- a/internal/mocks/gen.go +++ /dev/null @@ -1,7 +0,0 @@ -package mocks - -//go:generate go run github.com/golang/mock/mockgen -package mocks -destination conn.go net Conn - -//go:generate go run github.com/golang/mock/mockgen -package mocks -destination tunnel.go golang.ngrok.com/ngrok Tunnel - -//go:generate go run github.com/golang/mock/mockgen -package mocks -destination dialer.go github.com/ngrok/kubernetes-ingress-controller/pkg/tunneldriver Dialer diff --git a/internal/mocks/tunnel.go b/internal/mocks/tunnel.go deleted file mode 100644 index 3ee50931..00000000 --- a/internal/mocks/tunnel.go +++ /dev/null @@ -1,191 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: golang.ngrok.com/ngrok (interfaces: Tunnel) - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - gomock "github.com/golang/mock/gomock" - ngrok "golang.ngrok.com/ngrok" - net "net" - reflect "reflect" -) - -// MockTunnel is a mock of Tunnel interface -type MockTunnel struct { - ctrl *gomock.Controller - recorder *MockTunnelMockRecorder -} - -// MockTunnelMockRecorder is the mock recorder for MockTunnel -type MockTunnelMockRecorder struct { - mock *MockTunnel -} - -// NewMockTunnel creates a new mock instance -func NewMockTunnel(ctrl *gomock.Controller) *MockTunnel { - mock := &MockTunnel{ctrl: ctrl} - mock.recorder = &MockTunnelMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockTunnel) EXPECT() *MockTunnelMockRecorder { - return m.recorder -} - -// Accept mocks base method -func (m *MockTunnel) Accept() (net.Conn, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Accept") - ret0, _ := ret[0].(net.Conn) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Accept indicates an expected call of Accept -func (mr *MockTunnelMockRecorder) Accept() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockTunnel)(nil).Accept)) -} - -// Addr mocks base method -func (m *MockTunnel) Addr() net.Addr { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Addr") - ret0, _ := ret[0].(net.Addr) - return ret0 -} - -// Addr indicates an expected call of Addr -func (mr *MockTunnelMockRecorder) Addr() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addr", reflect.TypeOf((*MockTunnel)(nil).Addr)) -} - -// Close mocks base method -func (m *MockTunnel) Close() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close -func (mr *MockTunnelMockRecorder) Close() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockTunnel)(nil).Close)) -} - -// CloseWithContext mocks base method -func (m *MockTunnel) CloseWithContext(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CloseWithContext", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// CloseWithContext indicates an expected call of CloseWithContext -func (mr *MockTunnelMockRecorder) CloseWithContext(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithContext", reflect.TypeOf((*MockTunnel)(nil).CloseWithContext), arg0) -} - -// ForwardsTo mocks base method -func (m *MockTunnel) ForwardsTo() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ForwardsTo") - ret0, _ := ret[0].(string) - return ret0 -} - -// ForwardsTo indicates an expected call of ForwardsTo -func (mr *MockTunnelMockRecorder) ForwardsTo() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForwardsTo", reflect.TypeOf((*MockTunnel)(nil).ForwardsTo)) -} - -// ID mocks base method -func (m *MockTunnel) ID() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ID") - ret0, _ := ret[0].(string) - return ret0 -} - -// ID indicates an expected call of ID -func (mr *MockTunnelMockRecorder) ID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockTunnel)(nil).ID)) -} - -// Labels mocks base method -func (m *MockTunnel) Labels() map[string]string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Labels") - ret0, _ := ret[0].(map[string]string) - return ret0 -} - -// Labels indicates an expected call of Labels -func (mr *MockTunnelMockRecorder) Labels() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Labels", reflect.TypeOf((*MockTunnel)(nil).Labels)) -} - -// Metadata mocks base method -func (m *MockTunnel) Metadata() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Metadata") - ret0, _ := ret[0].(string) - return ret0 -} - -// Metadata indicates an expected call of Metadata -func (mr *MockTunnelMockRecorder) Metadata() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Metadata", reflect.TypeOf((*MockTunnel)(nil).Metadata)) -} - -// Proto mocks base method -func (m *MockTunnel) Proto() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Proto") - ret0, _ := ret[0].(string) - return ret0 -} - -// Proto indicates an expected call of Proto -func (mr *MockTunnelMockRecorder) Proto() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Proto", reflect.TypeOf((*MockTunnel)(nil).Proto)) -} - -// Session mocks base method -func (m *MockTunnel) Session() ngrok.Session { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Session") - ret0, _ := ret[0].(ngrok.Session) - return ret0 -} - -// Session indicates an expected call of Session -func (mr *MockTunnelMockRecorder) Session() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Session", reflect.TypeOf((*MockTunnel)(nil).Session)) -} - -// URL mocks base method -func (m *MockTunnel) URL() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "URL") - ret0, _ := ret[0].(string) - return ret0 -} - -// URL indicates an expected call of URL -func (mr *MockTunnelMockRecorder) URL() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "URL", reflect.TypeOf((*MockTunnel)(nil).URL)) -} diff --git a/pkg/tunneldriver/driver.go b/pkg/tunneldriver/driver.go index 9edef029..28502c20 100644 --- a/pkg/tunneldriver/driver.go +++ b/pkg/tunneldriver/driver.go @@ -5,10 +5,8 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" - "errors" "fmt" - "io" - "net" + "net/url" "os" "path/filepath" "strings" @@ -18,7 +16,6 @@ import ( ingressv1alpha1 "github.com/ngrok/kubernetes-ingress-controller/api/ingress/v1alpha1" "github.com/ngrok/kubernetes-ingress-controller/internal/version" "golang.org/x/exp/maps" - "golang.org/x/sync/errgroup" "sigs.k8s.io/controller-runtime/pkg/log" "golang.ngrok.com/ngrok" @@ -47,7 +44,7 @@ const ( // TunnelDriver is a driver for creating and deleting ngrok tunnels type TunnelDriver struct { session atomic.Pointer[sessionState] - tunnels map[string]ngrok.Tunnel + tunnels map[string]ngrok.Forwarder } // TunnelDriverOpts are options for creating a new TunnelDriver @@ -123,7 +120,7 @@ func New(ctx context.Context, logger logr.Logger, opts TunnelDriverOpts) (*Tunne } td := &TunnelDriver{ - tunnels: make(map[string]ngrok.Tunnel), + tunnels: make(map[string]ngrok.Forwarder), } td.session.Store(&sessionState{ @@ -267,18 +264,22 @@ func (td *TunnelDriver) CreateTunnel(ctx context.Context, name string, spec ingr defer td.stopTunnel(context.Background(), tun) } - tun, err := session.Listen(ctx, td.buildTunnelConfig(spec.Labels, spec.ForwardsTo, spec.AppProtocol)) + protocol := "tcp" + if spec.BackendConfig != nil { + protocol = spec.BackendConfig.Protocol + } + + destUrlStr := fmt.Sprintf("%s://%s", strings.ToLower(protocol), spec.ForwardsTo) + destUrl, err := url.Parse(destUrlStr) if err != nil { return err } - td.tunnels[name] = tun - protocol := "" - if spec.BackendConfig != nil { - protocol = spec.BackendConfig.Protocol + tun, err := session.ListenAndForward(ctx, destUrl, td.buildTunnelConfig(spec.Labels, spec.ForwardsTo, spec.AppProtocol)) + if err != nil { + return err } - - go handleConnections(ctx, &net.Dialer{}, tun, spec.ForwardsTo, protocol, spec.AppProtocol) + td.tunnels[name] = tun return nil } @@ -301,7 +302,7 @@ func (td *TunnelDriver) DeleteTunnel(ctx context.Context, name string) error { return nil } -func (td *TunnelDriver) stopTunnel(ctx context.Context, tun ngrok.Tunnel) error { +func (td *TunnelDriver) stopTunnel(ctx context.Context, tun ngrok.Forwarder) error { if tun == nil { return nil } @@ -317,83 +318,3 @@ func (td *TunnelDriver) buildTunnelConfig(labels map[string]string, destination, opts = append(opts, config.WithAppProtocol(appProtocol)) return config.LabeledTunnel(opts...) } - -func handleConnections(ctx context.Context, dialer Dialer, tun ngrok.Tunnel, dest string, protocol string, appProtocol string) { - logger := log.FromContext(ctx).WithValues("id", tun.ID(), "protocol", protocol, "dest", dest) - for { - conn, err := tun.Accept() - if err != nil { - logger.Error(err, "Error accepting connection") - // Right now, this can only be "Tunnel closed" https://github.com/ngrok/ngrok-go/blob/e1d90c382/internal/tunnel/client/tunnel.go#L81-L89 - // Since that's terminal, that means we should give up on this loop to - // ensure we don't leak a goroutine after a tunnel goes away. - // Unfortunately, it's not an exported error, so we can't verify with - // more certainty that's what's going on, but at the time of writing, - // that should be true. - return - } - connLogger := logger.WithValues("remoteAddr", conn.RemoteAddr()) - connLogger.Info("Accepted connection") - - go func() { - ctx := log.IntoContext(ctx, connLogger) - err := handleConn(ctx, dest, protocol, appProtocol, dialer, conn) - if err == nil || errors.Is(err, net.ErrClosed) { - connLogger.Info("Connection closed") - return - } - - connLogger.Error(err, "Error handling connection") - }() - } -} - -func handleConn(ctx context.Context, dest string, protocol string, appProtocol string, dialer Dialer, conn net.Conn) error { - log := log.FromContext(ctx) - next, err := dialer.DialContext(ctx, "tcp", dest) - if err != nil { - return err - } - - // Support HTTPS backends - if protocol == "HTTPS" { - host, _, err := net.SplitHostPort(dest) - if err != nil { - host = dest - } - var nextProtos []string - if appProtocol == "http2" { - nextProtos = []string{"h2", "http/1.1"} - } - - next = tls.Client(next, &tls.Config{ - ServerName: host, - InsecureSkipVerify: true, - Renegotiation: tls.RenegotiateFreelyAsClient, - NextProtos: nextProtos, - }) - } - - var g errgroup.Group - g.Go(func() error { - defer func() { - if err := next.Close(); err != nil { - log.Info("Error closing connection to destination: %v", err) - } - }() - - _, err := io.Copy(next, conn) - return err - }) - g.Go(func() error { - defer func() { - if err := conn.Close(); err != nil { - log.Info("Error closing connection from ngrok: %v", err) - } - }() - - _, err := io.Copy(conn, next) - return err - }) - return g.Wait() -} diff --git a/pkg/tunneldriver/driver_test.go b/pkg/tunneldriver/driver_test.go deleted file mode 100644 index 21c21405..00000000 --- a/pkg/tunneldriver/driver_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package tunneldriver - -import ( - "context" - "io" - "net" - "sync" - "testing" - - "github.com/golang/mock/gomock" - "github.com/ngrok/kubernetes-ingress-controller/internal/mocks" -) - -func TestConnectionIsClosed(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - ctrl := gomock.NewController(t) - mockTun := mocks.NewMockTunnel(ctrl) - mockDialer := mocks.NewMockDialer(ctrl) - mockNgrokConn := mocks.NewMockConn(ctrl) - mockBackendConn := mocks.NewMockConn(ctrl) - - bothClosed := sync.WaitGroup{} - bothClosed.Add(2) - - gomock.InOrder( - mockTun.EXPECT().ID().Return("logging id"), - // It should ask ngrok for a connection - mockTun.EXPECT().Accept().Return(mockNgrokConn, nil), - // dial the backend - mockNgrokConn.EXPECT().RemoteAddr().Return(&net.TCPAddr{}), - mockDialer.EXPECT().DialContext(gomock.Any(), "tcp", "target:port").Return(mockBackendConn, nil), - ) - - // both conns should receive a read, and if they EOF get closed. - // This is not in order because it depends on goroutine scheduling which - // happens first - for _, c := range []*mocks.MockConn{mockNgrokConn, mockBackendConn} { - c.EXPECT().Read(gomock.Any()).Return(0, io.EOF) - c.EXPECT().Close().Do(func() { - bothClosed.Done() - }).Return(nil) - } - mockTun.EXPECT().Accept().Do(func() { - select {} - }).AnyTimes() - - go handleConnections(ctx, mockDialer, mockTun, "target:port", "", "") - - bothClosed.Wait() - ctrl.Finish() -} diff --git a/tools.go b/tools.go index a5a65674..3abf6cfa 100644 --- a/tools.go +++ b/tools.go @@ -3,7 +3,6 @@ package main import ( - _ "github.com/golang/mock/mockgen" _ "sigs.k8s.io/controller-runtime/tools/setup-envtest" _ "sigs.k8s.io/controller-tools/cmd/controller-gen" _ "sigs.k8s.io/kustomize/kustomize/v3"