fix(coderd): pass block endpoints into servertailnet (#12149)

This commit is contained in:
Colin Adler 2024-03-07 23:29:54 -06:00 committed by GitHub
parent d2a74cf547
commit 66154f937e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 62 additions and 2 deletions

View File

@ -489,6 +489,7 @@ func New(options *Options) *API {
func(context.Context) (tailnet.MultiAgentConn, error) {
return (*api.TailnetCoordinator.Load()).ServeMultiAgent(uuid.New()), nil
},
options.DeploymentValues.DERP.Config.BlockDirect.Value(),
api.TracerProvider,
)
if err != nil {

View File

@ -49,6 +49,7 @@ func NewServerTailnet(
derpMapFn func() *tailcfg.DERPMap,
derpForceWebSockets bool,
getMultiAgent func(context.Context) (tailnet.MultiAgentConn, error),
blockEndpoints bool,
traceProvider trace.TracerProvider,
) (*ServerTailnet, error) {
logger = logger.Named("servertailnet")
@ -56,6 +57,7 @@ func NewServerTailnet(
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
DERPForceWebSockets: derpForceWebSockets,
Logger: logger,
BlockEndpoints: blockEndpoints,
})
if err != nil {
return nil, xerrors.Errorf("create tailnet conn: %w", err)
@ -166,6 +168,12 @@ func NewServerTailnet(
return tn, nil
}
// Conn is used to access the underlying tailnet conn of the ServerTailnet. It
// should only be used for read-only purposes.
func (s *ServerTailnet) Conn() *tailnet.Conn {
return s.conn
}
func (s *ServerTailnet) nodeCallback(node *tailnet.Node) {
pn, err := tailnet.NodeToProto(node)
if err != nil {

View File

@ -303,6 +303,36 @@ func TestServerTailnet_ReverseProxy(t *testing.T) {
assert.Equal(t, expectedResponseCode, res.StatusCode)
})
t.Run("BlockEndpoints", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
agents, serverTailnet := setupServerTailnetAgent(t, 1, tailnettest.DisableSTUN)
a := agents[0]
require.True(t, serverTailnet.Conn().GetBlockEndpoints(), "expected BlockEndpoints to be set")
u, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", codersdk.WorkspaceAgentHTTPAPIServerPort))
require.NoError(t, err)
rp := serverTailnet.ReverseProxy(u, u, a.id)
rw := httptest.NewRecorder()
req := httptest.NewRequest(
http.MethodGet,
u.String(),
nil,
).WithContext(ctx)
rp.ServeHTTP(rw, req)
res := rw.Result()
defer res.Body.Close()
assert.Equal(t, http.StatusOK, res.StatusCode)
})
}
type wrappedListener struct {
@ -375,6 +405,7 @@ func setupServerTailnetAgent(t *testing.T, agentNum int, opts ...tailnettest.DER
func() *tailcfg.DERPMap { return derpMap },
false,
func(context.Context) (tailnet.MultiAgentConn, error) { return coord.ServeMultiAgent(uuid.New()), nil },
!derpMap.HasSTUN(),
trace.NewNoopTracerProvider(),
)
require.NoError(t, err)

View File

@ -12,9 +12,8 @@ import (
"tailscale.com/derp/derphttp"
"tailscale.com/types/key"
"github.com/coder/coder/v2/tailnet"
"cdr.dev/slog"
"github.com/coder/coder/v2/tailnet"
)
// New constructs a new mesh for DERP servers.

View File

@ -251,6 +251,7 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
},
regResp.DERPForceWebSockets,
s.DialCoordinator,
false, // TODO: this will be covered in a subsequent pr.
s.TracerProvider,
)
if err != nil {

View File

@ -254,6 +254,14 @@ func (c *configMaps) setBlockEndpoints(blockEndpoints bool) {
c.Broadcast()
}
// getBlockEndpoints returns the value of the most recent setBlockEndpoints
// call.
func (c *configMaps) getBlockEndpoints() bool {
c.L.Lock()
defer c.L.Unlock()
return c.blockEndpoints
}
// setDERPMap sets the DERP map, triggering a configuration of the engine if it has changed.
// c.L MUST NOT be held.
func (c *configMaps) setDERPMap(derpMap *tailcfg.DERPMap) {

View File

@ -311,6 +311,10 @@ type Conn struct {
trafficStats *connstats.Statistics
}
func (c *Conn) GetBlockEndpoints() bool {
return c.configMaps.getBlockEndpoints() && c.nodeUpdater.getBlockEndpoints()
}
func (c *Conn) InstallCaptureHook(f capture.Callback) {
c.mutex.Lock()
defer c.mutex.Unlock()

View File

@ -239,3 +239,11 @@ func (u *nodeUpdater) fillPeerDiagnostics(d *PeerDiagnostics) {
d.PreferredDERP = u.preferredDERP
d.SentNode = u.sentNode
}
// getBlockEndpoints returns the value of the most recent setBlockEndpoints
// call.
func (u *nodeUpdater) getBlockEndpoints() bool {
u.L.Lock()
defer u.L.Unlock()
return u.blockEndpoints
}