Skip to content

Commit

Permalink
Simulate cascading PersistPreRunE calls
Browse files Browse the repository at this point in the history
Because cobra will only call the last PersistPreRunE we need to
simulate a cascading run.
spf13/cobra#252

We also switches every function to `...E` alternative
  • Loading branch information
mateimicu committed May 1, 2020
1 parent cc4711f commit fc5725e
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 24 deletions.
26 changes: 19 additions & 7 deletions cmd/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package cmd

import (
"fmt"
"os"

"github.com/mateimicu/kdiscover/internal"
"github.com/spf13/cobra"
Expand All @@ -20,7 +19,20 @@ func newAWSCommand() *cobra.Command {
AWSCommand := &cobra.Command{
Use: "aws",
Short: "Work with AWS EKS clusters",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// Because cobra will only run the last PersistentPreRunE
// we need to search for the root and run the function.
// This is not a robust solution as there may be multiple
// PersistentPreRunE function between the leaf command and root
// also this assumes that this is the root one
// An issue about this https://github.com/spf13/cobra/issues/252
root := cmd
for ; root.HasParent(); root = root.Parent() {
}
err := root.PersistentPreRunE(cmd, args)
if err != nil {
return err
}
log.WithFields(log.Fields{
"partitions": awsPartitions,
}).Debug("Search regions for partitions")
Expand All @@ -31,15 +43,17 @@ func newAWSCommand() *cobra.Command {
log.WithFields(log.Fields{
"partitions": awsPartitions,
}).Error("Can't find regions for partitions")
os.Exit(errorExitCode)
return fmt.Errorf("Can't find regions for partitions %v", awsPartitions)
}

log.WithFields(log.Fields{
"regions": awsRegions,
}).Info("Founds regions")
return nil
},
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
cmd.HelpFunc()(cmd, args)
return nil
},
}

Expand All @@ -55,8 +69,6 @@ func newAWSCommand() *cobra.Command {
internal.GetDefaultKubeconfigPath(),
"Path to the kubeconfig to work with")

AWSCommand.AddCommand(newListCommand())
AWSCommand.AddCommand(newUpdateCommand())

AWSCommand.AddCommand(newListCommand(), newUpdateCommand())
return AWSCommand
}
4 changes: 3 additions & 1 deletion cmd/aws_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func newListCommand() *cobra.Command {
listCommand := &cobra.Command{
Use: "list",
Short: "List all EKS Clusters",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
remoteEKSClusters := internal.GetEKSClusters(awsRegions)
log.Info(remoteEKSClusters)

Expand Down Expand Up @@ -45,6 +45,8 @@ func newListCommand() *cobra.Command {
})
// render it
fmt.Println(tw.Render())

return nil
},
}

Expand Down
9 changes: 4 additions & 5 deletions cmd/aws_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func newUpdateCommand() *cobra.Command {
updateCommand := &cobra.Command{
Use: "update",
Short: "Update all EKS Clusters",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println(cmd.Short)
remoteEKSClusters := internal.GetEKSClusters(awsRegions)
log.Info(remoteEKSClusters)
Expand All @@ -39,15 +39,14 @@ func newUpdateCommand() *cobra.Command {
fmt.Printf("Backup kubeconfig to %v\n", bName)
err = copy(kubeconfigPath, bName)
if err != nil {
fmt.Println(err.Error())
return
return err
}
}
err := internal.UpdateKubeconfig(remoteEKSClusters, kubeconfigPath, contextName{templateValue: alias})
if err != nil {
fmt.Println(err.Error())
return
return err
}
return nil
},
}
updateCommand.Flags().BoolVar(&backupKubeconfig, "backup-kubeconfig", true, "Backup cubeconfig before update")
Expand Down
55 changes: 44 additions & 11 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,50 @@ import (
const errorExitCode int = 1

var (
loggingLevels map[string]log.Level = map[string]log.Level{
"none": 0,
"panic": log.PanicLevel,
"fatal": log.FatalLevel,
"error": log.ErrorLevel,
"warn": log.WarnLevel,
"info": log.InfoLevel,
"debug": log.DebugLevel,
"trace": log.TraceLevel,
}
kubeconfigPath string
debug bool
rootCmd = &cobra.Command{
logLevel string
)

func NewRootCommand() *cobra.Command {
rootCmd := &cobra.Command{
Use: "kdiscover",
Short: "Discover all EKS clusters on an account.",
Long: `kdiscover is a simple utility that can search
all regions on an AWS account and try to find all EKS clsuters.
It will try to upgrade the kube-config for each cluster.`,

PersistentPreRun: func(cmd *cobra.Command, args []string) {
if debug {
log.SetLevel(log.DebugLevel)
} else {
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("root")
if logLevel == "none" {
log.SetOutput(ioutil.Discard)
return nil
}

if v, ok := loggingLevels[logLevel]; ok {
log.SetLevel(v)
return nil
}

return fmt.Errorf("Can't find logging level %v", logLevel)
},

Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
cmd.HelpFunc()(cmd, args)
return nil
},
}
)

// Execute will create the tree of commands and will start parsing and execution
func Execute() {
rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "set log level to debug")
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "none", fmt.Sprintf("Set logging lvl. Supported %v", getAllLogglingLevels()))

rootCmd.PersistentFlags().StringVar(
&kubeconfigPath,
Expand All @@ -49,9 +67,24 @@ func Execute() {
"Path to the kubeconfig to work with")

rootCmd.AddCommand(newAWSCommand())
return rootCmd
}

// Execute will create the tree of commands and will start parsing and execution
func Execute() {
rootCmd := NewRootCommand()

if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(errorExitCode)
}
}

func getAllLogglingLevels() []string {
keys := make([]string, 0, len(loggingLevels))
for k := range loggingLevels {
keys = append(keys, k)
}

return keys
}

0 comments on commit fc5725e

Please sign in to comment.