// Provide allows the provider to provide configurations to traefik // using the given configuration channel. func (provider *File) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error { watcher, err := fsnotify.NewWatcher() if err != nil { log.Error("Error creating file watcher", err) return err } file, err := os.Open(provider.Filename) if err != nil { log.Error("Error opening file", err) return err } defer file.Close() if provider.Watch { // Process events pool.Go(func(stop chan bool) { defer watcher.Close() for { select { case <-stop: return case event := <-watcher.Events: if strings.Contains(event.Name, file.Name()) { log.Debug("File event:", event) configuration := provider.loadFileConfig(file.Name()) if configuration != nil { configurationChan <- types.ConfigMessage{ ProviderName: "file", Configuration: configuration, } } } case error := <-watcher.Errors: log.Error("Watcher event error", error) } } }) err = watcher.Add(filepath.Dir(file.Name())) if err != nil { log.Error("Error adding file watcher", err) return err } } configuration := provider.loadFileConfig(file.Name()) configurationChan <- types.ConfigMessage{ ProviderName: "file", Configuration: configuration, } return nil }
func (provider *Kv) loadConfig() *types.Configuration { templateObjects := struct { Prefix string }{ // Allow `/traefik/alias` to superesede `provider.Prefix` strings.TrimSuffix(provider.get(provider.Prefix, provider.Prefix+"/alias"), "/"), } var KvFuncMap = template.FuncMap{ "List": provider.list, "ListServers": provider.listServers, "Get": provider.get, "SplitGet": provider.splitGet, "Last": provider.last, } configuration, err := provider.getConfiguration("templates/kv.tmpl", KvFuncMap, templateObjects) if err != nil { log.Error(err) } for key, frontend := range configuration.Frontends { if _, ok := configuration.Backends[frontend.Backend]; ok == false { delete(configuration.Frontends, key) } } return configuration }
func (provider *Marathon) loadMarathonConfig() *types.Configuration { var MarathonFuncMap = template.FuncMap{ "getBackend": provider.getBackend, "getPort": provider.getPort, "getWeight": provider.getWeight, "getDomain": provider.getDomain, "getProtocol": provider.getProtocol, "getPassHostHeader": provider.getPassHostHeader, "getPriority": provider.getPriority, "getEntryPoints": provider.getEntryPoints, "getFrontendRule": provider.getFrontendRule, "getFrontendBackend": provider.getFrontendBackend, "hasCircuitBreakerLabels": provider.hasCircuitBreakerLabels, "hasLoadBalancerLabels": provider.hasLoadBalancerLabels, "hasMaxConnLabels": provider.hasMaxConnLabels, "getMaxConnExtractorFunc": provider.getMaxConnExtractorFunc, "getMaxConnAmount": provider.getMaxConnAmount, "getLoadBalancerMethod": provider.getLoadBalancerMethod, "getCircuitBreakerExpression": provider.getCircuitBreakerExpression, "getSticky": provider.getSticky, } applications, err := provider.marathonClient.Applications(nil) if err != nil { log.Errorf("Failed to create a client for marathon, error: %s", err) return nil } tasks, err := provider.marathonClient.AllTasks(&marathon.AllTasksOpts{Status: "running"}) if err != nil { log.Errorf("Failed to create a client for marathon, error: %s", err) return nil } //filter tasks filteredTasks := fun.Filter(func(task marathon.Task) bool { return provider.taskFilter(task, applications, provider.ExposedByDefault) }, tasks.Tasks).([]marathon.Task) //filter apps filteredApps := fun.Filter(func(app marathon.Application) bool { return provider.applicationFilter(app, filteredTasks) }, applications.Apps).([]marathon.Application) templateObjects := struct { Applications []marathon.Application Tasks []marathon.Task Domain string }{ filteredApps, filteredTasks, provider.Domain, } configuration, err := provider.getConfiguration("templates/marathon.tmpl", MarathonFuncMap, templateObjects) if err != nil { log.Error(err) } return configuration }
func (server *Server) listenConfigurations(stop chan bool) { for { select { case <-stop: return case configMsg, ok := <-server.configurationValidatedChan: if !ok { return } currentConfigurations := server.currentConfigurations.Get().(configs) // Copy configurations to new map so we don't change current if LoadConfig fails newConfigurations := make(configs) for k, v := range currentConfigurations { newConfigurations[k] = v } newConfigurations[configMsg.ProviderName] = configMsg.Configuration newServerEntryPoints, err := server.loadConfig(newConfigurations, server.globalConfiguration) if err == nil { for newServerEntryPointName, newServerEntryPoint := range newServerEntryPoints { server.serverEntryPoints[newServerEntryPointName].httpRouter.UpdateHandler(newServerEntryPoint.httpRouter.GetHandler()) log.Infof("Server configuration reloaded on %s", server.serverEntryPoints[newServerEntryPointName].httpServer.Addr) } server.currentConfigurations.Set(newConfigurations) server.postLoadConfig() } else { log.Error("Error loading new configuration, aborted ", err) } } } }
func (provider *Docker) loadDockerConfig(containersInspected []dockerData) *types.Configuration { var DockerFuncMap = template.FuncMap{ "getBackend": provider.getBackend, "getIPAddress": provider.getIPAddress, "getPort": provider.getPort, "getWeight": provider.getWeight, "getDomain": provider.getDomain, "getProtocol": provider.getProtocol, "getPassHostHeader": provider.getPassHostHeader, "getPriority": provider.getPriority, "getEntryPoints": provider.getEntryPoints, "getFrontendRule": provider.getFrontendRule, "hasCircuitBreakerLabel": provider.hasCircuitBreakerLabel, "getCircuitBreakerExpression": provider.getCircuitBreakerExpression, "hasLoadBalancerLabel": provider.hasLoadBalancerLabel, "getLoadBalancerMethod": provider.getLoadBalancerMethod, "hasMaxConnLabels": provider.hasMaxConnLabels, "getMaxConnAmount": provider.getMaxConnAmount, "getMaxConnExtractorFunc": provider.getMaxConnExtractorFunc, "getSticky": provider.getSticky, "replace": replace, } // filter containers filteredContainers := fun.Filter(func(container dockerData) bool { return provider.containerFilter(container) }, containersInspected).([]dockerData) frontends := map[string][]dockerData{} backends := map[string]dockerData{} servers := map[string][]dockerData{} for _, container := range filteredContainers { frontendName := provider.getFrontendName(container) frontends[frontendName] = append(frontends[frontendName], container) backendName := provider.getBackend(container) backends[backendName] = container servers[backendName] = append(servers[backendName], container) } templateObjects := struct { Containers []dockerData Frontends map[string][]dockerData Backends map[string]dockerData Servers map[string][]dockerData Domain string }{ filteredContainers, frontends, backends, servers, provider.Domain, } configuration, err := provider.getConfiguration("templates/docker.tmpl", DockerFuncMap, templateObjects) if err != nil { log.Error(err) } return configuration }
func (provider *File) loadFileConfig(filename string) *types.Configuration { configuration := new(types.Configuration) if _, err := toml.DecodeFile(filename, configuration); err != nil { log.Error("Error reading file:", err) return nil } return configuration }
func (provider *Kubernetes) loadConfig(templateObjects types.Configuration) *types.Configuration { var FuncMap = template.FuncMap{} configuration, err := provider.getConfiguration("templates/kubernetes.tmpl", FuncMap, templateObjects) if err != nil { log.Error(err) } return configuration }
func (rewrite *Rewrite) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { handler, err := rewrite.rewriter.NewHandler(next) if err != nil { log.Error("Error in rewrite middleware ", err) return } handler.ServeHTTP(rw, r) }
func (provider *Mesos) loadMesosConfig() *types.Configuration { var mesosFuncMap = template.FuncMap{ "getBackend": provider.getBackend, "getPort": provider.getPort, "getHost": provider.getHost, "getWeight": provider.getWeight, "getDomain": provider.getDomain, "getProtocol": provider.getProtocol, "getPassHostHeader": provider.getPassHostHeader, "getPriority": provider.getPriority, "getEntryPoints": provider.getEntryPoints, "getFrontendRule": provider.getFrontendRule, "getFrontendBackend": provider.getFrontendBackend, "getID": provider.getID, "getFrontEndName": provider.getFrontEndName, "replace": replace, } t := records.NewRecordGenerator(time.Duration(provider.StateTimeoutSecond) * time.Second) sj, err := t.FindMaster(provider.Masters...) if err != nil { log.Errorf("Failed to create a client for mesos, error: %s", err) return nil } tasks := provider.taskRecords(sj) //filter tasks filteredTasks := fun.Filter(func(task state.Task) bool { return mesosTaskFilter(task, provider.ExposedByDefault) }, tasks).([]state.Task) filteredApps := []state.Task{} for _, value := range filteredTasks { if !taskInSlice(value, filteredApps) { filteredApps = append(filteredApps, value) } } templateObjects := struct { Applications []state.Task Tasks []state.Task Domain string }{ filteredApps, filteredTasks, provider.Domain, } configuration, err := provider.getConfiguration("templates/mesos.tmpl", mesosFuncMap, templateObjects) if err != nil { log.Error(err) } return configuration }
func (a *ACME) getDomainsCertificates(domains []string) (*Certificate, error) { domains = fun.Map(types.CanonicalDomain, domains).([]string) log.Debugf("Loading ACME certificates %s...", domains) bundle := true certificate, failures := a.client.ObtainCertificate(domains, bundle, nil, OSCPMustStaple) if len(failures) > 0 { log.Error(failures) return nil, fmt.Errorf("Cannot obtain certificates %s+v", failures) } log.Debugf("Loaded ACME certificates %s", domains) return &Certificate{ Domain: certificate.Domain, CertURL: certificate.CertURL, CertStableURL: certificate.CertStableURL, PrivateKey: certificate.PrivateKey, Certificate: certificate.Certificate, }, nil }
func run(traefikConfiguration *TraefikConfiguration) { fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags) // load global configuration globalConfiguration := traefikConfiguration.GlobalConfiguration http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = globalConfiguration.MaxIdleConnsPerHost if globalConfiguration.InsecureSkipVerify { http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} } loggerMiddleware := middlewares.NewLogger(globalConfiguration.AccessLogsFile) defer loggerMiddleware.Close() if globalConfiguration.File != nil && len(globalConfiguration.File.Filename) == 0 { // no filename, setting to global config file if len(traefikConfiguration.ConfigFile) != 0 { globalConfiguration.File.Filename = traefikConfiguration.ConfigFile } else { log.Errorln("Error using file configuration backend, no filename defined") } } if len(globalConfiguration.EntryPoints) == 0 { globalConfiguration.EntryPoints = map[string]*EntryPoint{"http": {Address: ":80"}} globalConfiguration.DefaultEntryPoints = []string{"http"} } if globalConfiguration.Debug { globalConfiguration.LogLevel = "DEBUG" } // logging level, err := logrus.ParseLevel(strings.ToLower(globalConfiguration.LogLevel)) if err != nil { log.Error("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 closing file", err) } }() if err != nil { log.Error("Error opening file", err) } else { log.SetOutput(fi) log.SetFormatter(&logrus.TextFormatter{DisableColors: true, FullTimestamp: true, DisableSorting: true}) } } else { log.SetFormatter(&logrus.TextFormatter{FullTimestamp: true, DisableSorting: true}) } jsonConf, _ := json.Marshal(globalConfiguration) log.Infof("Traefik version %s built on %s", version.Version, version.BuildDate) if globalConfiguration.CheckNewVersion { ticker := time.NewTicker(24 * time.Hour) safe.Go(func() { version.CheckNewVersion() for { select { case <-ticker.C: version.CheckNewVersion() } } }) } if len(traefikConfiguration.ConfigFile) != 0 { log.Infof("Using TOML configuration file %s", traefikConfiguration.ConfigFile) } log.Debugf("Global configuration loaded %s", string(jsonConf)) server := NewServer(globalConfiguration) server.Start() defer server.Close() sent, err := daemon.SdNotify("READY=1") if !sent && err != nil { log.Error("Fail to notify", err) } server.Wait() log.Info("Shutting down") }