diff --git a/cmd/root.go b/cmd/root.go index 1e01d1c70..b35bc6341 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "io" "os" @@ -15,7 +16,7 @@ var settings environment.AirshipADMSettings // NewRootCmd creates the root `airshipadm` command. All other commands are // subcommands branching from this one -func NewRootCmd(out io.Writer, client *kube.Client, args []string) *cobra.Command { +func NewRootCmd(out io.Writer, client *kube.Client, args []string) (*cobra.Command, error) { rootCmd := &cobra.Command{ Use: "airshipadm", Short: "airshipadm is a unified entrypoint to various airship components", @@ -25,9 +26,8 @@ func NewRootCmd(out io.Writer, client *kube.Client, args []string) *cobra.Comman // Settings flags - This section should probably be moved to pkg/environment rootCmd.PersistentFlags().StringVar(&settings.KubeConfigFilePath, "kubeconfig", "", "path to kubeconfig") rootCmd.PersistentFlags().BoolVar(&settings.Debug, "debug", false, "enable verbose output") - // TODO(howell): Remove this panic if err := rootCmd.PersistentFlags().Parse(args); err != nil { - panic(err.Error()) + return nil, errors.New("could not parse flags: " + err.Error()) } log.Init(&settings, out) @@ -36,21 +36,21 @@ func NewRootCmd(out io.Writer, client *kube.Client, args []string) *cobra.Comman // Compound commands rootCmd.AddCommand(NewWorkflowCommand()) - - return rootCmd + return rootCmd, nil } // Execute runs the base airshipadm command func Execute(out io.Writer) { - // TODO(howell): Remove this panic client, err := kube.NewForConfig(settings.KubeConfigFilePath) - if err != nil { - panic(err.Error()) - } + osExitIfError(out, err) + rootCmd, err := NewRootCmd(out, client, os.Args[1:]) + osExitIfError(out, err) + osExitIfError(out, rootCmd.Execute()) +} - rootCmd := NewRootCmd(out, client, os.Args[1:]) - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) +func osExitIfError(out io.Writer, err error) { + if err != nil { + fmt.Fprintln(out, err) os.Exit(1) } } diff --git a/cmd/version.go b/cmd/version.go index 1fb582c89..e834fbfeb 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -23,10 +23,17 @@ func NewVersionCommand(out io.Writer, client *kube.Client) *cobra.Command { Short: "Show the version number of airshipadm and its underlying tools", Long: versionLong, Run: func(cmd *cobra.Command, args []string) { + clientV := clientVersion() + kubeV, err := kubeVersion(client) + if err != nil { + fmt.Fprintf(out, "Could not get kubernetes version") + return + } + w := tabwriter.NewWriter(out, 0, 0, 1, ' ', 0) - fmt.Fprintf(w, "%s:\t%s\n", "client", clientVersion()) - fmt.Fprintf(w, "%s:\t%s\n", "kubernetes server", kubeVersion(client)) - w.Flush() + defer w.Flush() + fmt.Fprintf(w, "%s:\t%s\n", "client", clientV) + fmt.Fprintf(w, "%s:\t%s\n", "kubernetes server", kubeV) }, } return versionCmd @@ -37,11 +44,10 @@ func clientVersion() string { return "v0.1.0" } -func kubeVersion(client *kube.Client) string { +func kubeVersion(client *kube.Client) (string, error) { version, err := client.Discovery().ServerVersion() - // TODO(howell): Remove this panic if err != nil { - panic(err.Error()) + return "", err } - return version.String() + return version.String(), nil } diff --git a/internal/test/utilities.go b/internal/test/utilities.go index 98ee79421..c74162c6d 100644 --- a/internal/test/utilities.go +++ b/internal/test/utilities.go @@ -30,7 +30,6 @@ type CmdTest struct { func RunCmdTests(t *testing.T, tests []CmdTest) { t.Helper() - for _, test := range tests { cmdOutput := executeCmd(t, test.Command) if *shouldUpdateGolden { @@ -46,7 +45,11 @@ func executeCmd(t *testing.T, command string) []byte { client := &kube.Client{Interface: fake.NewSimpleClientset()} // TODO(howell): switch to shellwords (or similar) args := strings.Fields(command) - rootCmd := cmd.NewRootCmd(&actual, client, args) + rootCmd, err := cmd.NewRootCmd(&actual, client, args) + if err != nil { + t.Fatalf(err.Error()) + } + rootCmd.SetArgs(args) if err := rootCmd.Execute(); err != nil { diff --git a/pkg/kube/clientset.go b/pkg/kube/clientset.go index b1e856957..7cd778ba1 100644 --- a/pkg/kube/clientset.go +++ b/pkg/kube/clientset.go @@ -1,6 +1,7 @@ package kube import ( + "errors" "os" "path/filepath" @@ -18,7 +19,7 @@ func NewForConfig(kubeconfigFilepath string) (*Client, error) { if kubeconfigFilepath == "" { home, err := os.UserHomeDir() if err != nil { - panic(err.Error()) + return nil, errors.New("could not find kubernetes config file: " + err.Error()) } kubeconfigFilepath = filepath.Join(home, ".kube", "config") } @@ -26,13 +27,13 @@ func NewForConfig(kubeconfigFilepath string) (*Client, error) { // use the current context in kubeconfigFilepath config, err := clientcmd.BuildConfigFromFlags("", kubeconfigFilepath) if err != nil { - panic(err.Error()) + return nil, err } // create the clientset clientset, err := kubernetes.NewForConfig(config) if err != nil { - panic(err.Error()) + return nil, err } return &Client{clientset}, nil }