New static configuration loading system.
Co-authored-by: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
This commit is contained in:
parent
d18edd6f77
commit
8d7eccad5d
165 changed files with 10894 additions and 6076 deletions
|
@ -3,40 +3,27 @@ package cmd
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/pkg/config/static"
|
||||
"github.com/containous/traefik/pkg/middlewares/accesslog"
|
||||
"github.com/containous/traefik/pkg/ping"
|
||||
"github.com/containous/traefik/pkg/provider/docker"
|
||||
"github.com/containous/traefik/pkg/provider/file"
|
||||
"github.com/containous/traefik/pkg/provider/kubernetes/ingress"
|
||||
"github.com/containous/traefik/pkg/provider/marathon"
|
||||
"github.com/containous/traefik/pkg/provider/rancher"
|
||||
"github.com/containous/traefik/pkg/provider/rest"
|
||||
"github.com/containous/traefik/pkg/tracing/datadog"
|
||||
"github.com/containous/traefik/pkg/tracing/instana"
|
||||
"github.com/containous/traefik/pkg/tracing/jaeger"
|
||||
"github.com/containous/traefik/pkg/tracing/zipkin"
|
||||
"github.com/containous/traefik/pkg/types"
|
||||
jaegercli "github.com/uber/jaeger-client-go"
|
||||
)
|
||||
|
||||
// TraefikConfiguration holds GlobalConfiguration and other stuff
|
||||
type TraefikConfiguration struct {
|
||||
static.Configuration `mapstructure:",squash" export:"true"`
|
||||
ConfigFile string `short:"c" description:"Configuration file to use (TOML)." export:"true"`
|
||||
// TraefikCmdConfiguration wraps the static configuration and extra parameters.
|
||||
type TraefikCmdConfiguration struct {
|
||||
static.Configuration `export:"true"`
|
||||
// ConfigFile is the path to the configuration file.
|
||||
ConfigFile string `description:"Configuration file to use. If specified all other flags are ignored." export:"true"`
|
||||
}
|
||||
|
||||
// NewTraefikConfiguration creates a TraefikConfiguration with default values
|
||||
func NewTraefikConfiguration() *TraefikConfiguration {
|
||||
return &TraefikConfiguration{
|
||||
// NewTraefikConfiguration creates a TraefikCmdConfiguration with default values.
|
||||
func NewTraefikConfiguration() *TraefikCmdConfiguration {
|
||||
return &TraefikCmdConfiguration{
|
||||
Configuration: static.Configuration{
|
||||
Global: &static.Global{
|
||||
CheckNewVersion: true,
|
||||
},
|
||||
EntryPoints: make(static.EntryPoints),
|
||||
Providers: &static.Providers{
|
||||
ProvidersThrottleDuration: parse.Duration(2 * time.Second),
|
||||
ProvidersThrottleDuration: types.Duration(2 * time.Second),
|
||||
},
|
||||
ServersTransport: &static.ServersTransport{
|
||||
MaxIdleConnsPerHost: 200,
|
||||
|
@ -45,162 +32,3 @@ func NewTraefikConfiguration() *TraefikConfiguration {
|
|||
ConfigFile: "",
|
||||
}
|
||||
}
|
||||
|
||||
// NewTraefikDefaultPointersConfiguration creates a TraefikConfiguration with pointers default values
|
||||
func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
|
||||
// default File
|
||||
var defaultFile file.Provider
|
||||
defaultFile.Watch = true
|
||||
defaultFile.Filename = "" // needs equivalent to viper.ConfigFileUsed()
|
||||
|
||||
// default Ping
|
||||
var defaultPing = ping.Handler{
|
||||
EntryPoint: "traefik",
|
||||
}
|
||||
|
||||
// default TraefikLog
|
||||
defaultTraefikLog := types.TraefikLog{
|
||||
Format: "common",
|
||||
FilePath: "",
|
||||
}
|
||||
|
||||
// default AccessLog
|
||||
defaultAccessLog := types.AccessLog{
|
||||
Format: accesslog.CommonFormat,
|
||||
FilePath: "",
|
||||
Filters: &types.AccessLogFilters{},
|
||||
Fields: &types.AccessLogFields{
|
||||
DefaultMode: types.AccessLogKeep,
|
||||
Headers: &types.FieldHeaders{
|
||||
DefaultMode: types.AccessLogKeep,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// default Tracing
|
||||
defaultTracing := static.Tracing{
|
||||
Backend: "jaeger",
|
||||
ServiceName: "traefik",
|
||||
SpanNameLimit: 0,
|
||||
Jaeger: &jaeger.Config{
|
||||
SamplingServerURL: "http://localhost:5778/sampling",
|
||||
SamplingType: "const",
|
||||
SamplingParam: 1.0,
|
||||
LocalAgentHostPort: "127.0.0.1:6831",
|
||||
Propagation: "jaeger",
|
||||
Gen128Bit: false,
|
||||
TraceContextHeaderName: jaegercli.TraceContextHeaderName,
|
||||
},
|
||||
Zipkin: &zipkin.Config{
|
||||
HTTPEndpoint: "http://localhost:9411/api/v1/spans",
|
||||
SameSpan: false,
|
||||
ID128Bit: true,
|
||||
Debug: false,
|
||||
SampleRate: 1.0,
|
||||
},
|
||||
DataDog: &datadog.Config{
|
||||
LocalAgentHostPort: "localhost:8126",
|
||||
GlobalTag: "",
|
||||
Debug: false,
|
||||
PrioritySampling: false,
|
||||
},
|
||||
Instana: &instana.Config{
|
||||
LocalAgentHost: "localhost",
|
||||
LocalAgentPort: 42699,
|
||||
LogLevel: "info",
|
||||
},
|
||||
}
|
||||
|
||||
// default ApiConfiguration
|
||||
defaultAPI := static.API{
|
||||
EntryPoint: "traefik",
|
||||
Dashboard: true,
|
||||
}
|
||||
defaultAPI.Statistics = &types.Statistics{
|
||||
RecentErrors: 10,
|
||||
}
|
||||
|
||||
// default Metrics
|
||||
defaultMetrics := types.Metrics{
|
||||
Prometheus: &types.Prometheus{
|
||||
Buckets: types.Buckets{0.1, 0.3, 1.2, 5},
|
||||
EntryPoint: static.DefaultInternalEntryPointName,
|
||||
},
|
||||
Datadog: &types.Datadog{
|
||||
Address: "localhost:8125",
|
||||
PushInterval: "10s",
|
||||
},
|
||||
StatsD: &types.Statsd{
|
||||
Address: "localhost:8125",
|
||||
PushInterval: "10s",
|
||||
},
|
||||
InfluxDB: &types.InfluxDB{
|
||||
Address: "localhost:8089",
|
||||
Protocol: "udp",
|
||||
PushInterval: "10s",
|
||||
},
|
||||
}
|
||||
|
||||
defaultResolver := types.HostResolverConfig{
|
||||
CnameFlattening: false,
|
||||
ResolvConfig: "/etc/resolv.conf",
|
||||
ResolvDepth: 5,
|
||||
}
|
||||
|
||||
var defaultDocker docker.Provider
|
||||
defaultDocker.Watch = true
|
||||
defaultDocker.ExposedByDefault = true
|
||||
defaultDocker.Endpoint = "unix:///var/run/docker.sock"
|
||||
defaultDocker.SwarmMode = false
|
||||
defaultDocker.SwarmModeRefreshSeconds = 15
|
||||
defaultDocker.DefaultRule = docker.DefaultTemplateRule
|
||||
|
||||
// default Rest
|
||||
var defaultRest rest.Provider
|
||||
defaultRest.EntryPoint = static.DefaultInternalEntryPointName
|
||||
|
||||
// default Marathon
|
||||
var defaultMarathon marathon.Provider
|
||||
defaultMarathon.Watch = true
|
||||
defaultMarathon.Endpoint = "http://127.0.0.1:8080"
|
||||
defaultMarathon.ExposedByDefault = true
|
||||
defaultMarathon.DialerTimeout = parse.Duration(5 * time.Second)
|
||||
defaultMarathon.ResponseHeaderTimeout = parse.Duration(60 * time.Second)
|
||||
defaultMarathon.TLSHandshakeTimeout = parse.Duration(5 * time.Second)
|
||||
defaultMarathon.KeepAlive = parse.Duration(10 * time.Second)
|
||||
defaultMarathon.DefaultRule = marathon.DefaultTemplateRule
|
||||
|
||||
// default Kubernetes
|
||||
var defaultKubernetes ingress.Provider
|
||||
|
||||
// default Rancher
|
||||
var defaultRancher rancher.Provider
|
||||
defaultRancher.Watch = true
|
||||
defaultRancher.ExposedByDefault = true
|
||||
defaultRancher.EnableServiceHealthFilter = true
|
||||
defaultRancher.RefreshSeconds = 15
|
||||
defaultRancher.DefaultRule = rancher.DefaultTemplateRule
|
||||
defaultRancher.Prefix = "latest"
|
||||
|
||||
defaultProviders := static.Providers{
|
||||
File: &defaultFile,
|
||||
Docker: &defaultDocker,
|
||||
Rest: &defaultRest,
|
||||
Marathon: &defaultMarathon,
|
||||
Kubernetes: &defaultKubernetes,
|
||||
Rancher: &defaultRancher,
|
||||
}
|
||||
|
||||
return &TraefikConfiguration{
|
||||
Configuration: static.Configuration{
|
||||
Providers: &defaultProviders,
|
||||
Log: &defaultTraefikLog,
|
||||
AccessLog: &defaultAccessLog,
|
||||
Ping: &defaultPing,
|
||||
API: &defaultAPI,
|
||||
Metrics: &defaultMetrics,
|
||||
Tracing: &defaultTracing,
|
||||
HostResolver: &defaultResolver,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,34 +7,34 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/traefik/cmd"
|
||||
"github.com/containous/traefik/pkg/cli"
|
||||
"github.com/containous/traefik/pkg/config/static"
|
||||
)
|
||||
|
||||
// NewCmd builds a new HealthCheck command
|
||||
func NewCmd(traefikConfiguration *cmd.TraefikConfiguration, traefikPointersConfiguration *cmd.TraefikConfiguration) *flaeg.Command {
|
||||
return &flaeg.Command{
|
||||
Name: "healthcheck",
|
||||
Description: `Calls traefik /ping to check health (web provider must be enabled)`,
|
||||
Config: traefikConfiguration,
|
||||
DefaultPointersConfig: traefikPointersConfiguration,
|
||||
Run: runCmd(traefikConfiguration),
|
||||
Metadata: map[string]string{
|
||||
"parseAllSources": "true",
|
||||
},
|
||||
// NewCmd builds a new HealthCheck command.
|
||||
func NewCmd(traefikConfiguration *static.Configuration, loaders []cli.ResourceLoader) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "healthcheck",
|
||||
Description: `Calls Traefik /ping to check the health of Traefik (the API must be enabled).`,
|
||||
Configuration: traefikConfiguration,
|
||||
Run: runCmd(traefikConfiguration),
|
||||
Resources: loaders,
|
||||
}
|
||||
}
|
||||
|
||||
func runCmd(traefikConfiguration *cmd.TraefikConfiguration) func() error {
|
||||
return func() error {
|
||||
traefikConfiguration.Configuration.SetEffectiveConfiguration(traefikConfiguration.ConfigFile)
|
||||
func runCmd(traefikConfiguration *static.Configuration) func(_ []string) error {
|
||||
return func(_ []string) error {
|
||||
traefikConfiguration.SetEffectiveConfiguration("")
|
||||
|
||||
resp, errPing := Do(traefikConfiguration.Configuration)
|
||||
resp, errPing := Do(*traefikConfiguration)
|
||||
if resp != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
if errPing != nil {
|
||||
fmt.Printf("Error calling healthcheck: %s\n", errPing)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
fmt.Printf("Bad healthcheck status: %s\n", resp.Status)
|
||||
os.Exit(1)
|
||||
|
@ -50,6 +50,7 @@ func Do(staticConfiguration static.Configuration) (*http.Response, error) {
|
|||
if staticConfiguration.Ping == nil {
|
||||
return nil, errors.New("please enable `ping` to use health check")
|
||||
}
|
||||
|
||||
pingEntryPoint, ok := staticConfiguration.EntryPoints[staticConfiguration.Ping.EntryPoint]
|
||||
if !ok {
|
||||
return nil, errors.New("missing `ping` entrypoint")
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
package storeconfig
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
stdlog "log"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/staert"
|
||||
"github.com/containous/traefik/cmd"
|
||||
)
|
||||
|
||||
// NewCmd builds a new StoreConfig command
|
||||
func NewCmd(traefikConfiguration *cmd.TraefikConfiguration, traefikPointersConfiguration *cmd.TraefikConfiguration) *flaeg.Command {
|
||||
return &flaeg.Command{
|
||||
Name: "storeconfig",
|
||||
Description: `Stores the static traefik configuration into a Key-value store. Traefik will not start.`,
|
||||
Config: traefikConfiguration,
|
||||
DefaultPointersConfig: traefikPointersConfiguration,
|
||||
HideHelp: true, // TODO storeconfig
|
||||
Metadata: map[string]string{
|
||||
"parseAllSources": "true",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Run store config in KV
|
||||
func Run(kv *staert.KvSource, traefikConfiguration *cmd.TraefikConfiguration) func() error {
|
||||
return func() error {
|
||||
if kv == nil {
|
||||
return fmt.Errorf("error using command storeconfig, no Key-value store defined")
|
||||
}
|
||||
|
||||
fileConfig := traefikConfiguration.Providers.File
|
||||
if fileConfig != nil {
|
||||
traefikConfiguration.Providers.File = nil
|
||||
if len(fileConfig.Filename) == 0 && len(fileConfig.Directory) == 0 {
|
||||
fileConfig.Filename = traefikConfiguration.ConfigFile
|
||||
}
|
||||
}
|
||||
|
||||
jsonConf, err := json.Marshal(traefikConfiguration.Configuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stdlog.Printf("Storing configuration: %s\n", jsonConf)
|
||||
|
||||
err = kv.StoreConfig(traefikConfiguration.Configuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fileConfig != nil {
|
||||
jsonConf, err = json.Marshal(fileConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stdlog.Printf("Storing file configuration: %s\n", jsonConf)
|
||||
config, err := fileConfig.BuildConfiguration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stdlog.Print("Writing config to KV")
|
||||
err = kv.StoreConfig(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// if traefikConfiguration.Configuration.ACME != nil {
|
||||
// account := &acme.Account{}
|
||||
//
|
||||
// accountInitialized, err := keyExists(kv, traefikConfiguration.Configuration.ACME.Storage)
|
||||
// if err != nil && err != store.ErrKeyNotFound {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// // Check to see if ACME account object is already in kv store
|
||||
// if traefikConfiguration.Configuration.ACME.OverrideCertificates || !accountInitialized {
|
||||
//
|
||||
// // Stores the ACME Account into the KV Store
|
||||
// // Certificates in KV Stores will be overridden
|
||||
// meta := cluster.NewMetadata(account)
|
||||
// err = meta.Marshall()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// source := staert.KvSource{
|
||||
// Store: kv,
|
||||
// Prefix: traefikConfiguration.Configuration.ACME.Storage,
|
||||
// }
|
||||
//
|
||||
// err = source.StoreConfig(meta)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// func keyExists(source *staert.KvSource, key string) (bool, error) {
|
||||
// list, err := source.List(key, nil)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// return len(list) > 0, nil
|
||||
// }
|
||||
|
||||
// CreateKvSource creates KvSource
|
||||
// TLS support is enable for Consul and Etcd backends
|
||||
func CreateKvSource(traefikConfiguration *cmd.TraefikConfiguration) (*staert.KvSource, error) {
|
||||
var kv *staert.KvSource
|
||||
// var kvStore store.Store
|
||||
var err error
|
||||
|
||||
// TODO kv store
|
||||
// switch {
|
||||
// case traefikConfiguration.Providers.Consul != nil:
|
||||
// kvStore, err = traefikConfiguration.Providers.Consul.CreateStore()
|
||||
// kv = &staert.KvSource{
|
||||
// Store: kvStore,
|
||||
// Prefix: traefikConfiguration.Providers.Consul.Prefix,
|
||||
// }
|
||||
// case traefikConfiguration.Providers.Etcd != nil:
|
||||
// kvStore, err = traefikConfiguration.Providers.Etcd.CreateStore()
|
||||
// kv = &staert.KvSource{
|
||||
// Store: kvStore,
|
||||
// Prefix: traefikConfiguration.Providers.Etcd.Prefix,
|
||||
// }
|
||||
// case traefikConfiguration.Providers.Zookeeper != nil:
|
||||
// kvStore, err = traefikConfiguration.Providers.Zookeeper.CreateStore()
|
||||
// kv = &staert.KvSource{
|
||||
// Store: kvStore,
|
||||
// Prefix: traefikConfiguration.Providers.Zookeeper.Prefix,
|
||||
// }
|
||||
// case traefikConfiguration.Providers.Boltdb != nil:
|
||||
// kvStore, err = traefikConfiguration.Providers.Boltdb.CreateStore()
|
||||
// kv = &staert.KvSource{
|
||||
// Store: kvStore,
|
||||
// Prefix: traefikConfiguration.Providers.Boltdb.Prefix,
|
||||
// }
|
||||
// }
|
||||
return kv, err
|
||||
}
|
|
@ -4,38 +4,30 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
fmtlog "log"
|
||||
stdlog "log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/staert"
|
||||
"github.com/containous/traefik/autogen/genstatic"
|
||||
"github.com/containous/traefik/cmd"
|
||||
"github.com/containous/traefik/cmd/healthcheck"
|
||||
"github.com/containous/traefik/cmd/storeconfig"
|
||||
cmdVersion "github.com/containous/traefik/cmd/version"
|
||||
"github.com/containous/traefik/pkg/cli"
|
||||
"github.com/containous/traefik/pkg/collector"
|
||||
"github.com/containous/traefik/pkg/config"
|
||||
"github.com/containous/traefik/pkg/config/static"
|
||||
"github.com/containous/traefik/pkg/job"
|
||||
"github.com/containous/traefik/pkg/log"
|
||||
"github.com/containous/traefik/pkg/provider/aggregator"
|
||||
"github.com/containous/traefik/pkg/provider/kubernetes/k8s"
|
||||
"github.com/containous/traefik/pkg/safe"
|
||||
"github.com/containous/traefik/pkg/server"
|
||||
"github.com/containous/traefik/pkg/server/router"
|
||||
traefiktls "github.com/containous/traefik/pkg/tls"
|
||||
"github.com/containous/traefik/pkg/types"
|
||||
"github.com/containous/traefik/pkg/version"
|
||||
"github.com/coreos/go-systemd/daemon"
|
||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||
"github.com/ogier/pflag"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vulcand/oxy/roundrobin"
|
||||
)
|
||||
|
@ -48,141 +40,38 @@ func init() {
|
|||
os.Setenv("GODEBUG", goDebug+"tls13=1")
|
||||
}
|
||||
|
||||
// sliceOfStrings is the parser for []string
|
||||
type sliceOfStrings []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 (s *sliceOfStrings) String() string {
|
||||
return strings.Join(*s, ",")
|
||||
}
|
||||
|
||||
// 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 (s *sliceOfStrings) Set(value string) error {
|
||||
parts := strings.Split(value, ",")
|
||||
if len(parts) == 0 {
|
||||
return fmt.Errorf("bad []string format: %s", value)
|
||||
}
|
||||
for _, entrypoint := range parts {
|
||||
*s = append(*s, entrypoint)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get return the []string
|
||||
func (s *sliceOfStrings) Get() interface{} {
|
||||
return *s
|
||||
}
|
||||
|
||||
// SetValue sets the []string with val
|
||||
func (s *sliceOfStrings) SetValue(val interface{}) {
|
||||
*s = val.([]string)
|
||||
}
|
||||
|
||||
// Type is type of the struct
|
||||
func (s *sliceOfStrings) Type() string {
|
||||
return "sliceOfStrings"
|
||||
}
|
||||
|
||||
func main() {
|
||||
// traefik config inits
|
||||
traefikConfiguration := cmd.NewTraefikConfiguration()
|
||||
traefikPointersConfiguration := cmd.NewTraefikDefaultPointersConfiguration()
|
||||
tConfig := cmd.NewTraefikConfiguration()
|
||||
|
||||
// traefik Command init
|
||||
traefikCmd := &flaeg.Command{
|
||||
loaders := []cli.ResourceLoader{&cli.FileLoader{}, &cli.EnvLoader{}, &cli.FlagLoader{}}
|
||||
|
||||
cmdTraefik := &cli.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 {
|
||||
return runCmd(&traefikConfiguration.Configuration, traefikConfiguration.ConfigFile)
|
||||
Configuration: tConfig,
|
||||
Resources: loaders,
|
||||
Run: func(_ []string) error {
|
||||
return runCmd(&tConfig.Configuration, cli.GetConfigFile(loaders))
|
||||
},
|
||||
}
|
||||
|
||||
// storeconfig Command init
|
||||
storeConfigCmd := storeconfig.NewCmd(traefikConfiguration, traefikPointersConfiguration)
|
||||
|
||||
// init flaeg source
|
||||
f := flaeg.New(traefikCmd, os.Args[1:])
|
||||
// add custom parsers
|
||||
f.AddParser(reflect.TypeOf(static.EntryPoints{}), &static.EntryPoints{})
|
||||
|
||||
f.AddParser(reflect.SliceOf(reflect.TypeOf("")), &sliceOfStrings{})
|
||||
f.AddParser(reflect.TypeOf(traefiktls.FilesOrContents{}), &traefiktls.FilesOrContents{})
|
||||
f.AddParser(reflect.TypeOf(types.Constraints{}), &types.Constraints{})
|
||||
f.AddParser(reflect.TypeOf(k8s.Namespaces{}), &k8s.Namespaces{})
|
||||
f.AddParser(reflect.TypeOf([]types.Domain{}), &types.Domains{})
|
||||
f.AddParser(reflect.TypeOf(types.DNSResolvers{}), &types.DNSResolvers{})
|
||||
f.AddParser(reflect.TypeOf(types.Buckets{}), &types.Buckets{})
|
||||
|
||||
f.AddParser(reflect.TypeOf(types.StatusCodes{}), &types.StatusCodes{})
|
||||
f.AddParser(reflect.TypeOf(types.FieldNames{}), &types.FieldNames{})
|
||||
f.AddParser(reflect.TypeOf(types.FieldHeaderNames{}), &types.FieldHeaderNames{})
|
||||
|
||||
// add commands
|
||||
f.AddCommand(cmdVersion.NewCmd())
|
||||
f.AddCommand(storeConfigCmd)
|
||||
f.AddCommand(healthcheck.NewCmd(traefikConfiguration, traefikPointersConfiguration))
|
||||
|
||||
usedCmd, err := f.GetCommand()
|
||||
err := cmdTraefik.AddCommand(healthcheck.NewCmd(&tConfig.Configuration, loaders))
|
||||
if err != nil {
|
||||
fmtlog.Println(err)
|
||||
stdlog.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if _, err := f.Parse(usedCmd); err != nil {
|
||||
if err == pflag.ErrHelp {
|
||||
os.Exit(0)
|
||||
}
|
||||
fmtlog.Printf("Error parsing command: %s\n", 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(toml)
|
||||
s.AddSource(f)
|
||||
if _, err := s.LoadConfig(); err != nil {
|
||||
fmtlog.Printf("Error reading TOML config file %s : %s\n", toml.ConfigFileUsed(), err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
traefikConfiguration.ConfigFile = toml.ConfigFileUsed()
|
||||
|
||||
kv, err := storeconfig.CreateKvSource(traefikConfiguration)
|
||||
err = cmdTraefik.AddCommand(cmdVersion.NewCmd())
|
||||
if err != nil {
|
||||
fmtlog.Printf("Error creating kv store: %s\n", err)
|
||||
stdlog.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
storeConfigCmd.Run = storeconfig.Run(kv, traefikConfiguration)
|
||||
|
||||
// if a KV Store is enable and no sub-command called in args
|
||||
if kv != nil && usedCmd == traefikCmd {
|
||||
s.AddSource(kv)
|
||||
operation := func() error {
|
||||
_, err := s.LoadConfig()
|
||||
return err
|
||||
}
|
||||
notify := func(err error, time time.Duration) {
|
||||
log.WithoutContext().Errorf("Load config error: %+v, retrying in %s", err, time)
|
||||
}
|
||||
err := backoff.RetryNotify(safe.OperationWithRecover(operation), job.NewBackOff(backoff.NewExponentialBackOff()), notify)
|
||||
if err != nil {
|
||||
fmtlog.Printf("Error loading configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Run(); err != nil {
|
||||
fmtlog.Printf("Error running traefik: %s\n", err)
|
||||
err = cli.Execute(cmdTraefik)
|
||||
if err != nil {
|
||||
stdlog.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
@ -192,10 +81,6 @@ Complete documentation is available at https://traefik.io`,
|
|||
func runCmd(staticConfiguration *static.Configuration, configFile string) error {
|
||||
configureLogging(staticConfiguration)
|
||||
|
||||
if len(configFile) > 0 {
|
||||
log.WithoutContext().Infof("Using TOML configuration file %s", configFile)
|
||||
}
|
||||
|
||||
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
|
||||
|
||||
if err := roundrobin.SetDefaultWeight(0); err != nil {
|
||||
|
@ -289,7 +174,11 @@ func runCmd(staticConfiguration *static.Configuration, configFile string) error
|
|||
safe.Go(func() {
|
||||
tick := time.Tick(t)
|
||||
for range tick {
|
||||
_, errHealthCheck := healthcheck.Do(*staticConfiguration)
|
||||
resp, errHealthCheck := healthcheck.Do(*staticConfiguration)
|
||||
if resp != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
||||
if staticConfiguration.Ping == nil || errHealthCheck == nil {
|
||||
if ok, _ := daemon.SdNotify(false, "WATCHDOG=1"); !ok {
|
||||
log.WithoutContext().Error("Fail to tick watchdog")
|
||||
|
@ -309,7 +198,7 @@ func runCmd(staticConfiguration *static.Configuration, configFile string) error
|
|||
|
||||
func configureLogging(staticConfiguration *static.Configuration) {
|
||||
// configure default log flags
|
||||
fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags)
|
||||
stdlog.SetFlags(stdlog.Lshortfile | stdlog.LstdFlags)
|
||||
|
||||
// configure log level
|
||||
// an explicitly defined log level always has precedence. if none is
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"runtime"
|
||||
"text/template"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/traefik/pkg/cli"
|
||||
"github.com/containous/traefik/pkg/version"
|
||||
)
|
||||
|
||||
|
@ -18,19 +18,17 @@ Built: {{.BuildTime}}
|
|||
OS/Arch: {{.Os}}/{{.Arch}}`
|
||||
|
||||
// NewCmd builds a new Version command
|
||||
func NewCmd() *flaeg.Command {
|
||||
return &flaeg.Command{
|
||||
Name: "version",
|
||||
Description: `Print version`,
|
||||
Config: struct{}{},
|
||||
DefaultPointersConfig: struct{}{},
|
||||
Run: func() error {
|
||||
func NewCmd() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "version",
|
||||
Description: `Shows the current Traefik version.`,
|
||||
Configuration: nil,
|
||||
Run: func(_ []string) error {
|
||||
if err := GetPrint(os.Stdout); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Print("\n")
|
||||
return nil
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue