Files
Salah Al Saleh 2a87b280bf Add per-collector subcommands to the collect binary (#2071)
* Add per-collector subcommands to the collect binary

Add `collect http|postgres|mysql|mssql|redis` subcommands that run a single
collector and print its native result JSON to stdout, so a collector can run
inside a Pod via the troubleshoot image (e.g. as a runPod collector).

Each has its own flags mapping to the collector's spec fields and its own help.
The Kubernetes client (used only for TLS-from-Secret) is built to match the
production preflight/support-bundle path (QPS/Burst/UserAgent).

* Add clickhouse subcommand to the collect binary

Add `collect clickhouse`, matching the other per-collector subcommands, so the
clickhouse collector can run inside a Pod via the troubleshoot image (e.g. as a
runPod collector). Same flags as the other database collectors (--uri + --tls-*).

* Make global flags work on the collect subcommands

Register --debug and the Kubernetes flags (--kubeconfig, --context, etc.) as
persistent flags, and move the shared setup to PersistentPreRun/PersistentPostRun,
so the per-collector subcommands inherit the global flags and run the same
logger/profiling setup as `collect [url]`. Previously these were local flags with
setup in PreRun, so subcommands rejected --debug/--kubeconfig and ignored the setup.
2026-07-10 09:31:14 -07:00

104 lines
3.3 KiB
Go

package cli
import (
"os"
"strings"
"github.com/replicatedhq/troubleshoot/cmd/internal/util"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/logger"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/klog/v2"
)
func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "collect [url]",
Args: cobra.MinimumNArgs(1),
Short: "Run a collector",
Long: `Run a collector and output the results.`,
SilenceUsage: true,
// PersistentPreRun/PersistentPostRun (rather than PreRun/PostRun) so this
// setup also runs for the per-collector subcommands, not just `collect [url]`.
PersistentPreRun: func(cmd *cobra.Command, args []string) {
v := viper.GetViper()
v.BindPFlags(cmd.Flags())
logger.SetupLogger(v)
if err := util.StartProfiling(); err != nil {
klog.Errorf("Failed to start profiling: %v", err)
}
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
if err := checkAndSetChroot(v.GetString("chroot")); err != nil {
return err
}
return runCollect(v, args[0])
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
if err := util.StopProfiling(); err != nil {
klog.Errorf("Failed to stop profiling: %v", err)
}
},
}
cobra.OnInitialize(initConfig)
cmd.AddCommand(util.VersionCmd())
// Per-collector subcommands: run a single collector and print its native
// result JSON. Each has its own flags and help. These let a collector run
// inside a Pod via the troubleshoot image (e.g. as a runPod collector), so
// the check executes from within the cluster rather than wherever the CLI runs.
cmd.AddCommand(HTTPCmd())
cmd.AddCommand(PostgresCmd())
cmd.AddCommand(MysqlCmd())
cmd.AddCommand(MssqlCmd())
cmd.AddCommand(RedisCmd())
cmd.AddCommand(ClickhouseCmd())
cmd.Flags().StringSlice("redactors", []string{}, "names of the additional redactors to use")
cmd.Flags().Bool("redact", true, "enable/disable default redactions")
cmd.Flags().String("format", "json", "output format, one of json or raw.")
cmd.Flags().String("collector-image", "", "the full name of the collector image to use")
cmd.Flags().String("collector-pull-policy", "", "the pull policy of the collector image")
cmd.Flags().String("selector", "", "selector (label query) to filter remote collection nodes on.")
cmd.Flags().Bool("collect-without-permissions", false, "always generate a support bundle, even if it some require additional permissions")
cmd.PersistentFlags().Bool("debug", false, "enable debug logging")
cmd.Flags().String("chroot", "", "Chroot to path")
// hidden in favor of the `insecure-skip-tls-verify` flag
cmd.Flags().Bool("allow-insecure-connections", false, "when set, do not verify TLS certs when retrieving spec and reporting results")
cmd.Flags().MarkHidden("allow-insecure-connections")
viper.BindPFlags(cmd.Flags())
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
k8sutil.AddFlags(cmd.PersistentFlags())
// Initialize klog flags
logger.InitKlogFlags(cmd)
// CPU and memory profiling flags
util.AddProfilingFlags(cmd)
return cmd
}
func InitAndExecute() {
if err := RootCmd().Execute(); err != nil {
os.Exit(1)
}
}
func initConfig() {
viper.SetEnvPrefix("TROUBLESHOOT")
viper.AutomaticEnv()
}