Skip to content

feat(cmd): add collect support-data commands - #1734

Draft
dascole wants to merge 3 commits into
Kong:mainfrom
dascole:feat/kong-debug-tool-rebased
Draft

feat(cmd): add collect support-data commands#1734
dascole wants to merge 3 commits into
Kong:mainfrom
dascole:feat/kong-debug-tool-rebased

Conversation

@dascole

@dascole dascole commented Jul 29, 2026

Copy link
Copy Markdown

Summary

Adds collect and collect support-data commands to gather deployment
diagnostic information into a compressed archive for troubleshooting and
support workflows.

What changed

  • adds the top-level collect command
  • adds the collect support-data subcommand, with on-prem and
    konnect targets
  • auto-detects the runtime across Docker, Kubernetes, and VM
    deployments, overridable with --runtime
  • collects logs, configuration files, and system diagnostics
  • packages collected data into a compressed archive

Why

This makes it easier to gather the information typically needed for
support investigations and debugging without requiring users to collect
artifacts manually.

User impact

Users can run the new support-data collection command to generate a
single archive containing relevant diagnostic artifacts.

Collection settings follow the existing configuration layering of
library defaults, then config file, then flags, and are exposed under
the support_data.* config namespace. Sensitive values can be removed
with --sanitize and --redact, and TLS verification against the Kong
Admin API can be configured with --ca-cert or bypassed with
--tls-skip-verify.

🤖 Generated with Claude Code

Add `kongctl collect support-data` with `on-prem` and `konnect`
subcommands, wrapping kong-deployment-toolkit's collector to gather
logs, configuration, and system information into a support archive.

Runtime is auto-detected across Docker, Kubernetes, and VM deployments,
and can be pinned with --runtime. Collection settings follow kongctl's
existing layering: library defaults, then config file, then flags. For
Konnect, --base-url and --region take precedence over config, which is
consulted only when neither flag is set, so an invalid region in a
config file cannot block an otherwise valid flag.

Flags are exposed under the support_data.* config namespace and mirror
the toolkit's collector.Config, including --sanitize, --line-limit,
--logs-since, --redact, --disable-kdd, --dump-workspaces,
--tls-skip-verify, and --ca-cert. The unified --logs-since duration is
converted to seconds internally for the Kubernetes collector.

Results are written through the command's IOStreams so output can be
captured and redirected, with warnings on stderr to keep the JSON and
YAML forms parseable. The output format is resolved before collection
begins, so an invalid format fails immediately rather than after a long
collection run.

A reflection-based parity test guards the flag mapping: every field on
collector.Config must be either bound to a flag or explicitly listed as
intentionally unmapped with a documented reason, so a future toolkit
upgrade that adds a field fails the build rather than silently dropping
it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 29, 2026 21:55
@dascole
dascole requested review from a team as code owners July 29, 2026 21:55
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Trusted E2E is required for this fork PR.

After maintainer review, run trusted E2E from the base repository:

gh workflow run e2e.yaml --repo Kong/kongctl --ref main -f trusted_pr_number=1734 -f trusted_head_sha=25c16972a2f5a66a8dfdfff58c7fed141fd41fd9

This trusted E2E result will apply only to the exact reviewed SHA above. Re-run trusted E2E if the contributor pushes another commit.

Comment thread go.mod

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 Open source vulnerabilities detected - high severity
Aikido detected 4 vulnerabilities across 1 package, it includes 4 high vulnerabilities.

Details

Remediation:

  • github.com/docker/docker — 4 CVEs (high) — fixed in 29.3.1

Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github.com/docker/docker has no fixed version on this module path (ends at v28.5.2). All 4 CVEs are daemon-side. The "29.3.1" in this report is the Docker Engine product version.

curl -s "https://proxy.golang.org/github.com/docker/docker/@latest"
{"Version":"v28.5.2+incompatible","Time":"2025-11-05T14:19:32Z","Origin":{"VCS":"git","URL":"https://github.com/docker/docker","Hash":"89c5e8fd66634b6128fc4c0e6f1236e2540e46e0","Ref":"refs/tags/v28.5.2"}}%

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new collect verb (and collect support-data subcommands) to gather deployment diagnostics for troubleshooting, leveraging kong-deployment-toolkit’s collector and packaging results for user-friendly consumption.

Changes:

  • Adds a new top-level collect command wired into the root command tree.
  • Implements collect support-data {on-prem,konnect} with layered config/flag mapping and structured output (text/json/yaml).
  • Adds unit tests for flag/config mapping and updates module dependencies to include kong-deployment-toolkit.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
internal/cmd/root/verbs/verbs.go Registers the new collect verb constant.
internal/cmd/root/verbs/collect/collect.go Implements the top-level collect command and attaches support-data.
internal/cmd/root/verbs/collect/supportdata/supportdata.go Adds the support-data parent command and help/usage scaffolding.
internal/cmd/root/verbs/collect/supportdata/common.go Defines shared flags/config mapping and output formatting for collection results.
internal/cmd/root/verbs/collect/supportdata/onprem.go Implements the on-prem target (runtime/config/log collection options).
internal/cmd/root/verbs/collect/supportdata/konnect.go Implements the konnect target (control plane + optional runtime collection).
internal/cmd/root/verbs/collect/supportdata/common_test.go Adds tests for common flag registration, defaults, config/flag layering, and output formatting.
internal/cmd/root/verbs/collect/supportdata/onprem_test.go Adds tests for on-prem flag/config layering and basic validation expectations.
internal/cmd/root/verbs/collect/supportdata/konnect_test.go Adds tests for konnect flag/config layering and base-url/region resolution behavior.
internal/cmd/root/verbs/collect/supportdata/flagparity_test.go Adds reflection-based “parity” tests to ensure collector.Config fields are mapped or intentionally excluded.
internal/cmd/root/root.go Wires the new collect verb into the root command.
go.mod Adds github.com/kong/kong-deployment-toolkit dependency (plus new indirects).
go.sum Updates sums for the new module and its transitive dependencies.
Comments suppressed due to low confidence (2)

internal/cmd/root/verbs/collect/supportdata/common_test.go:79

  • TestCommonFlagDefaults doesn't assert default values for the newly added CommonFlags fields (TLSSkipVerify and CACertPath), so changes to their defaults would go untested.
	assert.Equal(t, "", flags.OutputDir)
	assert.False(t, flags.Sanitize)
	assert.Equal(t, int64(0), flags.LineLimit)
	assert.Equal(t, "", flags.LogsSince)
	assert.Nil(t, flags.RedactTerms)
	assert.False(t, flags.DisableKDD)
	assert.False(t, flags.DumpWorkspaces)
}

internal/cmd/root/verbs/collect/supportdata/common.go:165

  • ApplyCommonFlags has the same issue as ApplyCommonConfig: if --logs-since is provided but isn't a valid duration, K8sLogsSinceSeconds is not reset, so it can keep a prior value from config/defaults and diverge from DockerLogsSince.
		collectorCfg.DockerLogsSince = flags.LogsSince
		if d, err := time.ParseDuration(flags.LogsSince); err == nil {
			collectorCfg.K8sLogsSinceSeconds = int64(d.Seconds())
		}

Comment on lines +286 to +289
// Simulate the validation that runOnPrem performs
if cfg.Runtime == runtimeKubernetes && cfg.Namespace == "" {
assert.True(t, true, "should require namespace for kubernetes")
}
Comment on lines +48 to +55
{"output-dir", "output-dir", "string"},
{"sanitize", "sanitize", "bool"},
{"line-limit", "line-limit", "int64"},
{"logs-since", "logs-since", "string"},
{"redact", "redact", "stringSlice"},
{"disable-kdd", "disable-kdd", "bool"},
{"dump-workspaces", "dump-workspaces", "bool"},
}
Comment thread internal/cmd/root/verbs/collect/supportdata/konnect_test.go Outdated
Comment on lines +118 to +121
collectorCfg.DockerLogsSince = since
if d, err := time.ParseDuration(since); err == nil {
collectorCfg.K8sLogsSinceSeconds = int64(d.Seconds())
}
Reset the Kubernetes log window when --logs-since is not a Go duration.
Docker also accepts RFC3339 and Unix timestamps, so those values are
still passed through to it, but leaving K8sLogsSinceSeconds untouched
let a window set by an earlier configuration layer survive a flag that
was meant to override it, silently diverging the two runtimes.

Extract the Kubernetes namespace requirement into a shared helper. Both
commands carried an identical copy of the check, and both tests restated
the condition inline and asserted on the restatement rather than on the
validation itself, so neither would have caught a regression.

Cover --tls-skip-verify and --ca-cert in the common flag tests, which
were not updated when those flags were added.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 30, 2026 02:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

internal/cmd/root/verbs/collect/supportdata/common.go:36

  • The --runtime flag help strings (on-prem/konnect) list "vm" as a valid value, but the local runtime constants only define docker/kubernetes. This leaves "vm" as an undocumented magic string in code/tests and makes the comment above this const block inaccurate.
// Runtime identifiers accepted by the --runtime flag.
const (
	runtimeKubernetes = "kubernetes"
	runtimeDocker     = "docker"
)

internal/cmd/root/verbs/collect/supportdata/konnect.go:254

  • PR description says collection settings are exposed under the support_data.* config namespace, but Konnect auth/endpoint settings are still read from konnect.* (via konnectcommon.PATConfigPath and ResolveBaseURL). If this is intentional (reusing existing Konnect config), the PR description/docs should be updated; otherwise consider also supporting support_data.konnect.* keys (possibly with backward-compatible fallback to konnect.*).
	// Get token from config
	if token := cfg.GetString(konnectcommon.PATConfigPath); token != "" {
		collectorCfg.RBACHeaders = []string{token}
	}

@dascole
dascole marked this pull request as draft July 31, 2026 15:14
The --runtime flag help text advertises docker, kubernetes, and vm, but
only docker and kubernetes had constants. Adds runtimeVM so the const
block matches its comment, and replaces the bare "vm" literals in the
on-prem and konnect tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 31, 2026 16:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (2)

internal/cmd/root/verbs/collect/supportdata/common.go:168

  • ApplyCommonConfig sets collectorCfg.Debug=true for debug/trace log levels, but never resets it to false for other log levels. If collector.DefaultConfig() (or an earlier config layer) ever enables Debug, it will remain enabled even when kongctl is not in debug/trace mode.
		collectorCfg.Debug = true
		collectorCfg.Logger = os.Stderr
	} else {
		collectorCfg.Logger = io.Discard
	}

internal/cmd/root/verbs/collect/collect.go:61

  • The collect command registers alias "c", but the create command already uses aliases "c"/"C". Cobra command aliases must be unique among siblings; this will make kongctl c ... ambiguous and can break command registration.
	collectCommand := &cobra.Command{
		Use:     collectUse,
		Short:   collectShort,
		Long:    collectLong,
		Example: collectExamples,
		Aliases: []string{"c"},
		RunE: func(cmd *cobra.Command, _ []string) error {

@rspurgeon rspurgeon self-assigned this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants