Move o11y service settings tool to admin area

What does this MR do?

Moves the o11y service settings management tool from the flag-gated /-/experimental/o11y_service_settings namespace into the Admin area (/admin/o11y_service_settings), where it is enforced admin-only by Admin::ApplicationController. This tool is only ever used by admins, so gating it behind /admin is the right home for it.

Changes

  • New admin controller Admin::O11yServiceSettingsController (inherits Admin::ApplicationController) with the same index/new/create/edit/update/destroy actions.
  • New admin views/helper/JS under admin/o11y_service_settings (reusing the shared groups/observability/o11y_service_settings/_form_fields partial, which is left in place).
  • New top-level "Observability" admin sidebar menu (lib/sidebars/admin/menus/observability_menu.rb). Monitoring is for GitLab’s own health, so this gets its own top-level item.
  • Removed the experimental route namespace, the Experimental::O11yServiceSettingsController + views/helper/JS, and the experimental_group_o11y_settings_access feature flag — admin access is now the gate, so the flag is no longer needed.
  • Specs moved/adapted to the admin equivalents (request, helper, frontend, sidebar menu).

SSRF hardening (included)

While moving the write path, this also hardens Observability::GroupO11ySettingsUpdateService:

  • Validate o11y_service_name against a strict allowlist (\A[a-z0-9]+(?:-[a-z0-9]+)*\z) before interpolating it into the service URL, returning a graceful error otherwise.
  • Reject any o11y_service_url / o11y_otel_url / o11y_mcp_url value containing a URI fragment (#) or userinfo (@) component, which could otherwise make the parsed host differ from the visible host.

Access

The page is admin-only via Admin::ApplicationController (admin + admin mode), matching other admin tools such as Deploy keys and Spam logs. No feature flag.

HTTP Router sync (pipeline:skip-router-sync)

This MR moves the o11y service settings routes from /-/experimental to /admin, so the cells-routes:router-in-sync job reports drift against the HTTP Router snapshot. Applying pipeline:skip-router-sync because the HTTP Router snapshot on main can only match one GitLab ref at a time and there are paired route-changing MRs in flight; the router will be resynced from master after these merge. This is an admin-only, low-traffic tool.

Edited by Renée Hendricksen

Merge request reports

Loading
Loading