diff --git a/management/cmd/root.go b/management/cmd/root.go index 969dd60dd..ae03a09e8 100644 --- a/management/cmd/root.go +++ b/management/cmd/root.go @@ -54,6 +54,15 @@ func Execute() error { return rootCmd.Execute() } +// Customize hands the fully built root command to fn so an embedding binary +// can extend or adjust the command tree — most commonly attaching its own +// subcommands next to (or under) the built-in ones — before calling Execute. +// The root command is constructed in this package's init, so Customize may be +// called from the embedding binary's main at any point before Execute. +func Customize(fn func(root *cobra.Command)) { + fn(rootCmd) +} + func init() { mgmtCmd.Flags().IntVar(&mgmtPort, "port", 80, "server port to listen on (defaults to 443 if TLS is enabled, 80 otherwise") mgmtCmd.Flags().BoolVar(&disableLegacyManagementPort, "disable-legacy-port", false, "disabling the old legacy port (33073)") diff --git a/management/cmd/root_test.go b/management/cmd/root_test.go new file mode 100644 index 000000000..826fd2d50 --- /dev/null +++ b/management/cmd/root_test.go @@ -0,0 +1,42 @@ +package cmd + +import ( + "testing" + + "github.com/spf13/cobra" +) + +// TestCustomize verifies an embedding binary can extend the command tree: a +// top-level command attached through the hook, and a subcommand attached under +// the built-in admin group, are both resolvable exactly as Execute would +// resolve them. +func TestCustomize(t *testing.T) { + topLevel := &cobra.Command{Use: "some-extra", RunE: func(*cobra.Command, []string) error { return nil }} + nested := &cobra.Command{Use: "cluster", RunE: func(*cobra.Command, []string) error { return nil }} + + Customize(func(root *cobra.Command) { + root.AddCommand(topLevel) + for _, c := range root.Commands() { + if c.Name() == "admin" { + c.AddCommand(nested) + return + } + } + t.Fatal("admin command not found in the root tree") + }) + t.Cleanup(func() { + rootCmd.RemoveCommand(topLevel) + for _, c := range rootCmd.Commands() { + if c.Name() == "admin" { + c.RemoveCommand(nested) + } + } + }) + + if found, _, err := rootCmd.Find([]string{"some-extra"}); err != nil || found != topLevel { + t.Fatalf("top-level command not resolvable: found=%v err=%v", found, err) + } + if found, _, err := rootCmd.Find([]string{"admin", "cluster"}); err != nil || found != nested { + t.Fatalf("nested admin subcommand not resolvable: found=%v err=%v", found, err) + } +}