Skip to content

Commit 3b40687

Browse files
authored
feat(agent): expose HTTP debug server over tailnet API (#12582)
1 parent 0d16df9 commit 3b40687

File tree

3 files changed

+54
-38
lines changed

3 files changed

+54
-38
lines changed

agent/agent.go

+36-38
Original file line numberDiff line numberDiff line change
@@ -1660,52 +1660,50 @@ func (a *agent) isClosed() bool {
16601660
return a.hardCtx.Err() != nil
16611661
}
16621662

1663-
func (a *agent) HTTPDebug() http.Handler {
1664-
r := chi.NewRouter()
1665-
1666-
requireNetwork := func(w http.ResponseWriter) (*tailnet.Conn, bool) {
1667-
a.closeMutex.Lock()
1668-
network := a.network
1669-
a.closeMutex.Unlock()
1670-
1671-
if network == nil {
1672-
w.WriteHeader(http.StatusNotFound)
1673-
_, _ = w.Write([]byte("network is not ready yet"))
1674-
return nil, false
1675-
}
1663+
func (a *agent) requireNetwork() (*tailnet.Conn, bool) {
1664+
a.closeMutex.Lock()
1665+
defer a.closeMutex.Unlock()
1666+
return a.network, a.network != nil
1667+
}
16761668

1677-
return network, true
1669+
func (a *agent) HandleHTTPDebugMagicsock(w http.ResponseWriter, r *http.Request) {
1670+
network, ok := a.requireNetwork()
1671+
if !ok {
1672+
w.WriteHeader(http.StatusInternalServerError)
1673+
_, _ = w.Write([]byte("network is not ready yet"))
1674+
return
16781675
}
1676+
network.MagicsockServeHTTPDebug(w, r)
1677+
}
16791678

1680-
r.Get("/debug/magicsock", func(w http.ResponseWriter, r *http.Request) {
1681-
network, ok := requireNetwork(w)
1682-
if !ok {
1683-
return
1684-
}
1685-
network.MagicsockServeHTTPDebug(w, r)
1686-
})
1679+
func (a *agent) HandleHTTPMagicsockDebugLoggingState(w http.ResponseWriter, r *http.Request) {
1680+
state := chi.URLParam(r, "state")
1681+
stateBool, err := strconv.ParseBool(state)
1682+
if err != nil {
1683+
w.WriteHeader(http.StatusBadRequest)
1684+
_, _ = fmt.Fprintf(w, "invalid state %q, must be a boolean", state)
1685+
return
1686+
}
16871687

1688-
r.Get("/debug/magicsock/debug-logging/{state}", func(w http.ResponseWriter, r *http.Request) {
1689-
state := chi.URLParam(r, "state")
1690-
stateBool, err := strconv.ParseBool(state)
1691-
if err != nil {
1692-
w.WriteHeader(http.StatusBadRequest)
1693-
_, _ = fmt.Fprintf(w, "invalid state %q, must be a boolean", state)
1694-
return
1695-
}
1688+
network, ok := a.requireNetwork()
1689+
if !ok {
1690+
w.WriteHeader(http.StatusInternalServerError)
1691+
_, _ = w.Write([]byte("network is not ready yet"))
1692+
return
1693+
}
16961694

1697-
network, ok := requireNetwork(w)
1698-
if !ok {
1699-
return
1700-
}
1695+
network.MagicsockSetDebugLoggingEnabled(stateBool)
1696+
a.logger.Info(r.Context(), "updated magicsock debug logging due to debug request", slog.F("new_state", stateBool))
17011697

1702-
network.MagicsockSetDebugLoggingEnabled(stateBool)
1703-
a.logger.Info(r.Context(), "updated magicsock debug logging due to debug request", slog.F("new_state", stateBool))
1698+
w.WriteHeader(http.StatusOK)
1699+
_, _ = fmt.Fprintf(w, "updated magicsock debug logging to %v", stateBool)
1700+
}
17041701

1705-
w.WriteHeader(http.StatusOK)
1706-
_, _ = fmt.Fprintf(w, "updated magicsock debug logging to %v", stateBool)
1707-
})
1702+
func (a *agent) HTTPDebug() http.Handler {
1703+
r := chi.NewRouter()
17081704

1705+
r.Get("/debug/magicsock", a.HandleHTTPDebugMagicsock)
1706+
r.Get("/debug/magicsock/debug-logging/{state}", a.HandleHTTPMagicsockDebugLoggingState)
17091707
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
17101708
w.WriteHeader(http.StatusNotFound)
17111709
_, _ = w.Write([]byte("404 not found"))

agent/api.go

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ func (a *agent) apiHandler() http.Handler {
3636
cacheDuration: cacheDuration,
3737
}
3838
r.Get("/api/v0/listening-ports", lp.handler)
39+
r.Get("/debug/magicsock", a.HandleHTTPDebugMagicsock)
40+
r.Get("/debug/magicsock/debug-logging/{state}", a.HandleHTTPMagicsockDebugLoggingState)
3941

4042
return r
4143
}

codersdk/workspaceagentconn.go

+16
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,22 @@ func (c *WorkspaceAgentConn) ListeningPorts(ctx context.Context) (WorkspaceAgent
356356
return resp, json.NewDecoder(res.Body).Decode(&resp)
357357
}
358358

359+
// DebugMagicsock makes a request to the workspace agent's magicsock debug endpoint.
360+
func (c *WorkspaceAgentConn) DebugMagicsock(ctx context.Context) ([]byte, error) {
361+
ctx, span := tracing.StartSpan(ctx)
362+
defer span.End()
363+
res, err := c.apiRequest(ctx, http.MethodGet, "/debug/magicsock", nil)
364+
if err != nil {
365+
return nil, xerrors.Errorf("do request: %w", err)
366+
}
367+
defer res.Body.Close()
368+
bs, err := io.ReadAll(res.Body)
369+
if err != nil {
370+
return nil, xerrors.Errorf("read response body: %w", err)
371+
}
372+
return bs, nil
373+
}
374+
359375
// apiRequest makes a request to the workspace agent's HTTP API server.
360376
func (c *WorkspaceAgentConn) apiRequest(ctx context.Context, method, path string, body io.Reader) (*http.Response, error) {
361377
ctx, span := tracing.StartSpan(ctx)

0 commit comments

Comments
 (0)