func (p *BaseProvider) getConfiguration(defaultTemplateFile string, funcMap template.FuncMap, templateObjects interface{}) (*types.Configuration, error) { var ( buf []byte err error ) configuration := new(types.Configuration) tmpl := template.New(p.Filename).Funcs(funcMap) if len(p.Filename) > 0 { buf, err = ioutil.ReadFile(p.Filename) if err != nil { return nil, err } } else { buf, err = autogen.Asset(defaultTemplateFile) if err != nil { return nil, err } } _, err = tmpl.Parse(string(buf)) if err != nil { return nil, err } var buffer bytes.Buffer err = tmpl.Execute(&buffer, templateObjects) if err != nil { return nil, err } if _, err := toml.Decode(buffer.String(), configuration); err != nil { return nil, err } return configuration, nil }
func (provider *Docker) loadDockerConfig(dockerClient *docker.Client) *types.Configuration { var DockerFuncMap = template.FuncMap{ "getBackend": func(container docker.Container) string { if label, err := provider.getLabel(container, "traefik.backend"); err == nil { return label } return provider.getEscapedName(container.Name) }, "getPort": func(container docker.Container) string { if label, err := provider.getLabel(container, "traefik.port"); err == nil { return label } for key := range container.NetworkSettings.Ports { return key.Port() } return "" }, "getWeight": func(container docker.Container) string { if label, err := provider.getLabel(container, "traefik.weight"); err == nil { return label } return "0" }, "getDomain": func(container docker.Container) string { if label, err := provider.getLabel(container, "traefik.domain"); err == nil { return label } return provider.Domain }, "getProtocol": func(container docker.Container) string { if label, err := provider.getLabel(container, "traefik.protocol"); err == nil { return label } return "http" }, "getPassHostHeader": func(container docker.Container) string { if passHostHeader, err := provider.getLabel(container, "traefik.frontend.passHostHeader"); err == nil { return passHostHeader } return "false" }, "getFrontendValue": provider.GetFrontendValue, "getFrontendRule": provider.GetFrontendRule, "makeParsedUrl": func(s1 string) string { if u, err := url.Parse(s1); err == nil { return u.String() } return s1 }, "replace": func(s1 string, s2 string, s3 string) string { return strings.Replace(s3, s1, s2, -1) }, } configuration := new(types.Configuration) containerList, _ := dockerClient.ListContainers(docker.ListContainersOptions{}) containersInspected := []docker.Container{} frontends := map[string][]docker.Container{} // get inspect containers for _, container := range containerList { containerInspected, _ := dockerClient.InspectContainer(container.ID) containersInspected = append(containersInspected, *containerInspected) } // filter containers filteredContainers := fun.Filter(func(container docker.Container) bool { if len(container.NetworkSettings.Ports) == 0 { log.Debugf("Filtering container without port %s", container.Name) return false } _, err := strconv.Atoi(container.Config.Labels["traefik.port"]) if len(container.NetworkSettings.Ports) > 1 && err != nil { log.Debugf("Filtering container with more than 1 port and no traefik.port label %s", container.Name) return false } if container.Config.Labels["traefik.enable"] == "false" { log.Debugf("Filtering disabled container %s", container.Name) return false } labels, err := provider.getLabels(container, []string{"traefik.frontend.rule", "traefik.frontend.value"}) if len(labels) != 0 && err != nil { log.Debugf("Filtering bad labeled container %s", container.Name) return false } return true }, containersInspected).([]docker.Container) for _, container := range filteredContainers { frontends[provider.getFrontendName(container)] = append(frontends[provider.getFrontendName(container)], container) } templateObjects := struct { Containers []docker.Container Frontends map[string][]docker.Container Domain string }{ filteredContainers, frontends, provider.Domain, } tmpl := template.New(provider.Filename).Funcs(DockerFuncMap) if len(provider.Filename) > 0 { _, err := tmpl.ParseFiles(provider.Filename) if err != nil { log.Error("Error reading file", err) return nil } } else { buf, err := autogen.Asset("templates/docker.tmpl") if err != nil { log.Error("Error reading file", err) } _, err = tmpl.Parse(string(buf)) if err != nil { log.Error("Error reading file", err) return nil } } var buffer bytes.Buffer err := tmpl.Execute(&buffer, templateObjects) if err != nil { log.Error("Error with docker template", err) return nil } if _, err := toml.Decode(buffer.String(), configuration); err != nil { log.Error("Error creating docker configuration ", err) return nil } return configuration }
func (provider *Marathon) loadMarathonConfig() *types.Configuration { var MarathonFuncMap = template.FuncMap{ "getPort": func(task marathon.Task) string { for _, port := range task.Ports { return strconv.Itoa(port) } return "" }, "getWeight": func(task marathon.Task, applications []marathon.Application) string { application, errApp := getApplication(task, applications) if errApp != nil { log.Errorf("Unable to get marathon application from task %s", task.AppID) return "0" } if label, err := provider.getLabel(application, "traefik.weight"); err == nil { return label } return "0" }, "getDomain": func(application marathon.Application) string { if label, err := provider.getLabel(application, "traefik.domain"); err == nil { return label } return provider.Domain }, "replace": func(s1 string, s2 string, s3 string) string { return strings.Replace(s3, s1, s2, -1) }, "getProtocol": func(task marathon.Task, applications []marathon.Application) string { application, errApp := getApplication(task, applications) if errApp != nil { log.Errorf("Unable to get marathon application from task %s", task.AppID) return "http" } if label, err := provider.getLabel(application, "traefik.protocol"); err == nil { return label } return "http" }, "getPassHostHeader": func(application marathon.Application) string { if passHostHeader, err := provider.getLabel(application, "traefik.frontend.passHostHeader"); err == nil { return passHostHeader } return "false" }, "getFrontendValue": provider.GetFrontendValue, "getFrontendRule": provider.GetFrontendRule, } configuration := new(types.Configuration) 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() 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 { if len(task.Ports) == 0 { log.Debug("Filtering marathon task without port %s", task.AppID) return false } application, errApp := getApplication(task, applications.Apps) if errApp != nil { log.Errorf("Unable to get marathon application from task %s", task.AppID) return false } _, err := strconv.Atoi(application.Labels["traefik.port"]) if len(application.Ports) > 1 && err != nil { log.Debugf("Filtering marathon task %s with more than 1 port and no traefik.port label", task.AppID) return false } if application.Labels["traefik.enable"] == "false" { log.Debugf("Filtering disabled marathon task %s", task.AppID) return false } //filter healthchecks if application.HasHealthChecks() { if task.HasHealthCheckResults() { for _, healthcheck := range task.HealthCheckResult { // found one bad healthcheck, return false if !healthcheck.Alive { log.Debugf("Filtering marathon task %s with bad healthcheck", task.AppID) return false } } } else { log.Debugf("Filtering marathon task %s with bad healthcheck", task.AppID) return false } } return true }, tasks.Tasks).([]marathon.Task) //filter apps filteredApps := fun.Filter(func(app marathon.Application) bool { //get ports from app tasks if !fun.Exists(func(task marathon.Task) bool { if task.AppID == app.ID { return true } return false }, filteredTasks) { return false } return true }, applications.Apps).([]marathon.Application) templateObjects := struct { Applications []marathon.Application Tasks []marathon.Task Domain string }{ filteredApps, filteredTasks, provider.Domain, } tmpl := template.New(provider.Filename).Funcs(MarathonFuncMap) if len(provider.Filename) > 0 { _, err := tmpl.ParseFiles(provider.Filename) if err != nil { log.Error("Error reading file", err) return nil } } else { buf, err := autogen.Asset("templates/marathon.tmpl") if err != nil { log.Error("Error reading file", err) } _, err = tmpl.Parse(string(buf)) if err != nil { log.Error("Error reading file", err) return nil } } var buffer bytes.Buffer err = tmpl.Execute(&buffer, templateObjects) if err != nil { log.Error("Error with marathon template:", err) return nil } if _, err := toml.Decode(buffer.String(), configuration); err != nil { log.Error("Error creating marathon configuration:", err) return nil } return configuration }