2017-12-02 21:30:16 +03:00
package ecs
import (
2018-01-10 20:28:03 +03:00
"fmt"
2017-12-02 21:30:16 +03:00
"strconv"
"strings"
"text/template"
"github.com/BurntSushi/ty/fun"
2018-01-10 20:28:03 +03:00
"github.com/aws/aws-sdk-go/aws"
2018-04-11 13:26:03 +03:00
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/containous/traefik/log"
2018-01-10 20:28:03 +03:00
"github.com/containous/traefik/provider"
2017-12-02 21:30:16 +03:00
"github.com/containous/traefik/provider/label"
"github.com/containous/traefik/types"
)
// buildConfiguration fills the config template with the given instances
2018-04-11 13:26:03 +03:00
func ( p * Provider ) buildConfigurationV2 ( instances [ ] ecsInstance ) ( * types . Configuration , error ) {
services := make ( map [ string ] [ ] ecsInstance )
for _ , instance := range instances {
if p . filterInstance ( instance ) {
if serviceInstances , ok := services [ instance . Name ] ; ok {
services [ instance . Name ] = append ( serviceInstances , instance )
} else {
services [ instance . Name ] = [ ] ecsInstance { instance }
}
}
}
2017-12-02 21:30:16 +03:00
var ecsFuncMap = template . FuncMap {
2017-12-21 00:14:51 +03:00
// Backend functions
2018-01-10 20:28:03 +03:00
"getHost" : getHost ,
"getPort" : getPort ,
2018-03-28 03:13:48 +03:00
"getCircuitBreaker" : label . GetCircuitBreaker ,
"getLoadBalancer" : label . GetLoadBalancer ,
"getMaxConn" : label . GetMaxConn ,
"getHealthCheck" : label . GetHealthCheck ,
"getBuffering" : label . GetBuffering ,
2018-01-10 20:28:03 +03:00
"getServers" : getServers ,
2017-12-21 00:14:51 +03:00
// Frontend functions
2018-03-23 19:40:04 +03:00
"filterFrontends" : filterFrontends ,
"getFrontendRule" : p . getFrontendRule ,
2018-04-11 17:30:04 +03:00
"getPassHostHeader" : label . GetFuncBool ( label . TraefikFrontendPassHostHeader , label . DefaultPassHostHeader ) ,
2018-03-28 03:13:48 +03:00
"getPassTLSCert" : label . GetFuncBool ( label . TraefikFrontendPassTLSCert , label . DefaultPassTLSCert ) ,
2018-04-11 17:30:04 +03:00
"getPriority" : label . GetFuncInt ( label . TraefikFrontendPriority , label . DefaultFrontendPriority ) ,
2018-03-28 03:13:48 +03:00
"getBasicAuth" : label . GetFuncSliceString ( label . TraefikFrontendAuthBasic ) ,
"getEntryPoints" : label . GetFuncSliceString ( label . TraefikFrontendEntryPoints ) ,
"getRedirect" : label . GetRedirect ,
"getErrorPages" : label . GetErrorPages ,
"getRateLimit" : label . GetRateLimit ,
"getHeaders" : label . GetHeaders ,
"getWhiteList" : label . GetWhiteList ,
2017-12-02 21:30:16 +03:00
}
2018-03-28 03:13:48 +03:00
2017-12-02 21:30:16 +03:00
return p . GetConfiguration ( "templates/ecs.tmpl" , ecsFuncMap , struct {
Services map [ string ] [ ] ecsInstance
} {
2018-01-10 20:28:03 +03:00
Services : services ,
2017-12-02 21:30:16 +03:00
} )
}
2018-04-11 13:26:03 +03:00
func ( p * Provider ) filterInstance ( i ecsInstance ) bool {
if labelPort := label . GetStringValue ( i . TraefikLabels , label . TraefikPort , "" ) ; len ( i . container . NetworkBindings ) == 0 && labelPort == "" {
log . Debugf ( "Filtering ecs instance without port %s (%s)" , i . Name , i . ID )
return false
}
if i . machine == nil || i . machine . State == nil || i . machine . State . Name == nil {
log . Debugf ( "Filtering ecs instance with missing ec2 information %s (%s)" , i . Name , i . ID )
return false
}
if aws . StringValue ( i . machine . State . Name ) != ec2 . InstanceStateNameRunning {
log . Debugf ( "Filtering ecs instance with an incorrect state %s (%s) (state = %s)" , i . Name , i . ID , aws . StringValue ( i . machine . State . Name ) )
return false
}
if i . machine . PrivateIpAddress == nil {
log . Debugf ( "Filtering ecs instance without an ip address %s (%s)" , i . Name , i . ID )
return false
}
if ! isEnabled ( i , p . ExposedByDefault ) {
log . Debugf ( "Filtering disabled ecs instance %s (%s)" , i . Name , i . ID )
return false
}
return true
}
2017-12-02 21:30:16 +03:00
func ( p * Provider ) getFrontendRule ( i ecsInstance ) string {
2018-04-17 21:58:24 +03:00
domain := label . GetStringValue ( i . TraefikLabels , label . TraefikDomain , p . Domain )
defaultRule := "Host:" + strings . ToLower ( strings . Replace ( i . Name , "_" , "-" , - 1 ) ) + "." + domain
2018-03-28 03:13:48 +03:00
return label . GetStringValue ( i . TraefikLabels , label . TraefikFrontendRule , defaultRule )
2017-12-02 21:30:16 +03:00
}
func getHost ( i ecsInstance ) string {
2018-01-10 20:28:03 +03:00
return aws . StringValue ( i . machine . PrivateIpAddress )
2017-12-02 21:30:16 +03:00
}
func getPort ( i ecsInstance ) string {
2018-03-28 03:13:48 +03:00
if value := label . GetStringValue ( i . TraefikLabels , label . TraefikPort , "" ) ; len ( value ) > 0 {
2017-12-02 21:30:16 +03:00
return value
}
2018-01-10 20:28:03 +03:00
return strconv . FormatInt ( aws . Int64Value ( i . container . NetworkBindings [ 0 ] . HostPort ) , 10 )
2017-12-02 21:30:16 +03:00
}
func filterFrontends ( instances [ ] ecsInstance ) [ ] ecsInstance {
byName := make ( map [ string ] struct { } )
return fun . Filter ( func ( i ecsInstance ) bool {
_ , found := byName [ i . Name ]
if ! found {
byName [ i . Name ] = struct { } { }
}
return ! found
} , instances ) . ( [ ] ecsInstance )
}
2018-01-10 20:28:03 +03:00
func getServers ( instances [ ] ecsInstance ) map [ string ] types . Server {
var servers map [ string ] types . Server
for _ , instance := range instances {
if servers == nil {
servers = make ( map [ string ] types . Server )
}
2018-03-28 03:13:48 +03:00
protocol := label . GetStringValue ( instance . TraefikLabels , label . TraefikProtocol , label . DefaultProtocol )
2018-01-10 20:28:03 +03:00
host := getHost ( instance )
port := getPort ( instance )
serverName := provider . Normalize ( fmt . Sprintf ( "server-%s-%s" , instance . Name , instance . ID ) )
servers [ serverName ] = types . Server {
URL : fmt . Sprintf ( "%s://%s:%s" , protocol , host , port ) ,
2018-04-11 17:30:04 +03:00
Weight : label . GetIntValue ( instance . TraefikLabels , label . TraefikWeight , label . DefaultWeight ) ,
2018-01-10 20:28:03 +03:00
}
}
return servers
}
2017-12-02 21:30:16 +03:00
func isEnabled ( i ecsInstance , exposedByDefault bool ) bool {
2018-03-28 03:13:48 +03:00
return label . GetBoolValue ( i . TraefikLabels , label . TraefikEnable , exposedByDefault )
2017-12-02 21:30:16 +03:00
}