예제 #1
0
파일: provider.go 프로젝트: octoblu/traefik
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
}
예제 #2
0
파일: docker.go 프로젝트: polds/traefik
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
}
예제 #3
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
}