Skip to content

Commit 80696f1

Browse files
Allow users use a env vars or a config file instead of cli flags
1 parent d5c4aab commit 80696f1

File tree

7 files changed

+496
-24
lines changed

7 files changed

+496
-24
lines changed

go.mod

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/openshift/client-go v0.0.0-20230120202327-72f107311084
99
github.com/sirupsen/logrus v1.9.0
1010
github.com/spf13/cobra v1.6.0
11+
github.com/spf13/viper v1.15.0
1112
golang.org/x/mod v0.8.0
1213
k8s.io/api v0.26.1
1314
k8s.io/apimachinery v0.26.1
@@ -19,6 +20,7 @@ require (
1920
github.com/davecgh/go-spew v1.1.1 // indirect
2021
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
2122
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
23+
github.com/fsnotify/fsnotify v1.6.0 // indirect
2224
github.com/go-logr/logr v1.2.3 // indirect
2325
github.com/go-openapi/jsonpointer v0.19.6 // indirect
2426
github.com/go-openapi/jsonreference v0.20.2 // indirect
@@ -30,20 +32,27 @@ require (
3032
github.com/google/go-cmp v0.5.9 // indirect
3133
github.com/google/gofuzz v1.2.0 // indirect
3234
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
35+
github.com/hashicorp/hcl v1.0.0 // indirect
3336
github.com/imdario/mergo v0.3.13 // indirect
3437
github.com/inconshreveable/mousetrap v1.0.1 // indirect
3538
github.com/josharian/intern v1.0.0 // indirect
3639
github.com/json-iterator/go v1.1.12 // indirect
37-
github.com/kr/pretty v0.3.0 // indirect
40+
github.com/magiconair/properties v1.8.7 // indirect
3841
github.com/mailru/easyjson v0.7.7 // indirect
42+
github.com/mitchellh/mapstructure v1.5.0 // indirect
3943
github.com/moby/spdystream v0.2.0 // indirect
4044
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
4145
github.com/modern-go/reflect2 v1.0.2 // indirect
4246
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
4347
github.com/openshift/api v0.0.0-20230120195050-6ba31fa438f2 // indirect
48+
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
4449
github.com/pkg/errors v0.9.1 // indirect
4550
github.com/rogpeppe/go-internal v1.8.0 // indirect
51+
github.com/spf13/afero v1.9.3 // indirect
52+
github.com/spf13/cast v1.5.0 // indirect
53+
github.com/spf13/jwalterweatherman v1.1.0 // indirect
4654
github.com/spf13/pflag v1.0.5 // indirect
55+
github.com/subosito/gotenv v1.4.2 // indirect
4756
golang.org/x/net v0.8.0 // indirect
4857
golang.org/x/oauth2 v0.5.0 // indirect
4958
golang.org/x/sys v0.6.0 // indirect
@@ -54,6 +63,7 @@ require (
5463
google.golang.org/appengine v1.6.7 // indirect
5564
google.golang.org/protobuf v1.28.1 // indirect
5665
gopkg.in/inf.v0 v0.9.1 // indirect
66+
gopkg.in/ini.v1 v1.67.0 // indirect
5767
gopkg.in/yaml.v2 v2.4.0 // indirect
5868
gopkg.in/yaml.v3 v3.0.1 // indirect
5969
k8s.io/klog/v2 v2.90.0 // indirect

go.sum

+331-2
Large diffs are not rendered by default.

pkg/cmd/collect.go

+58-15
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
log "github.com/sirupsen/logrus"
1111
"github.com/spf13/cobra"
12+
"github.com/spf13/viper"
1213

1314
"github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/runner"
1415
"github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils"
@@ -27,29 +28,58 @@ var (
2728
collectorNames []string
2829
)
2930

31+
type CollectionParams struct {
32+
KubeConfig string `mapstructure:"kubeconfig"`
33+
PTPInterface string `mapstructure:"ptp_interface"`
34+
OutputFile string `mapstructure:"output_file"`
35+
Duration string `mapstructure:"duration"`
36+
CollectorNames []string `mapstructure:"collectors"`
37+
PollInterval int `mapstructure:"poll_rate"`
38+
DevInfoAnnouceInterval int `mapstructure:"announce_rate"`
39+
UseAnalyserJSON bool `mapstructure:"use_analyser_json"`
40+
}
41+
42+
func (p *CollectionParams) CheckForRequiredFields() error {
43+
missing := make([]string, 0)
44+
if p.KubeConfig == "" {
45+
missing = append(missing, "kubeconfig")
46+
}
47+
if p.PTPInterface == "" {
48+
missing = append(missing, "interface")
49+
}
50+
if len(missing) > 0 {
51+
return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missing, `", "`))
52+
}
53+
return nil
54+
}
55+
3056
// collectCmd represents the collect command
3157
var collectCmd = &cobra.Command{
3258
Use: "collect",
3359
Short: "Run the collector tool",
3460
Long: `Run the collector tool to gather data from your target cluster`,
3561
Run: func(cmd *cobra.Command, args []string) {
36-
collectionRunner := runner.NewCollectorRunner(collectorNames)
62+
runtimeConfig := &CollectionParams{}
63+
err := populateParams(cmd, runtimeConfig)
64+
if err == nil {
65+
requestedDuration, err := time.ParseDuration(runtimeConfig.Duration)
66+
if requestedDuration.Nanoseconds() < 0 {
67+
log.Panicf("Requested duration must be positive")
68+
}
69+
utils.IfErrorExitOrPanic(err)
3770

38-
requestedDuration, err := time.ParseDuration(requestedDurationStr)
39-
if requestedDuration.Nanoseconds() < 0 {
40-
log.Panicf("Requested duration must be positive")
71+
collectionRunner := runner.NewCollectorRunner(runtimeConfig.CollectorNames)
72+
collectionRunner.Run(
73+
runtimeConfig.KubeConfig,
74+
runtimeConfig.OutputFile,
75+
requestedDuration,
76+
runtimeConfig.PollInterval,
77+
runtimeConfig.DevInfoAnnouceInterval,
78+
runtimeConfig.PTPInterface,
79+
runtimeConfig.UseAnalyserJSON,
80+
)
4181
}
42-
utils.IfErrorExitOrPanic(err)
43-
44-
collectionRunner.Run(
45-
kubeConfig,
46-
outputFile,
47-
requestedDuration,
48-
pollInterval,
49-
devInfoAnnouceInterval,
50-
ptpInterface,
51-
useAnalyserJSON,
52-
)
82+
5383
},
5484
}
5585

@@ -69,6 +99,9 @@ func init() { //nolint:funlen // Allow this to get a little long
6999
"A positive duration string sequence of decimal numbers and a unit suffix, such as \"300ms\", \"1.5h\" or \"2h45m\"."+
70100
" Valid time units are \"s\", \"m\", \"h\".",
71101
)
102+
err := viper.BindPFlag("duration", collectCmd.Flags().Lookup("duration"))
103+
utils.IfErrorExitOrPanic(err)
104+
72105
collectCmd.Flags().IntVarP(
73106
&pollInterval,
74107
"rate",
@@ -77,13 +110,21 @@ func init() { //nolint:funlen // Allow this to get a little long
77110
"Poll interval for querying the cluster. The value will be polled once every interval. "+
78111
"Using --rate 10 will cause the value to be polled once every 10 seconds",
79112
)
113+
err = viper.BindPFlag("rate", collectCmd.Flags().Lookup("rate"))
114+
utils.IfErrorExitOrPanic(err)
115+
viper.RegisterAlias("poll_rate", "rate")
116+
80117
collectCmd.Flags().IntVarP(
81118
&devInfoAnnouceInterval,
82119
"announce",
83120
"a",
84121
defaultDevInfoInterval,
85122
"interval at which to emit the device info summary to the targeted output.",
86123
)
124+
err = viper.BindPFlag("announce", collectCmd.Flags().Lookup("announce"))
125+
utils.IfErrorExitOrPanic(err)
126+
viper.RegisterAlias("announce_rate", "announce")
127+
87128
defaultCollectorNames := make([]string, 0)
88129
defaultCollectorNames = append(defaultCollectorNames, runner.All)
89130
collectCmd.Flags().StringSliceVarP(
@@ -99,4 +140,6 @@ func init() { //nolint:funlen // Allow this to get a little long
99140
strings.Join(runner.OptionalCollectorNames, ", "),
100141
),
101142
)
143+
utils.IfErrorExitOrPanic(err)
144+
viper.RegisterAlias("collector", "collectors")
102145
}

pkg/cmd/common.go

+29-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
package cmd
44

55
import (
6+
"fmt"
7+
"os"
8+
69
"github.com/spf13/cobra"
10+
"github.com/spf13/viper"
711

812
"github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils"
913
)
@@ -17,12 +21,14 @@ var (
1721

1822
func AddKubeconfigFlag(targetCmd *cobra.Command) {
1923
targetCmd.Flags().StringVarP(&kubeConfig, "kubeconfig", "k", "", "Path to the kubeconfig file")
20-
err := targetCmd.MarkFlagRequired("kubeconfig")
24+
err := viper.BindPFlag("kubeconfig", targetCmd.Flags().Lookup("kubeconfig"))
2125
utils.IfErrorExitOrPanic(err)
2226
}
2327

2428
func AddOutputFlag(targetCmd *cobra.Command) {
2529
targetCmd.Flags().StringVarP(&outputFile, "output", "o", "", "Path to the output file")
30+
err := viper.BindPFlag("output", targetCmd.Flags().Lookup("output"))
31+
utils.IfErrorExitOrPanic(err)
2632
}
2733

2834
func AddFormatFlag(targetCmd *cobra.Command) {
@@ -33,10 +39,31 @@ func AddFormatFlag(targetCmd *cobra.Command) {
3339
false,
3440
"Output in a format to be used by analysers from vse-sync-pp",
3541
)
42+
err := viper.BindPFlag("use_analyser_format", targetCmd.Flags().Lookup("use-analyser-format"))
43+
utils.IfErrorExitOrPanic(err)
3644
}
3745

3846
func AddInterfaceFlag(targetCmd *cobra.Command) {
3947
targetCmd.Flags().StringVarP(&ptpInterface, "interface", "i", "", "Name of the PTP interface")
40-
err := targetCmd.MarkFlagRequired("interface")
48+
err := viper.BindPFlag("interface", targetCmd.Flags().Lookup("interface"))
49+
utils.IfErrorExitOrPanic(err)
50+
viper.RegisterAlias("ptp_interface", "interface")
51+
}
52+
53+
type Params interface {
54+
CheckForRequiredFields() error
55+
}
56+
57+
func populateParams(cmd *cobra.Command, params Params) error {
58+
err := viper.Unmarshal(params)
4159
utils.IfErrorExitOrPanic(err)
60+
err = params.CheckForRequiredFields()
61+
if err != nil {
62+
cmd.PrintErrln(err.Error())
63+
err = cmd.Usage()
64+
utils.IfErrorExitOrPanic(err)
65+
os.Exit(int(utils.InvalidArgs))
66+
return fmt.Errorf("failed to populate params: %w", err)
67+
}
68+
return nil
4269
}

pkg/cmd/root.go

+34-3
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,41 @@ import (
77

88
log "github.com/sirupsen/logrus"
99
"github.com/spf13/cobra"
10+
"github.com/spf13/viper"
1011

1112
"github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/logging"
13+
"github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils"
1214
)
1315

16+
type RootParams struct {
17+
LogLevel string `mapstructure:"verbosity"`
18+
}
19+
20+
func (p *RootParams) CheckForRequiredFields() error {
21+
return nil
22+
}
23+
1424
var (
15-
logLevel string
25+
configFile string
26+
logLevel string
1627

1728
// rootCmd represents the base command when called without any subcommands
1829
rootCmd = &cobra.Command{
19-
Use: "vse-sync-testsuite",
30+
Use: "vse-sync-collection-tools",
2031
Short: "A monitoring tool for PTP related metrics",
2132
Long: `A monitoring tool for PTP related metrics.`,
2233
PersistentPreRun: func(cmd *cobra.Command, args []string) {
23-
logging.SetupLogging(logLevel, os.Stdout)
34+
if configFile != "" {
35+
log.Debugf("config: %v", configFile)
36+
viper.SetConfigFile(configFile)
37+
err := viper.ReadInConfig()
38+
utils.IfErrorExitOrPanic(err)
39+
}
40+
params := RootParams{}
41+
err := populateParams(cmd, &params)
42+
if err == nil {
43+
logging.SetupLogging(params.LogLevel, os.Stdout)
44+
}
2445
},
2546
}
2647
)
@@ -35,11 +56,21 @@ func Execute() {
3556
}
3657

3758
func init() {
59+
viper.AutomaticEnv()
60+
viper.SetEnvPrefix("COLLECTOR")
61+
configureFlags()
62+
}
63+
64+
func configureFlags() { //nolint:funlen // Allow this to get a little long
65+
rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "Path to config file")
3866
rootCmd.PersistentFlags().StringVarP(
3967
&logLevel,
4068
"verbosity",
4169
"v",
4270
log.WarnLevel.String(),
4371
"Log level (debug, info, warn, error, fatal, panic)",
4472
)
73+
err := viper.BindPFlag("verbosity", rootCmd.PersistentFlags().Lookup("verbosity"))
74+
utils.IfErrorExitOrPanic(err)
75+
viper.RegisterAlias("log_level", "verbosity")
4576
}

pkg/cmd/verifyEnv.go

+32-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
package cmd
44

55
import (
6+
"fmt"
7+
"strings"
8+
69
"github.com/spf13/cobra"
710

811
"github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/verify"
@@ -14,13 +17,41 @@ var envCmd = &cobra.Command{
1417
Long: `environment based actions`,
1518
}
1619

20+
type VerifyParams struct {
21+
KubeConfig string `mapstructure:"kubeconfig"`
22+
PTPInterface string `mapstructure:"ptp_interface"`
23+
UseAnalyserJSON bool `mapstructure:"use_analyser_format"`
24+
}
25+
26+
func (p *VerifyParams) CheckForRequiredFields() error {
27+
missing := make([]string, 0)
28+
if p.KubeConfig == "" {
29+
missing = append(missing, "kubeconfig")
30+
}
31+
if p.PTPInterface == "" {
32+
missing = append(missing, "interface")
33+
}
34+
if len(missing) > 0 {
35+
return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missing, `", "`))
36+
}
37+
return nil
38+
}
39+
1740
// verifyEnvCmd represents the verifyEnv command
1841
var verifyEnvCmd = &cobra.Command{
1942
Use: "verify",
2043
Short: "verify the environment is ready for collection",
2144
Long: `verify the environment is ready for collection`,
2245
Run: func(cmd *cobra.Command, args []string) {
23-
verify.Verify(ptpInterface, kubeConfig, useAnalyserJSON)
46+
runtimeConfig := &VerifyParams{}
47+
err := populateParams(cmd, runtimeConfig)
48+
if err == nil {
49+
verify.Verify(
50+
runtimeConfig.PTPInterface,
51+
runtimeConfig.KubeConfig,
52+
runtimeConfig.UseAnalyserJSON,
53+
)
54+
}
2455
},
2556
}
2657

pkg/utils/errors.go

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type exitCode int
1313
const (
1414
// Exitcodes
1515
Success exitCode = iota
16+
InvalidArgs
1617
InvalidEnv
1718
MissingInput
1819
NotHandled

0 commit comments

Comments
 (0)