From 20e6f85ae2e4b4716c4b390f3ae0e22431ee76a8 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 13 Mar 2024 16:57:22 +0000 Subject: [PATCH 1/3] refactor(agent): extract debug handler into functions --- agent/agent.go | 74 ++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index fe81786b14ebc..6469ec98d1112 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -1660,52 +1660,50 @@ func (a *agent) isClosed() bool { return a.hardCtx.Err() != nil } -func (a *agent) HTTPDebug() http.Handler { - r := chi.NewRouter() - - requireNetwork := func(w http.ResponseWriter) (*tailnet.Conn, bool) { - a.closeMutex.Lock() - network := a.network - a.closeMutex.Unlock() - - if network == nil { - w.WriteHeader(http.StatusNotFound) - _, _ = w.Write([]byte("network is not ready yet")) - return nil, false - } +func (a *agent) requireNetwork() (*tailnet.Conn, bool) { + a.closeMutex.Lock() + defer a.closeMutex.Unlock() + return a.network, a.network != nil +} - return network, true +func (a *agent) HandleHTTPDebugMagicsock(w http.ResponseWriter, r *http.Request) { + network, ok := a.requireNetwork() + if !ok { + w.WriteHeader(http.StatusNotFound) + _, _ = w.Write([]byte("network is not ready yet")) + return } + network.MagicsockServeHTTPDebug(w, r) +} - r.Get("/debug/magicsock", func(w http.ResponseWriter, r *http.Request) { - network, ok := requireNetwork(w) - if !ok { - return - } - network.MagicsockServeHTTPDebug(w, r) - }) +func (a *agent) HandleHTTPMagicsockDebugLoggingState(w http.ResponseWriter, r *http.Request) { + state := chi.URLParam(r, "state") + stateBool, err := strconv.ParseBool(state) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + _, _ = fmt.Fprintf(w, "invalid state %q, must be a boolean", state) + return + } - r.Get("/debug/magicsock/debug-logging/{state}", func(w http.ResponseWriter, r *http.Request) { - state := chi.URLParam(r, "state") - stateBool, err := strconv.ParseBool(state) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - _, _ = fmt.Fprintf(w, "invalid state %q, must be a boolean", state) - return - } + network, ok := a.requireNetwork() + if !ok { + w.WriteHeader(http.StatusNotFound) + _, _ = w.Write([]byte("network is not ready yet")) + return + } - network, ok := requireNetwork(w) - if !ok { - return - } + network.MagicsockSetDebugLoggingEnabled(stateBool) + a.logger.Info(r.Context(), "updated magicsock debug logging due to debug request", slog.F("new_state", stateBool)) - network.MagicsockSetDebugLoggingEnabled(stateBool) - a.logger.Info(r.Context(), "updated magicsock debug logging due to debug request", slog.F("new_state", stateBool)) + w.WriteHeader(http.StatusOK) + _, _ = fmt.Fprintf(w, "updated magicsock debug logging to %v", stateBool) +} - w.WriteHeader(http.StatusOK) - _, _ = fmt.Fprintf(w, "updated magicsock debug logging to %v", stateBool) - }) +func (a *agent) HTTPDebug() http.Handler { + r := chi.NewRouter() + r.Get("/debug/magicsock", a.HandleHTTPDebugMagicsock) + r.Get("/debug/magicsock/debug-logging/{state}", a.HandleHTTPMagicsockDebugLoggingState) r.NotFound(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte("404 not found")) From ed377a5f40e260cf0bf347c5aa9aac44105abad5 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 13 Mar 2024 16:58:19 +0000 Subject: [PATCH 2/3] feat(agent): expose HTTP debug over tailnet api --- agent/api.go | 2 ++ codersdk/workspaceagentconn.go | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/agent/api.go b/agent/api.go index cb4639c0e0759..b81a7b9b44e41 100644 --- a/agent/api.go +++ b/agent/api.go @@ -36,6 +36,8 @@ func (a *agent) apiHandler() http.Handler { cacheDuration: cacheDuration, } r.Get("/api/v0/listening-ports", lp.handler) + r.Get("/debug/magicsock", a.HandleHTTPDebugMagicsock) + r.Get("/debug/magicsock/debug-logging/{state}", a.HandleHTTPMagicsockDebugLoggingState) return r } diff --git a/codersdk/workspaceagentconn.go b/codersdk/workspaceagentconn.go index 9fe229293d59d..e5451052bcd7e 100644 --- a/codersdk/workspaceagentconn.go +++ b/codersdk/workspaceagentconn.go @@ -356,6 +356,22 @@ func (c *WorkspaceAgentConn) ListeningPorts(ctx context.Context) (WorkspaceAgent return resp, json.NewDecoder(res.Body).Decode(&resp) } +// DebugMagicsock makes a request to the workspace agent's magicsock debug endpoint. +func (c *WorkspaceAgentConn) DebugMagicsock(ctx context.Context) ([]byte, error) { + ctx, span := tracing.StartSpan(ctx) + defer span.End() + res, err := c.apiRequest(ctx, http.MethodGet, "/debug/magicsock", nil) + if err != nil { + return nil, xerrors.Errorf("do request: %w", err) + } + defer res.Body.Close() + bs, err := io.ReadAll(res.Body) + if err != nil { + return nil, xerrors.Errorf("read response body: %w", err) + } + return bs, nil +} + // apiRequest makes a request to the workspace agent's HTTP API server. func (c *WorkspaceAgentConn) apiRequest(ctx context.Context, method, path string, body io.Reader) (*http.Response, error) { ctx, span := tracing.StartSpan(ctx) From b42bd41b5cb73f3ddc13dcbc6ea874ebc264f7e7 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 14 Mar 2024 09:30:49 +0000 Subject: [PATCH 3/3] change status code --- agent/agent.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index 6469ec98d1112..820856d42309a 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -1669,7 +1669,7 @@ func (a *agent) requireNetwork() (*tailnet.Conn, bool) { func (a *agent) HandleHTTPDebugMagicsock(w http.ResponseWriter, r *http.Request) { network, ok := a.requireNetwork() if !ok { - w.WriteHeader(http.StatusNotFound) + w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte("network is not ready yet")) return } @@ -1687,7 +1687,7 @@ func (a *agent) HandleHTTPMagicsockDebugLoggingState(w http.ResponseWriter, r *h network, ok := a.requireNetwork() if !ok { - w.WriteHeader(http.StatusNotFound) + w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte("network is not ready yet")) return }