2015-09-07 08:38:58 +00:00
|
|
|
package main
|
|
|
|
|
2015-09-25 09:44:19 +00:00
|
|
|
import (
|
2015-11-06 17:11:57 +00:00
|
|
|
fmtlog "log"
|
2015-10-08 15:56:45 +00:00
|
|
|
"time"
|
2015-11-01 15:35:01 +00:00
|
|
|
|
2016-01-13 21:46:44 +00:00
|
|
|
"fmt"
|
2015-11-01 15:35:01 +00:00
|
|
|
"github.com/emilevauge/traefik/provider"
|
|
|
|
"github.com/emilevauge/traefik/types"
|
2016-01-13 21:46:44 +00:00
|
|
|
"github.com/mitchellh/mapstructure"
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
"github.com/wendal/errors"
|
|
|
|
"strings"
|
2015-09-25 09:44:19 +00:00
|
|
|
)
|
|
|
|
|
2015-11-06 17:11:57 +00:00
|
|
|
// GlobalConfiguration holds global configuration (with providers, etc.).
|
|
|
|
// It's populated from the traefik configuration file passed as an argument to the binary.
|
2015-09-10 13:13:35 +00:00
|
|
|
type GlobalConfiguration struct {
|
2015-10-17 12:14:20 +00:00
|
|
|
Port string
|
|
|
|
GraceTimeOut int64
|
|
|
|
AccessLogsFile string
|
|
|
|
TraefikLogsFile string
|
2016-01-13 21:46:44 +00:00
|
|
|
Certificates Certificates
|
2015-10-17 12:14:20 +00:00
|
|
|
LogLevel string
|
|
|
|
ProvidersThrottleDuration time.Duration
|
2015-11-02 18:48:34 +00:00
|
|
|
Docker *provider.Docker
|
|
|
|
File *provider.File
|
2015-10-17 12:14:20 +00:00
|
|
|
Web *WebProvider
|
2015-11-02 18:48:34 +00:00
|
|
|
Marathon *provider.Marathon
|
|
|
|
Consul *provider.Consul
|
|
|
|
Etcd *provider.Etcd
|
|
|
|
Zookeeper *provider.Zookepper
|
|
|
|
Boltdb *provider.BoltDb
|
2015-09-10 13:13:35 +00:00
|
|
|
}
|
|
|
|
|
2016-01-13 21:46:44 +00:00
|
|
|
// Certificates defines traefik certificates type
|
|
|
|
type Certificates []Certificate
|
|
|
|
|
|
|
|
// String is the method to format the flag's value, part of the flag.Value interface.
|
|
|
|
// The String method's output will be used in diagnostics.
|
|
|
|
func (certs *Certificates) String() string {
|
|
|
|
if len(*certs) == 0 {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return (*certs)[0].CertFile + "," + (*certs)[0].KeyFile
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set is the method to set the flag value, part of the flag.Value interface.
|
|
|
|
// Set's argument is a string to be parsed to set the flag.
|
|
|
|
// It's a comma-separated list, so we split it.
|
|
|
|
func (certs *Certificates) Set(value string) error {
|
|
|
|
files := strings.Split(value, ",")
|
|
|
|
if len(files) != 2 {
|
|
|
|
return errors.New("Bad certificates format: " + value)
|
|
|
|
}
|
|
|
|
*certs = append(*certs, Certificate{
|
|
|
|
CertFile: files[0],
|
|
|
|
KeyFile: files[1],
|
|
|
|
})
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Type is type of the struct
|
|
|
|
func (certs *Certificates) Type() string {
|
|
|
|
return fmt.Sprint("certificates")
|
|
|
|
}
|
|
|
|
|
2015-11-21 01:59:49 +00:00
|
|
|
// Certificate holds a SSL cert/key pair
|
|
|
|
type Certificate struct {
|
|
|
|
CertFile string
|
|
|
|
KeyFile string
|
|
|
|
}
|
|
|
|
|
2015-11-06 17:11:57 +00:00
|
|
|
// NewGlobalConfiguration returns a GlobalConfiguration with default values.
|
2015-09-10 13:13:35 +00:00
|
|
|
func NewGlobalConfiguration() *GlobalConfiguration {
|
|
|
|
globalConfiguration := new(GlobalConfiguration)
|
|
|
|
// default values
|
2015-09-14 12:38:21 +00:00
|
|
|
globalConfiguration.Port = ":80"
|
2015-09-10 13:13:35 +00:00
|
|
|
globalConfiguration.GraceTimeOut = 10
|
2015-09-11 14:40:54 +00:00
|
|
|
globalConfiguration.LogLevel = "ERROR"
|
2015-10-17 12:14:20 +00:00
|
|
|
globalConfiguration.ProvidersThrottleDuration = time.Duration(2 * time.Second)
|
2015-09-10 13:13:35 +00:00
|
|
|
|
|
|
|
return globalConfiguration
|
|
|
|
}
|
2015-09-07 08:38:58 +00:00
|
|
|
|
2016-01-13 21:46:44 +00:00
|
|
|
// LoadConfiguration returns a GlobalConfiguration.
|
|
|
|
func LoadConfiguration() *GlobalConfiguration {
|
2015-11-06 17:11:57 +00:00
|
|
|
configuration := NewGlobalConfiguration()
|
2016-01-13 21:46:44 +00:00
|
|
|
viper.SetEnvPrefix("traefik")
|
|
|
|
viper.SetConfigType("toml")
|
|
|
|
viper.AutomaticEnv()
|
|
|
|
if len(viper.GetString("configFile")) > 0 {
|
|
|
|
viper.SetConfigFile(viper.GetString("configFile"))
|
|
|
|
} else {
|
|
|
|
viper.SetConfigName("traefik") // name of config file (without extension)
|
|
|
|
}
|
2016-01-22 11:36:24 +00:00
|
|
|
viper.AddConfigPath("/etc/traefik/") // path to look for the config file in
|
|
|
|
viper.AddConfigPath("$HOME/.traefik/") // call multiple times to add many search paths
|
|
|
|
viper.AddConfigPath(".") // optionally look for config in the working directory
|
|
|
|
err := viper.ReadInConfig() // Find and read the config file
|
|
|
|
if err != nil { // Handle errors reading the config file
|
2016-01-13 21:46:44 +00:00
|
|
|
fmtlog.Fatalf("Error reading file: %s", err)
|
|
|
|
}
|
|
|
|
if len(arguments.Certificates) > 0 {
|
|
|
|
viper.Set("certificates", arguments.Certificates)
|
|
|
|
}
|
|
|
|
if arguments.web {
|
|
|
|
viper.Set("web", arguments.Web)
|
|
|
|
}
|
|
|
|
if arguments.file {
|
|
|
|
viper.Set("file", arguments.File)
|
|
|
|
}
|
|
|
|
if !arguments.dockerTLS {
|
|
|
|
arguments.Docker.TLS = nil
|
|
|
|
}
|
|
|
|
if arguments.docker {
|
|
|
|
viper.Set("docker", arguments.Docker)
|
|
|
|
}
|
|
|
|
if arguments.marathon {
|
|
|
|
viper.Set("marathon", arguments.Marathon)
|
|
|
|
}
|
|
|
|
if arguments.consul {
|
|
|
|
viper.Set("consul", arguments.Consul)
|
|
|
|
}
|
|
|
|
if arguments.zookeeper {
|
|
|
|
viper.Set("zookeeper", arguments.Zookeeper)
|
|
|
|
}
|
|
|
|
if arguments.etcd {
|
|
|
|
viper.Set("etcd", arguments.Etcd)
|
|
|
|
}
|
|
|
|
if arguments.boltdb {
|
|
|
|
viper.Set("boltdb", arguments.Boltdb)
|
|
|
|
}
|
|
|
|
err = unmarshal(&configuration)
|
|
|
|
if err != nil {
|
2015-11-06 17:11:57 +00:00
|
|
|
fmtlog.Fatalf("Error reading file: %s", err)
|
|
|
|
}
|
2016-01-13 21:46:44 +00:00
|
|
|
|
2015-11-06 17:11:57 +00:00
|
|
|
return configuration
|
|
|
|
}
|
|
|
|
|
2016-01-13 21:46:44 +00:00
|
|
|
func unmarshal(rawVal interface{}) error {
|
|
|
|
config := &mapstructure.DecoderConfig{
|
|
|
|
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
|
|
|
|
Metadata: nil,
|
|
|
|
Result: rawVal,
|
|
|
|
WeaklyTypedInput: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
decoder, err := mapstructure.NewDecoder(config)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = decoder.Decode(viper.AllSettings())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-11-01 15:35:01 +00:00
|
|
|
type configs map[string]*types.Configuration
|