github.com/DataDog/viper@v1.13.3/viper.go (about) 1 // Copyright © 2014 Steve Francia <spf@spf13.com>. 2 // 3 // Use of this source code is governed by an MIT-style 4 // license that can be found in the LICENSE file. 5 6 // Viper is a application configuration system. 7 // It believes that applications can be configured a variety of ways 8 // via flags, ENVIRONMENT variables, configuration files retrieved 9 // from the file system, or a remote key/value store. 10 11 // Each item takes precedence over the item below it: 12 13 // overrides 14 // flag 15 // env 16 // config 17 // key/value store 18 // default 19 20 package viper 21 22 import ( 23 "bytes" 24 "encoding/csv" 25 "encoding/json" 26 "fmt" 27 "io" 28 "log" 29 "os" 30 "path/filepath" 31 "reflect" 32 "strings" 33 "time" 34 35 yaml "gopkg.in/yaml.v2" 36 37 "github.com/fsnotify/fsnotify" 38 "github.com/hashicorp/hcl" 39 "github.com/hashicorp/hcl/hcl/printer" 40 "github.com/magiconair/properties" 41 "github.com/mitchellh/mapstructure" 42 toml "github.com/pelletier/go-toml" 43 "github.com/spf13/afero" 44 "github.com/spf13/cast" 45 jww "github.com/spf13/jwalterweatherman" 46 "github.com/spf13/pflag" 47 ) 48 49 // ConfigMarshalError happens when failing to marshal the configuration. 50 type ConfigMarshalError struct { 51 err error 52 } 53 54 // Error returns the formatted configuration error. 55 func (e ConfigMarshalError) Error() string { 56 return fmt.Sprintf("While marshaling config: %s", e.err.Error()) 57 } 58 59 var v *Viper 60 61 type RemoteResponse struct { 62 Value []byte 63 Error error 64 } 65 66 func init() { 67 v = New() 68 } 69 70 type remoteConfigFactory interface { 71 Get(rp RemoteProvider) (io.Reader, error) 72 Watch(rp RemoteProvider) (io.Reader, error) 73 WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool) 74 } 75 76 // RemoteConfig is optional, see the remote package 77 var RemoteConfig remoteConfigFactory 78 79 // UnsupportedConfigError denotes encountering an unsupported 80 // configuration filetype. 81 type UnsupportedConfigError string 82 83 // Error returns the formatted configuration error. 84 func (str UnsupportedConfigError) Error() string { 85 return fmt.Sprintf("Unsupported Config Type %q", string(str)) 86 } 87 88 // UnsupportedRemoteProviderError denotes encountering an unsupported remote 89 // provider. Currently only etcd and Consul are supported. 90 type UnsupportedRemoteProviderError string 91 92 // Error returns the formatted remote provider error. 93 func (str UnsupportedRemoteProviderError) Error() string { 94 return fmt.Sprintf("Unsupported Remote Provider Type %q", string(str)) 95 } 96 97 // RemoteConfigError denotes encountering an error while trying to 98 // pull the configuration from the remote provider. 99 type RemoteConfigError string 100 101 // Error returns the formatted remote provider error 102 func (rce RemoteConfigError) Error() string { 103 return fmt.Sprintf("Remote Configurations Error: %s", string(rce)) 104 } 105 106 // ConfigFileNotFoundError denotes failing to find configuration file. 107 type ConfigFileNotFoundError struct { 108 name, locations string 109 } 110 111 // Error returns the formatted configuration error. 112 func (fnfe ConfigFileNotFoundError) Error() string { 113 return fmt.Sprintf("Config File %q Not Found in %q", fnfe.name, fnfe.locations) 114 } 115 116 // A DecoderConfigOption can be passed to viper.Unmarshal to configure 117 // mapstructure.DecoderConfig options 118 type DecoderConfigOption func(*mapstructure.DecoderConfig) 119 120 // DecodeHook returns a DecoderConfigOption which overrides the default 121 // DecoderConfig.DecodeHook value, the default is: 122 // 123 // mapstructure.ComposeDecodeHookFunc( 124 // mapstructure.StringToTimeDurationHookFunc(), 125 // mapstructure.StringToSliceHookFunc(","), 126 // ) 127 func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption { 128 return func(c *mapstructure.DecoderConfig) { 129 c.DecodeHook = hook 130 } 131 } 132 133 // Viper is a prioritized configuration registry. It 134 // maintains a set of configuration sources, fetches 135 // values to populate those, and provides them according 136 // to the source's priority. 137 // The priority of the sources is the following: 138 // 1. overrides 139 // 2. flags 140 // 3. env. variables 141 // 4. config file 142 // 5. key/value store 143 // 6. defaults 144 // 145 // For example, if values from the following sources were loaded: 146 // 147 // Defaults : { 148 // "secret": "", 149 // "user": "default", 150 // "endpoint": "https://localhost" 151 // } 152 // Config : { 153 // "user": "root" 154 // "secret": "defaultsecret" 155 // } 156 // Env : { 157 // "secret": "somesecretkey" 158 // } 159 // 160 // The resulting config will have the following values: 161 // 162 // { 163 // "secret": "somesecretkey", 164 // "user": "root", 165 // "endpoint": "https://localhost" 166 // } 167 type Viper struct { 168 // Delimiter that separates a list of keys 169 // used to access a nested value in one go 170 keyDelim string 171 172 // A set of paths to look for the config file in 173 configPaths []string 174 175 // The filesystem to read config from. 176 fs afero.Fs 177 178 // A set of remote providers to search for the configuration 179 remoteProviders []*defaultRemoteProvider 180 181 // Name of file to look for inside the path 182 configName string 183 configFile string 184 configType string 185 envPrefix string 186 187 automaticEnvApplied bool 188 envKeyReplacer *strings.Replacer 189 allowEmptyEnv bool 190 191 config map[string]interface{} 192 override map[string]interface{} 193 defaults map[string]interface{} 194 kvstore map[string]interface{} 195 pflags map[string]FlagValue 196 env map[string][]string 197 envTransform map[string]func(string) interface{} 198 aliases map[string]string 199 knownKeys map[string]interface{} 200 typeByDefValue bool 201 202 // Store read properties on the object so that we can write back in order with comments. 203 // This will only be used if the configuration read is a properties file. 204 properties *properties.Properties 205 206 onConfigChange func(fsnotify.Event) 207 } 208 209 // New returns an initialized Viper instance. 210 func New() *Viper { 211 v := new(Viper) 212 v.keyDelim = "." 213 v.configName = "config" 214 v.fs = afero.NewOsFs() 215 v.config = make(map[string]interface{}) 216 v.override = make(map[string]interface{}) 217 v.defaults = make(map[string]interface{}) 218 v.kvstore = make(map[string]interface{}) 219 v.pflags = make(map[string]FlagValue) 220 v.env = make(map[string][]string) 221 v.envTransform = make(map[string]func(string) interface{}) 222 v.aliases = make(map[string]string) 223 v.knownKeys = make(map[string]interface{}) 224 v.typeByDefValue = false 225 226 return v 227 } 228 229 // Intended for testing, will reset all to default settings. 230 // In the public interface for the viper package so applications 231 // can use it in their testing as well. 232 func Reset() { 233 v = New() 234 SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"} 235 SupportedRemoteProviders = []string{"etcd", "consul"} 236 } 237 238 type defaultRemoteProvider struct { 239 provider string 240 endpoint string 241 path string 242 secretKeyring string 243 } 244 245 func (rp defaultRemoteProvider) Provider() string { 246 return rp.provider 247 } 248 249 func (rp defaultRemoteProvider) Endpoint() string { 250 return rp.endpoint 251 } 252 253 func (rp defaultRemoteProvider) Path() string { 254 return rp.path 255 } 256 257 func (rp defaultRemoteProvider) SecretKeyring() string { 258 return rp.secretKeyring 259 } 260 261 // RemoteProvider stores the configuration necessary 262 // to connect to a remote key/value store. 263 // Optional secretKeyring to unencrypt encrypted values 264 // can be provided. 265 type RemoteProvider interface { 266 Provider() string 267 Endpoint() string 268 Path() string 269 SecretKeyring() string 270 } 271 272 // SupportedExts are universally supported extensions. 273 var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"} 274 275 // SupportedRemoteProviders are universally supported remote providers. 276 var SupportedRemoteProviders = []string{"etcd", "consul"} 277 278 func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) } 279 func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) { 280 v.onConfigChange = run 281 } 282 283 // SetConfigFile explicitly defines the path, name and extension of the config file. 284 // Viper will use this and not check any of the config paths. 285 func SetConfigFile(in string) { v.SetConfigFile(in) } 286 func (v *Viper) SetConfigFile(in string) { 287 if in != "" { 288 v.configFile = in 289 } 290 } 291 292 // SetEnvPrefix defines a prefix that ENVIRONMENT variables will use. 293 // E.g. if your prefix is "spf", the env registry will look for env 294 // variables that start with "SPF_". 295 func SetEnvPrefix(in string) { v.SetEnvPrefix(in) } 296 func (v *Viper) SetEnvPrefix(in string) { 297 if in != "" { 298 v.envPrefix = in 299 } 300 } 301 302 // SetEnvKeyTransformer allows defining a transformer function which decides 303 // how an environment variables value gets assigned to key. 304 func SetEnvKeyTransformer(key string, fn func(string) interface{}) { v.SetEnvKeyTransformer(key, fn) } 305 func (v *Viper) SetEnvKeyTransformer(key string, fn func(string) interface{}) { 306 v.envTransform[strings.ToLower(key)] = fn 307 } 308 309 func (v *Viper) mergeWithEnvPrefix(in string) string { 310 if v.envPrefix != "" { 311 return strings.ToUpper(v.envPrefix + "_" + in) 312 } 313 314 return strings.ToUpper(in) 315 } 316 317 // AllowEmptyEnv tells Viper to consider set, 318 // but empty environment variables as valid values instead of falling back. 319 // For backward compatibility reasons this is false by default. 320 func AllowEmptyEnv(allowEmptyEnv bool) { v.AllowEmptyEnv(allowEmptyEnv) } 321 func (v *Viper) AllowEmptyEnv(allowEmptyEnv bool) { 322 v.allowEmptyEnv = allowEmptyEnv 323 } 324 325 // TODO: should getEnv logic be moved into find(). Can generalize the use of 326 // rewriting keys many things, Ex: Get('someKey') -> some_key 327 // (camel case to snake case for JSON keys perhaps) 328 329 // getEnv is a wrapper around os.Getenv which replaces characters in the original 330 // key. This allows env vars which have different keys than the config object 331 // keys. 332 func (v *Viper) getEnv(key string) (string, bool) { 333 if v.envKeyReplacer != nil { 334 key = v.envKeyReplacer.Replace(key) 335 } 336 337 val, ok := os.LookupEnv(key) 338 339 return val, ok && (v.allowEmptyEnv || val != "") 340 } 341 342 // ConfigFileUsed returns the file used to populate the config registry. 343 func ConfigFileUsed() string { return v.ConfigFileUsed() } 344 func (v *Viper) ConfigFileUsed() string { return v.configFile } 345 346 // AddConfigPath adds a path for Viper to search for the config file in. 347 // Can be called multiple times to define multiple search paths. 348 func AddConfigPath(in string) { v.AddConfigPath(in) } 349 func (v *Viper) AddConfigPath(in string) { 350 if in != "" { 351 absin := absPathify(in) 352 jww.INFO.Println("adding", absin, "to paths to search") 353 if !stringInSlice(absin, v.configPaths) { 354 v.configPaths = append(v.configPaths, absin) 355 } 356 } 357 } 358 359 // AddRemoteProvider adds a remote configuration source. 360 // Remote Providers are searched in the order they are added. 361 // provider is a string value, "etcd" or "consul" are currently supported. 362 // endpoint is the url. etcd requires http://ip:port consul requires ip:port 363 // path is the path in the k/v store to retrieve configuration 364 // To retrieve a config file called myapp.json from /configs/myapp.json 365 // you should set path to /configs and set config name (SetConfigName()) to 366 // "myapp" 367 func AddRemoteProvider(provider, endpoint, path string) error { 368 return v.AddRemoteProvider(provider, endpoint, path) 369 } 370 func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error { 371 if !stringInSlice(provider, SupportedRemoteProviders) { 372 return UnsupportedRemoteProviderError(provider) 373 } 374 if provider != "" && endpoint != "" { 375 jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint) 376 rp := &defaultRemoteProvider{ 377 endpoint: endpoint, 378 provider: provider, 379 path: path, 380 } 381 if !v.providerPathExists(rp) { 382 v.remoteProviders = append(v.remoteProviders, rp) 383 } 384 } 385 return nil 386 } 387 388 // AddSecureRemoteProvider adds a remote configuration source. 389 // Secure Remote Providers are searched in the order they are added. 390 // provider is a string value, "etcd" or "consul" are currently supported. 391 // endpoint is the url. etcd requires http://ip:port consul requires ip:port 392 // secretkeyring is the filepath to your openpgp secret keyring. e.g. /etc/secrets/myring.gpg 393 // path is the path in the k/v store to retrieve configuration 394 // To retrieve a config file called myapp.json from /configs/myapp.json 395 // you should set path to /configs and set config name (SetConfigName()) to 396 // "myapp" 397 // Secure Remote Providers are implemented with github.com/xordataexchange/crypt 398 func AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error { 399 return v.AddSecureRemoteProvider(provider, endpoint, path, secretkeyring) 400 } 401 402 func (v *Viper) AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error { 403 if !stringInSlice(provider, SupportedRemoteProviders) { 404 return UnsupportedRemoteProviderError(provider) 405 } 406 if provider != "" && endpoint != "" { 407 jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint) 408 rp := &defaultRemoteProvider{ 409 endpoint: endpoint, 410 provider: provider, 411 path: path, 412 secretKeyring: secretkeyring, 413 } 414 if !v.providerPathExists(rp) { 415 v.remoteProviders = append(v.remoteProviders, rp) 416 } 417 } 418 return nil 419 } 420 421 func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool { 422 for _, y := range v.remoteProviders { 423 if reflect.DeepEqual(y, p) { 424 return true 425 } 426 } 427 return false 428 } 429 430 // searchMap recursively searches for a value for path in source map. 431 // Returns nil if not found. 432 // Note: This assumes that the path entries and map keys are lower cased. 433 func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} { 434 if len(path) == 0 { 435 return source 436 } 437 438 next, ok := source[path[0]] 439 if ok { 440 // Fast path 441 if len(path) == 1 { 442 return next 443 } 444 445 // Nested case 446 switch next.(type) { 447 case map[interface{}]interface{}: 448 return v.searchMap(cast.ToStringMap(next), path[1:]) 449 case map[string]interface{}: 450 // Type assertion is safe here since it is only reached 451 // if the type of `next` is the same as the type being asserted 452 return v.searchMap(next.(map[string]interface{}), path[1:]) 453 default: 454 // got a value but nested key expected, return "nil" for not found 455 return nil 456 } 457 } 458 return nil 459 } 460 461 // searchMapWithPathPrefixes recursively searches for a value for path in source map. 462 // 463 // While searchMap() considers each path element as a single map key, this 464 // function searches for, and prioritizes, merged path elements. 465 // e.g., if in the source, "foo" is defined with a sub-key "bar", and "foo.bar" 466 // is also defined, this latter value is returned for path ["foo", "bar"]. 467 // 468 // This should be useful only at config level (other maps may not contain dots 469 // in their keys). 470 // 471 // Note: This assumes that the path entries and map keys are lower cased. 472 func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path []string) interface{} { 473 if len(path) == 0 { 474 return source 475 } 476 477 // search for path prefixes, starting from the longest one 478 for i := len(path); i > 0; i-- { 479 prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim)) 480 481 next, ok := source[prefixKey] 482 if ok { 483 // Fast path 484 if i == len(path) { 485 return next 486 } 487 488 // Nested case 489 var val interface{} 490 switch next.(type) { 491 case map[interface{}]interface{}: 492 val = v.searchMapWithPathPrefixes(cast.ToStringMap(next), path[i:]) 493 case map[string]interface{}: 494 // Type assertion is safe here since it is only reached 495 // if the type of `next` is the same as the type being asserted 496 val = v.searchMapWithPathPrefixes(next.(map[string]interface{}), path[i:]) 497 default: 498 // got a value but nested key expected, do nothing and look for next prefix 499 } 500 if val != nil { 501 return val 502 } 503 } 504 } 505 506 // not found 507 return nil 508 } 509 510 // isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere 511 // on its path in the map. 512 // e.g., if "foo.bar" has a value in the given map, it “shadows” 513 // "foo.bar.baz" in a lower-priority map 514 func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string { 515 var parentVal interface{} 516 for i := 1; i < len(path); i++ { 517 parentVal = v.searchMap(m, path[0:i]) 518 if parentVal == nil { 519 // not found, no need to add more path elements 520 return "" 521 } 522 switch parentVal.(type) { 523 case map[interface{}]interface{}: 524 continue 525 case map[string]interface{}: 526 continue 527 default: 528 // parentVal is a regular value which shadows "path" 529 return strings.Join(path[0:i], v.keyDelim) 530 } 531 } 532 return "" 533 } 534 535 // isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere 536 // in a sub-path of the map. 537 // e.g., if "foo.bar" has a value in the given map, it “shadows” 538 // "foo.bar.baz" in a lower-priority map 539 func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string { 540 // unify input map 541 var m map[string]interface{} 542 switch mi.(type) { 543 case map[string]string, map[string]FlagValue: 544 m = cast.ToStringMap(mi) 545 default: 546 return "" 547 } 548 549 // scan paths 550 var parentKey string 551 for i := 1; i < len(path); i++ { 552 parentKey = strings.Join(path[0:i], v.keyDelim) 553 if _, ok := m[parentKey]; ok { 554 return parentKey 555 } 556 } 557 return "" 558 } 559 560 // isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere 561 // in the environment, when automatic env is on. 562 // e.g., if "foo.bar" has a value in the environment, it “shadows” 563 // "foo.bar.baz" in a lower-priority map 564 func (v *Viper) isPathShadowedInAutoEnv(path []string) string { 565 var parentKey string 566 for i := 1; i < len(path); i++ { 567 parentKey = strings.Join(path[0:i], v.keyDelim) 568 if _, ok := v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok { 569 return parentKey 570 } 571 } 572 return "" 573 } 574 575 // SetTypeByDefaultValue enables or disables the inference of a key value's 576 // type when the Get function is used based upon a key's default value as 577 // opposed to the value returned based on the normal fetch logic. 578 // 579 // For example, if a key has a default value of []string{} and the same key 580 // is set via an environment variable to "a b c", a call to the Get function 581 // would return a string slice for the key if the key's type is inferred by 582 // the default value and the Get function would return: 583 // 584 // []string {"a", "b", "c"} 585 // 586 // Otherwise the Get function would return: 587 // 588 // "a b c" 589 func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) } 590 func (v *Viper) SetTypeByDefaultValue(enable bool) { 591 v.typeByDefValue = enable 592 } 593 594 // GetViper gets the global Viper instance. 595 func GetViper() *Viper { 596 return v 597 } 598 599 // Get can retrieve any value given the key to use. 600 // Get is case-insensitive for a key. 601 // Get has the behavior of returning the value associated with the first 602 // place from where it is set. Viper will check in the following order: 603 // override, flag, env, config file, key/value store, default 604 // 605 // Get returns an interface. For a specific value use one of the Get____ methods. 606 func Get(key string) interface{} { return v.Get(key) } 607 func (v *Viper) Get(key string) interface{} { 608 val, _ := v.GetE(key) 609 return val 610 } 611 612 // GetSkipDefault returns an interface. For a specific value use one of the Get____ methods. 613 func GetSkipDefault(key string) interface{} { return v.GetSkipDefault(key) } 614 func (v *Viper) GetSkipDefault(key string) interface{} { 615 val, _ := v.GetESkipDefault(key) 616 return val 617 } 618 619 // GetE is like Get but also returns parsing errors. 620 func GetE(key string) (interface{}, error) { return v.GetE(key) } 621 func (v *Viper) GetE(key string) (interface{}, error) { 622 lcaseKey := strings.ToLower(key) 623 val := v.find(lcaseKey, false) 624 if val == nil { 625 return nil, nil 626 } 627 return v.castByDefValue(lcaseKey, val) 628 } 629 630 // GetESkipDefault is like GetE but ignors defaults. 631 func GetESkipDefault(key string) (interface{}, error) { return v.GetESkipDefault(key) } 632 func (v *Viper) GetESkipDefault(key string) (interface{}, error) { 633 lcaseKey := strings.ToLower(key) 634 val := v.find(lcaseKey, true) 635 if val == nil { 636 return nil, nil 637 } 638 return v.castByDefValue(lcaseKey, val) 639 } 640 641 func (v *Viper) castByDefValue(lcaseKey string, val interface{}) (interface{}, error) { 642 if v.typeByDefValue { 643 // TODO(bep) this branch isn't covered by a single test. 644 valType := val 645 path := strings.Split(lcaseKey, v.keyDelim) 646 defVal := v.searchMap(v.defaults, path) 647 if defVal != nil { 648 valType = defVal 649 } 650 651 switch valType.(type) { 652 case bool: 653 return cast.ToBoolE(val) 654 case string: 655 return cast.ToStringE(val) 656 case int32, int16, int8, int: 657 return cast.ToIntE(val) 658 case int64: 659 return cast.ToInt64E(val) 660 case float64, float32: 661 return cast.ToFloat64E(val) 662 case time.Time: 663 return cast.ToTimeE(val) 664 case time.Duration: 665 return cast.ToDurationE(val) 666 case []string: 667 return cast.ToStringSliceE(val) 668 } 669 } 670 671 return val, nil 672 } 673 674 // GetRaw is the same as Get except that it always return an uncast value. 675 func GetRaw(key string) interface{} { return v.GetRaw(key) } 676 func (v *Viper) GetRaw(key string) interface{} { 677 lcaseKey := strings.ToLower(key) 678 return v.find(lcaseKey, false) 679 } 680 681 // Sub returns new Viper instance representing a sub tree of this instance. 682 // Sub is case-insensitive for a key. 683 func Sub(key string) *Viper { return v.Sub(key) } 684 func (v *Viper) Sub(key string) *Viper { 685 subv := New() 686 data := v.Get(key) 687 if data == nil { 688 return nil 689 } 690 691 if reflect.TypeOf(data).Kind() == reflect.Map { 692 subv.config = cast.ToStringMap(data) 693 return subv 694 } 695 return nil 696 } 697 698 // GetString returns the value associated with the key as a string. 699 func GetString(key string) string { return v.GetString(key) } 700 func (v *Viper) GetString(key string) string { 701 return cast.ToString(v.Get(key)) 702 } 703 704 // GetStringE is the same as GetString but also returns parsing errors. 705 func GetStringE(key string) (string, error) { return v.GetStringE(key) } 706 func (v *Viper) GetStringE(key string) (string, error) { 707 return cast.ToStringE(v.GetRaw(key)) 708 } 709 710 // GetBool returns the value associated with the key as a boolean. 711 func GetBool(key string) bool { return v.GetBool(key) } 712 func (v *Viper) GetBool(key string) bool { 713 return cast.ToBool(v.Get(key)) 714 } 715 716 // GetBoolE is the same as GetBool but also returns parsing errors. 717 func GetBoolE(key string) (bool, error) { return v.GetBoolE(key) } 718 func (v *Viper) GetBoolE(key string) (bool, error) { 719 return cast.ToBoolE(v.GetRaw(key)) 720 } 721 722 // GetInt returns the value associated with the key as an integer. 723 func GetInt(key string) int { return v.GetInt(key) } 724 func (v *Viper) GetInt(key string) int { 725 return cast.ToInt(v.Get(key)) 726 } 727 728 // GetIntE is the same as GetInt but also returns parsing errors. 729 func GetIntE(key string) (int, error) { return v.GetIntE(key) } 730 func (v *Viper) GetIntE(key string) (int, error) { 731 return cast.ToIntE(v.GetRaw(key)) 732 } 733 734 // GetInt32 returns the value associated with the key as an integer. 735 func GetInt32(key string) int32 { return v.GetInt32(key) } 736 func (v *Viper) GetInt32(key string) int32 { 737 return cast.ToInt32(v.Get(key)) 738 } 739 740 // GetInt32E is the same as GetInt32 but also returns parsing errors. 741 func GetInt32E(key string) (int32, error) { return v.GetInt32E(key) } 742 func (v *Viper) GetInt32E(key string) (int32, error) { 743 return cast.ToInt32E(v.GetRaw(key)) 744 } 745 746 // GetInt64 returns the value associated with the key as an integer. 747 func GetInt64(key string) int64 { return v.GetInt64(key) } 748 func (v *Viper) GetInt64(key string) int64 { 749 return cast.ToInt64(v.Get(key)) 750 } 751 752 // GetInt64E is the same as GetInt64 but also returns parsing errors. 753 func GetInt64E(key string) (int64, error) { return v.GetInt64E(key) } 754 func (v *Viper) GetInt64E(key string) (int64, error) { 755 return cast.ToInt64E(v.GetRaw(key)) 756 } 757 758 // GetFloat64 returns the value associated with the key as a float64. 759 func GetFloat64(key string) float64 { return v.GetFloat64(key) } 760 func (v *Viper) GetFloat64(key string) float64 { 761 return cast.ToFloat64(v.GetRaw(key)) 762 } 763 764 // GetFloat64E is the same as GetFloat64 but also returns parsing errors. 765 func GetFloat64E(key string) (float64, error) { return v.GetFloat64E(key) } 766 func (v *Viper) GetFloat64E(key string) (float64, error) { 767 return cast.ToFloat64E(v.GetRaw(key)) 768 } 769 770 // GetTime returns the value associated with the key as time. 771 func GetTime(key string) time.Time { return v.GetTime(key) } 772 func (v *Viper) GetTime(key string) time.Time { 773 return cast.ToTime(v.Get(key)) 774 } 775 776 // GetTimeE is the same as GetTime but also returns parsing errors. 777 func GetTimeE(key string) (time.Time, error) { return v.GetTimeE(key) } 778 func (v *Viper) GetTimeE(key string) (time.Time, error) { 779 return cast.ToTimeE(v.GetRaw(key)) 780 } 781 782 // GetDuration returns the value associated with the key as a duration. 783 func GetDuration(key string) time.Duration { return v.GetDuration(key) } 784 func (v *Viper) GetDuration(key string) time.Duration { 785 return cast.ToDuration(v.Get(key)) 786 } 787 788 // GetDurationE is the same as GetDuration but also returns parsing errors. 789 func GetDurationE(key string) (time.Duration, error) { return v.GetDurationE(key) } 790 func (v *Viper) GetDurationE(key string) (time.Duration, error) { 791 return cast.ToDurationE(v.GetRaw(key)) 792 } 793 794 // GetStringSlice returns the value associated with the key as a slice of strings. 795 func GetStringSlice(key string) []string { return v.GetStringSlice(key) } 796 func (v *Viper) GetStringSlice(key string) []string { 797 return cast.ToStringSlice(v.Get(key)) 798 } 799 800 // GetStringSliceE is the same as GetStringSlice but also returns parsing errors. 801 func GetStringSliceE(key string) ([]string, error) { return v.GetStringSliceE(key) } 802 func (v *Viper) GetStringSliceE(key string) ([]string, error) { 803 return cast.ToStringSliceE(v.GetRaw(key)) 804 } 805 806 // GetStringMap returns the value associated with the key as a map of interfaces. 807 func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) } 808 func (v *Viper) GetStringMap(key string) map[string]interface{} { 809 return cast.ToStringMap(v.Get(key)) 810 } 811 812 // GetStringMapE is the same as GetStringMap but also returns parsing errors. 813 func GetStringMapE(key string) (map[string]interface{}, error) { return v.GetStringMapE(key) } 814 func (v *Viper) GetStringMapE(key string) (map[string]interface{}, error) { 815 return cast.ToStringMapE(v.GetRaw(key)) 816 } 817 818 // GetStringMapString returns the value associated with the key as a map of strings. 819 func GetStringMapString(key string) map[string]string { return v.GetStringMapString(key) } 820 func (v *Viper) GetStringMapString(key string) map[string]string { 821 return cast.ToStringMapString(v.Get(key)) 822 } 823 824 // GetStringMapStringE is the same as GetStringMapString but also returns parsing errors. 825 func GetStringMapStringE(key string) (map[string]string, error) { return v.GetStringMapStringE(key) } 826 func (v *Viper) GetStringMapStringE(key string) (map[string]string, error) { 827 return cast.ToStringMapStringE(v.GetRaw(key)) 828 } 829 830 // GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings. 831 func GetStringMapStringSlice(key string) map[string][]string { return v.GetStringMapStringSlice(key) } 832 func (v *Viper) GetStringMapStringSlice(key string) map[string][]string { 833 return cast.ToStringMapStringSlice(v.Get(key)) 834 } 835 836 // GetStringMapStringSliceE is the same as GetStringMapStringSlice but also returns parsing errors. 837 func GetStringMapStringSliceE(key string) (map[string][]string, error) { 838 return v.GetStringMapStringSliceE(key) 839 } 840 func (v *Viper) GetStringMapStringSliceE(key string) (map[string][]string, error) { 841 return cast.ToStringMapStringSliceE(v.GetRaw(key)) 842 } 843 844 // GetSizeInBytes returns the size of the value associated with the given key 845 // in bytes. 846 func GetSizeInBytes(key string) uint { return v.GetSizeInBytes(key) } 847 func (v *Viper) GetSizeInBytes(key string) uint { 848 sizeStr := cast.ToString(v.Get(key)) 849 size, _ := parseSizeInBytes(sizeStr) 850 return size 851 } 852 853 // GetSizeInBytesE is the same as GetSizeInBytes but also returns parsing errors. 854 func GetSizeInBytesE(key string) (uint, error) { return v.GetSizeInBytesE(key) } 855 func (v *Viper) GetSizeInBytesE(key string) (uint, error) { 856 sizeStr, err := cast.ToStringE(v.GetRaw(key)) 857 if err != nil { 858 return 0, err 859 } 860 return parseSizeInBytes(sizeStr) 861 } 862 863 // UnmarshalKey takes a single key and unmarshals it into a Struct. 864 func UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error { 865 return v.UnmarshalKey(key, rawVal, opts...) 866 } 867 func (v *Viper) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error { 868 err := decode(v.Get(key), defaultDecoderConfig(rawVal, opts...)) 869 870 if err != nil { 871 return err 872 } 873 874 return nil 875 } 876 877 // Unmarshal unmarshals the config into a Struct. Make sure that the tags 878 // on the fields of the structure are properly set. 879 func Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error { 880 return v.Unmarshal(rawVal, opts...) 881 } 882 func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error { 883 err := decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...)) 884 885 if err != nil { 886 return err 887 } 888 889 return nil 890 } 891 892 // defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot 893 // of time.Duration values & string slices 894 func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *mapstructure.DecoderConfig { 895 c := &mapstructure.DecoderConfig{ 896 Metadata: nil, 897 Result: output, 898 WeaklyTypedInput: true, 899 DecodeHook: mapstructure.ComposeDecodeHookFunc( 900 mapstructure.StringToTimeDurationHookFunc(), 901 mapstructure.StringToSliceHookFunc(","), 902 ), 903 } 904 for _, opt := range opts { 905 opt(c) 906 } 907 return c 908 } 909 910 // A wrapper around mapstructure.Decode that mimics the WeakDecode functionality 911 func decode(input interface{}, config *mapstructure.DecoderConfig) error { 912 decoder, err := mapstructure.NewDecoder(config) 913 if err != nil { 914 return err 915 } 916 return decoder.Decode(input) 917 } 918 919 // UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent 920 // in the destination struct. 921 func (v *Viper) UnmarshalExact(rawVal interface{}) error { 922 config := defaultDecoderConfig(rawVal) 923 config.ErrorUnused = true 924 925 err := decode(v.AllSettings(), config) 926 927 if err != nil { 928 return err 929 } 930 931 return nil 932 } 933 934 // BindPFlags binds a full flag set to the configuration, using each flag's long 935 // name as the config key. 936 func BindPFlags(flags *pflag.FlagSet) error { return v.BindPFlags(flags) } 937 func (v *Viper) BindPFlags(flags *pflag.FlagSet) error { 938 return v.BindFlagValues(pflagValueSet{flags}) 939 } 940 941 // BindPFlag binds a specific key to a pflag (as used by cobra). 942 // Example (where serverCmd is a Cobra instance): 943 // 944 // serverCmd.Flags().Int("port", 1138, "Port to run Application server on") 945 // Viper.BindPFlag("port", serverCmd.Flags().Lookup("port")) 946 // 947 func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) } 948 func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error { 949 return v.BindFlagValue(key, pflagValue{flag}) 950 } 951 952 // BindFlagValues binds a full FlagValue set to the configuration, using each flag's long 953 // name as the config key. 954 func BindFlagValues(flags FlagValueSet) error { return v.BindFlagValues(flags) } 955 func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) { 956 flags.VisitAll(func(flag FlagValue) { 957 if err = v.BindFlagValue(flag.Name(), flag); err != nil { 958 return 959 } 960 }) 961 return nil 962 } 963 964 // BindFlagValue binds a specific key to a FlagValue. 965 // Example (where serverCmd is a Cobra instance): 966 // 967 // serverCmd.Flags().Int("port", 1138, "Port to run Application server on") 968 // Viper.BindFlagValue("port", serverCmd.Flags().Lookup("port")) 969 // 970 func BindFlagValue(key string, flag FlagValue) error { return v.BindFlagValue(key, flag) } 971 func (v *Viper) BindFlagValue(key string, flag FlagValue) error { 972 if flag == nil { 973 return fmt.Errorf("flag for %q is nil", key) 974 } 975 v.pflags[strings.ToLower(key)] = flag 976 return nil 977 } 978 979 // BindEnv binds a Viper key to a ENV variable. 980 // ENV variables are case sensitive. 981 // If only a key is provided, it will use the env key matching the key, uppercased. 982 // EnvPrefix will be used when set when env name is not provided. 983 func BindEnv(input ...string) error { return v.BindEnv(input...) } 984 func (v *Viper) BindEnv(input ...string) error { 985 if len(input) == 0 { 986 return fmt.Errorf("BindEnv missing key to bind to") 987 } 988 989 key := strings.ToLower(input[0]) 990 var envkeys []string 991 992 if len(input) == 1 { 993 envkeys = []string{v.mergeWithEnvPrefix(key)} 994 } else { 995 envkeys = input[1:] 996 } 997 998 v.env[key] = append(v.env[key], envkeys...) 999 v.SetKnown(key) 1000 1001 return nil 1002 } 1003 1004 // Given a key, find the value. 1005 // Viper will check in the following order: 1006 // flag, env, config file, key/value store, default. 1007 // If skipDefault is set to true, find will ignore default values. 1008 // Viper will check to see if an alias exists first. 1009 // Note: this assumes a lower-cased key given. 1010 func (v *Viper) find(lcaseKey string, skipDefault bool) interface{} { 1011 1012 var ( 1013 val interface{} 1014 exists bool 1015 path = strings.Split(lcaseKey, v.keyDelim) 1016 nested = len(path) > 1 1017 ) 1018 1019 // compute the path through the nested maps to the nested value 1020 if nested && v.isPathShadowedInDeepMap(path, castMapStringToMapInterface(v.aliases)) != "" { 1021 return nil 1022 } 1023 1024 // if the requested key is an alias, then return the proper key 1025 lcaseKey = v.realKey(lcaseKey) 1026 path = strings.Split(lcaseKey, v.keyDelim) 1027 nested = len(path) > 1 1028 1029 // Set() override first 1030 val = v.searchMap(v.override, path) 1031 if val != nil { 1032 return val 1033 } 1034 if nested && v.isPathShadowedInDeepMap(path, v.override) != "" { 1035 return nil 1036 } 1037 1038 // PFlag override next 1039 flag, exists := v.pflags[lcaseKey] 1040 if exists && flag.HasChanged() { 1041 switch flag.ValueType() { 1042 case "int", "int8", "int16", "int32", "int64": 1043 return cast.ToInt(flag.ValueString()) 1044 case "bool": 1045 return cast.ToBool(flag.ValueString()) 1046 case "stringSlice": 1047 s := strings.TrimPrefix(flag.ValueString(), "[") 1048 s = strings.TrimSuffix(s, "]") 1049 res, _ := readAsCSV(s) 1050 return res 1051 default: 1052 return flag.ValueString() 1053 } 1054 } 1055 if nested && v.isPathShadowedInFlatMap(path, v.pflags) != "" { 1056 return nil 1057 } 1058 1059 // Env override next 1060 if v.automaticEnvApplied { 1061 // even if it hasn't been registered, if automaticEnv is used, 1062 // check any Get request 1063 if val, ok := v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); ok { 1064 return val 1065 } 1066 if nested && v.isPathShadowedInAutoEnv(path) != "" { 1067 return nil 1068 } 1069 } 1070 envkeys, exists := v.env[lcaseKey] 1071 if exists { 1072 for _, key := range envkeys { 1073 if val, ok := v.getEnv(key); ok { 1074 if fn, ok := v.envTransform[lcaseKey]; ok { 1075 return fn(val) 1076 } 1077 return val 1078 } 1079 } 1080 } 1081 if nested && v.isPathShadowedInFlatMap(path, v.env) != "" { 1082 return nil 1083 } 1084 1085 // Config file next 1086 val = v.searchMapWithPathPrefixes(v.config, path) 1087 if val != nil { 1088 return val 1089 } 1090 if nested && v.isPathShadowedInDeepMap(path, v.config) != "" { 1091 return nil 1092 } 1093 1094 // K/V store next 1095 val = v.searchMap(v.kvstore, path) 1096 if val != nil { 1097 return val 1098 } 1099 if nested && v.isPathShadowedInDeepMap(path, v.kvstore) != "" { 1100 return nil 1101 } 1102 1103 // Default next 1104 if !skipDefault { 1105 val = v.searchMap(v.defaults, path) 1106 if val != nil { 1107 return val 1108 } 1109 if nested && v.isPathShadowedInDeepMap(path, v.defaults) != "" { 1110 return nil 1111 } 1112 } 1113 1114 // last chance: if no other value is returned and a flag does exist for the value, 1115 // get the flag's value even if the flag's value has not changed 1116 if flag, exists := v.pflags[lcaseKey]; exists { 1117 switch flag.ValueType() { 1118 case "int", "int8", "int16", "int32", "int64": 1119 return cast.ToInt(flag.ValueString()) 1120 case "bool": 1121 return cast.ToBool(flag.ValueString()) 1122 case "stringSlice": 1123 s := strings.TrimPrefix(flag.ValueString(), "[") 1124 s = strings.TrimSuffix(s, "]") 1125 res, _ := readAsCSV(s) 1126 return res 1127 default: 1128 return flag.ValueString() 1129 } 1130 } 1131 // last item, no need to check shadowing 1132 1133 return nil 1134 } 1135 1136 func readAsCSV(val string) ([]string, error) { 1137 if val == "" { 1138 return []string{}, nil 1139 } 1140 stringReader := strings.NewReader(val) 1141 csvReader := csv.NewReader(stringReader) 1142 return csvReader.Read() 1143 } 1144 1145 // IsSet checks to see if the key has been set in any of the data locations. 1146 // IsSet is case-insensitive for a key. 1147 func IsSet(key string) bool { return v.IsSet(key) } 1148 func (v *Viper) IsSet(key string) bool { 1149 lcaseKey := strings.ToLower(key) 1150 val := v.find(lcaseKey, false) 1151 return val != nil 1152 } 1153 1154 // AutomaticEnv has Viper check ENV variables for all. 1155 // keys set in config, default & flags 1156 func AutomaticEnv() { v.AutomaticEnv() } 1157 func (v *Viper) AutomaticEnv() { 1158 v.automaticEnvApplied = true 1159 } 1160 1161 // SetEnvKeyReplacer sets the strings.Replacer on the viper object 1162 // Useful for mapping an environmental variable to a key that does 1163 // not match it. 1164 func SetEnvKeyReplacer(r *strings.Replacer) { v.SetEnvKeyReplacer(r) } 1165 func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) { 1166 v.envKeyReplacer = r 1167 } 1168 1169 // Aliases provide another accessor for the same key. 1170 // This enables one to change a name without breaking the application 1171 func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) } 1172 func (v *Viper) RegisterAlias(alias string, key string) { 1173 v.registerAlias(alias, strings.ToLower(key)) 1174 } 1175 1176 func (v *Viper) registerAlias(alias string, key string) { 1177 alias = strings.ToLower(alias) 1178 if alias != key && alias != v.realKey(key) { 1179 _, exists := v.aliases[alias] 1180 1181 if !exists { 1182 // if we alias something that exists in one of the maps to another 1183 // name, we'll never be able to get that value using the original 1184 // name, so move the config value to the new realkey. 1185 if val, ok := v.config[alias]; ok { 1186 delete(v.config, alias) 1187 v.config[key] = val 1188 } 1189 if val, ok := v.kvstore[alias]; ok { 1190 delete(v.kvstore, alias) 1191 v.kvstore[key] = val 1192 } 1193 if val, ok := v.defaults[alias]; ok { 1194 delete(v.defaults, alias) 1195 v.defaults[key] = val 1196 } 1197 if val, ok := v.override[alias]; ok { 1198 delete(v.override, alias) 1199 v.override[key] = val 1200 } 1201 v.aliases[alias] = key 1202 } 1203 } else { 1204 jww.WARN.Println("Creating circular reference alias", alias, key, v.realKey(key)) 1205 } 1206 v.SetKnown(alias) 1207 } 1208 1209 func (v *Viper) realKey(key string) string { 1210 newkey, exists := v.aliases[key] 1211 if exists { 1212 jww.DEBUG.Println("Alias", key, "to", newkey) 1213 return v.realKey(newkey) 1214 } 1215 return key 1216 } 1217 1218 // InConfig checks to see if the given key (or an alias) is in the config file. 1219 func InConfig(key string) bool { return v.InConfig(key) } 1220 func (v *Viper) InConfig(key string) bool { 1221 // if the requested key is an alias, then return the proper key 1222 key = v.realKey(key) 1223 1224 _, exists := v.config[key] 1225 return exists 1226 } 1227 1228 // SetDefault sets the default value for this key. 1229 // SetDefault is case-insensitive for a key. 1230 // Default only used when no value is provided by the user via flag, config or ENV. 1231 func SetDefault(key string, value interface{}) { v.SetDefault(key, value) } 1232 func (v *Viper) SetDefault(key string, value interface{}) { 1233 // If alias passed in, then set the proper default 1234 key = v.realKey(strings.ToLower(key)) 1235 value = toCaseInsensitiveValue(value) 1236 1237 path := strings.Split(key, v.keyDelim) 1238 lastKey := strings.ToLower(path[len(path)-1]) 1239 deepestMap := deepSearch(v.defaults, path[0:len(path)-1]) 1240 1241 // set innermost value 1242 deepestMap[lastKey] = value 1243 v.SetKnown(key) 1244 } 1245 1246 // SetKnown adds a key to the set of known valid config keys 1247 func SetKnown(key string) { v.SetKnown(key) } 1248 func (v *Viper) SetKnown(key string) { 1249 key = strings.ToLower(key) 1250 splitPath := strings.Split(key, v.keyDelim) 1251 for j := range splitPath { 1252 subKey := strings.Join(splitPath[:j+1], v.keyDelim) 1253 v.knownKeys[subKey] = struct{}{} 1254 } 1255 } 1256 1257 // GetKnownKeys returns all the keys that meet at least one of these criteria: 1258 // 1) have a default, 2) have an environment variable binded, 3) are an alias or 4) have been SetKnown() 1259 func GetKnownKeys() map[string]interface{} { return v.GetKnownKeys() } 1260 func (v *Viper) GetKnownKeys() map[string]interface{} { 1261 ret := make(map[string]interface{}) 1262 for key, value := range v.knownKeys { 1263 ret[key] = value 1264 } 1265 return ret 1266 } 1267 1268 // IsKnown returns whether the given key has been set as a known key 1269 func IsKnown(key string) bool { return v.IsKnown(key) } 1270 func (v *Viper) IsKnown(key string) bool { 1271 key = strings.ToLower(key) 1272 _, exists := v.knownKeys[key] 1273 return exists 1274 } 1275 1276 // Set sets the value for the key in the override register. 1277 // Set is case-insensitive for a key. 1278 // Will be used instead of values obtained via 1279 // flags, config file, ENV, default, or key/value store. 1280 func Set(key string, value interface{}) { v.Set(key, value) } 1281 func (v *Viper) Set(key string, value interface{}) { 1282 // If alias passed in, then set the proper override 1283 key = v.realKey(strings.ToLower(key)) 1284 value = toCaseInsensitiveValue(value) 1285 1286 path := strings.Split(key, v.keyDelim) 1287 lastKey := strings.ToLower(path[len(path)-1]) 1288 deepestMap := deepSearch(v.override, path[0:len(path)-1]) 1289 1290 // set innermost value 1291 deepestMap[lastKey] = value 1292 } 1293 1294 // ReadInConfig will discover and load the configuration file from disk 1295 // and key/value stores, searching in one of the defined paths. 1296 func ReadInConfig() error { return v.ReadInConfig() } 1297 func (v *Viper) ReadInConfig() error { 1298 jww.INFO.Println("Attempting to read in config file") 1299 filename, err := v.getConfigFile() 1300 if err != nil { 1301 return err 1302 } 1303 1304 if !stringInSlice(v.getConfigType(), SupportedExts) { 1305 return UnsupportedConfigError(v.getConfigType()) 1306 } 1307 1308 jww.DEBUG.Println("Reading file: ", filename) 1309 file, err := afero.ReadFile(v.fs, filename) 1310 if err != nil { 1311 return err 1312 } 1313 1314 config := make(map[string]interface{}) 1315 1316 err = v.unmarshalReader(bytes.NewReader(file), config) 1317 if err != nil { 1318 return err 1319 } 1320 1321 v.config = config 1322 return nil 1323 } 1324 1325 // MergeInConfig merges a new configuration with an existing config. 1326 func MergeInConfig() error { return v.MergeInConfig() } 1327 func (v *Viper) MergeInConfig() error { 1328 jww.INFO.Println("Attempting to merge in config file") 1329 filename, err := v.getConfigFile() 1330 if err != nil { 1331 return err 1332 } 1333 1334 if !stringInSlice(v.getConfigType(), SupportedExts) { 1335 return UnsupportedConfigError(v.getConfigType()) 1336 } 1337 1338 file, err := afero.ReadFile(v.fs, filename) 1339 if err != nil { 1340 return err 1341 } 1342 1343 return v.MergeConfig(bytes.NewReader(file)) 1344 } 1345 1346 // ReadConfig will read a configuration file, setting existing keys to nil if the 1347 // key does not exist in the file. 1348 func ReadConfig(in io.Reader) error { return v.ReadConfig(in) } 1349 func (v *Viper) ReadConfig(in io.Reader) error { 1350 v.config = make(map[string]interface{}) 1351 return v.unmarshalReader(in, v.config) 1352 } 1353 1354 // MergeConfig merges a new configuration with an existing config. 1355 func MergeConfig(in io.Reader) error { return v.MergeConfig(in) } 1356 func (v *Viper) MergeConfig(in io.Reader) error { 1357 cfg := make(map[string]interface{}) 1358 if err := v.unmarshalReader(in, cfg); err != nil { 1359 return err 1360 } 1361 return v.MergeConfigMap(cfg) 1362 } 1363 1364 // MergeConfigMap merges the configuration from the map given with an existing config. 1365 // Note that the map given may be modified. 1366 func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) } 1367 func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error { 1368 if v.config == nil { 1369 v.config = make(map[string]interface{}) 1370 } 1371 insensitiviseMap(cfg) 1372 mergeMaps(cfg, v.config, nil) 1373 return nil 1374 } 1375 1376 // MergeConfigOverride merges a new configuration within the config at the 1377 // highest lever of priority (similar to the 'Set' method). Key set here will 1378 // always be retrieved before values from env, files... 1379 func MergeConfigOverride(in io.Reader) error { return v.MergeConfigOverride(in) } 1380 func (v *Viper) MergeConfigOverride(in io.Reader) error { 1381 if v.override == nil { 1382 v.override = make(map[string]interface{}) 1383 } 1384 cfg := make(map[string]interface{}) 1385 if err := v.unmarshalReader(in, cfg); err != nil { 1386 return err 1387 } 1388 insensitiviseMap(cfg) 1389 mergeMaps(cfg, v.override, nil) 1390 return nil 1391 } 1392 1393 // WriteConfig writes the current configuration to a file. 1394 func WriteConfig() error { return v.WriteConfig() } 1395 func (v *Viper) WriteConfig() error { 1396 filename, err := v.getConfigFile() 1397 if err != nil { 1398 return err 1399 } 1400 return v.writeConfig(filename, true) 1401 } 1402 1403 // SafeWriteConfig writes current configuration to file only if the file does not exist. 1404 func SafeWriteConfig() error { return v.SafeWriteConfig() } 1405 func (v *Viper) SafeWriteConfig() error { 1406 filename, err := v.getConfigFile() 1407 if err != nil { 1408 return err 1409 } 1410 return v.writeConfig(filename, false) 1411 } 1412 1413 // WriteConfigAs writes current configuration to a given filename. 1414 func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) } 1415 func (v *Viper) WriteConfigAs(filename string) error { 1416 return v.writeConfig(filename, true) 1417 } 1418 1419 // SafeWriteConfigAs writes current configuration to a given filename if it does not exist. 1420 func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) } 1421 func (v *Viper) SafeWriteConfigAs(filename string) error { 1422 return v.writeConfig(filename, false) 1423 } 1424 1425 func writeConfig(filename string, force bool) error { return v.writeConfig(filename, force) } 1426 func (v *Viper) writeConfig(filename string, force bool) error { 1427 jww.INFO.Println("Attempting to write configuration to file.") 1428 ext := filepath.Ext(filename) 1429 if len(ext) <= 1 { 1430 return fmt.Errorf("Filename: %s requires valid extension.", filename) 1431 } 1432 configType := ext[1:] 1433 if !stringInSlice(configType, SupportedExts) { 1434 return UnsupportedConfigError(configType) 1435 } 1436 if v.config == nil { 1437 v.config = make(map[string]interface{}) 1438 } 1439 var flags int 1440 if force == true { 1441 flags = os.O_CREATE | os.O_TRUNC | os.O_WRONLY 1442 } else { 1443 if _, err := os.Stat(filename); os.IsNotExist(err) { 1444 flags = os.O_WRONLY 1445 } else { 1446 return fmt.Errorf("File: %s exists. Use WriteConfig to overwrite.", filename) 1447 } 1448 } 1449 f, err := v.fs.OpenFile(filename, flags, os.FileMode(0644)) 1450 if err != nil { 1451 return err 1452 } 1453 return v.marshalWriter(f, configType) 1454 } 1455 1456 // Unmarshal a Reader into a map. 1457 // Should probably be an unexported function. 1458 func unmarshalReader(in io.Reader, c map[string]interface{}) error { 1459 return v.unmarshalReader(in, c) 1460 } 1461 func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error { 1462 buf := new(bytes.Buffer) 1463 buf.ReadFrom(in) 1464 1465 switch strings.ToLower(v.getConfigType()) { 1466 case "yaml", "yml": 1467 // Try UnmarshalStrict first, so we can warn about duplicated keys 1468 if strictErr := yaml.UnmarshalStrict(buf.Bytes(), &c); strictErr != nil { 1469 if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil { 1470 return ConfigParseError{err} 1471 } 1472 log.Printf("warning reading config file: %v\n", strictErr) 1473 } 1474 1475 case "json": 1476 if err := json.Unmarshal(buf.Bytes(), &c); err != nil { 1477 return ConfigParseError{err} 1478 } 1479 1480 case "hcl": 1481 obj, err := hcl.Parse(string(buf.Bytes())) 1482 if err != nil { 1483 return ConfigParseError{err} 1484 } 1485 if err = hcl.DecodeObject(&c, obj); err != nil { 1486 return ConfigParseError{err} 1487 } 1488 1489 case "toml": 1490 tree, err := toml.LoadReader(buf) 1491 if err != nil { 1492 return ConfigParseError{err} 1493 } 1494 tmap := tree.ToMap() 1495 for k, v := range tmap { 1496 c[k] = v 1497 } 1498 1499 case "properties", "props", "prop": 1500 v.properties = properties.NewProperties() 1501 var err error 1502 if v.properties, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil { 1503 return ConfigParseError{err} 1504 } 1505 for _, key := range v.properties.Keys() { 1506 value, _ := v.properties.Get(key) 1507 // recursively build nested maps 1508 path := strings.Split(key, ".") 1509 lastKey := strings.ToLower(path[len(path)-1]) 1510 deepestMap := deepSearch(c, path[0:len(path)-1]) 1511 // set innermost value 1512 deepestMap[lastKey] = value 1513 } 1514 } 1515 1516 insensitiviseMap(c) 1517 return nil 1518 } 1519 1520 // Marshal a map into Writer. 1521 func marshalWriter(f afero.File, configType string) error { 1522 return v.marshalWriter(f, configType) 1523 } 1524 func (v *Viper) marshalWriter(f afero.File, configType string) error { 1525 c := v.AllSettings() 1526 switch configType { 1527 case "json": 1528 b, err := json.MarshalIndent(c, "", " ") 1529 if err != nil { 1530 return ConfigMarshalError{err} 1531 } 1532 _, err = f.WriteString(string(b)) 1533 if err != nil { 1534 return ConfigMarshalError{err} 1535 } 1536 1537 case "hcl": 1538 b, err := json.Marshal(c) 1539 ast, err := hcl.Parse(string(b)) 1540 if err != nil { 1541 return ConfigMarshalError{err} 1542 } 1543 err = printer.Fprint(f, ast.Node) 1544 if err != nil { 1545 return ConfigMarshalError{err} 1546 } 1547 1548 case "prop", "props", "properties": 1549 if v.properties == nil { 1550 v.properties = properties.NewProperties() 1551 } 1552 p := v.properties 1553 for _, key := range v.AllKeys() { 1554 _, _, err := p.Set(key, v.GetString(key)) 1555 if err != nil { 1556 return ConfigMarshalError{err} 1557 } 1558 } 1559 _, err := p.WriteComment(f, "#", properties.UTF8) 1560 if err != nil { 1561 return ConfigMarshalError{err} 1562 } 1563 1564 case "toml": 1565 t, err := toml.TreeFromMap(c) 1566 if err != nil { 1567 return ConfigMarshalError{err} 1568 } 1569 s := t.String() 1570 if _, err := f.WriteString(s); err != nil { 1571 return ConfigMarshalError{err} 1572 } 1573 1574 case "yaml", "yml": 1575 b, err := yaml.Marshal(c) 1576 if err != nil { 1577 return ConfigMarshalError{err} 1578 } 1579 if _, err = f.WriteString(string(b)); err != nil { 1580 return ConfigMarshalError{err} 1581 } 1582 } 1583 return nil 1584 } 1585 1586 func keyExists(k string, m map[string]interface{}) string { 1587 lk := strings.ToLower(k) 1588 for mk := range m { 1589 lmk := strings.ToLower(mk) 1590 if lmk == lk { 1591 return mk 1592 } 1593 } 1594 return "" 1595 } 1596 1597 func castToMapStringInterface( 1598 src map[interface{}]interface{}) map[string]interface{} { 1599 tgt := map[string]interface{}{} 1600 for k, v := range src { 1601 tgt[fmt.Sprintf("%v", k)] = v 1602 } 1603 return tgt 1604 } 1605 1606 func castMapStringSliceToMapInterface(src map[string][]string) map[string]interface{} { 1607 tgt := map[string]interface{}{} 1608 for k, v := range src { 1609 tgt[k] = v 1610 } 1611 return tgt 1612 } 1613 1614 func castMapStringToMapInterface(src map[string]string) map[string]interface{} { 1615 tgt := map[string]interface{}{} 1616 for k, v := range src { 1617 tgt[k] = v 1618 } 1619 return tgt 1620 } 1621 1622 func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} { 1623 tgt := map[string]interface{}{} 1624 for k, v := range src { 1625 tgt[k] = v 1626 } 1627 return tgt 1628 } 1629 1630 // mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's 1631 // insistence on parsing nested structures as `map[interface{}]interface{}` 1632 // instead of using a `string` as the key for nest structures beyond one level 1633 // deep. Both map types are supported as there is a go-yaml fork that uses 1634 // `map[string]interface{}` instead. 1635 func mergeMaps( 1636 src, tgt map[string]interface{}, itgt map[interface{}]interface{}) { 1637 for sk, sv := range src { 1638 tk := keyExists(sk, tgt) 1639 if tk == "" { 1640 jww.TRACE.Printf("tk=\"\", tgt[%s]=%v", sk, sv) 1641 tgt[sk] = sv 1642 if itgt != nil { 1643 itgt[sk] = sv 1644 } 1645 continue 1646 } 1647 1648 tv, ok := tgt[tk] 1649 if !ok { 1650 jww.TRACE.Printf("tgt[%s] != ok, tgt[%s]=%v", tk, sk, sv) 1651 tgt[sk] = sv 1652 if itgt != nil { 1653 itgt[sk] = sv 1654 } 1655 continue 1656 } 1657 1658 svType := reflect.TypeOf(sv) 1659 tvType := reflect.TypeOf(tv) 1660 if svType != tvType { 1661 jww.ERROR.Printf( 1662 "svType != tvType; key=%s, st=%v, tt=%v, sv=%v, tv=%v", 1663 sk, svType, tvType, sv, tv) 1664 continue 1665 } 1666 1667 jww.TRACE.Printf("processing key=%s, st=%v, tt=%v, sv=%v, tv=%v", 1668 sk, svType, tvType, sv, tv) 1669 1670 switch ttv := tv.(type) { 1671 case map[interface{}]interface{}: 1672 jww.TRACE.Printf("merging maps (must convert)") 1673 tsv := sv.(map[interface{}]interface{}) 1674 ssv := castToMapStringInterface(tsv) 1675 stv := castToMapStringInterface(ttv) 1676 mergeMaps(ssv, stv, ttv) 1677 case map[string]interface{}: 1678 jww.TRACE.Printf("merging maps") 1679 mergeMaps(sv.(map[string]interface{}), ttv, nil) 1680 default: 1681 jww.TRACE.Printf("setting value") 1682 tgt[tk] = sv 1683 if itgt != nil { 1684 itgt[tk] = sv 1685 } 1686 } 1687 } 1688 } 1689 1690 // ReadRemoteConfig attempts to get configuration from a remote source 1691 // and read it in the remote configuration registry. 1692 func ReadRemoteConfig() error { return v.ReadRemoteConfig() } 1693 func (v *Viper) ReadRemoteConfig() error { 1694 return v.getKeyValueConfig() 1695 } 1696 1697 func WatchRemoteConfig() error { return v.WatchRemoteConfig() } 1698 func (v *Viper) WatchRemoteConfig() error { 1699 return v.watchKeyValueConfig() 1700 } 1701 1702 func (v *Viper) WatchRemoteConfigOnChannel() error { 1703 return v.watchKeyValueConfigOnChannel() 1704 } 1705 1706 // Retrieve the first found remote configuration. 1707 func (v *Viper) getKeyValueConfig() error { 1708 if RemoteConfig == nil { 1709 return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'") 1710 } 1711 1712 for _, rp := range v.remoteProviders { 1713 val, err := v.getRemoteConfig(rp) 1714 if err != nil { 1715 continue 1716 } 1717 v.kvstore = val 1718 return nil 1719 } 1720 return RemoteConfigError("No Files Found") 1721 } 1722 1723 func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) { 1724 reader, err := RemoteConfig.Get(provider) 1725 if err != nil { 1726 return nil, err 1727 } 1728 err = v.unmarshalReader(reader, v.kvstore) 1729 return v.kvstore, err 1730 } 1731 1732 // Retrieve the first found remote configuration. 1733 func (v *Viper) watchKeyValueConfigOnChannel() error { 1734 for _, rp := range v.remoteProviders { 1735 respc, _ := RemoteConfig.WatchChannel(rp) 1736 //Todo: Add quit channel 1737 go func(rc <-chan *RemoteResponse) { 1738 for { 1739 b := <-rc 1740 reader := bytes.NewReader(b.Value) 1741 v.unmarshalReader(reader, v.kvstore) 1742 } 1743 }(respc) 1744 return nil 1745 } 1746 return RemoteConfigError("No Files Found") 1747 } 1748 1749 // Retrieve the first found remote configuration. 1750 func (v *Viper) watchKeyValueConfig() error { 1751 for _, rp := range v.remoteProviders { 1752 val, err := v.watchRemoteConfig(rp) 1753 if err != nil { 1754 continue 1755 } 1756 v.kvstore = val 1757 return nil 1758 } 1759 return RemoteConfigError("No Files Found") 1760 } 1761 1762 func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) { 1763 reader, err := RemoteConfig.Watch(provider) 1764 if err != nil { 1765 return nil, err 1766 } 1767 err = v.unmarshalReader(reader, v.kvstore) 1768 return v.kvstore, err 1769 } 1770 1771 // AllKeys returns all keys holding a value, regardless of where they are set. 1772 // Nested keys are returned with a v.keyDelim (= ".") separator 1773 func AllKeys() []string { return v.AllKeys() } 1774 func (v *Viper) AllKeys() []string { 1775 m := map[string]bool{} 1776 // add all paths, by order of descending priority to ensure correct shadowing 1777 m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "") 1778 m = v.flattenAndMergeMap(m, v.override, "") 1779 m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags)) 1780 m = v.mergeFlatMap(m, castMapStringSliceToMapInterface(v.env)) 1781 m = v.flattenAndMergeMap(m, v.config, "") 1782 m = v.flattenAndMergeMap(m, v.kvstore, "") 1783 m = v.flattenAndMergeMap(m, v.defaults, "") 1784 1785 // convert set of paths to list 1786 a := []string{} 1787 for x := range m { 1788 a = append(a, x) 1789 } 1790 return a 1791 } 1792 1793 // flattenAndMergeMap recursively flattens the given map into a map[string]bool 1794 // of key paths (used as a set, easier to manipulate than a []string): 1795 // - each path is merged into a single key string, delimited with v.keyDelim (= ".") 1796 // - if a path is shadowed by an earlier value in the initial shadow map, 1797 // it is skipped. 1798 // The resulting set of paths is merged to the given shadow set at the same time. 1799 func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool { 1800 if shadow != nil && prefix != "" && shadow[prefix] { 1801 // prefix is shadowed => nothing more to flatten 1802 return shadow 1803 } 1804 if shadow == nil { 1805 shadow = make(map[string]bool) 1806 } 1807 1808 var m2 map[string]interface{} 1809 if prefix != "" { 1810 prefix += v.keyDelim 1811 } 1812 for k, val := range m { 1813 fullKey := prefix + k 1814 switch val.(type) { 1815 case map[string]interface{}: 1816 m2 = val.(map[string]interface{}) 1817 case map[interface{}]interface{}: 1818 m2 = cast.ToStringMap(val) 1819 default: 1820 // immediate value 1821 shadow[strings.ToLower(fullKey)] = true 1822 continue 1823 } 1824 // recursively merge to shadow map 1825 shadow = v.flattenAndMergeMap(shadow, m2, fullKey) 1826 } 1827 return shadow 1828 } 1829 1830 // mergeFlatMap merges the given maps, excluding values of the second map 1831 // shadowed by values from the first map. 1832 func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool { 1833 // scan keys 1834 outer: 1835 for k := range m { 1836 path := strings.Split(k, v.keyDelim) 1837 // scan intermediate paths 1838 var parentKey string 1839 for i := 1; i < len(path); i++ { 1840 parentKey = strings.Join(path[0:i], v.keyDelim) 1841 if shadow[parentKey] { 1842 // path is shadowed, continue 1843 continue outer 1844 } 1845 } 1846 // add key 1847 shadow[strings.ToLower(k)] = true 1848 } 1849 return shadow 1850 } 1851 1852 // AllSettings merges all settings and returns them as a map[string]interface{}. 1853 func AllSettings() map[string]interface{} { return v.AllSettings() } 1854 func (v *Viper) AllSettings() map[string]interface{} { 1855 return v.allSettings(v.Get) 1856 } 1857 1858 // AllSettingsWithoutDefault merges all settings and returns them as a map[string]interface{}. 1859 func AllSettingsWithoutDefault() map[string]interface{} { return v.AllSettingsWithoutDefault() } 1860 func (v *Viper) AllSettingsWithoutDefault() map[string]interface{} { 1861 return v.allSettings(v.GetSkipDefault) 1862 } 1863 1864 func (v *Viper) allSettings(getter func(string) interface{}) map[string]interface{} { 1865 m := map[string]interface{}{} 1866 // start from the list of keys, and construct the map one value at a time 1867 for _, k := range v.AllKeys() { 1868 value := getter(k) 1869 if value == nil { 1870 // should only happens if we `getter` ignors defaults 1871 continue 1872 } 1873 1874 // Build key path by splitting the key by keyDelim and checking that the parent keys 1875 // are actually set. 1876 // Example use case: 1877 // Ensures sure that, for the yaml conf "foo.bar: baz", and keyDelim ".": 1878 // the generated path is []string{"foo.bar", "baz"}, instead of []string{"foo", "bar", "baz"} 1879 path := []string{} 1880 splitPath := strings.Split(k, v.keyDelim) 1881 i := 0 1882 for j := range splitPath { 1883 if v.IsSet(strings.Join(splitPath[:j+1], v.keyDelim)) { 1884 path = append(path, strings.Join(splitPath[i:j+1], v.keyDelim)) 1885 i = j + 1 1886 } 1887 } 1888 1889 lastKey := strings.ToLower(path[len(path)-1]) 1890 deepestMap := deepSearch(m, path[0:len(path)-1]) 1891 // set innermost value 1892 deepestMap[lastKey] = value 1893 } 1894 return m 1895 } 1896 1897 // SetFs sets the filesystem to use to read configuration. 1898 func SetFs(fs afero.Fs) { v.SetFs(fs) } 1899 func (v *Viper) SetFs(fs afero.Fs) { 1900 v.fs = fs 1901 } 1902 1903 // SetConfigName sets name for the config file. 1904 // Does not include extension. 1905 func SetConfigName(in string) { v.SetConfigName(in) } 1906 func (v *Viper) SetConfigName(in string) { 1907 if in != "" { 1908 v.configName = in 1909 v.configFile = "" 1910 } 1911 } 1912 1913 // SetConfigType sets the type of the configuration returned by the 1914 // remote source, e.g. "json". 1915 func SetConfigType(in string) { v.SetConfigType(in) } 1916 func (v *Viper) SetConfigType(in string) { 1917 if in != "" { 1918 v.configType = in 1919 } 1920 } 1921 1922 func (v *Viper) getConfigType() string { 1923 if v.configType != "" { 1924 return v.configType 1925 } 1926 1927 cf, err := v.getConfigFile() 1928 if err != nil { 1929 return "" 1930 } 1931 1932 ext := filepath.Ext(cf) 1933 1934 if len(ext) > 1 { 1935 return ext[1:] 1936 } 1937 1938 return "" 1939 } 1940 1941 func (v *Viper) getConfigFile() (string, error) { 1942 if v.configFile == "" { 1943 cf, err := v.findConfigFile() 1944 if err != nil { 1945 return "", err 1946 } 1947 v.configFile = cf 1948 } 1949 return v.configFile, nil 1950 } 1951 1952 func (v *Viper) searchInPath(in string) (filename string, err error) { 1953 var lastError error 1954 jww.DEBUG.Println("Searching for config in ", in) 1955 for _, ext := range SupportedExts { 1956 jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext)) 1957 b, err := exists(v.fs, filepath.Join(in, v.configName+"."+ext)) 1958 if err != nil { 1959 lastError = err 1960 } else if b { 1961 jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext)) 1962 return filepath.Join(in, v.configName+"."+ext), nil 1963 } 1964 } 1965 1966 return "", lastError 1967 } 1968 1969 // Search all configPaths for any config file. 1970 // Returns the first path that exists (and is a config file). 1971 func (v *Viper) findConfigFile() (string, error) { 1972 jww.INFO.Println("Searching for config in ", v.configPaths) 1973 1974 var lastError error 1975 for _, cp := range v.configPaths { 1976 file, err := v.searchInPath(cp) 1977 if file != "" { 1978 return file, nil 1979 } 1980 if err != nil { 1981 lastError = err 1982 } 1983 } 1984 1985 // If there was no more-specific error, assume this was a not-found error 1986 if lastError == nil { 1987 lastError = ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} 1988 } 1989 1990 return "", lastError 1991 } 1992 1993 // Debug prints all configuration registries for debugging 1994 // purposes. 1995 func Debug() { v.Debug() } 1996 func (v *Viper) Debug() { 1997 fmt.Printf("Aliases:\n%#v\n", v.aliases) 1998 fmt.Printf("Override:\n%#v\n", v.override) 1999 fmt.Printf("PFlags:\n%#v\n", v.pflags) 2000 fmt.Printf("Env:\n%#v\n", v.env) 2001 fmt.Printf("Key/Value Store:\n%#v\n", v.kvstore) 2002 fmt.Printf("Config:\n%#v\n", v.config) 2003 fmt.Printf("Defaults:\n%#v\n", v.defaults) 2004 }