feat(cmd): add collect support-data commands - #1734
Conversation
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>
|
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=25c16972a2f5a66a8dfdfff58c7fed141fd41fd9This trusted E2E result will apply only to the exact reviewed SHA above. Re-run trusted E2E if the contributor pushes another commit. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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"}}%
There was a problem hiding this comment.
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
collectcommand 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())
}
| // Simulate the validation that runOnPrem performs | ||
| if cfg.Runtime == runtimeKubernetes && cfg.Namespace == "" { | ||
| assert.True(t, true, "should require namespace for kubernetes") | ||
| } |
| {"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"}, | ||
| } |
| 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>
There was a problem hiding this comment.
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}
}
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>
There was a problem hiding this comment.
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 {
Summary
Adds
collectandcollect support-datacommands to gather deploymentdiagnostic information into a compressed archive for troubleshooting and
support workflows.
What changed
collectcommandcollect support-datasubcommand, withon-premandkonnecttargetsdeployments, overridable with
--runtimeWhy
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 removedwith
--sanitizeand--redact, and TLS verification against the KongAdmin API can be configured with
--ca-certor bypassed with--tls-skip-verify.🤖 Generated with Claude Code