Filters in Docker & Marathon

This commit is contained in:
emile 2015-09-10 22:54:37 +02:00
parent 0ae325c080
commit de592ed6b8
4 changed files with 84 additions and 15 deletions

View file

@ -1,8 +1,6 @@
* Default configuration values * Default configuration values
* Godoc * Godoc
* Licence * Licence
* Filter no exposed port apps
* Filter traefik.enabled=false apps
* Add traefik.indlude all/enabled policy * Add traefik.indlude all/enabled policy
* SSL frontend support * SSL frontend support
* SSL backends support * SSL backends support
@ -11,7 +9,9 @@
* Kubernetes support * Kubernetes support
* Smart configuration diff * Smart configuration diff
* README * README
* API enhancements
* ~~GraceTimeout~~ * ~~GraceTimeout~~
* ~~Weights~~ * ~~Weights~~
* ~~Filter traefik.enabled=false apps~~
* ~~Filter no exposed port apps~~

View file

@ -7,6 +7,8 @@ import (
"log" "log"
"text/template" "text/template"
"strings" "strings"
"github.com/BurntSushi/ty/fun"
"strconv"
) )
type DockerProvider struct { type DockerProvider struct {
@ -62,10 +64,12 @@ func (provider *DockerProvider) Provide(configurationChan chan <- *Configuration
go func() { go func() {
for { for {
event := <-dockerEvents event := <-dockerEvents
log.Println("Docker event receveived", event) if(event.Status == "start" || event.Status == "die"){
configuration := provider.loadDockerConfig() log.Println("Docker event receveived", event)
if (configuration != nil) { configuration := provider.loadDockerConfig()
configurationChan <- configuration if (configuration != nil) {
configurationChan <- configuration
}
} }
} }
}() }()
@ -81,12 +85,33 @@ func (provider *DockerProvider) loadDockerConfig() *Configuration {
containerList, _ := provider.dockerClient.ListContainers(docker.ListContainersOptions{}) containerList, _ := provider.dockerClient.ListContainers(docker.ListContainersOptions{})
containersInspected := []docker.Container{} containersInspected := []docker.Container{}
hosts := map[string][]docker.Container{} hosts := map[string][]docker.Container{}
// get inspect containers
for _, container := range containerList { for _, container := range containerList {
if(container.Labels["traefik.enable"] != "false"){ containerInspected, _ := provider.dockerClient.InspectContainer(container.ID)
containerInspected, _ := provider.dockerClient.InspectContainer(container.ID) containersInspected = append(containersInspected, *containerInspected)
containersInspected = append(containersInspected, *containerInspected) }
hosts[getHost(*containerInspected)] = append(hosts[getHost(*containerInspected)], *containerInspected)
// filter containers
filteredContainers := fun.Filter(func(container docker.Container) bool {
if (len(container.NetworkSettings.Ports) == 0) {
log.Println("Filtering container without port", container.Name)
return false
} }
_, err := strconv.Atoi(container.Config.Labels["traefik.port"])
if (len(container.NetworkSettings.Ports) > 1 && err != nil) {
log.Println("Filtering container with more than 1 port and no traefik.port label", container.Name)
return false
}
if (container.Config.Labels["traefik.enable"] == "false") {
log.Println("Filtering disabled container", container.Name)
return false
}
return true
}, containersInspected).([]docker.Container)
for _, container := range filteredContainers {
hosts[getHost(container)] = append(hosts[getHost(container)], container)
} }
templateObjects := struct { templateObjects := struct {
@ -94,7 +119,7 @@ func (provider *DockerProvider) loadDockerConfig() *Configuration {
Hosts map[string][]docker.Container Hosts map[string][]docker.Container
Domain string Domain string
}{ }{
containersInspected, filteredContainers,
hosts, hosts,
provider.Domain, provider.Domain,
} }

View file

@ -8,6 +8,7 @@ import (
"text/template" "text/template"
"strings" "strings"
"strconv" "strconv"
"github.com/BurntSushi/ty/fun"
) )
type MarathonProvider struct { type MarathonProvider struct {
@ -86,19 +87,53 @@ func (provider *MarathonProvider) loadMarathonConfig() *Configuration {
log.Println("Failed to create a client for marathon, error: %s", err) log.Println("Failed to create a client for marathon, error: %s", err)
return nil return nil
} }
tasks, err := provider.marathonClient.AllTasks() tasks, err := provider.marathonClient.AllTasks()
if (err != nil) { if (err != nil) {
log.Println("Failed to create a client for marathon, error: %s", err) log.Println("Failed to create a client for marathon, error: %s", err)
return nil return nil
} }
//filter tasks
filteredTasks := fun.Filter(func(task marathon.Task) bool {
if (len(task.Ports) == 0) {
log.Println("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.Println("Filtering marathon task with more than 1 port and no traefik.port label", task.AppID)
return false
}
if (application.Labels["traefik.enable"] == "false") {
log.Println("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 { templateObjects := struct {
Applications []marathon.Application Applications []marathon.Application
Tasks []marathon.Task Tasks []marathon.Task
Domain string Domain string
}{ }{
applications.Apps, filteredApps,
tasks.Tasks, filteredTasks,
provider.Domain, provider.Domain,
} }
@ -123,4 +158,13 @@ func (provider *MarathonProvider) loadMarathonConfig() *Configuration {
} }
return configuration return configuration
}
func getApplication(task marathon.Task, apps []marathon.Application) *marathon.Application {
for _, application := range apps {
if (application.ID == task.AppID) {
return &application
}
}
return nil
} }

View file

@ -6,7 +6,7 @@ endpoint = "unix:///var/run/docker.sock"
watch = true watch = true
domain = "toto.fr" domain = "toto.fr"
filename = "docker.tmpl" filename = "docker.tmpl"
#
# [marathon] # [marathon]
# endpoint = "http://127.0.0.1:8080" # endpoint = "http://127.0.0.1:8080"
# networkInterface = "eth0" # networkInterface = "eth0"