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 {