Skip to content

backend: config: Parse: Shorten function #3283

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 60 additions & 38 deletions backend/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,55 @@ func (c *Config) Validate() error {
// go run ./cmd --port=3456
// the value of port will be 3456.

//nolint:funlen
func Parse(args []string) (*Config, error) {
var config Config

f := flagset()

k := koanf.New(".")

if err := setupAndParseArgs(f, k, args); err != nil {
return nil, err
}

explicitFlags := make(map[string]bool)

// Record which flags were explicitly set by the user
f.Visit(func(f *flag.Flag) {
explicitFlags[f.Name] = true
})

if err := loadConfigFromEnv(k); err != nil {
return nil, err
}

if err := loadExplicitFlags(f, k); err != nil {
return nil, err
}

if err := k.Unmarshal("", &config); err != nil {
logger.Log(logger.LevelError, nil, err, "unmarshalling config")
return nil, fmt.Errorf("error unmarshal config: %w", err)
}

// If running in-cluster and the user did not explicitly set the watch flag,
// then force WatchPluginsChanges to false.
if config.InCluster && !explicitFlags["watch-plugins-changes"] {
config.WatchPluginsChanges = false
}

// Validate parsed config
if err := config.Validate(); err != nil {
logger.Log(logger.LevelError, nil, err, "validating config")
return nil, err
}

setKubeConfigPath(&config)

return &config, nil
}

// setupAndParseArgs prepares and parses command line arguments.
func setupAndParseArgs(f *flag.FlagSet, k *koanf.Koanf, args []string) error {
if args == nil {
args = []string{}
} else if len(args) > 0 {
Expand All @@ -109,34 +150,32 @@ func Parse(args []string) (*Config, error) {
// First Load default args from flags
if err := k.Load(basicflag.Provider(f, "."), nil); err != nil {
logger.Log(logger.LevelError, nil, err, "loading default config from flags")

return nil, fmt.Errorf("error loading default config from flags: %w", err)
return fmt.Errorf("error loading default config from flags: %w", err)
}

// Parse args
if err := f.Parse(args); err != nil {
logger.Log(logger.LevelError, nil, err, "parsing flags")

return nil, fmt.Errorf("error parsing flags: %w", err)
return fmt.Errorf("error parsing flags: %w", err)
}

explicitFlags := make(map[string]bool)

// Record which flags were explicitly set by the user
f.Visit(func(f *flag.Flag) {
explicitFlags[f.Name] = true
})
return nil
}

// Load config from env
// loadConfigFromEnv loads configuration from environment variables.
func loadConfigFromEnv(k *koanf.Koanf) error {
if err := k.Load(env.Provider("HEADLAMP_CONFIG_", ".", func(s string) string {
return strings.ReplaceAll(strings.ToLower(strings.TrimPrefix(s, "HEADLAMP_CONFIG_")), "_", "-")
}), nil); err != nil {
logger.Log(logger.LevelError, nil, err, "loading config from env")

return nil, fmt.Errorf("error loading config from env: %w", err)
return fmt.Errorf("error loading config from env: %w", err)
}

// Load only the flags that were set
return nil
}

// loadExplicitFlags loads only the flags that were explicitly set.
func loadExplicitFlags(f *flag.FlagSet, k *koanf.Koanf) error {
if err := k.Load(basicflag.ProviderWithValue(f, ".", func(key string, value string) (string, interface{}) {
flagSet := false
f.Visit(func(f *flag.Flag) {
Expand All @@ -150,29 +189,14 @@ func Parse(args []string) (*Config, error) {
return "", nil
}), nil); err != nil {
logger.Log(logger.LevelError, nil, err, "loading config from flags")

return nil, fmt.Errorf("error loading config from flags: %w", err)
return fmt.Errorf("error loading config from flags: %w", err)
}

if err := k.Unmarshal("", &config); err != nil {
logger.Log(logger.LevelError, nil, err, "unmarshalling config")

return nil, fmt.Errorf("error unmarshal config: %w", err)
}

// If running in-cluster and the user did not explicitly set the watch flag,
// then force WatchPluginsChanges to false.
if config.InCluster && !explicitFlags["watch-plugins-changes"] {
config.WatchPluginsChanges = false
}

// Validate parsed config
if err := config.Validate(); err != nil {
logger.Log(logger.LevelError, nil, err, "validating config")

return nil, err
}
return nil
}

// setKubeConfigPath sets the appropriate kubeconfig path.
func setKubeConfigPath(config *Config) {
kubeConfigPath := ""

// If we don't have a specified kubeConfig path, and we are not running
Expand All @@ -189,8 +213,6 @@ func Parse(args []string) (*Config, error) {
}

config.KubeConfigPath = kubeConfigPath

return &config, nil
}

func flagset() *flag.FlagSet {
Expand Down
Loading