Add WebSocket connectivity check to Duo self-hosted verification

What does this MR do and why?

When agentic chat (GitLab Duo Agent Platform) fails to connect, the browser only surfaces a generic "Duo workflow service not reachable" error. The underlying cause is frequently a failed WebSocket upgrade handshake on the /api/v4/ai/duo_workflows/ws request — for example when a load balancer or reverse proxy (HAProxy, NGINX) in front of GitLab does not forward the Upgrade/Connection headers, or strips authentication. The browser WebSocket API deliberately hides the HTTP handshake status and body from JavaScript, so the real cause (403 pre-auth, or a stuck-at-non-101 upgrade) is invisible in the UI.

The existing self-hosted diagnostics only test the outbound Rails → Duo Workflow Service gRPC path (list_tools), which can pass while the inbound browser → proxy → Workhorse upgrade path fails.

This MR adds a WebSocket connectivity check to the gitlab:duo:verify_self_hosted_setup rake task. It replays the browser's upgrade handshake against the instance's own external URL (traversing the same inbound proxy chain) and classifies the outcome:

  • 101 — healthy
  • 401/403 — reached GitLab but unauthorized (license/seat, or a proxy stripped auth cookies/headers)
  • other status — upgrade not completed; a load balancer/proxy is likely not forwarding the Upgrade/Connection headers (includes the NGINX directives to fix)
  • connection error — the instance cannot reach its own external URL

The mechanism lives in a dedicated, unit-tested Gitlab::Duo::Administration::AgentPlatformWebsocketCheck class that returns a structured result; the rake task handles presentation and populates the diagnostics summary.

How to test

bundle exec rake "gitlab:duo:verify_self_hosted_setup[root]"

Look for the agent_platform_websocket entry in the diagnostic summary.

Closes #604755 (closed)

Merge request reports

Loading
Loading