Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
//构建实体模型的插入函数
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
	}
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
//构建实体模型的更新函数
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
		}
	}
}
Пример #9
0
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)
}
Пример #10
0
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
}
Пример #11
0
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
}
Пример #12
0
	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, "/")
Пример #13
0
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
}
Пример #14
0
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
}
Пример #15
0
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
}