-
Notifications
You must be signed in to change notification settings - Fork 141
/
Copy pathloaders.go
126 lines (97 loc) · 3.67 KB
/
loaders.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package cmd
import (
"fmt"
"os"
"strings"
"github.com/sirupsen/logrus"
"github.com/traefik/paerser/cli"
"github.com/traefik/paerser/env"
"github.com/traefik/paerser/file"
"github.com/traefik/paerser/flag"
"github.com/traefik/paerser/parser"
)
const (
meshPrefix = "MESH_"
maeshPrefix = "MAESH_"
traefikMeshPrefix = "TRAEFIK_MESH_"
)
// EnvLoader loads a configuration from all the environment variables.
type EnvLoader struct{}
// Load loads the command's configuration from the environment variables prefixed with "TRAEFIK_MESH_" or "MAESH_".
// The "MAESH_" prefix is deprecated and will be removed in the next major release.
// If "TRAEFIK_MESH_" and "MAESH_" env variables are mixed up an error is returned.
// As it is not possible to have a prefix with multiple "_" everything is normalized to "MESH_" under the hood for the decoding.
func (e *EnvLoader) Load(_ []string, cmd *cli.Command) (bool, error) {
logger := logrus.StandardLogger()
traefikMeshVars := findAndNormalizePrefixedEnvVars(traefikMeshPrefix, cmd.Configuration)
maeshVars := findAndNormalizePrefixedEnvVars(maeshPrefix, cmd.Configuration)
if len(maeshVars) > 0 && len(traefikMeshVars) > 0 {
return false, fmt.Errorf("environment variable prefixed by %q cannot be mixed with variable prefixed by %q", maeshPrefix, traefikMeshPrefix)
}
vars := traefikMeshVars
if len(maeshVars) > 0 {
vars = maeshVars
}
if len(vars) == 0 {
return false, nil
}
if err := env.Decode(vars, meshPrefix, cmd.Configuration); err != nil {
logger.Debug("environment variables", strings.Join(vars, ", "))
return false, fmt.Errorf("failed to decode configuration from environment variables: %w ", err)
}
logger.Println("Configuration loaded from environment variables.")
return true, nil
}
func findAndNormalizePrefixedEnvVars(prefix string, config interface{}) []string {
vars := env.FindPrefixedEnvVars(os.Environ(), prefix, config)
for _, v := range vars {
vars = append(vars, strings.Replace(v, prefix, meshPrefix, 1))
}
return vars
}
// FileLoader loads a configuration from a file.
type FileLoader struct{}
// Load loads the command's configuration from a file either specified with the --configFile flag, or from default locations.
func (f *FileLoader) Load(args []string, cmd *cli.Command) (bool, error) {
logger := logrus.StandardLogger()
ref, err := flag.Parse(args, cmd.Configuration)
if err != nil {
_ = cmd.PrintHelp(os.Stdout)
return false, err
}
configFileFlag := fmt.Sprintf("%s.configFile", parser.DefaultRootName)
configFile, err := loadConfigFiles(ref[configFileFlag], cmd.Configuration)
if err != nil {
return false, err
}
if configFile == "" {
return false, nil
}
logger.Printf("Configuration loaded from file: %s", configFile)
content, _ := os.ReadFile(configFile)
logger.Debug(string(content))
return true, nil
}
// loadConfigFiles tries to decode the given configuration file and all default locations for the configuration file.
// It stops as soon as decoding one of them is successful.
// The default maesh locations are deprecated and will be removed in a future major release.
func loadConfigFiles(configFile string, element interface{}) (string, error) {
finder := cli.Finder{
BasePaths: []string{
"/etc/maesh/maesh", "$XDG_CONFIG_HOME/maesh", "$HOME/.config/maesh", "./maesh",
"/etc/traefik-mesh/traefik-mesh", "$XDG_CONFIG_HOME/traefik-mesh", "$HOME/.config/traefik-mesh", "./traefik-mesh",
},
Extensions: []string{"toml", "yaml", "yml"},
}
filePath, err := finder.Find(configFile)
if err != nil {
return "", err
}
if len(filePath) == 0 {
return "", nil
}
if err = file.Decode(filePath, element); err != nil {
return "", err
}
return filePath, nil
}