github.com/argoproj/argo-cd/v3@v3.2.1/util/env/env.go (about)

     1  package env
     2  
     3  import (
     4  	"math"
     5  	"os"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  
    10  	log "github.com/sirupsen/logrus"
    11  )
    12  
    13  // Helper function to parse a number from an environment variable. Returns a
    14  // default if env is not set, is not parseable to a number, exceeds maximum (if
    15  // maximum is greater than 0) or is less than minimum.
    16  func ParseNumFromEnv(env string, defaultValue, minimum, maximum int) int {
    17  	str := os.Getenv(env)
    18  	if str == "" {
    19  		return defaultValue
    20  	}
    21  	num, err := strconv.ParseInt(str, 10, 0)
    22  	if err != nil {
    23  		log.Warnf("Could not parse '%s' as a number from environment %s", str, env)
    24  		return defaultValue
    25  	}
    26  	if num > math.MaxInt || num < math.MinInt {
    27  		log.Warnf("Value in %s is %d is outside of the min and max %d allowed values. Using default %d", env, num, minimum, defaultValue)
    28  		return defaultValue
    29  	}
    30  	if int(num) < minimum {
    31  		log.Warnf("Value in %s is %d, which is less than minimum %d allowed", env, num, minimum)
    32  		return defaultValue
    33  	}
    34  	if int(num) > maximum {
    35  		log.Warnf("Value in %s is %d, which is greater than maximum %d allowed", env, num, maximum)
    36  		return defaultValue
    37  	}
    38  	return int(num)
    39  }
    40  
    41  // Helper function to parse a int64 from an environment variable. Returns a
    42  // default if env is not set, is not parseable to a number, exceeds maximum (if
    43  // maximum is greater than 0) or is less than minimum.
    44  func ParseInt64FromEnv(env string, defaultValue, minimum, maximum int64) int64 {
    45  	str := os.Getenv(env)
    46  	if str == "" {
    47  		return defaultValue
    48  	}
    49  
    50  	num, err := strconv.ParseInt(str, 10, 64)
    51  	if err != nil {
    52  		log.Warnf("Could not parse '%s' as a int64 from environment %s", str, env)
    53  		return defaultValue
    54  	}
    55  	if num < minimum {
    56  		log.Warnf("Value in %s is %d, which is less than minimum %d allowed", env, num, minimum)
    57  		return defaultValue
    58  	}
    59  	if num > maximum {
    60  		log.Warnf("Value in %s is %d, which is greater than maximum %d allowed", env, num, maximum)
    61  		return defaultValue
    62  	}
    63  	return num
    64  }
    65  
    66  // Helper function to parse a float32 from an environment variable. Returns a
    67  // default if env is not set, is not parseable to a number, exceeds maximum (if
    68  // maximum is greater than 0) or is less than minimum (and minimum is greater than 0).
    69  func ParseFloatFromEnv(env string, defaultValue, minimum, maximum float32) float32 {
    70  	str := os.Getenv(env)
    71  	if str == "" {
    72  		return defaultValue
    73  	}
    74  
    75  	num, err := strconv.ParseFloat(str, 32)
    76  	if err != nil {
    77  		log.Warnf("Could not parse '%s' as a float32 from environment %s", str, env)
    78  		return defaultValue
    79  	}
    80  	if float32(num) < minimum {
    81  		log.Warnf("Value in %s is %f, which is less than minimum %f allowed", env, num, minimum)
    82  		return defaultValue
    83  	}
    84  	if float32(num) > maximum {
    85  		log.Warnf("Value in %s is %f, which is greater than maximum %f allowed", env, num, maximum)
    86  		return defaultValue
    87  	}
    88  	return float32(num)
    89  }
    90  
    91  // Helper function to parse a float64 from an environment variable. Returns a
    92  // default if env is not set, is not parseable to a number, exceeds maximum (if
    93  // maximum is greater than 0) or is less than minimum (and minimum is greater than 0).
    94  func ParseFloat64FromEnv(env string, defaultValue, minimum, maximum float64) float64 {
    95  	str := os.Getenv(env)
    96  	if str == "" {
    97  		return defaultValue
    98  	}
    99  
   100  	num, err := strconv.ParseFloat(str, 64)
   101  	if err != nil {
   102  		log.Warnf("Could not parse '%s' as a float64 from environment %s", str, env)
   103  		return defaultValue
   104  	}
   105  	if num < minimum {
   106  		log.Warnf("Value in %s is %f, which is less than minimum %f allowed", env, num, minimum)
   107  		return defaultValue
   108  	}
   109  	if num > maximum {
   110  		log.Warnf("Value in %s is %f, which is greater than maximum %f allowed", env, num, maximum)
   111  		return defaultValue
   112  	}
   113  	return num
   114  }
   115  
   116  // Helper function to parse a time duration from an environment variable. Returns a
   117  // default if env is not set, is not parseable to a duration, exceeds maximum (if
   118  // maximum is greater than 0) or is less than minimum.
   119  //
   120  // nolint:unparam
   121  func ParseDurationFromEnv(env string, defaultValue, minimum, maximum time.Duration) time.Duration {
   122  	str := os.Getenv(env)
   123  	if str == "" {
   124  		return defaultValue
   125  	}
   126  	dur, err := time.ParseDuration(str)
   127  	if err != nil {
   128  		log.Warnf("Could not parse '%s' as a duration string from environment %s", str, env)
   129  		return defaultValue
   130  	}
   131  
   132  	if dur < minimum {
   133  		log.Warnf("Value in %s is %s, which is less than minimum %s allowed", env, dur, minimum)
   134  		return defaultValue
   135  	}
   136  	if dur > maximum {
   137  		log.Warnf("Value in %s is %s, which is greater than maximum %s allowed", env, dur, maximum)
   138  		return defaultValue
   139  	}
   140  	return dur
   141  }
   142  
   143  type StringFromEnvOpts struct {
   144  	// AllowEmpty allows the value to be empty as long as the environment variable is set.
   145  	AllowEmpty bool
   146  }
   147  
   148  func StringFromEnv(env string, defaultValue string, opts ...StringFromEnvOpts) string {
   149  	opt := StringFromEnvOpts{}
   150  	for _, o := range opts {
   151  		opt.AllowEmpty = opt.AllowEmpty || o.AllowEmpty
   152  	}
   153  	if str, ok := os.LookupEnv(env); opt.AllowEmpty && ok || str != "" {
   154  		return str
   155  	}
   156  	return defaultValue
   157  }
   158  
   159  // StringsFromEnv parses given value from the environment as a list of strings,
   160  // using separator as the delimeter, and returns them as a slice. The strings
   161  // in the returned slice will have leading and trailing white space removed.
   162  func StringsFromEnv(env string, defaultValue []string, separator string) []string {
   163  	if str := os.Getenv(env); str != "" {
   164  		ss := strings.Split(str, separator)
   165  		for i, s := range ss {
   166  			ss[i] = strings.TrimSpace(s)
   167  		}
   168  		return ss
   169  	}
   170  	return defaultValue
   171  }
   172  
   173  // ParseBoolFromEnv retrieves a boolean value from given environment envVar.
   174  // Returns default value if envVar is not set.
   175  //
   176  // nolint:unparam
   177  func ParseBoolFromEnv(envVar string, defaultValue bool) bool {
   178  	if val := os.Getenv(envVar); val != "" {
   179  		if strings.EqualFold(val, "true") {
   180  			return true
   181  		} else if strings.EqualFold(val, "false") {
   182  			return false
   183  		}
   184  	}
   185  	return defaultValue
   186  }
   187  
   188  // ParseStringToStringFromEnv parses given value from the environment as a map of string.
   189  // Returns default value if envVar is not set.
   190  func ParseStringToStringFromEnv(envVar string, defaultValue map[string]string, separator string) map[string]string {
   191  	str := os.Getenv(envVar)
   192  	str = strings.TrimSpace(str)
   193  	if str == "" {
   194  		return defaultValue
   195  	}
   196  
   197  	parsed := make(map[string]string)
   198  	for _, pair := range strings.Split(str, separator) {
   199  		keyvalue := strings.Split(pair, "=")
   200  		if len(keyvalue) != 2 {
   201  			log.Warnf("Invalid key-value pair when parsing environment '%s' as a string map", str)
   202  			return defaultValue
   203  		}
   204  		key := strings.TrimSpace(keyvalue[0])
   205  		value := strings.TrimSpace(keyvalue[1])
   206  		if _, ok := parsed[key]; ok {
   207  			log.Warnf("Duplicate key '%s' when parsing environment '%s' as a string map", key, str)
   208  			return defaultValue
   209  		}
   210  		parsed[key] = value
   211  	}
   212  	return parsed
   213  }