The Router Support Tool is a lightweight, external diagnostic tool that collects a sanitized snapshot of Apollo Router and Kubernetes cluster state — version, configuration, logs, metrics, and pod status — into a single bundle. Collection runs on demand, requires no router restart, and is safe to run against a degraded router.
Bundles stay in customer infrastructure. Sensitive data is redacted automatically before the bundle is written, and customers can inspect the contents before sharing anything with support.
Built on troubleshoot.sh: this repository contains the SupportBundle spec defining what is collected, custom redactors for router-specific sensitive data, and the Helm chart that renders the spec into a cluster.
This project is source-available under the Elastic License 2.0. Please refer to the LICENSE file in the root of the repo for further information.
Design specifications live in specs/. Start with specs/architecture.md — it defines the layer model the rest of the directory follows.
The architecture separates three concerns that vary independently:
| Layer | What varies |
|---|---|
| Collection | What data is collected, and how it is sanitized |
| Trigger | What causes a collection to happen |
| Storage | Where the resulting bundle lands |
Deployment — where collection runs, what permissions it needs, and how the customer deployed their router — is documented alongside these but is deliberately not a layer. See architecture.md for the reasoning.
specs/
├── architecture.md # Layer model — start here
├── user_experience.md # Customer-facing flows and invocation
├── artifact-distribution.md # How the chart/image/collect script are built and published
├── release-process.md # Versioning across those artifacts, and how to cut a release
├── scope.md # What the tool ships today, and what it deliberately does not
├── collection/ # What is collected and how it is sanitized
├── trigger/ # What causes collection to happen
├── storage/ # Where bundles land
└── deployment/ # Execution location, RBAC, deployment tiers
specs/scope.md is the authority on what the tool actually ships today and what it deliberately does not — the layer specs above describe the design, including parts that may not exist yet. Check it before assuming a capability is present.
Specifications in specs/ describe current intended behavior. They are reviewed and merged like code — a merged spec is an accepted decision. Design changes go through a PR against the relevant spec, so review happens where the change is proposed rather than in a separate process.
Git history is the decision record. To understand why something is the way it is, read the PR that introduced it.
Where a design choice involved rejecting a viable alternative, the spec records it in a Rejected alternatives section — not as history, but because knowing what was ruled out and why is part of understanding the current design. If you are considering an approach listed there, engage with the recorded reasoning rather than re-proposing it.
This repo uses mise tasks (mise-tasks/) as the single source of truth for its static checks — CI (.github/workflows/static-checks.yaml) and local lefthook hooks (lefthook.yml) both just call mise run <task>, so there's one place to fix a check rather than two. After cloning, install the hooks once:
mise install
mise exec -- lefthook installgit commit then runs the fast, local-only checks (check-ghafmt, generate-helm-docs, helm-lint, test-storage-credentials) against whatever you changed, and git push additionally runs spec-lint. CI runs all checks regardless, as the backstop for a skipped or bypassed hook, go to .github/workflows/static-checks.yaml for the full set. Run mise tasks to see every available task with a description.
See testing/README.md for what lives in each subdirectory of testing/.
Chainsaw installs router-diagnostics-chart against a real Kubernetes cluster (testing/chainsaw/official-chart, official-chart-metrics-no-servicemonitor, raw-manifest, multi-release) and asserts on the actual collected bundle. This is what exercises collection, redaction, and the host-collector diagnostics sidecar end-to-end.
These tests only cover mode: local, against a local KinD cluster. mode: job is covered separately via RTF (testing/data/, testing/test-plan.yaml).
mise install already provides everything these tests need (chainsaw, kind, helm, kubectl). To run them:
mise run kind-up # creates a local KinD cluster named router-support-tool-test
mise run e2e-chainsaw # runs every tier against it
mise run kind-down # tear it down when you're doneScope a run to one tier with CHAINSAW_TEST_DIRS:
CHAINSAW_TEST_DIRS=testing/chainsaw/raw-manifest mise run e2e-chainsawmise run kind-up reuses an existing cluster of the same name if one is already up — run mise run kind-down first if you want a clean one.
router-diagnostics-chart/README.md is generated from values.yaml's # -- comments via helm-docs. CI enforces it stays in sync (fail-on-diff: true) — after changing router-diagnostics-chart/values.yaml, regenerate it locally and commit the result:
mise run generate-helm-docsWorkflow files under .github/workflows/ are formatted with ghafmt, and CI checks that they stay formatted. Before pushing a workflow change, check formatting locally:
mise run check-ghafmtIf it reports a diff, fix it in place:
docker run --rm -v "$(pwd)":/repo --workdir /repo ghcr.io/jonathanrainer/ghafmt:0.1.5 --mode=write .github/workflows/