feat(clientproxy): automatically close boundary connect when proxy is no longer in use (#6232)
Co-authored-by: Andrew Gaffney <andrew@gaffney.cc>
This commit is contained in:
1 parent
d0050ad881
commit
08015e9d98
7 files changed
+289
-48
No files matched your search
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/tests/helper"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/atomic"
|
||||
|
||||
_ "github.com/hashicorp/boundary/internal/daemon/controller/handlers/targets/tcp"
|
||||
)
|
||||
@@ -140,3 +141,99 @@ func TestConnectionsLeft(t *testing.T) {
|
||||
// Wait to ensure cleanup and that the second-start logic works
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestConnectionTimeout(t *testing.T) {
|
||||
require := require.New(t)
|
||||
logger := hclog.New(&hclog.LoggerOptions{
|
||||
Name: t.Name(),
|
||||
Level: hclog.Trace,
|
||||
})
|
||||
|
||||
// Create controller and worker
|
||||
conf, err := config.DevController()
|
||||
require.NoError(err)
|
||||
c1 := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
Config: conf,
|
||||
InitialResourcesSuffix: "1234567890",
|
||||
Logger: logger.Named("c1"),
|
||||
WorkerRPCGracePeriod: helper.DefaultControllerRPCGracePeriod,
|
||||
})
|
||||
helper.ExpectWorkers(t, c1)
|
||||
|
||||
w1 := worker.NewTestWorker(t, &worker.TestWorkerOpts{
|
||||
WorkerAuthKms: c1.Config().WorkerAuthKms,
|
||||
InitialUpstreams: c1.ClusterAddrs(),
|
||||
Logger: logger.Named("w1"),
|
||||
SuccessfulControllerRPCGracePeriodDuration: helper.DefaultControllerRPCGracePeriod,
|
||||
Name: "w1",
|
||||
})
|
||||
helper.ExpectWorkers(t, c1, w1)
|
||||
|
||||
// Connect target
|
||||
client := c1.Client()
|
||||
client.SetToken(c1.Token().Token)
|
||||
tcl := targets.NewClient(client)
|
||||
tgt, err := tcl.Read(c1.Context(), "ttcp_1234567890")
|
||||
require.NoError(err)
|
||||
require.NotNil(tgt)
|
||||
|
||||
// Create test server, update default port on target
|
||||
ts := helper.NewTestTcpServer(t)
|
||||
require.NotNil(t, ts)
|
||||
defer ts.Close()
|
||||
var sessionConnsLimit int32 = 2
|
||||
|
||||
tgt = updateTargetForProxy(t, c1.Context(), tcl, tgt, ts.Port(), sessionConnsLimit, w1.Name())
|
||||
|
||||
// Authorize session to get authorization data
|
||||
sess, err := tcl.AuthorizeSession(c1.Context(), tgt.Item.Id)
|
||||
require.NoError(err)
|
||||
sessAuthz, err := sess.GetSessionAuthorization()
|
||||
require.NoError(err)
|
||||
|
||||
// Create a context we can cancel to stop the proxy, a channel for conns
|
||||
// left, and a waitgroup to ensure cleanup
|
||||
pxyCtx, pxyCancel := context.WithCancel(c1.Context())
|
||||
defer pxyCancel()
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
pxy, err := proxy.New(pxyCtx, sessAuthz.AuthorizationToken)
|
||||
require.NoError(err)
|
||||
wg.Add(1)
|
||||
done := atomic.NewBool(false)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
require.NoError(pxy.Start(proxy.WithInactivityTimeout(time.Second)))
|
||||
done.Store(true)
|
||||
}()
|
||||
|
||||
addr := pxy.ListenerAddress(context.Background())
|
||||
require.NotEmpty(addr)
|
||||
addrPort, err := netip.ParseAddrPort(addr)
|
||||
require.NoError(err)
|
||||
|
||||
echo := []byte("echo")
|
||||
readBuf := make([]byte, len(echo))
|
||||
|
||||
conn, err := net.DialTCP("tcp", nil, net.TCPAddrFromAddrPort(addrPort))
|
||||
require.NoError(err)
|
||||
written, err := conn.Write(echo)
|
||||
require.NoError(err)
|
||||
require.Equal(written, len(echo))
|
||||
read, err := conn.Read(readBuf)
|
||||
require.NoError(err)
|
||||
require.Equal(read, len(echo))
|
||||
require.NoError(conn.Close())
|
||||
|
||||
start := time.Now()
|
||||
for {
|
||||
if done.Load() || time.Since(start) > time.Second*2 {
|
||||
require.True(done.Load(), "proxy did not close itself within the expected time frame (2 seconds)")
|
||||
break
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
require.Equal("Inactivity timeout reached", pxy.CloseReason())
|
||||
pxyCancel()
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in new issue
Block a user