From fe0a8f3363d3cae4785b18b9293f5984f8ea35f2 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 3 May 2016 16:52:14 +0200 Subject: [PATCH 01/16] Flaeg integration --- cmd.go | 230 -------------------------------- configuration.go | 266 ++++++++++++++++++------------------- flaeg_test.go | 91 +++++++++++++ provider/boltdb.go | 2 +- provider/consul.go | 2 +- provider/consul_catalog.go | 4 +- provider/docker.go | 14 +- provider/etcd.go | 2 +- provider/file.go | 2 +- provider/kubernetes.go | 11 +- provider/kv.go | 16 +-- provider/marathon.go | 10 +- provider/provider.go | 4 +- provider/zk.go | 2 +- traefik.go | 97 +++++++++++++- web.go | 9 +- 16 files changed, 361 insertions(+), 401 deletions(-) delete mode 100644 cmd.go create mode 100644 flaeg_test.go diff --git a/cmd.go b/cmd.go deleted file mode 100644 index 6580d6a15..000000000 --- a/cmd.go +++ /dev/null @@ -1,230 +0,0 @@ -/* -Copyright -*/ -package main - -import ( - "encoding/json" - fmtlog "log" - "os" - "strings" - "time" - - "net/http" - - log "github.com/Sirupsen/logrus" - "github.com/containous/traefik/middlewares" - "github.com/containous/traefik/provider" - "github.com/spf13/cobra" - "github.com/spf13/viper" -) - -var traefikCmd = &cobra.Command{ - Use: "traefik", - Short: "traefik, a modern reverse proxy", - Long: `traefik is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. -Complete documentation is available at http://traefik.io`, - Run: func(cmd *cobra.Command, args []string) { - run() - }, -} -var versionCmd = &cobra.Command{ - Use: "version", - Short: "Print version", - Long: `Print version`, - Run: func(cmd *cobra.Command, args []string) { - fmtlog.Println(Version + " built on the " + BuildDate) - os.Exit(0) - }, -} - -var arguments = struct { - GlobalConfiguration - web bool - file bool - docker bool - dockerTLS bool - marathon bool - consul bool - consulTLS bool - consulCatalog bool - zookeeper bool - etcd bool - etcdTLS bool - boltdb bool - kubernetes bool -}{ - GlobalConfiguration{ - EntryPoints: make(EntryPoints), - Docker: &provider.Docker{ - TLS: &provider.DockerTLS{}, - }, - File: &provider.File{}, - Web: &WebProvider{}, - Marathon: &provider.Marathon{}, - Consul: &provider.Consul{ - Kv: provider.Kv{ - TLS: &provider.KvTLS{}, - }, - }, - ConsulCatalog: &provider.ConsulCatalog{}, - Zookeeper: &provider.Zookepper{}, - Etcd: &provider.Etcd{ - Kv: provider.Kv{ - TLS: &provider.KvTLS{}, - }, - }, - Boltdb: &provider.BoltDb{}, - Kubernetes: &provider.Kubernetes{}, - }, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, -} - -func init() { - traefikCmd.AddCommand(versionCmd) - traefikCmd.PersistentFlags().StringP("configFile", "c", "", "Configuration file to use (TOML).") - traefikCmd.PersistentFlags().BoolVarP(&arguments.Debug, "debug", "d", false, "Enable debug mode") - traefikCmd.PersistentFlags().StringP("graceTimeOut", "g", "10", "Timeout in seconds. Duration to give active requests a chance to finish during hot-reloads") - traefikCmd.PersistentFlags().String("accessLogsFile", "log/access.log", "Access logs file") - traefikCmd.PersistentFlags().String("traefikLogsFile", "log/traefik.log", "Traefik logs file") - traefikCmd.PersistentFlags().Var(&arguments.EntryPoints, "entryPoints", "Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key'") - traefikCmd.PersistentFlags().Var(&arguments.DefaultEntryPoints, "defaultEntryPoints", "Entrypoints to be used by frontends that do not specify any entrypoint") - traefikCmd.PersistentFlags().StringP("logLevel", "l", "ERROR", "Log level") - traefikCmd.PersistentFlags().DurationVar(&arguments.ProvidersThrottleDuration, "providersThrottleDuration", time.Duration(2*time.Second), "Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time.") - traefikCmd.PersistentFlags().Int("maxIdleConnsPerHost", 0, "If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used") - - traefikCmd.PersistentFlags().BoolVar(&arguments.web, "web", false, "Enable Web backend") - traefikCmd.PersistentFlags().StringVar(&arguments.Web.Address, "web.address", ":8080", "Web administration port") - traefikCmd.PersistentFlags().StringVar(&arguments.Web.CertFile, "web.cerFile", "", "SSL certificate") - traefikCmd.PersistentFlags().StringVar(&arguments.Web.KeyFile, "web.keyFile", "", "SSL certificate") - traefikCmd.PersistentFlags().BoolVar(&arguments.Web.ReadOnly, "web.readOnly", false, "Enable read only API") - - traefikCmd.PersistentFlags().BoolVar(&arguments.file, "file", false, "Enable File backend") - traefikCmd.PersistentFlags().BoolVar(&arguments.File.Watch, "file.watch", true, "Watch provider") - traefikCmd.PersistentFlags().StringVar(&arguments.File.Filename, "file.filename", "", "Override default configuration template. For advanced users :)") - - traefikCmd.PersistentFlags().BoolVar(&arguments.docker, "docker", false, "Enable Docker backend") - traefikCmd.PersistentFlags().BoolVar(&arguments.Docker.Watch, "docker.watch", true, "Watch provider") - traefikCmd.PersistentFlags().StringVar(&arguments.Docker.Filename, "docker.filename", "", "Override default configuration template. For advanced users :)") - traefikCmd.PersistentFlags().StringVar(&arguments.Docker.Endpoint, "docker.endpoint", "unix:///var/run/docker.sock", "Docker server endpoint. Can be a tcp or a unix socket endpoint") - traefikCmd.PersistentFlags().StringVar(&arguments.Docker.Domain, "docker.domain", "", "Default domain used") - traefikCmd.PersistentFlags().BoolVar(&arguments.dockerTLS, "docker.tls", false, "Enable Docker TLS support") - traefikCmd.PersistentFlags().StringVar(&arguments.Docker.TLS.CA, "docker.tls.ca", "", "TLS CA") - traefikCmd.PersistentFlags().StringVar(&arguments.Docker.TLS.Cert, "docker.tls.cert", "", "TLS cert") - traefikCmd.PersistentFlags().StringVar(&arguments.Docker.TLS.Key, "docker.tls.key", "", "TLS key") - traefikCmd.PersistentFlags().BoolVar(&arguments.Docker.TLS.InsecureSkipVerify, "docker.tls.insecureSkipVerify", false, "TLS insecure skip verify") - - traefikCmd.PersistentFlags().BoolVar(&arguments.marathon, "marathon", false, "Enable Marathon backend") - traefikCmd.PersistentFlags().BoolVar(&arguments.Marathon.Watch, "marathon.watch", true, "Watch provider") - traefikCmd.PersistentFlags().StringVar(&arguments.Marathon.Filename, "marathon.filename", "", "Override default configuration template. For advanced users :)") - traefikCmd.PersistentFlags().StringVar(&arguments.Marathon.Endpoint, "marathon.endpoint", "http://127.0.0.1:8080", "Marathon server endpoint. You can also specify multiple endpoint for Marathon") - traefikCmd.PersistentFlags().StringVar(&arguments.Marathon.Domain, "marathon.domain", "", "Default domain used") - traefikCmd.PersistentFlags().BoolVar(&arguments.Marathon.ExposedByDefault, "marathon.exposedByDefault", true, "Expose Marathon apps by default") - - traefikCmd.PersistentFlags().BoolVar(&arguments.consul, "consul", false, "Enable Consul backend") - traefikCmd.PersistentFlags().BoolVar(&arguments.Consul.Watch, "consul.watch", true, "Watch provider") - traefikCmd.PersistentFlags().StringVar(&arguments.Consul.Filename, "consul.filename", "", "Override default configuration template. For advanced users :)") - traefikCmd.PersistentFlags().StringVar(&arguments.Consul.Endpoint, "consul.endpoint", "127.0.0.1:8500", "Comma sepparated Consul server endpoints") - traefikCmd.PersistentFlags().StringVar(&arguments.Consul.Prefix, "consul.prefix", "/traefik", "Prefix used for KV store") - traefikCmd.PersistentFlags().BoolVar(&arguments.consulTLS, "consul.tls", false, "Enable Consul TLS support") - traefikCmd.PersistentFlags().StringVar(&arguments.Consul.TLS.CA, "consul.tls.ca", "", "TLS CA") - traefikCmd.PersistentFlags().StringVar(&arguments.Consul.TLS.Cert, "consul.tls.cert", "", "TLS cert") - traefikCmd.PersistentFlags().StringVar(&arguments.Consul.TLS.Key, "consul.tls.key", "", "TLS key") - traefikCmd.PersistentFlags().BoolVar(&arguments.Consul.TLS.InsecureSkipVerify, "consul.tls.insecureSkipVerify", false, "TLS insecure skip verify") - - traefikCmd.PersistentFlags().BoolVar(&arguments.consulCatalog, "consulCatalog", false, "Enable Consul catalog backend") - traefikCmd.PersistentFlags().StringVar(&arguments.ConsulCatalog.Domain, "consulCatalog.domain", "", "Default domain used") - traefikCmd.PersistentFlags().StringVar(&arguments.ConsulCatalog.Endpoint, "consulCatalog.endpoint", "127.0.0.1:8500", "Consul server endpoint") - traefikCmd.PersistentFlags().StringVar(&arguments.ConsulCatalog.Prefix, "consulCatalog.prefix", "traefik", "Consul catalog tag prefix") - - traefikCmd.PersistentFlags().BoolVar(&arguments.zookeeper, "zookeeper", false, "Enable Zookeeper backend") - traefikCmd.PersistentFlags().BoolVar(&arguments.Zookeeper.Watch, "zookeeper.watch", true, "Watch provider") - traefikCmd.PersistentFlags().StringVar(&arguments.Zookeeper.Filename, "zookeeper.filename", "", "Override default configuration template. For advanced users :)") - traefikCmd.PersistentFlags().StringVar(&arguments.Zookeeper.Endpoint, "zookeeper.endpoint", "127.0.0.1:2181", "Comma sepparated Zookeeper server endpoints") - traefikCmd.PersistentFlags().StringVar(&arguments.Zookeeper.Prefix, "zookeeper.prefix", "/traefik", "Prefix used for KV store") - - traefikCmd.PersistentFlags().BoolVar(&arguments.etcd, "etcd", false, "Enable Etcd backend") - traefikCmd.PersistentFlags().BoolVar(&arguments.Etcd.Watch, "etcd.watch", true, "Watch provider") - traefikCmd.PersistentFlags().StringVar(&arguments.Etcd.Filename, "etcd.filename", "", "Override default configuration template. For advanced users :)") - traefikCmd.PersistentFlags().StringVar(&arguments.Etcd.Endpoint, "etcd.endpoint", "127.0.0.1:4001", "Comma sepparated Etcd server endpoints") - traefikCmd.PersistentFlags().StringVar(&arguments.Etcd.Prefix, "etcd.prefix", "/traefik", "Prefix used for KV store") - traefikCmd.PersistentFlags().BoolVar(&arguments.etcdTLS, "etcd.tls", false, "Enable Etcd TLS support") - traefikCmd.PersistentFlags().StringVar(&arguments.Etcd.TLS.CA, "etcd.tls.ca", "", "TLS CA") - traefikCmd.PersistentFlags().StringVar(&arguments.Etcd.TLS.Cert, "etcd.tls.cert", "", "TLS cert") - traefikCmd.PersistentFlags().StringVar(&arguments.Etcd.TLS.Key, "etcd.tls.key", "", "TLS key") - traefikCmd.PersistentFlags().BoolVar(&arguments.Etcd.TLS.InsecureSkipVerify, "etcd.tls.insecureSkipVerify", false, "TLS insecure skip verify") - - traefikCmd.PersistentFlags().BoolVar(&arguments.boltdb, "boltdb", false, "Enable Boltdb backend") - traefikCmd.PersistentFlags().BoolVar(&arguments.Boltdb.Watch, "boltdb.watch", true, "Watch provider") - traefikCmd.PersistentFlags().StringVar(&arguments.Boltdb.Filename, "boltdb.filename", "", "Override default configuration template. For advanced users :)") - traefikCmd.PersistentFlags().StringVar(&arguments.Boltdb.Endpoint, "boltdb.endpoint", "127.0.0.1:4001", "Boltdb server endpoint") - traefikCmd.PersistentFlags().StringVar(&arguments.Boltdb.Prefix, "boltdb.prefix", "/traefik", "Prefix used for KV store") - - traefikCmd.PersistentFlags().BoolVar(&arguments.kubernetes, "kubernetes", false, "Enable Kubernetes backend") - traefikCmd.PersistentFlags().StringVar(&arguments.Kubernetes.Endpoint, "kubernetes.endpoint", "http://127.0.0.1:8080", "Kubernetes server endpoint") - traefikCmd.PersistentFlags().StringSliceVar(&arguments.Kubernetes.Namespaces, "kubernetes.namespaces", []string{}, "Kubernetes namespaces") - - _ = viper.BindPFlag("configFile", traefikCmd.PersistentFlags().Lookup("configFile")) - _ = viper.BindPFlag("graceTimeOut", traefikCmd.PersistentFlags().Lookup("graceTimeOut")) - _ = viper.BindPFlag("logLevel", traefikCmd.PersistentFlags().Lookup("logLevel")) - _ = viper.BindPFlag("debug", traefikCmd.PersistentFlags().Lookup("debug")) - // TODO: wait for this issue to be corrected: https://github.com/spf13/viper/issues/105 - _ = viper.BindPFlag("providersThrottleDuration", traefikCmd.PersistentFlags().Lookup("providersThrottleDuration")) - _ = viper.BindPFlag("maxIdleConnsPerHost", traefikCmd.PersistentFlags().Lookup("maxIdleConnsPerHost")) - viper.SetDefault("providersThrottleDuration", time.Duration(2*time.Second)) - viper.SetDefault("logLevel", "ERROR") - viper.SetDefault("MaxIdleConnsPerHost", 200) -} - -func run() { - fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags) - - // load global configuration - globalConfiguration := LoadConfiguration() - - http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = globalConfiguration.MaxIdleConnsPerHost - loggerMiddleware := middlewares.NewLogger(globalConfiguration.AccessLogsFile) - defer loggerMiddleware.Close() - - // logging - level, err := log.ParseLevel(strings.ToLower(globalConfiguration.LogLevel)) - if err != nil { - log.Fatal("Error getting level", err) - } - log.SetLevel(level) - - if len(globalConfiguration.TraefikLogsFile) > 0 { - fi, err := os.OpenFile(globalConfiguration.TraefikLogsFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) - defer func() { - if err := fi.Close(); err != nil { - log.Error("Error closinf file", err) - } - }() - if err != nil { - log.Fatal("Error opening file", err) - } else { - log.SetOutput(fi) - log.SetFormatter(&log.TextFormatter{DisableColors: true, FullTimestamp: true, DisableSorting: true}) - } - } else { - log.SetFormatter(&log.TextFormatter{FullTimestamp: true, DisableSorting: true}) - } - jsonConf, _ := json.Marshal(globalConfiguration) - log.Debugf("Global configuration loaded %s", string(jsonConf)) - server := NewServer(*globalConfiguration) - server.Start() - defer server.Close() - log.Info("Shutting down") -} diff --git a/configuration.go b/configuration.go index bae48d7cb..9b39d5db6 100644 --- a/configuration.go +++ b/configuration.go @@ -3,42 +3,44 @@ package main import ( "errors" "fmt" - fmtlog "log" - "regexp" - "strings" - "time" - "github.com/containous/traefik/acme" "github.com/containous/traefik/provider" "github.com/containous/traefik/types" - "github.com/mitchellh/mapstructure" - "github.com/spf13/viper" + "regexp" + "strings" + "time" ) +// TraefikConfiguration holds GlobalConfiguration and other stuff +type TraefikConfiguration struct { + GlobalConfiguration + ConfigFile string `short:"c" description:"Timeout in seconds. Duration to give active requests a chance to finish during hot-reloads"` +} + // GlobalConfiguration holds global configuration (with providers, etc.). // It's populated from the traefik configuration file passed as an argument to the binary. type GlobalConfiguration struct { - GraceTimeOut int64 + GraceTimeOut int64 `short:"g" description:"Configuration file to use (TOML)."` Debug bool - AccessLogsFile string - TraefikLogsFile string - LogLevel string - EntryPoints EntryPoints + AccessLogsFile string `description:"Access logs file"` + TraefikLogsFile string `description:"Traefik logs file"` + LogLevel string `short:"l" description:"Log level"` + EntryPoints EntryPoints `description:"Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key'"` ACME *acme.ACME - DefaultEntryPoints DefaultEntryPoints - ProvidersThrottleDuration time.Duration - MaxIdleConnsPerHost int + DefaultEntryPoints DefaultEntryPoints `description:"Entrypoints to be used by frontends that do not specify any entrypoint"` + ProvidersThrottleDuration time.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time."` + MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used"` Retry *Retry - Docker *provider.Docker - File *provider.File - Web *WebProvider - Marathon *provider.Marathon - Consul *provider.Consul - ConsulCatalog *provider.ConsulCatalog - Etcd *provider.Etcd - Zookeeper *provider.Zookepper - Boltdb *provider.BoltDb - Kubernetes *provider.Kubernetes + Docker *provider.Docker `description:"Enable Docker backend"` + File *provider.File `description:"Enable File backend"` + Web *WebProvider `description:"Enable Web backend"` + Marathon *provider.Marathon `description:"Enable Marathon backend"` + Consul *provider.Consul `description:"Enable Consul backend"` + ConsulCatalog *provider.ConsulCatalog `description:"Enable Consul catalog backend"` + Etcd *provider.Etcd `description:"Enable Etcd backend"` + Zookeeper *provider.Zookepper `description:"Enable Zookeeper backend"` + Boltdb *provider.BoltDb `description:"Enable Boltdb backend"` + Kubernetes *provider.Kubernetes `description:"Enable Kubernetes backend"` } // DefaultEntryPoints holds default entry points @@ -47,6 +49,7 @@ type DefaultEntryPoints []string // 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 (dep *DefaultEntryPoints) String() string { + //TODO : return fmt.Sprintf("%#v", dep) } @@ -64,6 +67,14 @@ func (dep *DefaultEntryPoints) Set(value string) error { return nil } +// Get return the EntryPoints map +func (dep *DefaultEntryPoints) Get() interface{} { return DefaultEntryPoints(*dep) } + +// SetValue sets the EntryPoints map with val +func (dep *DefaultEntryPoints) SetValue(val interface{}) { + *dep = DefaultEntryPoints(val.(DefaultEntryPoints)) +} + // Type is type of the struct func (dep *DefaultEntryPoints) Type() string { return fmt.Sprint("defaultentrypoints²") @@ -75,6 +86,7 @@ type EntryPoints map[string]*EntryPoint // 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 (ep *EntryPoints) String() string { + //TODO : return "" } @@ -122,6 +134,14 @@ func (ep *EntryPoints) Set(value string) error { return nil } +// Get return the EntryPoints map +func (ep *EntryPoints) Get() interface{} { return EntryPoints(*ep) } + +// SetValue sets the EntryPoints map with val +func (ep *EntryPoints) SetValue(val interface{}) { + *ep = EntryPoints(val.(EntryPoints)) +} + // Type is type of the struct func (ep *EntryPoints) Type() string { return fmt.Sprint("entrypoints²") @@ -154,6 +174,7 @@ type Certificates []Certificate // The String method's output will be used in diagnostics. func (certs *Certificates) String() string { if len(*certs) == 0 { + //TODO : return "" } return (*certs)[0].CertFile + "," + (*certs)[0].KeyFile @@ -191,117 +212,96 @@ type Retry struct { MaxMem int64 } -// NewGlobalConfiguration returns a GlobalConfiguration with default values. -func NewGlobalConfiguration() *GlobalConfiguration { - return new(GlobalConfiguration) +// NewTraefikPointersConfiguration creates a TraefikConfiguration with pointers default values +func NewTraefikPointersConfiguration() *TraefikConfiguration { + //default Docker + var defaultDocker provider.Docker + defaultDocker.Watch = true + defaultDocker.Endpoint = "unix:///var/run/docker.sock" + defaultDocker.TLS = &provider.DockerTLS{} + + // default File + var defaultFile provider.File + defaultFile.Watch = true + defaultFile.Filename = "" //needs equivalent to viper.ConfigFileUsed() + + // default Web + var defaultWeb WebProvider + defaultWeb.Address = ":8080" + + // default Marathon + var defaultMarathon provider.Marathon + defaultMarathon.Watch = true + defaultMarathon.Endpoint = "http://127.0.0.1:8080" + defaultMarathon.ExposedByDefault = true + + // default Consul + var defaultConsul provider.Consul + defaultConsul.Watch = true + defaultConsul.Endpoint = "127.0.0.1:8500" + defaultConsul.Prefix = "/traefik" + defaultConsul.TLS = &provider.KvTLS{} + + // default ConsulCatalog + var defaultConsulCatalog provider.ConsulCatalog + defaultConsulCatalog.Endpoint = "127.0.0.1:8500" + + // default Etcd + var defaultEtcd provider.Etcd + defaultEtcd.Watch = true + defaultEtcd.Endpoint = "127.0.0.1:400" + defaultEtcd.Prefix = "/traefik" + defaultEtcd.TLS = &provider.KvTLS{} + + //default Zookeeper + var defaultZookeeper provider.Zookepper + defaultZookeeper.Watch = true + defaultZookeeper.Endpoint = "127.0.0.1:2181" + defaultZookeeper.Prefix = "/traefik" + + //default Boltdb + var defaultBoltDb provider.BoltDb + defaultBoltDb.Watch = true + defaultBoltDb.Endpoint = "127.0.0.1:4001" + defaultBoltDb.Prefix = "/traefik" + + //default Kubernetes + var defaultKubernetes provider.Kubernetes + defaultKubernetes.Watch = true + defaultKubernetes.Endpoint = "127.0.0.1:8080" + + defaultConfiguration := GlobalConfiguration{ + Docker: &defaultDocker, + File: &defaultFile, + Web: &defaultWeb, + Marathon: &defaultMarathon, + Consul: &defaultConsul, + ConsulCatalog: &defaultConsulCatalog, + Etcd: &defaultEtcd, + Zookeeper: &defaultZookeeper, + Boltdb: &defaultBoltDb, + Kubernetes: &defaultKubernetes, + } + return &TraefikConfiguration{ + GlobalConfiguration: defaultConfiguration, + } } -// LoadConfiguration returns a GlobalConfiguration. -func LoadConfiguration() *GlobalConfiguration { - configuration := NewGlobalConfiguration() - 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) +// NewTraefikConfiguration creates a TraefikConfiguration with default values +func NewTraefikConfiguration() *TraefikConfiguration { + return &TraefikConfiguration{ + GlobalConfiguration: GlobalConfiguration{ + GraceTimeOut: 10, + AccessLogsFile: "log/access.log", + TraefikLogsFile: "log/traefik.log", + LogLevel: "ERROR", + EntryPoints: map[string]*EntryPoint{"http": &EntryPoint{Address: ":80"}}, + DefaultEntryPoints: []string{"http"}, + ProvidersThrottleDuration: time.Duration(2 * time.Second), + MaxIdleConnsPerHost: 200, + }, + ConfigFile: "", } - 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 - if err := viper.ReadInConfig(); err != nil { - if len(viper.ConfigFileUsed()) > 0 { - fmtlog.Printf("Error reading configuration file: %s", err) - } else { - fmtlog.Printf("No configuration file found") - } - } - - if len(arguments.EntryPoints) > 0 { - viper.Set("entryPoints", arguments.EntryPoints) - } - if len(arguments.DefaultEntryPoints) > 0 { - viper.Set("defaultEntryPoints", arguments.DefaultEntryPoints) - } - 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.consulTLS { - arguments.Consul.TLS = nil - } - if arguments.consul { - viper.Set("consul", arguments.Consul) - } - if arguments.consulCatalog { - viper.Set("consulCatalog", arguments.ConsulCatalog) - } - if arguments.zookeeper { - viper.Set("zookeeper", arguments.Zookeeper) - } - if !arguments.etcdTLS { - arguments.Etcd.TLS = nil - } - if arguments.etcd { - viper.Set("etcd", arguments.Etcd) - } - if arguments.boltdb { - viper.Set("boltdb", arguments.Boltdb) - } - if arguments.kubernetes { - viper.Set("kubernetes", arguments.Kubernetes) - } - if err := unmarshal(&configuration); err != nil { - - fmtlog.Fatalf("Error reading file: %s", err) - } - - if len(configuration.EntryPoints) == 0 { - configuration.EntryPoints = make(map[string]*EntryPoint) - configuration.EntryPoints["http"] = &EntryPoint{ - Address: ":80", - } - configuration.DefaultEntryPoints = []string{"http"} - } - - if configuration.File != nil && len(configuration.File.Filename) == 0 { - // no filename, setting to global config file - configuration.File.Filename = viper.ConfigFileUsed() - } - - return configuration -} - -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 } type configs map[string]*types.Configuration diff --git a/flaeg_test.go b/flaeg_test.go new file mode 100644 index 000000000..bbf36c42d --- /dev/null +++ b/flaeg_test.go @@ -0,0 +1,91 @@ +package main + +import ( + "github.com/cocap10/flaeg" + "reflect" + "testing" + "time" +) + +func TestLoad(t *testing.T) { + var configuration GlobalConfiguration + defaultConfiguration := NewGlobalConfiguration() + args := []string{ + // "-h", + "--docker", + "--file", + "--web", + "--marathon", + "--consul", + "--consulcatalog", + "--etcd", + "--zookeeper", + "--boltdb", + } + if err := flaeg.Load(&configuration, defaultConfiguration, args); err != nil { + t.Fatalf("Error: %s", err) + } + // fmt.Printf("result : \n%+v\n", configuration) + if !reflect.DeepEqual(configuration, *defaultConfiguration) { + t.Fatalf("\nexpected\t: %+v\ngot\t\t\t: %+v", *defaultConfiguration, configuration) + } +} + +func TestLoadWithParsers(t *testing.T) { + var configuration GlobalConfiguration + defaultConfiguration := NewGlobalConfiguration() + args := []string{ + // "-h", + "--docker", + // "--file", + "--web.address=:8888", + "--marathon", + "--consul", + "--consulcatalog", + "--etcd.tls.insecureskipverify", + "--zookeeper", + "--boltdb", + "--accesslogsfile=log2/access.log", + "--entrypoints=Name:http Address::8000 Redirect.EntryPoint:https", + "--entrypoints=Name:https Address::8443 Redirect.EntryPoint:http", + "--defaultentrypoints=https", + "--defaultentrypoints=ssh", + "--providersthrottleduration=4s", + } + parsers := map[reflect.Type]flaeg.Parser{} + var defaultEntryPointsParser DefaultEntryPoints + parsers[reflect.TypeOf(DefaultEntryPoints{})] = &defaultEntryPointsParser + entryPointsParser := EntryPoints{} + parsers[reflect.TypeOf(EntryPoints{})] = &entryPointsParser + + if err := flaeg.LoadWithParsers(&configuration, defaultConfiguration, args, parsers); err != nil { + t.Fatalf("Error: %s", err) + } + // fmt.Printf("result : \n%+v\n", configuration) + + //Check + check := *defaultConfiguration + check.File = nil + check.Web.Address = ":8888" + check.AccessLogsFile = "log2/access.log" + check.Etcd.TLS.InsecureSkipVerify = true + check.EntryPoints = make(map[string]*EntryPoint) + check.EntryPoints["http"] = &EntryPoint{ + Address: ":8000", + Redirect: &Redirect{ + EntryPoint: "https", + }, + } + check.EntryPoints["https"] = &EntryPoint{ + Address: ":8443", + Redirect: &Redirect{ + EntryPoint: "http", + }, + } + check.DefaultEntryPoints = []string{"https", "ssh"} + check.ProvidersThrottleDuration = time.Duration(4 * time.Second) + + if !reflect.DeepEqual(&configuration, &check) { + t.Fatalf("\nexpected\t: %+v\ngot\t\t\t: %+v", check, configuration) + } +} diff --git a/provider/boltdb.go b/provider/boltdb.go index 0f941627e..966a4b8da 100644 --- a/provider/boltdb.go +++ b/provider/boltdb.go @@ -9,7 +9,7 @@ import ( // BoltDb holds configurations of the BoltDb provider. type BoltDb struct { - Kv `mapstructure:",squash"` + Kv `mapstructure:",squash" description:"go through"` } // Provide allows the provider to provide configurations to traefik diff --git a/provider/consul.go b/provider/consul.go index a2df6852b..d6d81f3e7 100644 --- a/provider/consul.go +++ b/provider/consul.go @@ -9,7 +9,7 @@ import ( // Consul holds configurations of the Consul provider. type Consul struct { - Kv `mapstructure:",squash"` + Kv `mapstructure:",squash" description:"go through"` } // Provide allows the provider to provide configurations to traefik diff --git a/provider/consul_catalog.go b/provider/consul_catalog.go index 90606e9d4..c17cfe0a9 100644 --- a/provider/consul_catalog.go +++ b/provider/consul_catalog.go @@ -24,8 +24,8 @@ const ( // ConsulCatalog holds configurations of the Consul catalog provider. type ConsulCatalog struct { BaseProvider `mapstructure:",squash"` - Endpoint string - Domain string + Endpoint string `description:"Consul server endpoint"` + Domain string `description:"Default domain used"` client *api.Client Prefix string } diff --git a/provider/docker.go b/provider/docker.go index 7169f20e1..55b73f8b6 100644 --- a/provider/docker.go +++ b/provider/docker.go @@ -30,17 +30,17 @@ const DockerAPIVersion string = "1.21" // Docker holds configurations of the Docker provider. type Docker struct { BaseProvider `mapstructure:",squash"` - Endpoint string - Domain string - TLS *DockerTLS + Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint"` + Domain string `description:"Default domain used"` + TLS *DockerTLS `description:"Enable Docker TLS support"` } // DockerTLS holds TLS specific configurations type DockerTLS struct { - CA string - Cert string - Key string - InsecureSkipVerify bool + CA string `description:"TLS CA"` + Cert string `description:"TLS cert"` + Key string `description:"TLS key"` + InsecureSkipVerify bool `description:"TLS insecure skip verify"` } func (provider *Docker) createClient() (client.APIClient, error) { diff --git a/provider/etcd.go b/provider/etcd.go index 3d0b9e428..3344245e4 100644 --- a/provider/etcd.go +++ b/provider/etcd.go @@ -9,7 +9,7 @@ import ( // Etcd holds configurations of the Etcd provider. type Etcd struct { - Kv `mapstructure:",squash"` + Kv `mapstructure:",squash" description:"go through"` } // Provide allows the provider to provide configurations to traefik diff --git a/provider/file.go b/provider/file.go index 6b943b199..c5597ec19 100644 --- a/provider/file.go +++ b/provider/file.go @@ -14,7 +14,7 @@ import ( // File holds configurations of the File provider. type File struct { - BaseProvider `mapstructure:",squash"` + BaseProvider `mapstructure:",squash" description:"go through"` } // Provide allows the provider to provide configurations to traefik diff --git a/provider/kubernetes.go b/provider/kubernetes.go index abb527af6..bdaf245ce 100644 --- a/provider/kubernetes.go +++ b/provider/kubernetes.go @@ -20,12 +20,15 @@ const ( serviceAccountCACert = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" ) +// Namespaces holds kubernetes namespaces +type Namespaces []string + // Kubernetes holds configurations of the Kubernetes provider. type Kubernetes struct { BaseProvider `mapstructure:",squash"` - Endpoint string - disablePassHostHeaders bool - Namespaces []string + Endpoint string `description:"Kubernetes server endpoint"` + DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers"` + Namespaces Namespaces `description:"Kubernetes namespaces"` } func (provider *Kubernetes) createClient() (k8s.Client, error) { @@ -259,7 +262,7 @@ func equalPorts(servicePort k8s.ServicePort, ingressPort k8s.IntOrString) bool { } func (provider *Kubernetes) getPassHostHeader() bool { - if provider.disablePassHostHeaders { + if provider.DisablePassHostHeaders { return false } return true diff --git a/provider/kv.go b/provider/kv.go index b257fd71e..852799dcb 100644 --- a/provider/kv.go +++ b/provider/kv.go @@ -22,20 +22,20 @@ import ( // Kv holds common configurations of key-value providers. type Kv struct { - BaseProvider `mapstructure:",squash"` - Endpoint string - Prefix string - TLS *KvTLS + BaseProvider `mapstructure:",squash" description:"go through"` + Endpoint string `description:"Comma sepparated server endpoints"` + Prefix string `description:"Prefix used for KV store"` + TLS *KvTLS `description:"Enable TLS support"` storeType store.Backend kvclient store.Store } // KvTLS holds TLS specific configurations type KvTLS struct { - CA string - Cert string - Key string - InsecureSkipVerify bool + CA string `description:"TLS CA"` + Cert string `description:"TLS cert"` + Key string `description:"TLS key"` + InsecureSkipVerify bool `description:"TLS insecure skip verify"` } func (provider *Kv) watchKv(configurationChan chan<- types.ConfigMessage, prefix string, stop chan bool) error { diff --git a/provider/marathon.go b/provider/marathon.go index 63ba9d8c0..91b4a2e8d 100644 --- a/provider/marathon.go +++ b/provider/marathon.go @@ -20,10 +20,10 @@ import ( // Marathon holds configuration of the Marathon provider. type Marathon struct { - BaseProvider `mapstructure:",squash"` - Endpoint string - Domain string - ExposedByDefault bool + BaseProvider `mapstructure:",squash" description:"go through"` + Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon"` + Domain string `description:"Default domain used"` + ExposedByDefault bool `description:"Expose Marathon apps by default"` Basic *MarathonBasic TLS *tls.Config marathonClient marathon.Marathon @@ -36,8 +36,8 @@ type MarathonBasic struct { } type lightMarathonClient interface { - Applications(url.Values) (*marathon.Applications, error) AllTasks(v url.Values) (*marathon.Tasks, error) + Applications(url.Values) (*marathon.Applications, error) } // Provide allows the provider to provide configurations to traefik diff --git a/provider/provider.go b/provider/provider.go index 3fa7612ec..eddf5a76c 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -22,8 +22,8 @@ type Provider interface { // BaseProvider should be inherited by providers type BaseProvider struct { - Watch bool - Filename string + Watch bool `description:"Watch provider"` + Filename string `description:"Override default configuration template. For advanced users :)"` } func (p *BaseProvider) getConfiguration(defaultTemplateFile string, funcMap template.FuncMap, templateObjects interface{}) (*types.Configuration, error) { diff --git a/provider/zk.go b/provider/zk.go index 77b28100f..e8164a75f 100644 --- a/provider/zk.go +++ b/provider/zk.go @@ -9,7 +9,7 @@ import ( // Zookepper holds configurations of the Zookepper provider. type Zookepper struct { - Kv + Kv `description:"go through"` } // Provide allows the provider to provide configurations to traefik diff --git a/traefik.go b/traefik.go index dec978a6f..a1c060914 100644 --- a/traefik.go +++ b/traefik.go @@ -1,16 +1,111 @@ package main import ( + "encoding/json" + log "github.com/Sirupsen/logrus" + "github.com/containous/flaeg" + "github.com/containous/staert" + "github.com/containous/traefik/middlewares" fmtlog "log" + "net/http" "os" + "reflect" "runtime" + "strings" ) func main() { runtime.GOMAXPROCS(runtime.NumCPU()) - if err := traefikCmd.Execute(); err != nil { + + //traefik config inits + traefikConfiguration := NewTraefikConfiguration() + traefikPointersConfiguration := NewTraefikPointersConfiguration() + //traefik Command init + traefikCmd := &flaeg.Command{ + Name: "traefik", + Description: `traefik is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. +Complete documentation is available at https://traefik.io`, + Config: traefikConfiguration, + DefaultPointersConfig: traefikPointersConfiguration, + Run: func() error { + run(traefikConfiguration) + return nil + }, + } + + //version Command init + versionCmd := &flaeg.Command{ + Name: "version", + Description: `Print version`, + Run: func() error { + fmtlog.Println(Version + " built on the " + BuildDate) + return nil + }, + } + + //staert init + s := staert.NewStaert(traefikCmd) + + //init toml source + toml := staert.NewTomlSource("traefik", []string{traefikConfiguration.ConfigFile, "/etc/traefik/", "$HOME/.traefik/", "."}) + //init flaeg source + f := flaeg.New(traefikCmd, os.Args[1:]) + //add custom parsers + f.AddParser(reflect.TypeOf(EntryPoints{}), &EntryPoints{}) + f.AddParser(reflect.TypeOf(DefaultEntryPoints{}), &DefaultEntryPoints{}) + //Wait for DefaultSliceStringParser + //add version command + f.AddCommand(versionCmd) + + //add sources to staert + s.AddSource(f) + s.AddSource(toml) + s.AddSource(f) + if err := s.Run(); err != nil { fmtlog.Println(err) os.Exit(-1) } + os.Exit(0) } + +func run(traefikConfiguration *TraefikConfiguration) { + fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags) + + // load global configuration + globalConfiguration := traefikConfiguration.GlobalConfiguration + + http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = globalConfiguration.MaxIdleConnsPerHost + loggerMiddleware := middlewares.NewLogger(globalConfiguration.AccessLogsFile) + defer loggerMiddleware.Close() + + // logging + level, err := log.ParseLevel(strings.ToLower(globalConfiguration.LogLevel)) + if err != nil { + log.Fatal("Error getting level", err) + } + log.SetLevel(level) + + if len(globalConfiguration.TraefikLogsFile) > 0 { + fi, err := os.OpenFile(globalConfiguration.TraefikLogsFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + defer func() { + if err := fi.Close(); err != nil { + log.Error("Error closinf file", err) + } + }() + if err != nil { + log.Fatal("Error opening file", err) + } else { + log.SetOutput(fi) + log.SetFormatter(&log.TextFormatter{DisableColors: true, FullTimestamp: true, DisableSorting: true}) + } + } else { + log.SetFormatter(&log.TextFormatter{FullTimestamp: true, DisableSorting: true}) + } + jsonConf, _ := json.Marshal(globalConfiguration) + log.Debugf("Global configuration loaded %s", string(jsonConf)) + server := NewServer(globalConfiguration) + server.Start() + defer server.Close() + log.Info("Shutting down") +} diff --git a/web.go b/web.go index f32874aa6..bf77685a4 100644 --- a/web.go +++ b/web.go @@ -23,10 +23,11 @@ var metrics = stats.New() // WebProvider is a provider.Provider implementation that provides the UI. // FIXME to be handled another way. type WebProvider struct { - Address string - CertFile, KeyFile string - ReadOnly bool - server *Server + Address string `description:"Web administration port"` + CertFile string `description:"SSL certificate"` + KeyFile string `description:"SSL certificate"` + ReadOnly bool `description:"Enable read only API"` + server *Server } var ( From 414fb1f406951f17226fda57172c574cd55dc4e1 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 18 May 2016 15:45:48 +0200 Subject: [PATCH 02/16] add kubernetes.Namespaces parser --- provider/kubernetes.go | 24 ++++++++++++++++++++++++ traefik.go | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/provider/kubernetes.go b/provider/kubernetes.go index bdaf245ce..3dd3e9e4e 100644 --- a/provider/kubernetes.go +++ b/provider/kubernetes.go @@ -1,6 +1,7 @@ package provider import ( + "fmt" log "github.com/Sirupsen/logrus" "github.com/cenkalti/backoff" "github.com/containous/traefik/provider/k8s" @@ -23,6 +24,29 @@ const ( // Namespaces holds kubernetes namespaces type Namespaces []string +//Set adds strings elem into the the parser +//it splits str on , and ; +func (ns *Namespaces) Set(str string) error { + fargs := func(c rune) bool { + return c == ',' || c == ';' + } + // get function + slice := strings.FieldsFunc(str, fargs) + *ns = append(*ns, slice...) + return nil +} + +//Get []string +func (ns *Namespaces) Get() interface{} { return Namespaces(*ns) } + +//String return slice in a string +func (ns *Namespaces) String() string { return fmt.Sprintf("%v", *ns) } + +//SetValue sets []string into the parser +func (ns *Namespaces) SetValue(val interface{}) { + *ns = Namespaces(val.(Namespaces)) +} + // Kubernetes holds configurations of the Kubernetes provider. type Kubernetes struct { BaseProvider `mapstructure:",squash"` diff --git a/traefik.go b/traefik.go index a1c060914..b0e2cb745 100644 --- a/traefik.go +++ b/traefik.go @@ -6,6 +6,7 @@ import ( "github.com/containous/flaeg" "github.com/containous/staert" "github.com/containous/traefik/middlewares" + "github.com/containous/traefik/provider" fmtlog "log" "net/http" "os" @@ -53,7 +54,7 @@ Complete documentation is available at https://traefik.io`, //add custom parsers f.AddParser(reflect.TypeOf(EntryPoints{}), &EntryPoints{}) f.AddParser(reflect.TypeOf(DefaultEntryPoints{}), &DefaultEntryPoints{}) - //Wait for DefaultSliceStringParser + f.AddParser(reflect.TypeOf(provider.Namespaces{}), &provider.Namespaces{}) //add version command f.AddCommand(versionCmd) From e115e3c4e70b4f5a0aa83a35303450c17508d277 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 19 May 2016 17:12:36 +0200 Subject: [PATCH 03/16] fix default value --- configuration.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration.go b/configuration.go index 9b39d5db6..e54e49c90 100644 --- a/configuration.go +++ b/configuration.go @@ -292,8 +292,8 @@ func NewTraefikConfiguration() *TraefikConfiguration { return &TraefikConfiguration{ GlobalConfiguration: GlobalConfiguration{ GraceTimeOut: 10, - AccessLogsFile: "log/access.log", - TraefikLogsFile: "log/traefik.log", + AccessLogsFile: "", + TraefikLogsFile: "", LogLevel: "ERROR", EntryPoints: map[string]*EntryPoint{"http": &EntryPoint{Address: ":80"}}, DefaultEntryPoints: []string{"http"}, From 629be45c4a779ea7553a80abacdeb6a31b5682c1 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 19 May 2016 17:44:33 +0200 Subject: [PATCH 04/16] fix DisablePassHostHeaders --- provider/kubernetes_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/provider/kubernetes_test.go b/provider/kubernetes_test.go index 2e31a7df9..8426b73ad 100644 --- a/provider/kubernetes_test.go +++ b/provider/kubernetes_test.go @@ -416,7 +416,7 @@ func TestRuleType(t *testing.T) { services: services, watchChan: watchChan, } - provider := Kubernetes{disablePassHostHeaders: true} + provider := Kubernetes{DisablePassHostHeaders: true} actualConfig, err := provider.loadIngresses(client) actual := actualConfig.Frontends if err != nil { @@ -538,7 +538,7 @@ func TestGetPassHostHeader(t *testing.T) { services: services, watchChan: watchChan, } - provider := Kubernetes{disablePassHostHeaders: true} + provider := Kubernetes{DisablePassHostHeaders: true} actual, err := provider.loadIngresses(client) if err != nil { t.Fatalf("error %+v", err) From 1e27c2dabe9cbaa63493b86559d43f8ada19aebf Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 24 May 2016 14:23:42 +0200 Subject: [PATCH 05/16] fix TestNoOrInexistentConfigShouldNotFail --- integration/basic_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integration/basic_test.go b/integration/basic_test.go index 40f5ab997..0e7220279 100644 --- a/integration/basic_test.go +++ b/integration/basic_test.go @@ -15,7 +15,7 @@ import ( // SimpleSuite type SimpleSuite struct{ BaseSuite } -func (s *SimpleSuite) TestNoOrInexistentConfigShouldFail(c *check.C) { +func (s *SimpleSuite) TestNoOrInexistentConfigShouldNotFail(c *check.C) { cmd := exec.Command(traefikBinary) var b bytes.Buffer @@ -26,7 +26,7 @@ func (s *SimpleSuite) TestNoOrInexistentConfigShouldFail(c *check.C) { time.Sleep(500 * time.Millisecond) output := b.Bytes() - c.Assert(string(output), checker.Contains, "No configuration file found") + c.Assert(string(output), checker.Not(checker.Contains), "No configuration file found") cmd.Process.Kill() nonExistentFile := "non/existent/file.toml" @@ -39,7 +39,7 @@ func (s *SimpleSuite) TestNoOrInexistentConfigShouldFail(c *check.C) { time.Sleep(500 * time.Millisecond) output = b.Bytes() - c.Assert(string(output), checker.Contains, fmt.Sprintf("Error reading configuration file: open %s: no such file or directory", nonExistentFile)) + c.Assert(string(output), checker.Not(checker.Contains), fmt.Sprintf("Error reading configuration file: open %s: no such file or directory", nonExistentFile)) cmd.Process.Kill() } @@ -55,7 +55,7 @@ func (s *SimpleSuite) TestInvalidConfigShouldFail(c *check.C) { defer cmd.Process.Kill() output := b.Bytes() - c.Assert(string(output), checker.Contains, "While parsing config: Near line 0 (last key parsed ''): Bare keys cannot contain '{'") + c.Assert(string(output), checker.Contains, "Near line 0 (last key parsed ''): Bare keys cannot contain '{'") } func (s *SimpleSuite) TestSimpleDefaultConfig(c *check.C) { From 1a0f347023b32dc687b1206ec08e50ce6a6ae8e2 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 24 May 2016 14:58:25 +0200 Subject: [PATCH 06/16] update default value --- configuration.go | 6 +++--- traefik.go | 33 +++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/configuration.go b/configuration.go index e54e49c90..daa037246 100644 --- a/configuration.go +++ b/configuration.go @@ -77,7 +77,7 @@ func (dep *DefaultEntryPoints) SetValue(val interface{}) { // Type is type of the struct func (dep *DefaultEntryPoints) Type() string { - return fmt.Sprint("defaultentrypoints²") + return fmt.Sprint("defaultentrypoints") } // EntryPoints holds entry points configuration of the reverse proxy (ip, port, TLS...) @@ -295,8 +295,8 @@ func NewTraefikConfiguration() *TraefikConfiguration { AccessLogsFile: "", TraefikLogsFile: "", LogLevel: "ERROR", - EntryPoints: map[string]*EntryPoint{"http": &EntryPoint{Address: ":80"}}, - DefaultEntryPoints: []string{"http"}, + EntryPoints: map[string]*EntryPoint{}, + DefaultEntryPoints: []string{}, ProvidersThrottleDuration: time.Duration(2 * time.Second), MaxIdleConnsPerHost: 200, }, diff --git a/traefik.go b/traefik.go index b0e2cb745..adb5c4475 100644 --- a/traefik.go +++ b/traefik.go @@ -36,19 +36,16 @@ Complete documentation is available at https://traefik.io`, //version Command init versionCmd := &flaeg.Command{ - Name: "version", - Description: `Print version`, + Name: "version", + Description: `Print version`, + Config: struct{}{}, + DefaultPointersConfig: struct{}{}, Run: func() error { fmtlog.Println(Version + " built on the " + BuildDate) return nil }, } - //staert init - s := staert.NewStaert(traefikCmd) - - //init toml source - toml := staert.NewTomlSource("traefik", []string{traefikConfiguration.ConfigFile, "/etc/traefik/", "$HOME/.traefik/", "."}) //init flaeg source f := flaeg.New(traefikCmd, os.Args[1:]) //add custom parsers @@ -57,11 +54,31 @@ Complete documentation is available at https://traefik.io`, f.AddParser(reflect.TypeOf(provider.Namespaces{}), &provider.Namespaces{}) //add version command f.AddCommand(versionCmd) + if _, err := f.Parse(traefikCmd); err != nil { + fmtlog.Println(err) + os.Exit(-1) + } + + //staert init + s := staert.NewStaert(traefikCmd) + //init toml source + toml := staert.NewTomlSource("traefik", []string{traefikConfiguration.ConfigFile, "/etc/traefik/", "$HOME/.traefik/", "."}) //add sources to staert - s.AddSource(f) s.AddSource(toml) s.AddSource(f) + if _, err := s.GetConfig(); err != nil { + fmtlog.Println(err) + } + if traefikConfiguration.File != nil && len(traefikConfiguration.File.Filename) == 0 { + // no filename, setting to global config file + log.Debugf("ConfigFileUsed %s", toml.ConfigFileUsed()) + traefikConfiguration.File.Filename = toml.ConfigFileUsed() + } + if len(traefikConfiguration.EntryPoints) == 0 { + traefikConfiguration.EntryPoints = map[string]*EntryPoint{"http": &EntryPoint{Address: ":80"}} + traefikConfiguration.DefaultEntryPoints = []string{"http"} + } if err := s.Run(); err != nil { fmtlog.Println(err) os.Exit(-1) From 89e00eb5a452f0a4e2e7f5767a3e0fc0e6f157c8 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 24 May 2016 14:59:18 +0200 Subject: [PATCH 07/16] add staert & fleag --- glide.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/glide.yaml b/glide.yaml index 3ca22fb8c..7d9d76ba8 100644 --- a/glide.yaml +++ b/glide.yaml @@ -187,3 +187,6 @@ import: - package: github.com/parnurzeal/gorequest - package: github.com/mattn/go-shellwords - package: github.com/moul/http2curl +- package: github.com/containous/flaeg +- package: github.com/containous/staert +- package: github.com/ogier/pflag From 0821c7bdd9c72521a756184142cbd098e070227d Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 24 May 2016 15:45:20 +0200 Subject: [PATCH 08/16] Add version in logs --- traefik.go | 1 + 1 file changed, 1 insertion(+) diff --git a/traefik.go b/traefik.go index adb5c4475..636514f2d 100644 --- a/traefik.go +++ b/traefik.go @@ -121,6 +121,7 @@ func run(traefikConfiguration *TraefikConfiguration) { log.SetFormatter(&log.TextFormatter{FullTimestamp: true, DisableSorting: true}) } jsonConf, _ := json.Marshal(globalConfiguration) + log.Infof("Traefik version %s built on %s", Version, BuildDate) log.Debugf("Global configuration loaded %s", string(jsonConf)) server := NewServer(globalConfiguration) server.Start() From 059da90a96565cdbd506b5b4c2dcbf4ff6806e50 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 24 May 2016 15:45:41 +0200 Subject: [PATCH 09/16] clean glide dependancies --- glide.lock | 172 +++++++++++----------------------------- glide.yaml | 228 +++++++++++++---------------------------------------- 2 files changed, 103 insertions(+), 297 deletions(-) diff --git a/glide.lock b/glide.lock index b52394f42..a88e1030c 100644 --- a/glide.lock +++ b/glide.lock @@ -1,39 +1,40 @@ -hash: 68bc4f87206f9a486e1455f1dfcad737369c359a803566271432fcb85de3a12c -updated: 2016-05-23T13:57:35.191541555+02:00 +hash: 50e873651126f0af9204fd8cc11f10917ce56b76479310ada578f5487162e0c4 +updated: 2016-05-24T15:42:45.810673781+02:00 imports: -- name: github.com/alecthomas/template - version: b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0 -- name: github.com/alecthomas/units - version: 6b4e7dc5e3143b85ea77909c72caf89416fc2915 - name: github.com/boltdb/bolt - version: 51f99c862475898df9773747d3accd05a7ca33c1 + version: dfb21201d9270c1082d5fb0f07f500311ff72f18 - name: github.com/BurntSushi/toml - version: bbd5bb678321a0d6e58f1099321dfa73391c1b6f + version: f0aeabca5a127c4078abb8c8d64298b147264b55 - name: github.com/BurntSushi/ty version: 6add9cd6ad42d389d6ead1dde60b4ad71e46fd74 subpackages: - fun - name: github.com/cenkalti/backoff - version: 4dc77674aceaabba2c7e3da25d4c823edfb73f99 + version: c29158af31815ccc31ca29c86c121bc39e00d3d8 - name: github.com/codahale/hdrhistogram - version: 954f16e8b9ef0e5d5189456aa4c1202758e04f17 + version: 9208b142303c12d8899bae836fd524ac9338b4fd - name: github.com/codegangsta/cli version: bf4a526f48af7badd25d2cb02d587e1b01be3b50 - name: github.com/codegangsta/negroni - version: c7477ad8e330bef55bf1ebe300cf8aa67c492d1b + version: ffbc66b612ee3eac2eba29aedce4c3a65e4dd0a1 +- name: github.com/containous/flaeg + version: e390ea90e4ee21ff73fb1630b8c50a843a6d7674 - name: github.com/containous/oxy version: 183212964e13e7b8afe01a08b193d04300554a68 subpackages: - cbreaker - - forward - - memmetrics - - roundrobin - - utils - connlimit + - forward + - roundrobin - stream + - utils +- name: github.com/containous/staert + version: f0da5ea8404f0d3999d72ba8f8736d3aa4b8c8f1 - name: github.com/coreos/etcd - version: 26e52d2bce9e3e11b77b68cc84bf91aebb1ef637 + version: c400d05d0aa73e21e431c16145e558d624098018 subpackages: + - Godeps/_workspace/src/github.com/ugorji/go/codec + - Godeps/_workspace/src/golang.org/x/net/context - client - pkg/pathutil - pkg/types @@ -42,72 +43,37 @@ imports: subpackages: - spew - name: github.com/docker/distribution - version: 467fc068d88aa6610691b7f1a677271a3fac4aac + version: 5bbf65499960b184fe8e0f045397375e1a6722b8 subpackages: - reference - digest - name: github.com/docker/docker version: 9837ec4da53f15f9120d53a6e1517491ba8b0261 subpackages: - - autogen - - api - - cliconfig - - daemon/network - - graph/tags - - image - - opts - - pkg/archive - - pkg/fileutils - - pkg/homedir - - pkg/httputils - - pkg/ioutils - - pkg/jsonmessage - - pkg/mflag - - pkg/nat - - pkg/parsers - - pkg/pools - - pkg/promise - - pkg/random - - pkg/stdcopy - - pkg/stringid - - pkg/symlink - - pkg/system - - pkg/tarsum - - pkg/term - - pkg/timeutils - - pkg/tlsconfig - - pkg/ulimit - - pkg/units - - pkg/urlutil - - pkg/useragent - - pkg/version - - registry - - runconfig - - utils - - volume + - namesgenerator - name: github.com/docker/engine-api version: 3d3d0b6c9d2651aac27f416a6da0224c1875b3eb subpackages: - client - types - - types/container - - types/filters - - types/strslice - types/events + - types/filters - client/transport - client/transport/cancellable + - types/container - types/network - types/reference - types/registry - types/time - types/versions - types/blkiodev + - types/strslice - name: github.com/docker/go-connections version: c7838b258fbfa3fe88eecfb2a0e08ea0dbd6a646 subpackages: - - nat - sockets - tlsconfig + - nat - name: github.com/docker/go-units version: 5d2041e26a699eaca682e2ea41c8f891e1060444 - name: github.com/docker/libcompose @@ -120,61 +86,39 @@ imports: - store/consul - store/etcd - store/zookeeper -- name: github.com/docker/libtrust - version: 9cbd2a1374f46905c68a4eb3694a130610adc62a - name: github.com/donovanhide/eventsource - version: d8a3071799b98cacd30b6da92f536050ccfe6da4 + version: c3f57f280ec708df24886d9e62f2fd178d69d8e8 - name: github.com/elazarl/go-bindata-assetfs - version: d5cac425555ca5cf00694df246e04f05e6a55150 -- name: github.com/flynn/go-shlex - version: 3f9db97f856818214da2e1057f8ad84803971cff + version: 57eb5e1fc594ad4b0b1dbea7b286d299e0cb43c2 - name: github.com/gambol99/go-marathon version: ade11d1dc2884ee1f387078fc28509559b6235d1 - name: github.com/go-check/check - version: 11d3bc7aa68e238947792f30573146a3231fc0f1 -- name: github.com/golang/glog - version: fca8c8854093a154ff1eb580aae10276ad6b1b5f + version: 4f90aeace3a26ad7021961c297b22c42160c7b25 - name: github.com/google/go-querystring version: 9235644dd9e52eeae6fa48efd539fdc351a0af53 subpackages: - query - name: github.com/gorilla/context - version: 215affda49addc4c8ef7e2534915df2c8c35c6cd -- name: github.com/gorilla/handlers - version: 40694b40f4a928c062f56849989d3e9cd0570e5f + version: a8d44e7d8e4d532b6a27a02dd82abb31cc1b01bd - name: github.com/gorilla/mux - version: f15e0c49460fd49eebe2bcc8486b05d1bef68d3a -- name: github.com/gorilla/websocket - version: 1f512fc3f05332ba7117626cdfb4e07474e58e60 + version: 9c19ed558d5df4da88e2ade9c8940d742aef0e7e - name: github.com/hashicorp/consul - version: de080672fee9e6104572eeea89eccdca135bb918 + version: f6fef66e1bf17be4f3c9855fbec6de802ca6bd7d subpackages: - api -- name: github.com/hashicorp/hcl - version: 9a905a34e6280ce905da1a32344b25e81011197a +- name: github.com/hashicorp/go-cleanhttp + version: 875fb671b3ddc66f8e2f0acc33829c8cb989a38d +- name: github.com/hashicorp/serf + version: e4ec8cc423bbe20d26584b96efbeb9102e16d05f subpackages: - - hcl/ast - - hcl/parser - - hcl/token - - json/parser - - hcl/scanner - - hcl/strconv - - json/scanner - - json/token -- name: github.com/inconshreveable/mousetrap - version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 -- name: github.com/kr/pretty - version: add1dbc86daf0f983cd4a48ceb39deb95c729b67 -- name: github.com/kr/text - version: 7cafcd837844e784b526369c9bce262804aebc60 + - coordinate + - serf - name: github.com/libkermit/docker version: 3b5eb2973efff7af33cfb65141deaf4ed25c6d02 - name: github.com/libkermit/docker-check version: bb75a86b169c6c5d22c0ee98278124036f272d7b -- name: github.com/magiconair/properties - version: c265cfa48dda6474e208715ca93e987829f572f8 - name: github.com/mailgun/log - version: 44874009257d4d47ba9806f1b7f72a32a015e4d8 + version: 2f35a4607f1abf71f97f77f99b0de8493ef6f4ef - name: github.com/mailgun/manners version: fada45142db3f93097ca917da107aa3fad0ffcb5 - name: github.com/mailgun/multibuf @@ -187,12 +131,12 @@ imports: version: 4f1a71750d95a5a8a46c40a67ffbed8129c2f138 - name: github.com/miekg/dns version: 48ab6605c66ac797e07f615101c3e9e10e932b66 -- name: github.com/mitchellh/mapstructure - version: d2dd0262208475919e1a362f675cfc0e7c10e905 - name: github.com/moul/http2curl version: b1479103caacaa39319f75e7f57fc545287fca0d +- name: github.com/ogier/pflag + version: 45c278ab3607870051a2ea9040bb85fcb8557481 - name: github.com/opencontainers/runc - version: 2441732d6fcc0fb0a542671a4372e0c7bc99c19e + version: d2d09b9bcd0573c58d7cd94e57bd7555af0c2072 subpackages: - libcontainer/user - name: github.com/parnurzeal/gorequest @@ -202,25 +146,13 @@ imports: subpackages: - difflib - name: github.com/samuel/go-zookeeper - version: fa6674abf3f4580b946a01bf7a1ce4ba8766205b + version: 6eb1b09c6ce23f305f4c81bf748b22fbc6f3f9e9 subpackages: - zk - name: github.com/Sirupsen/logrus - version: 418b41d23a1bf978c06faea5313ba194650ac088 -- name: github.com/spf13/cast - version: ee7b3e0353166ab1f3a605294ac8cd2b77953778 -- name: github.com/spf13/cobra - version: f368244301305f414206f889b1735a54cfc8bde8 - subpackages: - - cobra -- name: github.com/spf13/jwalterweatherman - version: 33c24e77fb80341fe7130ee7c594256ff08ccc46 -- name: github.com/spf13/pflag - version: cb88ea77998c3f024757528e3305022ab50b43be -- name: github.com/spf13/viper - version: a212099cbe6fbe8d07476bfda8d2d39b6ff8f325 + version: 6d9ae300aaf85d6acd2e5424081c7fcddb21dab8 - name: github.com/streamrail/concurrent-map - version: 1ce4642e5a162df67825d273a86b87e6cc8a076b + version: 65a174a3a4188c0b7099acbc6cfa0c53628d3287 - name: github.com/stretchr/objx version: cbeaeb16a013161a98496fad62933b1d21786672 - name: github.com/stretchr/testify @@ -229,13 +161,9 @@ imports: - mock - assert - name: github.com/thoas/stats - version: 54ed61c2b47e263ae2f01b86837b0c4bd1da28e8 -- name: github.com/ugorji/go - version: ea9cd21fa0bc41ee4bdd50ac7ed8cbc7ea2ed960 - subpackages: - - codec + version: 69e3c072eec2df2df41afe6214f62eb940e4cd80 - name: github.com/unrolled/render - version: 26b4e3aac686940fe29521545afad9966ddfc80c + version: 198ad4d8b8a4612176b804ca10555b222a086b40 - name: github.com/vdemeester/docker-events version: b308d2e8d639d928c882913bcb4f85b3a84c7a07 - name: github.com/vdemeester/shakers @@ -255,8 +183,6 @@ imports: - plugin/rewrite - plugin - router -- name: github.com/wendal/errors - version: f66c77a7882b399795a8987ebf87ef64a427417e - name: github.com/xenolf/lego version: b119bc45fbd1cc71348003541aac9d3a7da63654 subpackages: @@ -266,7 +192,7 @@ imports: subpackages: - ocsp - name: golang.org/x/net - version: d9558e5c97f85372afee28cf2b6059d7d3818919 + version: 6460565bec1e8891e29ff478184c71b9e443ac36 subpackages: - context - publicsuffix @@ -276,12 +202,10 @@ imports: subpackages: - unix - windows -- name: gopkg.in/alecthomas/kingpin.v2 - version: 639879d6110b1b0409410c7b737ef0bb18325038 - name: gopkg.in/fsnotify.v1 - version: 96c060f6a6b7e0d6f75fddd10efeaca3e5d1bcb0 + version: 30411dbcefb7a1da7e84f75530ad3abe4011b4f8 - name: gopkg.in/mgo.v2 - version: 22287bab4379e1fbf6002fb4eb769888f3fb224c + version: b6e2fa371e64216a45e61072a96d4e3859f169da subpackages: - bson - name: gopkg.in/square/go-jose.v1 @@ -289,6 +213,4 @@ imports: subpackages: - cipher - json -- name: gopkg.in/yaml.v2 - version: 7ad95dd0798a40da1ccdff6dff35fd177b5edf40 devImports: [] diff --git a/glide.yaml b/glide.yaml index 7d9d76ba8..df8f8dcf5 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,192 +1,76 @@ -package: main +package: github.com/containous/traefik import: -- package: github.com/coreos/etcd - version: 26e52d2bce9e3e11b77b68cc84bf91aebb1ef637 +- package: github.com/BurntSushi/toml +- package: github.com/BurntSushi/ty subpackages: - - client -- package: github.com/mailgun/log - version: 44874009257d4d47ba9806f1b7f72a32a015e4d8 + - fun +- package: github.com/Sirupsen/logrus +- package: github.com/cenkalti/backoff +- package: github.com/codegangsta/negroni +- package: github.com/containous/flaeg - package: github.com/containous/oxy - version: 183212964e13e7b8afe01a08b193d04300554a68 subpackages: - cbreaker + - connlimit - forward - - memmetrics - roundrobin + - stream - utils -- package: github.com/hashicorp/consul - version: de080672fee9e6104572eeea89eccdca135bb918 - subpackages: - - api -- package: github.com/samuel/go-zookeeper - version: fa6674abf3f4580b946a01bf7a1ce4ba8766205b - subpackages: - - zk -- package: github.com/docker/libtrust - version: 9cbd2a1374f46905c68a4eb3694a130610adc62a -- package: github.com/go-check/check - version: 11d3bc7aa68e238947792f30573146a3231fc0f1 -- package: golang.org/x/net - version: d9558e5c97f85372afee28cf2b6059d7d3818919 - subpackages: - - context -- package: github.com/gorilla/handlers - version: 40694b40f4a928c062f56849989d3e9cd0570e5f -- package: github.com/docker/libkv - version: 7283ef27ed32fe267388510a91709b307bb9942c -- package: github.com/alecthomas/template - version: b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0 -- package: github.com/vdemeester/shakers - version: 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 -- package: github.com/alecthomas/units - version: 6b4e7dc5e3143b85ea77909c72caf89416fc2915 -- package: github.com/gambol99/go-marathon - version: ade11d1dc2884ee1f387078fc28509559b6235d1 -- package: github.com/vulcand/predicate - version: cb0bff91a7ab7cf7571e661ff883fc997bc554a3 -- package: github.com/thoas/stats - version: 54ed61c2b47e263ae2f01b86837b0c4bd1da28e8 -- package: github.com/Sirupsen/logrus - version: 418b41d23a1bf978c06faea5313ba194650ac088 -- package: github.com/unrolled/render - version: 26b4e3aac686940fe29521545afad9966ddfc80c -- package: github.com/flynn/go-shlex - version: 3f9db97f856818214da2e1057f8ad84803971cff -- package: github.com/boltdb/bolt - version: 51f99c862475898df9773747d3accd05a7ca33c1 -- package: gopkg.in/mgo.v2 - version: 22287bab4379e1fbf6002fb4eb769888f3fb224c - subpackages: - - bson -- package: github.com/docker/docker - version: 9837ec4da53f15f9120d53a6e1517491ba8b0261 - subpackages: - - autogen - - api - - cliconfig - - daemon/network - - graph/tags - - image - - opts - - pkg/archive - - pkg/fileutils - - pkg/homedir - - pkg/httputils - - pkg/ioutils - - pkg/jsonmessage - - pkg/mflag - - pkg/nat - - pkg/parsers - - pkg/pools - - pkg/promise - - pkg/random - - pkg/stdcopy - - pkg/stringid - - pkg/symlink - - pkg/system - - pkg/tarsum - - pkg/term - - pkg/timeutils - - pkg/tlsconfig - - pkg/ulimit - - pkg/units - - pkg/urlutil - - pkg/useragent - - pkg/version - - registry - - runconfig - - utils - - volume -- package: github.com/mailgun/timetools - version: fd192d755b00c968d312d23f521eb0cdc6f66bd0 -- package: github.com/codegangsta/negroni - version: c7477ad8e330bef55bf1ebe300cf8aa67c492d1b -- package: gopkg.in/yaml.v2 - version: 7ad95dd0798a40da1ccdff6dff35fd177b5edf -- package: github.com/opencontainers/runc - version: 2441732d6fcc0fb0a542671a4372e0c7bc99c19e - subpackages: - - libcontainer/user -- package: github.com/gorilla/mux - version: f15e0c49460fd49eebe2bcc8486b05d1bef68d3a -- package: github.com/BurntSushi/ty - version: 6add9cd6ad42d389d6ead1dde60b4ad71e46fd74 -- package: github.com/elazarl/go-bindata-assetfs - version: d5cac425555ca5cf00694df246e04f05e6a55150 -- package: github.com/BurntSushi/toml - version: bbd5bb678321a0d6e58f1099321dfa73391c1b6f -- package: gopkg.in/alecthomas/kingpin.v2 - version: 639879d6110b1b0409410c7b737ef0bb18325038 -- package: github.com/cenkalti/backoff - version: 4dc77674aceaabba2c7e3da25d4c823edfb73f99 -- package: gopkg.in/fsnotify.v1 - version: 96c060f6a6b7e0d6f75fddd10efeaca3e5d1bcb0 -- package: github.com/mailgun/manners - version: fada45142db3f93097ca917da107aa3fad0ffcb5 -- package: github.com/gorilla/context - version: 215affda49addc4c8ef7e2534915df2c8c35c6cd -- package: github.com/codahale/hdrhistogram - version: 954f16e8b9ef0e5d5189456aa4c1202758e04f17 -- package: github.com/gorilla/websocket -- package: github.com/donovanhide/eventsource - version: d8a3071799b98cacd30b6da92f536050ccfe6da4 -- package: github.com/golang/glog - version: fca8c8854093a154ff1eb580aae10276ad6b1b5f -- package: github.com/spf13/cast - version: ee7b3e0353166ab1f3a605294ac8cd2b77953778 -- package: github.com/mitchellh/mapstructure -- package: github.com/spf13/jwalterweatherman -- package: github.com/spf13/pflag -- package: github.com/wendal/errors -- package: github.com/hashicorp/hcl -- package: github.com/kr/pretty -- package: github.com/magiconair/properties -- package: github.com/kr/text -- package: github.com/spf13/viper - version: a212099cbe6fbe8d07476bfda8d2d39b6ff8f325 -- package: github.com/spf13/cobra - subpackages: - - cobra -- package: github.com/google/go-querystring - subpackages: - - query -- package: github.com/vulcand/vulcand - subpackages: - - plugin/rewrite -- package: github.com/stretchr/testify - subpackages: - - mock -- package: github.com/xenolf/lego -- package: github.com/libkermit/docker-check - version: bb75a86b169c6c5d22c0ee98278124036f272d7b -- package: github.com/libkermit/docker - version: 3b5eb2973efff7af33cfb65141deaf4ed25c6d02 -- package: github.com/docker/libcompose - version: 8ee7bcc364f7b8194581a3c6bd9fa019467c7873 -- package: github.com/docker/distribution - version: 467fc068d88aa6610691b7f1a677271a3fac4aac - subpackages: - - reference +- package: github.com/containous/staert - package: github.com/docker/engine-api version: 3d3d0b6c9d2651aac27f416a6da0224c1875b3eb subpackages: - client - types - - types/container + - types/events - types/filters - - types/strslice -- package: github.com/vdemeester/docker-events - package: github.com/docker/go-connections subpackages: - - nat - sockets - tlsconfig -- package: github.com/docker/go-units -- package: github.com/mailgun/multibuf -- package: github.com/streamrail/concurrent-map +- package: github.com/docker/libkv + subpackages: + - store + - store/boltdb + - store/consul + - store/etcd + - store/zookeeper +- package: github.com/elazarl/go-bindata-assetfs +- package: github.com/gambol99/go-marathon + version: ade11d1dc2884ee1f387078fc28509559b6235d1 +- package: github.com/gorilla/mux +- package: github.com/hashicorp/consul + subpackages: + - api +- package: github.com/mailgun/manners - package: github.com/parnurzeal/gorequest +- package: github.com/streamrail/concurrent-map +- package: github.com/stretchr/testify + subpackages: + - mock +- package: github.com/thoas/stats +- package: github.com/unrolled/render +- package: github.com/vdemeester/docker-events +- package: github.com/vulcand/vulcand + subpackages: + - plugin/rewrite +- package: github.com/xenolf/lego + subpackages: + - acme +- package: golang.org/x/net + subpackages: + - context +- package: gopkg.in/fsnotify.v1 +- package: github.com/libkermit/docker-check + version: bb75a86b169c6c5d22c0ee98278124036f272d7b +- package: github.com/libkermit/docker + version: 3b5eb2973efff7af33cfb65141deaf4ed25c6d02 +- package: github.com/docker/docker + version: 9837ec4da53f15f9120d53a6e1517491ba8b0261 + subpackages: + - namesgenerator +- package: github.com/go-check/check +- package: github.com/docker/libcompose + version: 8ee7bcc364f7b8194581a3c6bd9fa019467c7873 - package: github.com/mattn/go-shellwords -- package: github.com/moul/http2curl -- package: github.com/containous/flaeg -- package: github.com/containous/staert -- package: github.com/ogier/pflag +- package: github.com/vdemeester/shakers From ab138e7df12f4c632bc587e2e192f8d5f9d0bbe9 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 24 May 2016 17:29:56 +0200 Subject: [PATCH 10/16] update to new version go-bindata-assetfs --- web.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web.go b/web.go index bf77685a4..f402edfec 100644 --- a/web.go +++ b/web.go @@ -93,7 +93,7 @@ func (provider *WebProvider) Provide(configurationChan chan<- types.ConfigMessag systemRouter.Methods("GET").Path("/").HandlerFunc(func(response http.ResponseWriter, request *http.Request) { http.Redirect(response, request, "/dashboard/", 302) }) - systemRouter.Methods("GET").PathPrefix("/dashboard/").Handler(http.StripPrefix("/dashboard/", http.FileServer(&assetfs.AssetFS{Asset: autogen.Asset, AssetDir: autogen.AssetDir, Prefix: "static"}))) + systemRouter.Methods("GET").PathPrefix("/dashboard/").Handler(http.StripPrefix("/dashboard/", http.FileServer(&assetfs.AssetFS{Asset: autogen.Asset, AssetInfo: autogen.AssetInfo, AssetDir: autogen.AssetDir, Prefix: "static"}))) // expvars if provider.server.globalConfiguration.Debug { From 6752b495369763aee445f22e63c786e447456dbd Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 24 May 2016 17:31:50 +0200 Subject: [PATCH 11/16] rm useless StrucTag --- flaeg_test.go | 91 -------------------------------------- provider/boltdb.go | 2 +- provider/consul.go | 2 +- provider/consul_catalog.go | 10 ++--- provider/docker.go | 8 ++-- provider/etcd.go | 2 +- provider/file.go | 2 +- provider/kubernetes.go | 2 +- provider/kv.go | 12 ++--- traefik.go | 2 +- 10 files changed, 21 insertions(+), 112 deletions(-) delete mode 100644 flaeg_test.go diff --git a/flaeg_test.go b/flaeg_test.go deleted file mode 100644 index bbf36c42d..000000000 --- a/flaeg_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package main - -import ( - "github.com/cocap10/flaeg" - "reflect" - "testing" - "time" -) - -func TestLoad(t *testing.T) { - var configuration GlobalConfiguration - defaultConfiguration := NewGlobalConfiguration() - args := []string{ - // "-h", - "--docker", - "--file", - "--web", - "--marathon", - "--consul", - "--consulcatalog", - "--etcd", - "--zookeeper", - "--boltdb", - } - if err := flaeg.Load(&configuration, defaultConfiguration, args); err != nil { - t.Fatalf("Error: %s", err) - } - // fmt.Printf("result : \n%+v\n", configuration) - if !reflect.DeepEqual(configuration, *defaultConfiguration) { - t.Fatalf("\nexpected\t: %+v\ngot\t\t\t: %+v", *defaultConfiguration, configuration) - } -} - -func TestLoadWithParsers(t *testing.T) { - var configuration GlobalConfiguration - defaultConfiguration := NewGlobalConfiguration() - args := []string{ - // "-h", - "--docker", - // "--file", - "--web.address=:8888", - "--marathon", - "--consul", - "--consulcatalog", - "--etcd.tls.insecureskipverify", - "--zookeeper", - "--boltdb", - "--accesslogsfile=log2/access.log", - "--entrypoints=Name:http Address::8000 Redirect.EntryPoint:https", - "--entrypoints=Name:https Address::8443 Redirect.EntryPoint:http", - "--defaultentrypoints=https", - "--defaultentrypoints=ssh", - "--providersthrottleduration=4s", - } - parsers := map[reflect.Type]flaeg.Parser{} - var defaultEntryPointsParser DefaultEntryPoints - parsers[reflect.TypeOf(DefaultEntryPoints{})] = &defaultEntryPointsParser - entryPointsParser := EntryPoints{} - parsers[reflect.TypeOf(EntryPoints{})] = &entryPointsParser - - if err := flaeg.LoadWithParsers(&configuration, defaultConfiguration, args, parsers); err != nil { - t.Fatalf("Error: %s", err) - } - // fmt.Printf("result : \n%+v\n", configuration) - - //Check - check := *defaultConfiguration - check.File = nil - check.Web.Address = ":8888" - check.AccessLogsFile = "log2/access.log" - check.Etcd.TLS.InsecureSkipVerify = true - check.EntryPoints = make(map[string]*EntryPoint) - check.EntryPoints["http"] = &EntryPoint{ - Address: ":8000", - Redirect: &Redirect{ - EntryPoint: "https", - }, - } - check.EntryPoints["https"] = &EntryPoint{ - Address: ":8443", - Redirect: &Redirect{ - EntryPoint: "http", - }, - } - check.DefaultEntryPoints = []string{"https", "ssh"} - check.ProvidersThrottleDuration = time.Duration(4 * time.Second) - - if !reflect.DeepEqual(&configuration, &check) { - t.Fatalf("\nexpected\t: %+v\ngot\t\t\t: %+v", check, configuration) - } -} diff --git a/provider/boltdb.go b/provider/boltdb.go index 966a4b8da..4c2a33844 100644 --- a/provider/boltdb.go +++ b/provider/boltdb.go @@ -9,7 +9,7 @@ import ( // BoltDb holds configurations of the BoltDb provider. type BoltDb struct { - Kv `mapstructure:",squash" description:"go through"` + Kv } // Provide allows the provider to provide configurations to traefik diff --git a/provider/consul.go b/provider/consul.go index d6d81f3e7..d94dc7e03 100644 --- a/provider/consul.go +++ b/provider/consul.go @@ -9,7 +9,7 @@ import ( // Consul holds configurations of the Consul provider. type Consul struct { - Kv `mapstructure:",squash" description:"go through"` + Kv } // Provide allows the provider to provide configurations to traefik diff --git a/provider/consul_catalog.go b/provider/consul_catalog.go index c17cfe0a9..2aecc4622 100644 --- a/provider/consul_catalog.go +++ b/provider/consul_catalog.go @@ -23,11 +23,11 @@ const ( // ConsulCatalog holds configurations of the Consul catalog provider. type ConsulCatalog struct { - BaseProvider `mapstructure:",squash"` - Endpoint string `description:"Consul server endpoint"` - Domain string `description:"Default domain used"` - client *api.Client - Prefix string + BaseProvider + Endpoint string `description:"Consul server endpoint"` + Domain string `description:"Default domain used"` + client *api.Client + Prefix string } type serviceUpdate struct { diff --git a/provider/docker.go b/provider/docker.go index 55b73f8b6..75f5c4ef8 100644 --- a/provider/docker.go +++ b/provider/docker.go @@ -29,10 +29,10 @@ const DockerAPIVersion string = "1.21" // Docker holds configurations of the Docker provider. type Docker struct { - BaseProvider `mapstructure:",squash"` - Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint"` - Domain string `description:"Default domain used"` - TLS *DockerTLS `description:"Enable Docker TLS support"` + BaseProvider + Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint"` + Domain string `description:"Default domain used"` + TLS *DockerTLS `description:"Enable Docker TLS support"` } // DockerTLS holds TLS specific configurations diff --git a/provider/etcd.go b/provider/etcd.go index 3344245e4..a7fd7ae6a 100644 --- a/provider/etcd.go +++ b/provider/etcd.go @@ -9,7 +9,7 @@ import ( // Etcd holds configurations of the Etcd provider. type Etcd struct { - Kv `mapstructure:",squash" description:"go through"` + Kv } // Provide allows the provider to provide configurations to traefik diff --git a/provider/file.go b/provider/file.go index c5597ec19..1b463593a 100644 --- a/provider/file.go +++ b/provider/file.go @@ -14,7 +14,7 @@ import ( // File holds configurations of the File provider. type File struct { - BaseProvider `mapstructure:",squash" description:"go through"` + BaseProvider } // Provide allows the provider to provide configurations to traefik diff --git a/provider/kubernetes.go b/provider/kubernetes.go index 3dd3e9e4e..cab4217ea 100644 --- a/provider/kubernetes.go +++ b/provider/kubernetes.go @@ -49,7 +49,7 @@ func (ns *Namespaces) SetValue(val interface{}) { // Kubernetes holds configurations of the Kubernetes provider. type Kubernetes struct { - BaseProvider `mapstructure:",squash"` + BaseProvider Endpoint string `description:"Kubernetes server endpoint"` DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers"` Namespaces Namespaces `description:"Kubernetes namespaces"` diff --git a/provider/kv.go b/provider/kv.go index 852799dcb..713416781 100644 --- a/provider/kv.go +++ b/provider/kv.go @@ -22,12 +22,12 @@ import ( // Kv holds common configurations of key-value providers. type Kv struct { - BaseProvider `mapstructure:",squash" description:"go through"` - Endpoint string `description:"Comma sepparated server endpoints"` - Prefix string `description:"Prefix used for KV store"` - TLS *KvTLS `description:"Enable TLS support"` - storeType store.Backend - kvclient store.Store + BaseProvider + Endpoint string `description:"Comma sepparated server endpoints"` + Prefix string `description:"Prefix used for KV store"` + TLS *KvTLS `description:"Enable TLS support"` + storeType store.Backend + kvclient store.Store } // KvTLS holds TLS specific configurations diff --git a/traefik.go b/traefik.go index 636514f2d..fbc6a4f7f 100644 --- a/traefik.go +++ b/traefik.go @@ -76,7 +76,7 @@ Complete documentation is available at https://traefik.io`, traefikConfiguration.File.Filename = toml.ConfigFileUsed() } if len(traefikConfiguration.EntryPoints) == 0 { - traefikConfiguration.EntryPoints = map[string]*EntryPoint{"http": &EntryPoint{Address: ":80"}} + traefikConfiguration.EntryPoints = map[string]*EntryPoint{"http": {Address: ":80"}} traefikConfiguration.DefaultEntryPoints = []string{"http"} } if err := s.Run(); err != nil { From f64c2bc065c0e306c40748ec9aceefeb3e55a7af Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 25 May 2016 17:06:34 +0200 Subject: [PATCH 12/16] add flag on ACME add flag on Retry set Retry.MaxMem to 2 by default rm useless import rm useless structtag add custom parser on []acme.Domain type add commants + refactor --- acme/acme.go | 45 +++++++++++++++++++++++++++++++++++++++------ configuration.go | 39 +++++++++++++++++++++------------------ provider/zk.go | 2 +- traefik.go | 5 ++++- 4 files changed, 65 insertions(+), 26 deletions(-) diff --git a/acme/acme.go b/acme/acme.go index 53c1bd123..081e4d8e4 100644 --- a/acme/acme.go +++ b/acme/acme.go @@ -16,6 +16,7 @@ import ( fmtlog "log" "os" "reflect" + "strings" "sync" "time" ) @@ -161,15 +162,47 @@ func (dc *DomainsCertificate) needRenew() bool { // ACME allows to connect to lets encrypt and retrieve certs type ACME struct { - Email string - Domains []Domain - StorageFile string - OnDemand bool - CAServer string - EntryPoint string + Email string `description:"Email address used for registration"` + Domains []Domain `description:"SANs (alternative domains) to each main domain"` + StorageFile string `description:"File used for certificates storage."` + OnDemand bool `description:"Enable on demand certificate. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate."` + CAServer string `description:"CA server to use."` + EntryPoint string `description:"Entrypoint to proxy acme challenge to."` storageLock sync.RWMutex } +//Domains parse []Domain +type Domains []Domain + +//Set []Domain +func (ds *Domains) Set(str string) error { + fargs := func(c rune) bool { + return c == ',' || c == ';' + } + // get function + slice := strings.FieldsFunc(str, fargs) + if len(slice) >= 2 { + return fmt.Errorf("Parse error ACME.Domain. Imposible to parse %s", str) + } + d := Domain{ + Main: slice[0], + SANs: slice[1:], + } + *ds = append(*ds, d) + return nil +} + +//Get []Domain +func (ds *Domains) Get() interface{} { return []Domain(*ds) } + +//String returns []Domain in string +func (ds *Domains) String() string { return fmt.Sprintf("%+v", *ds) } + +//SetValue sets []Domain into the parser +func (ds *Domains) SetValue(val interface{}) { + *ds = Domains(val.([]Domain)) +} + // Domain holds a domain name with SANs type Domain struct { Main string diff --git a/configuration.go b/configuration.go index daa037246..201a61fe8 100644 --- a/configuration.go +++ b/configuration.go @@ -20,17 +20,17 @@ type TraefikConfiguration struct { // GlobalConfiguration holds global configuration (with providers, etc.). // It's populated from the traefik configuration file passed as an argument to the binary. type GlobalConfiguration struct { - GraceTimeOut int64 `short:"g" description:"Configuration file to use (TOML)."` - Debug bool - AccessLogsFile string `description:"Access logs file"` - TraefikLogsFile string `description:"Traefik logs file"` - LogLevel string `short:"l" description:"Log level"` - EntryPoints EntryPoints `description:"Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key'"` - ACME *acme.ACME - DefaultEntryPoints DefaultEntryPoints `description:"Entrypoints to be used by frontends that do not specify any entrypoint"` - ProvidersThrottleDuration time.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time."` - MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used"` - Retry *Retry + GraceTimeOut int64 `short:"g" description:"Configuration file to use (TOML)."` + Debug bool + AccessLogsFile string `description:"Access logs file"` + TraefikLogsFile string `description:"Traefik logs file"` + LogLevel string `short:"l" description:"Log level"` + EntryPoints EntryPoints `description:"Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key'"` + ACME *acme.ACME `description:"Enable ACME (Let's Encrypt): automatic SSL"` + DefaultEntryPoints DefaultEntryPoints `description:"Entrypoints to be used by frontends that do not specify any entrypoint"` + ProvidersThrottleDuration time.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time."` + MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used"` + Retry *Retry `description:"Enable retry sending request if network error"` Docker *provider.Docker `description:"Enable Docker backend"` File *provider.File `description:"Enable File backend"` Web *WebProvider `description:"Enable Web backend"` @@ -49,7 +49,7 @@ type DefaultEntryPoints []string // 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 (dep *DefaultEntryPoints) String() string { - //TODO : + //TODO : The string returned should be formatted in such way that the func Set below could parse it. return fmt.Sprintf("%#v", dep) } @@ -86,8 +86,10 @@ type EntryPoints map[string]*EntryPoint // 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 (ep *EntryPoints) String() string { - //TODO : - return "" + //TODO : The string returned should be formatted in such way that the func Set below could parse it. + //Like this --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' + //But the Set func parses entrypoint one by one only + return fmt.Sprintf("%+v", *ep) } // Set is the method to set the flag value, part of the flag.Value interface. @@ -208,12 +210,12 @@ type Certificate struct { // Retry contains request retry config type Retry struct { - Attempts int - MaxMem int64 + Attempts int `description:"Number of attempts"` + MaxMem int64 `description:"Maximum request body to be stored in memory in Mo"` } -// NewTraefikPointersConfiguration creates a TraefikConfiguration with pointers default values -func NewTraefikPointersConfiguration() *TraefikConfiguration { +// NewTraefikDefaultPointersConfiguration creates a TraefikConfiguration with pointers default values +func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration { //default Docker var defaultDocker provider.Docker defaultDocker.Watch = true @@ -281,6 +283,7 @@ func NewTraefikPointersConfiguration() *TraefikConfiguration { Zookeeper: &defaultZookeeper, Boltdb: &defaultBoltDb, Kubernetes: &defaultKubernetes, + Retry: &Retry{MaxMem: 2}, } return &TraefikConfiguration{ GlobalConfiguration: defaultConfiguration, diff --git a/provider/zk.go b/provider/zk.go index e8164a75f..77b28100f 100644 --- a/provider/zk.go +++ b/provider/zk.go @@ -9,7 +9,7 @@ import ( // Zookepper holds configurations of the Zookepper provider. type Zookepper struct { - Kv `description:"go through"` + Kv } // Provide allows the provider to provide configurations to traefik diff --git a/traefik.go b/traefik.go index fbc6a4f7f..898cac622 100644 --- a/traefik.go +++ b/traefik.go @@ -5,6 +5,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/containous/flaeg" "github.com/containous/staert" + "github.com/containous/traefik/acme" "github.com/containous/traefik/middlewares" "github.com/containous/traefik/provider" fmtlog "log" @@ -20,7 +21,7 @@ func main() { //traefik config inits traefikConfiguration := NewTraefikConfiguration() - traefikPointersConfiguration := NewTraefikPointersConfiguration() + traefikPointersConfiguration := NewTraefikDefaultPointersConfiguration() //traefik Command init traefikCmd := &flaeg.Command{ Name: "traefik", @@ -52,6 +53,8 @@ Complete documentation is available at https://traefik.io`, f.AddParser(reflect.TypeOf(EntryPoints{}), &EntryPoints{}) f.AddParser(reflect.TypeOf(DefaultEntryPoints{}), &DefaultEntryPoints{}) f.AddParser(reflect.TypeOf(provider.Namespaces{}), &provider.Namespaces{}) + f.AddParser(reflect.TypeOf([]acme.Domain{}), &acme.Domains{}) + //add version command f.AddCommand(versionCmd) if _, err := f.Parse(traefikCmd); err != nil { From 7f6b2b80f8850cbb4cefec9b8b2a004873ab1d31 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 26 May 2016 11:09:20 +0200 Subject: [PATCH 13/16] rm useless TestNoOrInexistentConfigShouldNotFail Signed-off-by: Martin --- integration/basic_test.go | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/integration/basic_test.go b/integration/basic_test.go index 0e7220279..7e5549174 100644 --- a/integration/basic_test.go +++ b/integration/basic_test.go @@ -5,7 +5,6 @@ import ( "os/exec" "time" - "fmt" "github.com/go-check/check" "bytes" @@ -15,34 +14,6 @@ import ( // SimpleSuite type SimpleSuite struct{ BaseSuite } -func (s *SimpleSuite) TestNoOrInexistentConfigShouldNotFail(c *check.C) { - cmd := exec.Command(traefikBinary) - - var b bytes.Buffer - cmd.Stdout = &b - cmd.Stderr = &b - - cmd.Start() - time.Sleep(500 * time.Millisecond) - output := b.Bytes() - - c.Assert(string(output), checker.Not(checker.Contains), "No configuration file found") - cmd.Process.Kill() - - nonExistentFile := "non/existent/file.toml" - cmd = exec.Command(traefikBinary, "--configFile="+nonExistentFile) - - cmd.Stdout = &b - cmd.Stderr = &b - - cmd.Start() - time.Sleep(500 * time.Millisecond) - output = b.Bytes() - - c.Assert(string(output), checker.Not(checker.Contains), fmt.Sprintf("Error reading configuration file: open %s: no such file or directory", nonExistentFile)) - cmd.Process.Kill() -} - func (s *SimpleSuite) TestInvalidConfigShouldFail(c *check.C) { cmd := exec.Command(traefikBinary, "--configFile=fixtures/invalid_configuration.toml") From cc2735f7332eaf627e978eedd4267f91722608e9 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 26 May 2016 15:55:50 +0200 Subject: [PATCH 14/16] add Debug StructTag Signed-off-by: Martin --- configuration.go | 2 +- provider/kubernetes_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration.go b/configuration.go index 201a61fe8..35a7234de 100644 --- a/configuration.go +++ b/configuration.go @@ -21,7 +21,7 @@ type TraefikConfiguration struct { // It's populated from the traefik configuration file passed as an argument to the binary. type GlobalConfiguration struct { GraceTimeOut int64 `short:"g" description:"Configuration file to use (TOML)."` - Debug bool + Debug bool `short:"d" description:"Enable debug mode"` AccessLogsFile string `description:"Access logs file"` TraefikLogsFile string `description:"Traefik logs file"` LogLevel string `short:"l" description:"Log level"` diff --git a/provider/kubernetes_test.go b/provider/kubernetes_test.go index 8426b73ad..25e48b8d7 100644 --- a/provider/kubernetes_test.go +++ b/provider/kubernetes_test.go @@ -1205,7 +1205,7 @@ func TestHostlessIngress(t *testing.T) { services: services, watchChan: watchChan, } - provider := Kubernetes{disablePassHostHeaders: true} + provider := Kubernetes{DisablePassHostHeaders: true} actual, err := provider.loadIngresses(client) if err != nil { t.Fatalf("error %+v", err) From c5084fd02523d7025417dfacecda5360e0c66eb6 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 May 2016 10:04:56 +0200 Subject: [PATCH 15/16] update staert + glide pin version --- glide.lock | 8 ++++---- glide.yaml | 2 ++ traefik.go | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/glide.lock b/glide.lock index a88e1030c..cd8969fca 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 50e873651126f0af9204fd8cc11f10917ce56b76479310ada578f5487162e0c4 -updated: 2016-05-24T15:42:45.810673781+02:00 +hash: 660249b4d5cbcfd0cb0a2d9d39ce798ec8df7d3277c53ed4043fe2f61b29eeb9 +updated: 2016-05-27T09:59:17.855890752+02:00 imports: - name: github.com/boltdb/bolt version: dfb21201d9270c1082d5fb0f07f500311ff72f18 @@ -18,7 +18,7 @@ imports: - name: github.com/codegangsta/negroni version: ffbc66b612ee3eac2eba29aedce4c3a65e4dd0a1 - name: github.com/containous/flaeg - version: e390ea90e4ee21ff73fb1630b8c50a843a6d7674 + version: c425b9d758df1864ca838dbd433f1cf8f5097d51 - name: github.com/containous/oxy version: 183212964e13e7b8afe01a08b193d04300554a68 subpackages: @@ -29,7 +29,7 @@ imports: - stream - utils - name: github.com/containous/staert - version: f0da5ea8404f0d3999d72ba8f8736d3aa4b8c8f1 + version: ff272631ecfc9c22490b651fea0f08d364d46518 - name: github.com/coreos/etcd version: c400d05d0aa73e21e431c16145e558d624098018 subpackages: diff --git a/glide.yaml b/glide.yaml index df8f8dcf5..d64ed3c4c 100644 --- a/glide.yaml +++ b/glide.yaml @@ -8,6 +8,7 @@ import: - package: github.com/cenkalti/backoff - package: github.com/codegangsta/negroni - package: github.com/containous/flaeg + version: c425b9d758df1864ca838dbd433f1cf8f5097d51 - package: github.com/containous/oxy subpackages: - cbreaker @@ -17,6 +18,7 @@ import: - stream - utils - package: github.com/containous/staert + version: ff272631ecfc9c22490b651fea0f08d364d46518 - package: github.com/docker/engine-api version: 3d3d0b6c9d2651aac27f416a6da0224c1875b3eb subpackages: diff --git a/traefik.go b/traefik.go index 898cac622..a313c6466 100644 --- a/traefik.go +++ b/traefik.go @@ -70,7 +70,7 @@ Complete documentation is available at https://traefik.io`, //add sources to staert s.AddSource(toml) s.AddSource(f) - if _, err := s.GetConfig(); err != nil { + if _, err := s.LoadConfig(); err != nil { fmtlog.Println(err) } if traefikConfiguration.File != nil && len(traefikConfiguration.File.Filename) == 0 { From 4776fa136112e714747391b70a296dff2e913831 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 May 2016 11:13:34 +0200 Subject: [PATCH 16/16] add parsers tests Signed-off-by: Martin --- acme/acme.go | 9 ++++--- acme/acme_test.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++ configuration.go | 7 +----- 3 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 acme/acme_test.go diff --git a/acme/acme.go b/acme/acme.go index 081e4d8e4..99e340ae4 100644 --- a/acme/acme.go +++ b/acme/acme.go @@ -163,7 +163,7 @@ func (dc *DomainsCertificate) needRenew() bool { // ACME allows to connect to lets encrypt and retrieve certs type ACME struct { Email string `description:"Email address used for registration"` - Domains []Domain `description:"SANs (alternative domains) to each main domain"` + Domains []Domain `description:"SANs (alternative domains) to each main domain using format: --acme.domains='main.com,san1.com,san2.com' --acme.domains='main.net,san1.net,san2.net'"` StorageFile string `description:"File used for certificates storage."` OnDemand bool `description:"Enable on demand certificate. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate."` CAServer string `description:"CA server to use."` @@ -181,12 +181,15 @@ func (ds *Domains) Set(str string) error { } // get function slice := strings.FieldsFunc(str, fargs) - if len(slice) >= 2 { + if len(slice) < 1 { return fmt.Errorf("Parse error ACME.Domain. Imposible to parse %s", str) } d := Domain{ Main: slice[0], - SANs: slice[1:], + SANs: []string{}, + } + if len(slice) > 1 { + d.SANs = slice[1:] } *ds = append(*ds, d) return nil diff --git a/acme/acme_test.go b/acme/acme_test.go new file mode 100644 index 000000000..302c5866e --- /dev/null +++ b/acme/acme_test.go @@ -0,0 +1,61 @@ +package acme + +import ( + "reflect" + "testing" +) + +func TestDomainsSet(t *testing.T) { + checkMap := map[string]Domains{ + "": {}, + "foo.com": {Domain{Main: "foo.com", SANs: []string{}}}, + "foo.com,bar.net": {Domain{Main: "foo.com", SANs: []string{"bar.net"}}}, + "foo.com,bar1.net,bar2.net,bar3.net": {Domain{Main: "foo.com", SANs: []string{"bar1.net", "bar2.net", "bar3.net"}}}, + } + for in, check := range checkMap { + ds := Domains{} + ds.Set(in) + if !reflect.DeepEqual(check, ds) { + t.Errorf("Expected %+v\nGo %+v", check, ds) + } + } +} + +func TestDomainsSetAppend(t *testing.T) { + inSlice := []string{ + "", + "foo1.com", + "foo2.com,bar.net", + "foo3.com,bar1.net,bar2.net,bar3.net", + } + checkSlice := []Domains{ + {}, + { + Domain{ + Main: "foo1.com", + SANs: []string{}}}, + { + Domain{ + Main: "foo1.com", + SANs: []string{}}, + Domain{ + Main: "foo2.com", + SANs: []string{"bar.net"}}}, + { + Domain{ + Main: "foo1.com", + SANs: []string{}}, + Domain{ + Main: "foo2.com", + SANs: []string{"bar.net"}}, + Domain{Main: "foo3.com", + SANs: []string{"bar1.net", "bar2.net", "bar3.net"}}}, + } + ds := Domains{} + for i, in := range inSlice { + ds.Set(in) + if !reflect.DeepEqual(checkSlice[i], ds) { + t.Errorf("Expected %s %+v\nGo %+v", in, checkSlice[i], ds) + } + } +} diff --git a/configuration.go b/configuration.go index 35a7234de..72703e177 100644 --- a/configuration.go +++ b/configuration.go @@ -49,8 +49,7 @@ type DefaultEntryPoints []string // 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 (dep *DefaultEntryPoints) String() string { - //TODO : The string returned should be formatted in such way that the func Set below could parse it. - return fmt.Sprintf("%#v", dep) + return strings.Join(*dep, ",") } // Set is the method to set the flag value, part of the flag.Value interface. @@ -86,9 +85,6 @@ type EntryPoints map[string]*EntryPoint // 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 (ep *EntryPoints) String() string { - //TODO : The string returned should be formatted in such way that the func Set below could parse it. - //Like this --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' - //But the Set func parses entrypoint one by one only return fmt.Sprintf("%+v", *ep) } @@ -176,7 +172,6 @@ type Certificates []Certificate // The String method's output will be used in diagnostics. func (certs *Certificates) String() string { if len(*certs) == 0 { - //TODO : return "" } return (*certs)[0].CertFile + "," + (*certs)[0].KeyFile