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