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 (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, "getEntryPoints": provider.getEntryPoints, "getFrontendValue": provider.getFrontendValue, "getFrontendRule": provider.getFrontendRule, "getFrontendBackend": provider.getFrontendBackend, "replace": replace, } 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 taskFilter(task, applications) }, tasks.Tasks).([]marathon.Task) //filter apps filteredApps := fun.Filter(func(app marathon.Application) bool { return 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 (provider *ConsulCatalog) healthyNodes(service string) (catalogUpdate, error) { health := provider.client.Health() opts := &api.QueryOptions{} data, _, err := health.Service(service, "", true, opts) if err != nil { log.WithError(err).Errorf("Failed to fetch details of " + service) return catalogUpdate{}, err } nodes := fun.Filter(func(node *api.ServiceEntry) bool { constraintTags := provider.getContraintTags(node.Service.Tags) ok, failingConstraint := provider.MatchConstraints(constraintTags) if ok == false && failingConstraint != nil { log.Debugf("Service %v pruned by '%v' constraint", service, failingConstraint.String()) } return ok }, data).([]*api.ServiceEntry) //Merge tags of nodes matching constraints, in a single slice. tags := fun.Foldl(func(node *api.ServiceEntry, set []string) []string { return fun.Keys(fun.Union( fun.Set(set), fun.Set(node.Service.Tags), ).(map[string]bool)).([]string) }, []string{}, nodes).([]string) return catalogUpdate{ Service: &serviceUpdate{ ServiceName: service, Attributes: tags, }, Nodes: nodes, }, nil }
//构建实体模型的插入函数 func createInsertFunc(modelInfo *modelMeta) EntityCFunc { insertFields := fun.Filter(exceptIdPred, modelInfo.fields).([]*modelField) columns := strings.Join(fun.Map(func(field *modelField) string { return field.column }, insertFields).([]string), ",") params := strings.Join(toSlice("?", len(insertFields)), ",") return func(executor interface{}, entity EntityInterface) error { ind := checkEntity(modelInfo, entity, executor) paramValues := make([]interface{}, 0, len(insertFields)) for _, field := range insertFields { fv := ind.Field(field.index).Interface() paramValues = append(paramValues, fv) } insertSql := fmt.Sprintf("INSERT INTO %s (%s) VALUES(%s)", entity.TableName(), columns, params) c.Debugf("insertSql:%v", insertSql) rs, err := exec(executor, insertSql, paramValues) if err != nil { return err } if modelInfo.pkField.pkAuto { if id, err := rs.LastInsertId(); err == nil { ind.Field(modelInfo.pkField.index).SetInt(id) } else { return err } } return nil } }
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 *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 (provider *Docker) loadDockerConfig(containersInspected []dockertypes.ContainerJSON) *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, "replace": replace, } // filter containers filteredContainers := fun.Filter(provider.ContainerFilter, containersInspected).([]dockertypes.ContainerJSON) frontends := map[string][]dockertypes.ContainerJSON{} for _, container := range filteredContainers { frontendName := provider.getFrontendName(container) frontends[frontendName] = append(frontends[frontendName], container) } templateObjects := struct { Containers []dockertypes.ContainerJSON Frontends map[string][]dockertypes.ContainerJSON Domain string }{ filteredContainers, frontends, provider.Domain, } configuration, err := provider.getConfiguration("templates/docker.tmpl", DockerFuncMap, templateObjects) if err != nil { log.Error(err) } return configuration }
//构建实体模型的更新函数 func createUpdateFunc(modelInfo *modelMeta) EntityUFunc { updateFields := fun.Filter(exceptIdPred, modelInfo.fields).([]*modelField) columns := strings.Join(fun.Map(func(field *modelField) string { return field.column + "=?" }, updateFields).([]string), ",") return func(executor interface{}, entity EntityInterface) (bool, error) { ind := checkEntity(modelInfo, entity, executor) paramValues := make([]interface{}, 0, len(updateFields)+1) for _, field := range updateFields { fv := ind.Field(field.index).Interface() paramValues = append(paramValues, fv) } id := ind.Field(modelInfo.pkField.index).Interface() paramValues = append(paramValues, id) updateSql := fmt.Sprintf("UPDATE %s SET %s where %s = %s", entity.TableName(), columns, modelInfo.pkField.column, "?") c.Debugf("updateSql:%v", updateSql) rs, err := exec(executor, updateSql, paramValues) if err != nil { return false, err } //检查更新的记录数 if rows, err := rs.RowsAffected(); err == nil { if rows != 1 { return false, err } else { return true, err } } else { return false, err } } }
func (provider *Kv) listServers(backend string) []string { serverNames := provider.list(backend, "/servers/") return fun.Filter(func(serverName string) bool { return provider.checkConstraints(serverName, "/tags") }, serverNames).([]string) }
func (provider *MarathonProvider) loadMarathonConfig() *Configuration { configuration := new(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", task.AppID) return false } application := getApplication(task, applications.Apps) _, err := strconv.Atoi(application.Labels["traefik.port"]) if len(application.Ports) > 1 && err != nil { log.Debug("Filtering marathon task with more than 1 port and no traefik.port label", task.AppID) return false } if application.Labels["traefik.enable"] == "false" { log.Debug("Filtering disabled marathon task", 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 := Asset("providerTemplates/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 }
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 }
consulClient *api.Client } var kvClient *api.KV var ConsulFuncMap = template.FuncMap{ "List": func(keys ...string) []string { joinedKeys := strings.Join(keys, "") keysPairs, _, err := kvClient.Keys(joinedKeys, "/", nil) if err != nil { log.Error("Error getting keys ", joinedKeys, err) return nil } keysPairs = fun.Filter(func(key string) bool { if key == joinedKeys { return false } return true }, keysPairs).([]string) return keysPairs }, "Get": func(keys ...string) string { joinedKeys := strings.Join(keys, "") keyPair, _, err := kvClient.Get(joinedKeys, nil) if err != nil { log.Error("Error getting key ", joinedKeys, err) return "" } return string(keyPair.Value) }, "Last": func(key string) string { splittedKey := strings.Split(key, "/")
func (provider *DockerProvider) loadDockerConfig(dockerClient *docker.Client) *Configuration { var DockerFuncMap = template.FuncMap{ "getBackend": func(container docker.Container) string { for key, value := range container.Config.Labels { if key == "traefik.backend" { return value } } return getHost(container) }, "getPort": func(container docker.Container) string { for key, value := range container.Config.Labels { if key == "traefik.port" { return value } } for key := range container.NetworkSettings.Ports { return key.Port() } return "" }, "getWeight": func(container docker.Container) string { for key, value := range container.Config.Labels { if key == "traefik.weight" { return value } } return "0" }, "getDomain": func(container docker.Container) string { for key, value := range container.Config.Labels { if key == "traefik.domain" { return value } } return provider.Domain }, "replace": func(s1 string, s2 string, s3 string) string { return strings.Replace(s3, s1, s2, -1) }, "getHost": getHost, } configuration := new(Configuration) containerList, _ := dockerClient.ListContainers(docker.ListContainersOptions{}) containersInspected := []docker.Container{} hosts := 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 } return true }, containersInspected).([]docker.Container) for _, container := range filteredContainers { hosts[getHost(container)] = append(hosts[getHost(container)], container) } templateObjects := struct { Containers []docker.Container Hosts map[string][]docker.Container Domain string }{ filteredContainers, hosts, 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 := Asset("providerTemplates/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 }
func (provider *MarathonProvider) loadMarathonConfig() *Configuration { var MarathonFuncMap = template.FuncMap{ "getPort": func(task marathon.Task) string { for _, port := range task.Ports { return strconv.Itoa(port) } return "" }, "getHost": func(application marathon.Application) string { for key, value := range application.Labels { if key == "traefik.host" { return value } } return strings.Replace(application.ID, "/", "", 1) }, "getWeight": func(application marathon.Application) string { for key, value := range application.Labels { if key == "traefik.weight" { return value } } return "0" }, "getDomain": func(application marathon.Application) string { for key, value := range application.Labels { if key == "traefik.domain" { return value } } return provider.Domain }, "getPrefixes": func(application marathon.Application) ([]string, error) { for key, value := range application.Labels { if key == "traefik.prefixes" { return strings.Split(value, ","), nil } } return []string{}, nil }, "replace": func(s1 string, s2 string, s3 string) string { return strings.Replace(s3, s1, s2, -1) }, } configuration := new(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", task.AppID) return false } application := getApplication(task, applications.Apps) if application == 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.Debug("Filtering marathon task with more than 1 port and no traefik.port label", task.AppID) return false } if application.Labels["traefik.enable"] == "false" { log.Debug("Filtering disabled marathon task", 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 := Asset("providerTemplates/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 }