From 5f74fc00a3b1128d949225a39678207f5e8e4b26 Mon Sep 17 00:00:00 2001 From: dprunier Date: Wed, 29 May 2024 14:02:56 -0400 Subject: [PATCH 1/5] allow config and pre-processed configuration to leverage environment variables --- cmd/cluster/clusterCreate.go | 11 ++++++----- cmd/cluster/clusterDelete.go | 30 +++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/cmd/cluster/clusterCreate.go b/cmd/cluster/clusterCreate.go index 8fbd28fa9..bd11b408c 100644 --- a/cmd/cluster/clusterCreate.go +++ b/cmd/cluster/clusterCreate.go @@ -47,8 +47,6 @@ import ( "github.com/k3d-io/k3d/v5/version" ) -var configFile string - const clusterCreateDescription = ` Create a new k3s cluster with containerized nodes (k3s in docker). Every cluster will consist of one or more containers: @@ -72,13 +70,15 @@ var ( func initConfig() error { // Viper for pre-processed config options ppViper.SetEnvPrefix("K3D") + ppViper.AutomaticEnv() + ppViper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) if l.Log().GetLevel() >= logrus.DebugLevel { c, _ := yaml.Marshal(ppViper.AllSettings()) l.Log().Debugf("Additional CLI Configuration:\n%s", c) } - return cliconfig.InitViperWithConfigFile(cfgViper, configFile) + return cliconfig.InitViperWithConfigFile(cfgViper, ppViper.GetString("config")) } // NewCmdClusterCreate returns a new cobra command @@ -123,7 +123,7 @@ func NewCmdClusterCreate() *cobra.Command { l.Log().Fatalf("error processing/sanitizing simple config: %v", err) } - clusterConfig, err := config.TransformSimpleToClusterConfig(cmd.Context(), runtimes.SelectedRuntime, simpleCfg, configFile) + clusterConfig, err := config.TransformSimpleToClusterConfig(cmd.Context(), runtimes.SelectedRuntime, simpleCfg, ppViper.GetString("config")) if err != nil { l.Log().Fatalln(err) } @@ -208,7 +208,8 @@ func NewCmdClusterCreate() *cobra.Command { * Config File * ***************/ - cmd.Flags().StringVarP(&configFile, "config", "c", "", "Path of a config file to use") + cmd.Flags().StringP("config", "c", "", "Path of a config file to use") + _ = ppViper.BindPFlag("config", cmd.Flags().Lookup("config")) if err := cmd.MarkFlagFilename("config", "yaml", "yml"); err != nil { l.Log().Fatalln("Failed to mark flag 'config' as filename flag") } diff --git a/cmd/cluster/clusterDelete.go b/cmd/cluster/clusterDelete.go index 07f6c57d1..98f668644 100644 --- a/cmd/cluster/clusterDelete.go +++ b/cmd/cluster/clusterDelete.go @@ -26,6 +26,7 @@ import ( "fmt" "os" "path" + "strings" "github.com/k3d-io/k3d/v5/cmd/util" cliconfig "github.com/k3d-io/k3d/v5/cmd/util/config" @@ -35,13 +36,31 @@ import ( "github.com/k3d-io/k3d/v5/pkg/runtimes" k3d "github.com/k3d-io/k3d/v5/pkg/types" k3dutil "github.com/k3d-io/k3d/v5/pkg/util" + "github.com/sirupsen/logrus" + "sigs.k8s.io/yaml" "github.com/spf13/cobra" "github.com/spf13/viper" ) -var clusterDeleteConfigFile string -var clusterDeleteCfgViper = viper.New() +var ( + clusterDeleteCfgViper = viper.New() + clusterDeletePpViper = viper.New() +) + +func initClusterDeleteConfig() error { + // Viper for pre-processed config options + ppViper.SetEnvPrefix("K3D") + ppViper.AutomaticEnv() + ppViper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + + if l.Log().GetLevel() >= logrus.DebugLevel { + c, _ := yaml.Marshal(ppViper.AllSettings()) + l.Log().Debugf("Additional CLI Configuration:\n%s", c) + } + + return cliconfig.InitViperWithConfigFile(cfgViper, ppViper.GetString("config")) +} // NewCmdClusterDelete returns a new cobra command func NewCmdClusterDelete() *cobra.Command { @@ -54,7 +73,7 @@ func NewCmdClusterDelete() *cobra.Command { Args: cobra.MinimumNArgs(0), // 0 or n arguments; 0 = default cluster name ValidArgsFunction: util.ValidArgsAvailableClusters, PreRunE: func(cmd *cobra.Command, args []string) error { - return cliconfig.InitViperWithConfigFile(clusterDeleteCfgViper, clusterDeleteConfigFile) + return initClusterDeleteConfig() }, Run: func(cmd *cobra.Command, args []string) { clusters := parseDeleteClusterCmd(cmd, args) @@ -99,7 +118,8 @@ func NewCmdClusterDelete() *cobra.Command { * Config File * ***************/ - cmd.Flags().StringVarP(&clusterDeleteConfigFile, "config", "c", "", "Path of a config file to use") + cmd.Flags().StringP("config", "c", "", "Path of a config file to use") + _ = ppViper.BindPFlag("config", cmd.Flags().Lookup("config")) if err := cmd.MarkFlagFilename("config", "yaml", "yml"); err != nil { l.Log().Fatalln("Failed to mark flag 'config' as filename flag") } @@ -119,7 +139,7 @@ func parseDeleteClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { } // --config - if clusterDeleteConfigFile != "" { + if clusterDeletePpViper.GetString("config") != "" { // not allowed with --all or more args if len(args) > 0 || all { l.Log().Fatalln("failed to delete cluster: cannot use `--config` flag with additional arguments or `--all`") From a8241796a9daf2aa31c497ca959a9d66fa3ea136 Mon Sep 17 00:00:00 2001 From: dprunier Date: Mon, 15 Jul 2024 10:57:10 -0400 Subject: [PATCH 2/5] cluster delete command was not using the correct viper instance... --- cmd/cluster/clusterDelete.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/cluster/clusterDelete.go b/cmd/cluster/clusterDelete.go index 98f668644..c88f03b53 100644 --- a/cmd/cluster/clusterDelete.go +++ b/cmd/cluster/clusterDelete.go @@ -50,16 +50,16 @@ var ( func initClusterDeleteConfig() error { // Viper for pre-processed config options - ppViper.SetEnvPrefix("K3D") - ppViper.AutomaticEnv() - ppViper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + clusterDeletePpViper.SetEnvPrefix("K3D") + clusterDeletePpViper.AutomaticEnv() + clusterDeletePpViper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) if l.Log().GetLevel() >= logrus.DebugLevel { - c, _ := yaml.Marshal(ppViper.AllSettings()) + c, _ := yaml.Marshal(clusterDeletePpViper.AllSettings()) l.Log().Debugf("Additional CLI Configuration:\n%s", c) } - return cliconfig.InitViperWithConfigFile(cfgViper, ppViper.GetString("config")) + return cliconfig.InitViperWithConfigFile(cfgViper, clusterDeletePpViper.GetString("config")) } // NewCmdClusterDelete returns a new cobra command @@ -119,7 +119,7 @@ func NewCmdClusterDelete() *cobra.Command { ***************/ cmd.Flags().StringP("config", "c", "", "Path of a config file to use") - _ = ppViper.BindPFlag("config", cmd.Flags().Lookup("config")) + _ = clusterDeletePpViper.BindPFlag("config", cmd.Flags().Lookup("config")) if err := cmd.MarkFlagFilename("config", "yaml", "yml"); err != nil { l.Log().Fatalln("Failed to mark flag 'config' as filename flag") } From 376692e847e833b4aad7faf62a4363a765d6892d Mon Sep 17 00:00:00 2001 From: dprunier Date: Mon, 15 Jul 2024 11:22:01 -0400 Subject: [PATCH 3/5] cluster delete command was not using the correct viper instance again... --- cmd/cluster/clusterDelete.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cluster/clusterDelete.go b/cmd/cluster/clusterDelete.go index c88f03b53..984ca0189 100644 --- a/cmd/cluster/clusterDelete.go +++ b/cmd/cluster/clusterDelete.go @@ -59,7 +59,7 @@ func initClusterDeleteConfig() error { l.Log().Debugf("Additional CLI Configuration:\n%s", c) } - return cliconfig.InitViperWithConfigFile(cfgViper, clusterDeletePpViper.GetString("config")) + return cliconfig.InitViperWithConfigFile(clusterDeleteCfgViper, clusterDeletePpViper.GetString("config")) } // NewCmdClusterDelete returns a new cobra command From fff51e92f802506dd32e74f804bb50fe1ca545f1 Mon Sep 17 00:00:00 2001 From: dprunier Date: Mon, 15 Jul 2024 17:04:47 -0400 Subject: [PATCH 4/5] ignore configuration provided to cluster delete command if it doesnt provide a name --- cmd/cluster/clusterDelete.go | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/cmd/cluster/clusterDelete.go b/cmd/cluster/clusterDelete.go index 984ca0189..b526d4b96 100644 --- a/cmd/cluster/clusterDelete.go +++ b/cmd/cluster/clusterDelete.go @@ -140,28 +140,26 @@ func parseDeleteClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { // --config if clusterDeletePpViper.GetString("config") != "" { - // not allowed with --all or more args - if len(args) > 0 || all { - l.Log().Fatalln("failed to delete cluster: cannot use `--config` flag with additional arguments or `--all`") - } - cfg, err := config.SimpleConfigFromViper(clusterDeleteCfgViper) if err != nil { l.Log().Fatalln(err) } - if cfg.Name == "" { - l.Log().Fatalln("failed to delete cluster via config file: no name in config file") - } + if cfg.Name != "" { + // not allowed with --all or more args + if len(args) > 0 || all { + l.Log().Fatalln("failed to delete cluster: cannot use name from configuration file with additional arguments or `--all`") + } - c, err := client.ClusterGet(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: cfg.Name}) - if errors.Is(err, client.ClusterGetNoNodesFoundError) { - l.Log().Infof("No nodes found for cluster '%s', nothing to delete.", cfg.Name) - return nil - } + c, err := client.ClusterGet(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: cfg.Name}) + if errors.Is(err, client.ClusterGetNoNodesFoundError) { + l.Log().Infof("No nodes found for cluster '%s', nothing to delete.", cfg.Name) + return nil + } - clusters = append(clusters, c) - return clusters + clusters = append(clusters, c) + return clusters + } } // --all was set From a8445fca0b355d31654528e90b4eb10804b368b5 Mon Sep 17 00:00:00 2001 From: dprunier Date: Mon, 18 Nov 2024 15:07:33 -0500 Subject: [PATCH 5/5] allow --all or args to override configuration name --- cmd/cluster/clusterDelete.go | 57 +++++++++++++++--------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/cmd/cluster/clusterDelete.go b/cmd/cluster/clusterDelete.go index b526d4b96..847516bd9 100644 --- a/cmd/cluster/clusterDelete.go +++ b/cmd/cluster/clusterDelete.go @@ -22,6 +22,7 @@ THE SOFTWARE. package cluster import ( + "context" "errors" "fmt" "os" @@ -130,64 +131,54 @@ func NewCmdClusterDelete() *cobra.Command { // parseDeleteClusterCmd parses the command input into variables required to delete clusters func parseDeleteClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { - var clusters []*k3d.Cluster - // --all all, err := cmd.Flags().GetBool("all") if err != nil { l.Log().Fatalln(err) } - // --config - if clusterDeletePpViper.GetString("config") != "" { - cfg, err := config.SimpleConfigFromViper(clusterDeleteCfgViper) - if err != nil { - l.Log().Fatalln(err) - } - - if cfg.Name != "" { - // not allowed with --all or more args - if len(args) > 0 || all { - l.Log().Fatalln("failed to delete cluster: cannot use name from configuration file with additional arguments or `--all`") - } - - c, err := client.ClusterGet(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: cfg.Name}) - if errors.Is(err, client.ClusterGetNoNodesFoundError) { - l.Log().Infof("No nodes found for cluster '%s', nothing to delete.", cfg.Name) - return nil - } - - clusters = append(clusters, c) - return clusters - } - } - // --all was set if all { l.Log().Infoln("Deleting all clusters...") - clusters, err = client.ClusterList(cmd.Context(), runtimes.SelectedRuntime) + clusters, err := client.ClusterList(cmd.Context(), runtimes.SelectedRuntime) if err != nil { l.Log().Fatalln(err) } return clusters } - // args only - clusternames := []string{k3d.DefaultClusterName} + // args if len(args) != 0 { - clusternames = args + return getClusters(cmd.Context(), args...) + } + + // --config + if clusterDeletePpViper.GetString("config") != "" { + cfg, err := config.SimpleConfigFromViper(clusterDeleteCfgViper) + if err != nil { + l.Log().Fatalln(err) + } + if cfg.Name != "" { + return getClusters(cmd.Context(), cfg.Name) + } } + // default + return getClusters(cmd.Context(), k3d.DefaultClusterName) +} + +func getClusters(ctx context.Context, clusternames ...string) []*k3d.Cluster { + var clusters []*k3d.Cluster for _, name := range clusternames { - c, err := client.ClusterGet(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: name}) + c, err := client.ClusterGet(ctx, runtimes.SelectedRuntime, &k3d.Cluster{Name: name}) if err != nil { - if err == client.ClusterGetNoNodesFoundError { + if errors.Is(err, client.ClusterGetNoNodesFoundError) { + l.Log().Infof("No nodes found for cluster '%s', nothing to delete.", name) continue } l.Log().Fatalln(err) } clusters = append(clusters, c) } - return clusters }