2015-09-07 11:38:58 +03:00
package main
2015-09-08 01:15:14 +03:00
import (
2015-09-07 11:38:58 +03:00
"github.com/fsouza/go-dockerclient"
"github.com/leekchan/gtf"
"bytes"
"github.com/BurntSushi/toml"
2015-09-07 16:25:13 +03:00
"log"
2015-09-09 17:49:51 +03:00
"text/template"
"strings"
2015-09-07 11:38:58 +03:00
)
2015-09-09 23:39:08 +03:00
type DockerProvider struct {
Watch bool
Endpoint string
dockerClient * docker . Client
Filename string
Domain string
}
2015-09-09 17:49:51 +03:00
var DockerFuncMap = template . FuncMap {
"getBackend" : func ( container docker . Container ) string {
for key , value := range container . Config . Labels {
2015-09-10 17:46:27 +03:00
if ( key == "traefik.backend" ) {
2015-09-09 17:49:51 +03:00
return value
}
}
2015-09-10 16:12:28 +03:00
return getHost ( container )
2015-09-09 17:49:51 +03:00
} ,
"getPort" : func ( container docker . Container ) string {
for key , value := range container . Config . Labels {
2015-09-10 17:46:27 +03:00
if ( key == "traefik.port" ) {
2015-09-09 17:49:51 +03:00
return value
}
}
for key , _ := range container . NetworkSettings . Ports {
return key . Port ( )
}
return ""
} ,
2015-09-10 17:14:08 +03:00
"getWeight" : func ( container docker . Container ) string {
for key , value := range container . Config . Labels {
2015-09-10 17:46:27 +03:00
if ( key == "traefik.weight" ) {
2015-09-10 17:14:08 +03:00
return value
}
}
return "0"
} ,
2015-09-10 16:12:28 +03:00
"replace" : func ( s1 string , s2 string , s3 string ) string {
return strings . Replace ( s3 , s1 , s2 , - 1 )
} ,
2015-09-09 17:49:51 +03:00
"getHost" : getHost ,
}
2015-09-07 11:38:58 +03:00
2015-09-08 01:15:14 +03:00
func ( provider * DockerProvider ) Provide ( configurationChan chan <- * Configuration ) {
2015-09-09 23:39:08 +03:00
if client , err := docker . NewClient ( provider . Endpoint ) ; err != nil {
log . Fatalf ( "Failed to create a client for docker, error: %s" , err )
} else {
provider . dockerClient = client
dockerEvents := make ( chan * docker . APIEvents )
if ( provider . Watch ) {
provider . dockerClient . AddEventListener ( dockerEvents )
2015-09-10 10:06:37 +03:00
go func ( ) {
for {
event := <- dockerEvents
log . Println ( "Docker event receveived" , event )
configuration := provider . loadDockerConfig ( )
if ( configuration != nil ) {
configurationChan <- configuration
}
2015-09-09 23:39:08 +03:00
}
2015-09-10 10:06:37 +03:00
} ( )
}
2015-09-07 11:38:58 +03:00
2015-09-09 23:39:08 +03:00
configuration := provider . loadDockerConfig ( )
configurationChan <- configuration
}
2015-09-07 11:38:58 +03:00
}
2015-09-08 01:15:14 +03:00
func ( provider * DockerProvider ) loadDockerConfig ( ) * Configuration {
configuration := new ( Configuration )
2015-09-07 11:38:58 +03:00
containerList , _ := provider . dockerClient . ListContainers ( docker . ListContainersOptions { } )
containersInspected := [ ] docker . Container { }
2015-09-09 17:49:51 +03:00
hosts := map [ string ] [ ] docker . Container { }
2015-09-07 11:38:58 +03:00
for _ , container := range containerList {
containerInspected , _ := provider . dockerClient . InspectContainer ( container . ID )
containersInspected = append ( containersInspected , * containerInspected )
2015-09-09 17:49:51 +03:00
hosts [ getHost ( * containerInspected ) ] = append ( hosts [ getHost ( * containerInspected ) ] , * containerInspected )
2015-09-07 11:38:58 +03:00
}
2015-09-09 17:49:51 +03:00
templateObjects := struct {
2015-09-07 11:38:58 +03:00
Containers [ ] docker . Container
2015-09-09 18:10:43 +03:00
Hosts map [ string ] [ ] docker . Container
2015-09-09 18:50:02 +03:00
Domain string
2015-09-07 11:38:58 +03:00
} {
containersInspected ,
2015-09-09 17:49:51 +03:00
hosts ,
2015-09-09 18:10:43 +03:00
provider . Domain ,
2015-09-07 11:38:58 +03:00
}
2015-09-09 17:49:51 +03:00
gtf . Inject ( DockerFuncMap )
2015-09-09 18:50:02 +03:00
tmpl , err := template . New ( provider . Filename ) . Funcs ( DockerFuncMap ) . ParseFiles ( provider . Filename )
2015-09-07 11:38:58 +03:00
if err != nil {
2015-09-07 16:25:13 +03:00
log . Println ( "Error reading file:" , err )
return nil
2015-09-07 11:38:58 +03:00
}
var buffer bytes . Buffer
2015-09-09 17:49:51 +03:00
err = tmpl . Execute ( & buffer , templateObjects )
2015-09-07 11:38:58 +03:00
if err != nil {
2015-09-07 16:25:13 +03:00
log . Println ( "Error with docker template:" , err )
return nil
2015-09-07 11:38:58 +03:00
}
2015-09-08 01:15:14 +03:00
if _ , err := toml . Decode ( buffer . String ( ) , configuration ) ; err != nil {
log . Println ( "Error creating docker configuration:" , err )
2015-09-07 11:38:58 +03:00
return nil
}
2015-09-08 01:15:14 +03:00
return configuration
2015-09-09 17:49:51 +03:00
}
func getHost ( container docker . Container ) string {
for key , value := range container . Config . Labels {
2015-09-10 17:46:27 +03:00
if ( key == "traefik.host" ) {
2015-09-09 17:49:51 +03:00
return value
}
}
2015-09-10 16:12:28 +03:00
return strings . Replace ( strings . Replace ( container . Name , "/" , "" , - 1 ) , "." , "-" , - 1 )
2015-09-07 11:38:58 +03:00
}