2017-08-25 14:10:03 +00:00
package configuration
2015-09-07 08:38:58 +00:00
2015-09-25 09:44:19 +00:00
import (
2016-06-27 10:19:14 +00:00
"crypto/tls"
2016-01-23 16:41:56 +00:00
"fmt"
2017-06-23 13:15:07 +00:00
"io/ioutil"
2016-06-27 10:19:14 +00:00
"os"
2016-05-03 14:52:14 +00:00
"regexp"
"strings"
"time"
2016-08-05 14:02:46 +00:00
2017-03-27 09:51:53 +00:00
"github.com/containous/flaeg"
2016-08-05 14:02:46 +00:00
"github.com/containous/traefik/acme"
2017-09-26 08:22:03 +00:00
"github.com/containous/traefik/log"
2017-04-17 10:50:02 +00:00
"github.com/containous/traefik/provider/boltdb"
"github.com/containous/traefik/provider/consul"
2017-04-15 13:49:53 +00:00
"github.com/containous/traefik/provider/docker"
2017-04-17 10:50:02 +00:00
"github.com/containous/traefik/provider/dynamodb"
"github.com/containous/traefik/provider/ecs"
"github.com/containous/traefik/provider/etcd"
"github.com/containous/traefik/provider/eureka"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/provider/kubernetes"
"github.com/containous/traefik/provider/marathon"
"github.com/containous/traefik/provider/mesos"
"github.com/containous/traefik/provider/rancher"
2017-08-25 14:10:03 +00:00
"github.com/containous/traefik/provider/web"
2017-04-17 10:50:02 +00:00
"github.com/containous/traefik/provider/zk"
2016-08-05 14:02:46 +00:00
"github.com/containous/traefik/types"
2015-09-25 09:44:19 +00:00
)
2017-08-18 13:34:04 +00:00
const (
// DefaultHealthCheckInterval is the default health check interval.
DefaultHealthCheckInterval = 30 * time . Second
// DefaultDialTimeout when connecting to a backend server.
DefaultDialTimeout = 30 * time . Second
2017-08-25 14:10:03 +00:00
2017-08-18 13:34:04 +00:00
// DefaultIdleTimeout before closing an idle connection.
DefaultIdleTimeout = 180 * time . Second
2017-09-26 08:22:03 +00:00
// DefaultGraceTimeout controls how long Traefik serves pending requests
// prior to shutting down.
DefaultGraceTimeout = 10 * time . Second
2017-08-18 13:34:04 +00:00
)
2017-03-24 08:36:33 +00:00
2015-11-06 17:11:57 +00:00
// GlobalConfiguration holds global configuration (with providers, etc.).
// It's populated from the traefik configuration file passed as an argument to the binary.
2015-09-10 13:13:35 +00:00
type GlobalConfiguration struct {
2017-10-02 15:18:24 +00:00
LifeCycle * LifeCycle ` description:"Timeouts influencing the server life cycle" export:"true" `
GraceTimeOut flaeg . Duration ` short:"g" description:"(Deprecated) Duration to give active requests a chance to finish before Traefik stops" export:"true" ` // Deprecated
2017-10-02 08:32:02 +00:00
Debug bool ` short:"d" description:"Enable debug mode" export:"true" `
CheckNewVersion bool ` description:"Periodically check if a new version has been released" export:"true" `
AccessLogsFile string ` description:"(Deprecated) Access logs file" export:"true" ` // Deprecated
AccessLog * types . AccessLog ` description:"Access log settings" export:"true" `
2017-10-02 15:18:24 +00:00
TraefikLogsFile string ` description:"(Deprecated) Traefik logs file. Stdout is used when omitted or empty" export:"true" ` // Deprecated
TraefikLog * types . TraefikLog ` description:"Traefik log settings" export:"true" `
2017-10-02 08:32:02 +00:00
LogLevel string ` short:"l" description:"Log level" export:"true" `
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;prod/traefik.crt,prod/traefik.key'" export:"true" `
Cluster * types . Cluster ` description:"Enable clustering" export:"true" `
Constraints types . Constraints ` description:"Filter services by constraint, matching with service tags" export:"true" `
ACME * acme . ACME ` description:"Enable ACME (Let's Encrypt): automatic SSL" export:"true" `
DefaultEntryPoints DefaultEntryPoints ` description:"Entrypoints to be used by frontends that do not specify any entrypoint" export:"true" `
ProvidersThrottleDuration flaeg . 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." export:"true" `
MaxIdleConnsPerHost int ` description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" export:"true" `
IdleTimeout flaeg . Duration ` description:"(Deprecated) maximum amount of time an idle (keep-alive) connection will remain idle before closing itself." export:"true" ` // Deprecated
InsecureSkipVerify bool ` description:"Disable SSL certificate verification" export:"true" `
RootCAs RootCAs ` description:"Add cert file for self-signed certificate" `
Retry * Retry ` description:"Enable retry sending request if network error" export:"true" `
HealthCheck * HealthCheckConfig ` description:"Health check parameters" export:"true" `
RespondingTimeouts * RespondingTimeouts ` description:"Timeouts for incoming requests to the Traefik instance" export:"true" `
ForwardingTimeouts * ForwardingTimeouts ` description:"Timeouts for requests forwarded to the backend servers" export:"true" `
Docker * docker . Provider ` description:"Enable Docker backend with default settings" export:"true" `
File * file . Provider ` description:"Enable File backend with default settings" export:"true" `
Web * web . Provider ` description:"Enable Web backend with default settings" export:"true" `
Marathon * marathon . Provider ` description:"Enable Marathon backend with default settings" export:"true" `
Consul * consul . Provider ` description:"Enable Consul backend with default settings" export:"true" `
ConsulCatalog * consul . CatalogProvider ` description:"Enable Consul catalog backend with default settings" export:"true" `
Etcd * etcd . Provider ` description:"Enable Etcd backend with default settings" export:"true" `
Zookeeper * zk . Provider ` description:"Enable Zookeeper backend with default settings" export:"true" `
Boltdb * boltdb . Provider ` description:"Enable Boltdb backend with default settings" export:"true" `
Kubernetes * kubernetes . Provider ` description:"Enable Kubernetes backend with default settings" export:"true" `
Mesos * mesos . Provider ` description:"Enable Mesos backend with default settings" export:"true" `
Eureka * eureka . Provider ` description:"Enable Eureka backend with default settings" export:"true" `
ECS * ecs . Provider ` description:"Enable ECS backend with default settings" export:"true" `
Rancher * rancher . Provider ` description:"Enable Rancher backend with default settings" export:"true" `
DynamoDB * dynamodb . Provider ` description:"Enable DynamoDB backend with default settings" export:"true" `
2015-09-10 13:13:35 +00:00
}
2017-09-26 08:22:03 +00:00
// SetEffectiveConfiguration adds missing configuration parameters derived from
// existing ones. It also takes care of maintaining backwards compatibility.
func ( gc * GlobalConfiguration ) SetEffectiveConfiguration ( ) {
if len ( gc . EntryPoints ) == 0 {
gc . EntryPoints = map [ string ] * EntryPoint { "http" : { Address : ":80" } }
gc . DefaultEntryPoints = [ ] string { "http" }
}
// Make sure LifeCycle isn't nil to spare nil checks elsewhere.
if gc . LifeCycle == nil {
gc . LifeCycle = & LifeCycle { }
}
// Prefer legacy grace timeout parameter for backwards compatibility reasons.
if gc . GraceTimeOut > 0 {
log . Warn ( "top-level grace period configuration has been deprecated -- please use lifecycle grace period" )
gc . LifeCycle . GraceTimeOut = gc . GraceTimeOut
}
if gc . Rancher != nil {
// Ensure backwards compatibility for now
if len ( gc . Rancher . AccessKey ) > 0 ||
len ( gc . Rancher . Endpoint ) > 0 ||
len ( gc . Rancher . SecretKey ) > 0 {
if gc . Rancher . API == nil {
gc . Rancher . API = & rancher . APIConfiguration {
AccessKey : gc . Rancher . AccessKey ,
SecretKey : gc . Rancher . SecretKey ,
Endpoint : gc . Rancher . Endpoint ,
}
}
log . Warn ( "Deprecated configuration found: rancher.[accesskey|secretkey|endpoint]. " +
"Please use rancher.api.[accesskey|secretkey|endpoint] instead." )
}
if gc . Rancher . Metadata != nil && len ( gc . Rancher . Metadata . Prefix ) == 0 {
gc . Rancher . Metadata . Prefix = "latest"
}
}
if gc . Debug {
gc . LogLevel = "DEBUG"
}
}
2016-01-29 19:34:17 +00:00
// DefaultEntryPoints holds default entry points
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 {
2016-05-27 09:13:34 +00:00
return strings . Join ( * dep , "," )
2016-01-29 19:34:17 +00:00
}
// Set is the method to set the flag value, part of the flag.Value interface.
// Set's argument is a string to be parsed to set the flag.
// It's a comma-separated list, so we split it.
func ( dep * DefaultEntryPoints ) Set ( value string ) error {
entrypoints := strings . Split ( value , "," )
if len ( entrypoints ) == 0 {
2017-05-26 15:03:14 +00:00
return fmt . Errorf ( "bad DefaultEntryPoints format: %s" , value )
2016-01-29 19:34:17 +00:00
}
for _ , entrypoint := range entrypoints {
* dep = append ( * dep , entrypoint )
}
return nil
}
2016-05-03 14:52:14 +00:00
// Get return the EntryPoints map
2016-08-16 17:13:18 +00:00
func ( dep * DefaultEntryPoints ) Get ( ) interface { } {
return DefaultEntryPoints ( * dep )
}
2016-05-03 14:52:14 +00:00
// SetValue sets the EntryPoints map with val
func ( dep * DefaultEntryPoints ) SetValue ( val interface { } ) {
* dep = DefaultEntryPoints ( val . ( DefaultEntryPoints ) )
}
2016-01-29 19:34:17 +00:00
// Type is type of the struct
func ( dep * DefaultEntryPoints ) Type ( ) string {
2017-06-23 13:15:07 +00:00
return "defaultentrypoints"
}
// RootCAs hold the CA we want to have in root
type RootCAs [ ] FileOrContent
// FileOrContent hold a file path or content
type FileOrContent string
func ( f FileOrContent ) String ( ) string {
return string ( f )
}
func ( f FileOrContent ) Read ( ) ( [ ] byte , error ) {
var content [ ] byte
if _ , err := os . Stat ( f . String ( ) ) ; err == nil {
content , err = ioutil . ReadFile ( f . String ( ) )
if err != nil {
return nil , err
}
} else {
content = [ ] byte ( f )
}
return content , nil
}
// 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 ( r * RootCAs ) String ( ) string {
sliceOfString := make ( [ ] string , len ( [ ] FileOrContent ( * r ) ) )
for key , value := range * r {
sliceOfString [ key ] = value . String ( )
}
return strings . Join ( sliceOfString , "," )
}
// Set is the method to set the flag value, part of the flag.Value interface.
// Set's argument is a string to be parsed to set the flag.
// It's a comma-separated list, so we split it.
func ( r * RootCAs ) Set ( value string ) error {
rootCAs := strings . Split ( value , "," )
if len ( rootCAs ) == 0 {
return fmt . Errorf ( "bad RootCAs format: %s" , value )
}
for _ , rootCA := range rootCAs {
* r = append ( * r , FileOrContent ( rootCA ) )
}
return nil
}
// Get return the EntryPoints map
func ( r * RootCAs ) Get ( ) interface { } {
return RootCAs ( * r )
}
// SetValue sets the EntryPoints map with val
func ( r * RootCAs ) SetValue ( val interface { } ) {
* r = RootCAs ( val . ( RootCAs ) )
}
// Type is type of the struct
func ( r * RootCAs ) Type ( ) string {
return "rootcas"
2016-01-29 19:34:17 +00:00
}
// EntryPoints holds entry points configuration of the reverse proxy (ip, port, TLS...)
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 {
2016-05-25 15:06:34 +00:00
return fmt . Sprintf ( "%+v" , * ep )
2016-01-29 19:34:17 +00:00
}
// Set is the method to set the flag value, part of the flag.Value interface.
// Set's argument is a string to be parsed to set the flag.
// It's a comma-separated list, so we split it.
func ( ep * EntryPoints ) Set ( value string ) error {
2017-09-15 18:56:04 +00:00
result , err := parseEntryPointsConfiguration ( value )
if err != nil {
return err
2016-01-29 19:34:17 +00:00
}
2017-09-15 18:56:04 +00:00
2017-08-25 14:10:03 +00:00
var configTLS * TLS
2016-01-29 19:34:17 +00:00
if len ( result [ "TLS" ] ) > 0 {
certs := Certificates { }
2016-03-22 00:32:02 +00:00
if err := certs . Set ( result [ "TLS" ] ) ; err != nil {
return err
}
2017-08-25 14:10:03 +00:00
configTLS = & TLS {
2016-01-29 19:34:17 +00:00
Certificates : certs ,
}
2016-07-05 08:54:58 +00:00
} else if len ( result [ "TLSACME" ] ) > 0 {
2017-08-25 14:10:03 +00:00
configTLS = & TLS {
2016-07-05 08:54:58 +00:00
Certificates : Certificates { } ,
}
2016-01-29 19:34:17 +00:00
}
2016-06-15 20:38:40 +00:00
if len ( result [ "CA" ] ) > 0 {
files := strings . Split ( result [ "CA" ] , "," )
2017-08-25 14:10:03 +00:00
configTLS . ClientCAFiles = files
2016-06-15 20:38:40 +00:00
}
2016-01-29 19:34:17 +00:00
var redirect * Redirect
if len ( result [ "RedirectEntryPoint" ] ) > 0 || len ( result [ "RedirectRegex" ] ) > 0 || len ( result [ "RedirectReplacement" ] ) > 0 {
redirect = & Redirect {
EntryPoint : result [ "RedirectEntryPoint" ] ,
Regex : result [ "RedirectRegex" ] ,
Replacement : result [ "RedirectReplacement" ] ,
}
}
2017-07-08 10:21:14 +00:00
whiteListSourceRange := [ ] string { }
if len ( result [ "WhiteListSourceRange" ] ) > 0 {
whiteListSourceRange = strings . Split ( result [ "WhiteListSourceRange" ] , "," )
}
2017-09-15 18:56:04 +00:00
compress := toBool ( result , "Compress" )
proxyProtocol := toBool ( result , "ProxyProtocol" )
2017-08-25 19:32:03 +00:00
2016-01-29 19:34:17 +00:00
( * ep ) [ result [ "Name" ] ] = & EntryPoint {
2017-07-08 10:21:14 +00:00
Address : result [ "Address" ] ,
2017-08-25 14:10:03 +00:00
TLS : configTLS ,
2017-07-08 10:21:14 +00:00
Redirect : redirect ,
Compress : compress ,
WhitelistSourceRange : whiteListSourceRange ,
2017-09-15 18:56:04 +00:00
ProxyProtocol : proxyProtocol ,
2016-01-29 19:34:17 +00:00
}
return nil
}
2017-09-15 18:56:04 +00:00
func parseEntryPointsConfiguration ( value string ) ( map [ string ] string , error ) {
regex := regexp . MustCompile ( ` (?:Name:(?P<Name>\S*))\s*(?:Address:(?P<Address>\S*))?\s*(?:TLS:(?P<TLS>\S*))?\s*(?P<TLSACME>TLS)?\s*(?:CA:(?P<CA>\S*))?\s*(?:Redirect\.EntryPoint:(?P<RedirectEntryPoint>\S*))?\s*(?:Redirect\.Regex:(?P<RedirectRegex>\S*))?\s*(?:Redirect\.Replacement:(?P<RedirectReplacement>\S*))?\s*(?:Compress:(?P<Compress>\S*))?\s*(?:WhiteListSourceRange:(?P<WhiteListSourceRange>\S*))?\s*(?:ProxyProtocol:(?P<ProxyProtocol>\S*))? ` )
match := regex . FindAllStringSubmatch ( value , - 1 )
if match == nil {
return nil , fmt . Errorf ( "bad EntryPoints format: %s" , value )
}
matchResult := match [ 0 ]
result := make ( map [ string ] string )
for i , name := range regex . SubexpNames ( ) {
if i != 0 && len ( matchResult [ i ] ) != 0 {
result [ name ] = matchResult [ i ]
}
}
return result , nil
}
func toBool ( conf map [ string ] string , key string ) bool {
if val , ok := conf [ key ] ; ok {
return strings . EqualFold ( val , "true" ) ||
strings . EqualFold ( val , "enable" ) ||
strings . EqualFold ( val , "on" )
}
return false
}
2016-05-03 14:52:14 +00:00
// Get return the EntryPoints map
2016-08-16 17:13:18 +00:00
func ( ep * EntryPoints ) Get ( ) interface { } {
return EntryPoints ( * ep )
}
2016-05-03 14:52:14 +00:00
// SetValue sets the EntryPoints map with val
func ( ep * EntryPoints ) SetValue ( val interface { } ) {
* ep = EntryPoints ( val . ( EntryPoints ) )
}
2016-01-29 19:34:17 +00:00
// Type is type of the struct
func ( ep * EntryPoints ) Type ( ) string {
2017-06-23 13:15:07 +00:00
return "entrypoints"
2016-05-31 07:54:42 +00:00
}
2016-01-29 19:34:17 +00:00
// EntryPoint holds an entry point configuration of the reverse proxy (ip, port, TLS...)
type EntryPoint struct {
2017-07-08 10:21:14 +00:00
Network string
Address string
2017-10-02 08:32:02 +00:00
TLS * TLS ` export:"true" `
Redirect * Redirect ` export:"true" `
Auth * types . Auth ` export:"true" `
2017-07-08 10:21:14 +00:00
WhitelistSourceRange [ ] string
2017-10-02 08:32:02 +00:00
Compress bool ` export:"true" `
ProxyProtocol bool ` export:"true" `
2016-01-29 19:34:17 +00:00
}
// Redirect configures a redirection of an entry point to another, or to an URL
type Redirect struct {
EntryPoint string
Regex string
Replacement string
}
// TLS configures TLS for an entry point
type TLS struct {
2017-10-02 08:32:02 +00:00
MinVersion string ` export:"true" `
2016-09-20 06:06:06 +00:00
CipherSuites [ ] string
2016-06-15 20:38:40 +00:00
Certificates Certificates
ClientCAFiles [ ] string
2016-01-29 19:34:17 +00:00
}
2017-08-25 14:10:03 +00:00
// MinVersion Map of allowed TLS minimum versions
var MinVersion = map [ string ] uint16 {
2016-09-20 06:06:06 +00:00
` VersionTLS10 ` : tls . VersionTLS10 ,
` VersionTLS11 ` : tls . VersionTLS11 ,
` VersionTLS12 ` : tls . VersionTLS12 ,
}
2017-08-25 14:10:03 +00:00
// CipherSuites Map of TLS CipherSuites from crypto/tls
2017-03-13 05:18:00 +00:00
// Available CipherSuites defined at https://golang.org/pkg/crypto/tls/#pkg-constants
2017-08-25 14:10:03 +00:00
var CipherSuites = map [ string ] uint16 {
2017-03-13 05:18:00 +00:00
` TLS_RSA_WITH_RC4_128_SHA ` : tls . TLS_RSA_WITH_RC4_128_SHA ,
` TLS_RSA_WITH_3DES_EDE_CBC_SHA ` : tls . TLS_RSA_WITH_3DES_EDE_CBC_SHA ,
` TLS_RSA_WITH_AES_128_CBC_SHA ` : tls . TLS_RSA_WITH_AES_128_CBC_SHA ,
` TLS_RSA_WITH_AES_256_CBC_SHA ` : tls . TLS_RSA_WITH_AES_256_CBC_SHA ,
` TLS_RSA_WITH_AES_128_CBC_SHA256 ` : tls . TLS_RSA_WITH_AES_128_CBC_SHA256 ,
` TLS_RSA_WITH_AES_128_GCM_SHA256 ` : tls . TLS_RSA_WITH_AES_128_GCM_SHA256 ,
` TLS_RSA_WITH_AES_256_GCM_SHA384 ` : tls . TLS_RSA_WITH_AES_256_GCM_SHA384 ,
` TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ` : tls . TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ,
` TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ` : tls . TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ,
` TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ` : tls . TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ,
` TLS_ECDHE_RSA_WITH_RC4_128_SHA ` : tls . TLS_ECDHE_RSA_WITH_RC4_128_SHA ,
` TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ` : tls . TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ,
` TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ` : tls . TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ,
` TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ` : tls . TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ,
` TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ` : tls . TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ,
` TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ` : tls . TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,
` TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ` : tls . TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ,
` TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ` : tls . TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ,
` TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ` : tls . TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,
` TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ` : tls . TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ,
` TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 ` : tls . TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 ,
` TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 ` : tls . TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 ,
2016-09-20 06:06:06 +00:00
}
2016-01-13 21:46:44 +00:00
// Certificates defines traefik certificates type
2016-07-13 15:18:55 +00:00
// Certs and Keys could be either a file path, or the file content itself
2016-01-13 21:46:44 +00:00
type Certificates [ ] Certificate
2016-06-27 10:19:14 +00:00
//CreateTLSConfig creates a TLS config from Certificate structures
func ( certs * Certificates ) CreateTLSConfig ( ) ( * tls . Config , error ) {
config := & tls . Config { }
config . Certificates = [ ] tls . Certificate { }
certsSlice := [ ] Certificate ( * certs )
for _ , v := range certsSlice {
var err error
2017-06-23 13:15:07 +00:00
certContent , err := v . CertFile . Read ( )
if err != nil {
return nil , err
2016-06-27 10:19:14 +00:00
}
2017-06-23 13:15:07 +00:00
keyContent , err := v . KeyFile . Read ( )
if err != nil {
return nil , err
}
2017-10-02 08:32:02 +00:00
cert , err := tls . X509KeyPair ( certContent , keyContent )
2017-06-23 13:15:07 +00:00
if err != nil {
return nil , err
}
2016-06-27 10:19:14 +00:00
config . Certificates = append ( config . Certificates , cert )
}
return config , nil
}
2016-01-13 21:46:44 +00:00
// String is the method to format the flag's value, part of the flag.Value interface.
// The String method's output will be used in diagnostics.
func ( certs * Certificates ) String ( ) string {
if len ( * certs ) == 0 {
return ""
}
2016-10-21 11:41:11 +00:00
var result [ ] string
for _ , certificate := range * certs {
2017-06-23 13:15:07 +00:00
result = append ( result , certificate . CertFile . String ( ) + "," + certificate . KeyFile . String ( ) )
2016-10-21 11:41:11 +00:00
}
return strings . Join ( result , ";" )
2016-01-13 21:46:44 +00:00
}
// Set is the method to set the flag value, part of the flag.Value interface.
// Set's argument is a string to be parsed to set the flag.
// It's a comma-separated list, so we split it.
func ( certs * Certificates ) Set ( value string ) error {
2016-10-21 11:41:11 +00:00
certificates := strings . Split ( value , ";" )
for _ , certificate := range certificates {
files := strings . Split ( certificate , "," )
if len ( files ) != 2 {
2017-05-26 15:03:14 +00:00
return fmt . Errorf ( "bad certificates format: %s" , value )
2016-10-21 11:41:11 +00:00
}
* certs = append ( * certs , Certificate {
2017-06-23 13:15:07 +00:00
CertFile : FileOrContent ( files [ 0 ] ) ,
KeyFile : FileOrContent ( files [ 1 ] ) ,
2016-10-21 11:41:11 +00:00
} )
2016-01-13 21:46:44 +00:00
}
return nil
}
// Type is type of the struct
func ( certs * Certificates ) Type ( ) string {
2017-06-23 13:15:07 +00:00
return "certificates"
2016-01-13 21:46:44 +00:00
}
2015-11-21 01:59:49 +00:00
// Certificate holds a SSL cert/key pair
2016-07-13 15:18:55 +00:00
// Certs and Key could be either a file path, or the file content itself
2015-11-21 01:59:49 +00:00
type Certificate struct {
2017-06-23 13:15:07 +00:00
CertFile FileOrContent
KeyFile FileOrContent
2015-11-21 01:59:49 +00:00
}
2016-03-29 20:25:32 +00:00
// Retry contains request retry config
type Retry struct {
2017-10-02 08:32:02 +00:00
Attempts int ` description:"Number of attempts" export:"true" `
2016-03-29 20:25:32 +00:00
}
2017-03-24 08:36:33 +00:00
// HealthCheckConfig contains health check configuration parameters.
type HealthCheckConfig struct {
2017-10-02 08:32:02 +00:00
Interval flaeg . Duration ` description:"Default periodicity of enabled health checks" export:"true" `
2017-03-24 08:36:33 +00:00
}
2017-08-18 13:34:04 +00:00
// RespondingTimeouts contains timeout configurations for incoming requests to the Traefik instance.
type RespondingTimeouts struct {
2017-10-02 08:32:02 +00:00
ReadTimeout flaeg . Duration ` description:"ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set" export:"true" `
WriteTimeout flaeg . Duration ` description:"WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set" export:"true" `
IdleTimeout flaeg . Duration ` description:"IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. Defaults to 180 seconds. If zero, no timeout is set" export:"true" `
2017-08-18 13:34:04 +00:00
}
// ForwardingTimeouts contains timeout configurations for forwarding requests to the backend servers.
type ForwardingTimeouts struct {
2017-10-02 08:32:02 +00:00
DialTimeout flaeg . Duration ` description:"The amount of time to wait until a connection to a backend server can be established. Defaults to 30 seconds. If zero, no timeout exists" export:"true" `
ResponseHeaderTimeout flaeg . Duration ` description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists" export:"true" `
2017-08-18 13:34:04 +00:00
}
2017-09-26 08:22:03 +00:00
// LifeCycle contains configurations relevant to the lifecycle (such as the
// shutdown phase) of Traefik.
type LifeCycle struct {
RequestAcceptGraceTimeout flaeg . Duration ` description:"Duration to keep accepting requests before Traefik initiates the graceful shutdown procedure" `
GraceTimeOut flaeg . Duration ` description:"Duration to give active requests a chance to finish before Traefik stops" `
}