clusterloader2/pkg/flags/flags.go (147 lines of code) (raw):

/* Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package flags import ( "flag" "fmt" "os" "strconv" "strings" "time" "github.com/spf13/pflag" "k8s.io/klog/v2" ) func init() { pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) klog.InitFlags(nil) pflag.CommandLine.AddGoFlagSet(flag.CommandLine) } var flags []flagFunc // StringVar creates string flag with given parameters. func StringVar(s *string, flagName, defaultValue, description string) { pflag.StringVar(s, flagName, defaultValue, description) } // IntVar creates int flag with given parameters. func IntVar(i *int, flagName string, defaultValue int, description string) { pflag.IntVar(i, flagName, defaultValue, description) } // BoolVar creates a bool flag with given parameters. func BoolVar(b *bool, flagName string, defaultValue bool, description string) { pflag.BoolVar(b, flagName, defaultValue, description) } // DurationVar creates a time.Duration flag with given parameters. func DurationVar(d *time.Duration, flagName string, defaultValue time.Duration, description string) { pflag.DurationVar(d, flagName, defaultValue, description) } // StringEnvVar creates string flag with given parameters. // If flag is not provided, it will try to get env variable. func StringEnvVar(s *string, flagName, envVariable, defaultValue, description string) { stringFlag := &stringFlagFunc{ valPtr: s, initializeFunc: func() error { return parseEnvString(s, envVariable, defaultValue) }, } pflag.Var(stringFlag, flagName, description) flags = append(flags, stringFlag) } // StringArrayVar creates string flag with given parameters. Flag can be used multiple times. func StringArrayVar(s *[]string, flagName string, defaultValue []string, description string) { pflag.StringArrayVar(s, flagName, defaultValue, description) } // StringSliceEnvVar creates a string slice flag with the given parameters. // If the flag is not provided, it will try to get the env variable. // Flag accepts multiple values separated by commas. func StringSliceEnvVar(s *[]string, flagName, envVariable string, defaultValue []string, description string) { stringSliceFlag := &stringSliceFlagFunc{ valPtr: s, initializeFunc: func() error { return parseEnvStringSlice(s, envVariable, defaultValue) }, } pflag.Var(stringSliceFlag, flagName, description) flags = append(flags, stringSliceFlag) } // IntEnvVar creates int flag with given parameters. // If flag is not provided, it will try to get env variable. func IntEnvVar(i *int, flagName, envVariable string, defaultValue int, description string) { intFlag := &intFlagFunc{ valPtr: i, initializeFunc: func() error { return parseEnvInt(i, envVariable, defaultValue) }, } pflag.Var(intFlag, flagName, description) flags = append(flags, intFlag) } // BoolEnvVar creates bool flag with given parameters. // If flag is not provided, it will try to get env variable. func BoolEnvVar(b *bool, flagName, envVariable string, defaultValue bool, description string) { boolFlag := &boolFlagFunc{ valPtr: b, initializeFunc: func() error { return parseEnvBool(b, envVariable, defaultValue) }, } // Set NoOptDefValue, to make --flag-name equivalent to --flag-name=true pflag.CommandLine.VarPF(boolFlag, flagName, "", description).NoOptDefVal = "true" flags = append(flags, boolFlag) } // DurationEnvVar creates time.Duration flag with given parameters. // If flag is not provided, it will try to get env variable. func DurationEnvVar(d *time.Duration, flagName, envVariable string, defaultValue time.Duration, description string) { durationFlag := &durationFlagFunc{ valPtr: d, initializeFunc: func() error { return parseEnvDuration(d, envVariable, defaultValue) }, } pflag.Var(durationFlag, flagName, description) flags = append(flags, durationFlag) } // Parse parses provided flags and env variables. func Parse() error { for i := range flags { if err := flags[i].initialize(); err != nil { return err } } if err := pflag.CommandLine.Parse(os.Args[1:]); err != nil { return err } return nil } // MarkDeprecated indicates that a flag is deprecated func MarkDeprecated(name string, usageMessage string) error { return pflag.CommandLine.MarkDeprecated(name, usageMessage) } func parseEnvString(s *string, envVariable, defaultValue string) error { *s = defaultValue if envVariable != "" { if val, ok := os.LookupEnv(envVariable); ok { *s = val return nil } } return nil } func parseEnvStringSlice(s *[]string, envVariable string, defaultValue []string) error { *s = defaultValue if envVariable != "" { if val, ok := os.LookupEnv(envVariable); ok && val != "" { *s = strings.Split(val, ",") } } return nil } func parseEnvInt(i *int, envVariable string, defaultValue int) error { *i = defaultValue if envVariable != "" { if val, ok := os.LookupEnv(envVariable); ok { iVal, err := strconv.Atoi(val) if err != nil { return fmt.Errorf("parsing env variable %s failed", envVariable) } *i = iVal return nil } } return nil } func parseEnvBool(b *bool, envVariable string, defaultValue bool) error { *b = defaultValue if envVariable != "" { if val, ok := os.LookupEnv(envVariable); ok { bVal, err := strconv.ParseBool(val) if err != nil { return fmt.Errorf("parsing env variable %s failed", envVariable) } *b = bVal return nil } } return nil } func parseEnvDuration(d *time.Duration, envVariable string, defaultValue time.Duration) error { *d = defaultValue if envVariable != "" { if val, ok := os.LookupEnv(envVariable); ok { dVal, err := time.ParseDuration(val) if err != nil { return fmt.Errorf("parsing env variable %s failed", envVariable) } *d = dVal return nil } } return nil }