IP-per-task: (#841)

Support IP per task with marathon/mesos
This commit is contained in:
Diego de Oliveira 2017-01-06 13:26:50 -02:00 committed by Emile Vauge
parent 8004132a3a
commit d74ea22d7d
6 changed files with 279 additions and 74 deletions

89
glide.lock generated
View file

@ -1,5 +1,5 @@
hash: 0801f9e0d663717d9cc81ee3440380d82d22a0af7dc00b078d812bd3e734c7f3
updated: 2016-12-19T15:05:24.156719846+01:00
hash: b45763571b0e62d44908c8c5088d9d596831f70cd3534b4ed7f8b7f62e37a38e
updated: 2016-12-29T23:00:30.216963153-02:00
imports:
- name: github.com/abbot/go-http-auth
version: cb4372376e1e00e9f6ab9ec142e029302c9e7140
@ -35,11 +35,11 @@ imports:
- private/waiter
- service/route53
- name: github.com/Azure/azure-sdk-for-go
version: 0984e0641ae43b89283223034574d6465be93bf4
version: 1620af6b32398bfc91827ceae54a8cc1f55df04d
subpackages:
- arm/dns
- name: github.com/Azure/go-autorest
version: e0c77ecbe74311e03f2a629834d2110f031f1453
version: 32cc2321122a649b7ba4e323527bcb145134fd47
subpackages:
- autorest
- autorest/azure
@ -49,7 +49,7 @@ imports:
- name: github.com/blang/semver
version: 3a37c301dda64cbe17f16f661b4c976803c0e2d2
- name: github.com/boltdb/bolt
version: f4c032d907f61f08dba2d719c58f108a1abb8e81
version: 5cc10bbbc5c141029940133bb33c9e969512a698
- name: github.com/BurntSushi/toml
version: 99064174e013895bbd9b025c31100bd1d9b590ca
- name: github.com/BurntSushi/ty
@ -63,7 +63,7 @@ imports:
- name: github.com/codegangsta/cli
version: bf4a526f48af7badd25d2cb02d587e1b01be3b50
- name: github.com/codegangsta/negroni
version: 3f7ce7b928e14ff890b067e5bbbc80af73690a9c
version: dc6b9d037e8dab60cbfc09c61d6932537829be8b
- name: github.com/containous/flaeg
version: a731c034dda967333efce5f8d276aeff11f8ff87
- name: github.com/containous/mux
@ -79,7 +79,7 @@ imports:
- pkg/pathutil
- pkg/types
- name: github.com/coreos/go-oidc
version: dedb650fb29c39c2f21aa88c1e4cec66da8754d1
version: 9e117111587506b9dc83b7b38263268bf48352ea
subpackages:
- http
- jose
@ -108,7 +108,7 @@ imports:
- name: github.com/dgrijalva/jwt-go
version: 9ed569b5d1ac936e6494082958d63a6aa4fff99a
- name: github.com/docker/distribution
version: 99cb7c0946d2f5a38015443e515dc916295064d7
version: 87917f30529e6a7fca8eaff2932424915fb11225
subpackages:
- context
- digest
@ -188,7 +188,7 @@ imports:
- types/time
- types/versions
- name: github.com/docker/go-connections
version: 988efe982fdecb46f01d53465878ff1f2ff411ce
version: 990a1a1a70b0da4c4cb70e117971a4f0babfbf1a
subpackages:
- nat
- sockets
@ -196,9 +196,9 @@ imports:
- name: github.com/docker/go-units
version: f2d77a61e3c169b43402a0a1e84f06daf29b8190
- name: github.com/docker/leadership
version: 0a913e2d71a12fd14a028452435cb71ac8d82cb6
version: bfc7753dd48af19513b29deec23c364bf0f274eb
- name: github.com/docker/libkv
version: 3fce6a0f26e07da3eac45796a8e255547a47a750
version: 35d3e2084c650109e7bcc7282655b1bc8ba924ff
subpackages:
- store
- store/boltdb
@ -216,26 +216,26 @@ imports:
- tokens
- zones
- name: github.com/elazarl/go-bindata-assetfs
version: 9a6736ed45b44bf3835afeebb3034b57ed329f3e
version: 57eb5e1fc594ad4b0b1dbea7b286d299e0cb43c2
- name: github.com/emicklei/go-restful
version: 892402ba11a2e2fd5e1295dd633481f27365f14d
subpackages:
- log
- swagger
- name: github.com/gambol99/go-marathon
version: a558128c87724cd7430060ef5aedf39f83937f55
version: 9ab64d9f0259e8800911d92ebcd4d5b981917919
- name: github.com/ghodss/yaml
version: a54de18a07046d8c4b26e9327698a2ebb9285b36
version: 04f313413ffd65ce25f2541bfd2b2ceec5c0908c
- name: github.com/go-ini/ini
version: 2ba15ac2dc9cdf88c110ec2dc0ced7fa45f5678c
version: 6f66b0e091edb3c7b380f7c4f0f884274d550b67
- name: github.com/go-openapi/jsonpointer
version: 8d96a2dc61536b690bd36b2e9df0b3c0b62825b2
- name: github.com/go-openapi/jsonreference
version: 36d33bfe519efae5632669801b180bf1a245da3b
- name: github.com/go-openapi/spec
version: f7ae86df5bc115a2744343016c789a89f065a4bd
version: 34b5ffff717ab4535aef76e3dd90818bddde571b
- name: github.com/go-openapi/swag
version: 3b6d86cd965820f968760d5d419cb4add096bdd7
version: 96d7b9ebd181a1735a1c9ac87914f2b32fbf56c9
- name: github.com/gogo/protobuf
version: 909568be09de550ed094403c2bf8a261b5bb730a
subpackages:
@ -248,7 +248,7 @@ imports:
subpackages:
- proto
- name: github.com/google/go-github
version: 55263f30529cb06f5b478efc333390b791cfe3b1
version: c8ebe3a4d7f0791a6315b7410353d4084c58805d
subpackages:
- github
- name: github.com/google/go-querystring
@ -258,21 +258,22 @@ imports:
- name: github.com/google/gofuzz
version: 44d81051d367757e1c7c6a5a86423ece9afcf63c
- name: github.com/gorilla/context
version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42
version: 1ea25387ff6f684839d82767c1733ff4d4d15d0a
- name: github.com/hashicorp/consul
version: d8e2fb7dd594163e25a89bc52c1a4613f5c5bfb8
version: fce7d75609a04eeb9d4bf41c8dc592aac18fc97d
subpackages:
- api
- name: github.com/hashicorp/go-cleanhttp
version: ad28ea4487f05916463e2423a55166280e8254b5
version: 875fb671b3ddc66f8e2f0acc33829c8cb989a38d
- name: github.com/hashicorp/go-version
version: e96d3840402619007766590ecea8dd7af1292276
- name: github.com/hashicorp/serf
version: b03bf85930b2349eb04b97c8fac437495296e3e7
version: 6c4672d66fc6312ddde18399262943e21175d831
subpackages:
- coordinate
- serf
- name: github.com/JamesClonk/vultr
version: a798a2e08fafd0594d113fc6123e5c147bd66213
version: 9ec0427d51411407c0402b093a1771cb75af9679
subpackages:
- lib
- name: github.com/jarcoal/httpmock
@ -288,7 +289,7 @@ imports:
- name: github.com/mailgun/timetools
version: fd192d755b00c968d312d23f521eb0cdc6f66bd0
- name: github.com/mailru/easyjson
version: 159cdb893c982e3d1bc6450322fedd514f9c9de3
version: 9d6630dc8c577b56cb9687a9cf9e8578aca7298a
subpackages:
- buffer
- jlexer
@ -324,23 +325,23 @@ imports:
- name: github.com/mitchellh/mapstructure
version: f3009df150dadf309fdee4a54ed65c124afad715
- name: github.com/mvdan/xurls
version: de85a6f607af2e645cce05905efd9420e43b91f1
version: fa08908f19eca8c491d68c6bd8b4b44faea6daf8
- name: github.com/NYTimes/gziphandler
version: f6438dbf4a82c56684964b03956aa727b0d7816b
- name: github.com/ogier/pflag
version: 45c278ab3607870051a2ea9040bb85fcb8557481
- name: github.com/opencontainers/runc
version: 02f8fa7863dd3f82909a73e2061897828460d52f
version: 1a81e9ab1f138c091fe5c86d0883f87716088527
subpackages:
- libcontainer/user
- name: github.com/ovh/go-ovh
version: 99a1e00db4397517d87ab82c92b9d8cb60e5940b
version: a8a4c0bc40e56322142649bda7b2b4bb15145b6e
subpackages:
- ovh
- name: github.com/parnurzeal/gorequest
version: e30af16d4e485943aab0b0885ad6bdbb8c0d3dc7
version: 045012d33ef41ea146c1b675df9296d0dc1a212d
- name: github.com/pborman/uuid
version: 3d4f2ba23642d3cfd06bd4b54cf03d99d95c0f1b
version: 5007efa264d92316c43112bc573e754bc889b7b1
- name: github.com/pmezard/go-difflib
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
subpackages:
@ -356,26 +357,26 @@ imports:
- name: github.com/ryanuber/go-glob
version: 572520ed46dbddaed19ea3d9541bdd0494163693
- name: github.com/samuel/go-zookeeper
version: 87e1bca4477a3cc767ca71be023ced183d74e538
version: e64db453f3512cade908163702045e0f31137843
subpackages:
- zk
- name: github.com/satori/go.uuid
version: 879c5887cd475cd7864858769793b2ceb0d44feb
- name: github.com/Sirupsen/logrus
version: 3ec0642a7fb6488f65b06f9040adc67e3990296a
version: a283a10442df8dc09befd873fab202bf8a253d6a
- name: github.com/spf13/pflag
version: 5644820622454e71517561946e3d94b9f9db6842
- name: github.com/streamrail/concurrent-map
version: 8bf1e9bacbf65b10c81d0f4314cf2b1ebef728b5
version: 65a174a3a4188c0b7099acbc6cfa0c53628d3287
- name: github.com/stretchr/objx
version: cbeaeb16a013161a98496fad62933b1d21786672
- name: github.com/stretchr/testify
version: 976c720a22c8eb4eb6a0b4348ad85ad12491a506
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
subpackages:
- assert
- mock
- name: github.com/thoas/stats
version: 152b5d051953fdb6e45f14b6826962aadc032324
version: 79b768ff1780f4e5b0ed132e192bfeefe9f85a9c
- name: github.com/timewasted/linode
version: 37e84520dcf74488f67654f9c775b9752c232dc1
subpackages:
@ -387,9 +388,9 @@ imports:
subpackages:
- codec
- name: github.com/unrolled/render
version: 526faf80cd4b305bb8134abea8d20d5ced74faa6
version: 198ad4d8b8a4612176b804ca10555b222a086b40
- name: github.com/urfave/negroni
version: e0e50f7dc431c043cb33f91b09c3419d48b7cff5
version: fde5e16d32adc7ad637e9cd9ad21d4ebc6192535
- name: github.com/vdemeester/docker-events
version: be74d4929ec1ad118df54349fda4b0cba60f849b
- name: github.com/vulcand/oxy
@ -420,7 +421,7 @@ imports:
subpackages:
- dnsimple
- name: github.com/xenolf/lego
version: cbd5d04c891979c23c3924f198e07ce32b39d282
version: ce8fb060cb8361a9ff8b5fb7c2347fa907b6fcac
subpackages:
- acme
- providers/dns
@ -474,7 +475,7 @@ imports:
- unix
- windows
- name: golang.org/x/text
version: 5c6cf4f9a2357d38515014cea8c488ed22bdab90
version: a49bea13b776691cb1b49873e5d8df96ec74831a
repo: https://github.com/golang/text.git
vcs: git
subpackages:
@ -507,13 +508,13 @@ imports:
- compute/metadata
- internal
- name: gopkg.in/fsnotify.v1
version: 944cff21b3baf3ced9a880365682152ba577d348
version: a8a77c9133d2d6fd8334f3260d06f60e8d80a5fb
- name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/ini.v1
version: 6e4869b434bd001f6983749881c7ead3545887d8
version: 6f66b0e091edb3c7b380f7c4f0f884274d550b67
- name: gopkg.in/mgo.v2
version: 22287bab4379e1fbf6002fb4eb769888f3fb224c
version: 29cc868a5ca65f401ff318143f9408d02f4799cc
subpackages:
- bson
- name: gopkg.in/ns1/ns1-go.v2
@ -526,7 +527,7 @@ imports:
- rest/model/filter
- rest/model/monitor
- name: gopkg.in/square/go-jose.v1
version: aa2e30fdd1fe9dd3394119af66451ae790d50e0d
version: e3f973b66b91445ec816dd7411ad1b6495a5a2fc
subpackages:
- cipher
- json
@ -665,7 +666,7 @@ testImports:
- name: github.com/flynn/go-shlex
version: 3f9db97f856818214da2e1057f8ad84803971cff
- name: github.com/go-check/check
version: 4f90aeace3a26ad7021961c297b22c42160c7b25
version: 11d3bc7aa68e238947792f30573146a3231fc0f1
- name: github.com/gorilla/mux
version: e444e69cbd2e2e3e0749a2f3c717cec491552bbf
- name: github.com/libkermit/compose
@ -677,7 +678,7 @@ testImports:
- name: github.com/libkermit/docker-check
version: cbe0ef03b3d23070eac4d00ba8828f2cc7f7e5a3
- name: github.com/vbatts/tar-split
version: bd4c5d64c3e9297f410025a3b1bd0c58f659e721
version: 6810cedb21b2c3d0b9bb8f9af12ff2dc7a2f14df
subpackages:
- archive/tar
- tar/asm

View file

@ -43,8 +43,6 @@ import:
- store/etcd
- store/zookeeper
- package: github.com/elazarl/go-bindata-assetfs
- package: github.com/gambol99/go-marathon
version: a558128c87724cd7430060ef5aedf39f83937f55
- package: github.com/containous/mux
- package: github.com/hashicorp/consul
subpackages:
@ -64,7 +62,7 @@ import:
subpackages:
- plugin/rewrite
- package: github.com/xenolf/lego
version: cbd5d04c891979c23c3924f198e07ce32b39d282
version: ce8fb060cb8361a9ff8b5fb7c2347fa907b6fcac
subpackages:
- acme
- package: golang.org/x/net
@ -100,6 +98,8 @@ import:
version: ^1.1.0
- package: k8s.io/client-go
version: ^v1.5.0
- package: github.com/gambol99/go-marathon
version: ^0.5.1
- package: github.com/gogo/protobuf
version: 0.3
- package: github.com/ArthurHlt/go-eureka-client
@ -113,4 +113,4 @@ import:
- daemon
- package: github.com/google/go-github
- package: github.com/hashicorp/go-version
- package: github.com/mvdan/xurls
- package: github.com/mvdan/xurls

View file

@ -147,7 +147,7 @@ func (_m *Marathon) CreateApplication(application *marathon.Application) (*marat
}
// DeleteApplication provides a mock function with given fields: name
func (_m *Marathon) DeleteApplication(name string) (*marathon.DeploymentID, error) {
func (_m *Marathon) DeleteApplication(name string, force bool) (*marathon.DeploymentID, error) {
ret := _m.Called(name)
var r0 *marathon.DeploymentID
@ -534,7 +534,7 @@ func (_m *Marathon) CreateGroup(group *marathon.Group) error {
}
// DeleteGroup provides a mock function with given fields: name
func (_m *Marathon) DeleteGroup(name string) (*marathon.DeploymentID, error) {
func (_m *Marathon) DeleteGroup(name string, force bool) (*marathon.DeploymentID, error) {
ret := _m.Called(name)
var r0 *marathon.DeploymentID
@ -557,7 +557,7 @@ func (_m *Marathon) DeleteGroup(name string) (*marathon.DeploymentID, error) {
}
// UpdateGroup provides a mock function with given fields: id, group
func (_m *Marathon) UpdateGroup(id string, group *marathon.Group) (*marathon.DeploymentID, error) {
func (_m *Marathon) UpdateGroup(id string, group *marathon.Group, force bool) (*marathon.DeploymentID, error) {
ret := _m.Called(id, group)
var r0 *marathon.DeploymentID
@ -719,17 +719,18 @@ func (_m *Marathon) Subscriptions() (*marathon.Subscriptions, error) {
}
// AddEventsListener provides a mock function with given fields: channel, filter
func (_m *Marathon) AddEventsListener(channel marathon.EventsChannel, filter int) error {
ret := _m.Called(channel, filter)
func (_m *Marathon) AddEventsListener(filter int) (marathon.EventsChannel, error) {
update := make(marathon.EventsChannel, 5)
ret := _m.Called(update, filter)
var r0 error
if rf, ok := ret.Get(0).(func(marathon.EventsChannel, int) error); ok {
r0 = rf(channel, filter)
r0 = rf(update, filter)
} else {
r0 = ret.Error(0)
}
return r0
return update, r0
}
// RemoveEventsListener provides a mock function with given fields: channel
@ -850,3 +851,33 @@ func (_m *Marathon) AbdicateLeader() (string, error) {
return r0, r1
}
// ApplicationBy mocks the marathon client function but does nothing
func (_m *Marathon) ApplicationBy(name string, opts *marathon.GetAppOpts) (*marathon.Application, error) {
return nil, nil
}
// Subscribe mocks the marathon client function but does nothing
func (_m *Marathon) Subscribe(string) error {
return nil
}
// Queue mocks the marathon client function but does nothing
func (_m *Marathon) Queue() (*marathon.Queue, error) {
return nil, nil
}
// DeleteQueueDelay mocks the marathon client function but does nothing
func (_m *Marathon) DeleteQueueDelay(appID string) error {
return nil
}
// GroupsBy mocks the marathon client function but does nothing
func (_m *Marathon) GroupsBy(opts *marathon.GetGroupOpts) (*marathon.Groups, error) {
return nil, nil
}
// GroupBy mocks the marathon client function but does nothing
func (_m *Marathon) GroupBy(name string, opts *marathon.GetGroupOpts) (*marathon.Group, error) {
return nil, nil
}

View file

@ -83,9 +83,10 @@ func (provider *Marathon) Provide(configurationChan chan<- types.ConfigMessage,
return err
}
provider.marathonClient = client
update := make(marathon.EventsChannel, 5)
if provider.Watch {
if err := client.AddEventsListener(update, marathon.EventIDApplications); err != nil {
update, err := client.AddEventsListener(marathon.EventIDApplications)
if err != nil {
log.Errorf("Failed to register for events, %s", err)
return err
}
@ -129,6 +130,7 @@ func (provider *Marathon) Provide(configurationChan chan<- types.ConfigMessage,
func (provider *Marathon) loadMarathonConfig() *types.Configuration {
var MarathonFuncMap = template.FuncMap{
"getBackend": provider.getBackend,
"getBackendServer": provider.getBackendServer,
"getPort": provider.getPort,
"getWeight": provider.getWeight,
"getDomain": provider.getDomain,
@ -188,15 +190,16 @@ func (provider *Marathon) loadMarathonConfig() *types.Configuration {
}
func (provider *Marathon) taskFilter(task marathon.Task, applications *marathon.Applications, exposedByDefaultFlag bool) bool {
if len(task.Ports) == 0 {
log.Debug("Filtering marathon task without port %s", task.AppID)
return false
}
application, err := getApplication(task, applications.Apps)
if err != nil {
log.Errorf("Unable to get marathon application from task %s", task.AppID)
return false
}
ports := processPorts(application, task)
if len(ports) == 0 {
log.Debug("Filtering marathon task without port %s", task.AppID)
return false
}
label, _ := provider.getLabel(application, "traefik.tags")
constraintTags := strings.Split(label, ",")
if provider.MarathonLBCompatibility {
@ -223,10 +226,9 @@ func (provider *Marathon) taskFilter(task marathon.Task, applications *marathon.
log.Debugf("Filtering marathon task %s specifying both traefik.portIndex and traefik.port labels", task.AppID)
return false
}
if portIndexLabel != "" {
index, err := strconv.Atoi((*application.Labels)["traefik.portIndex"])
if err != nil || index < 0 || index > len(application.Ports)-1 {
if err != nil || index < 0 || index > len(ports)-1 {
log.Debugf("Filtering marathon task %s with unexpected value for traefik.portIndex label", task.AppID)
return false
}
@ -239,7 +241,7 @@ func (provider *Marathon) taskFilter(task marathon.Task, applications *marathon.
}
var foundPort bool
for _, exposedPort := range task.Ports {
for _, exposedPort := range ports {
if port == exposedPort {
foundPort = true
break
@ -315,17 +317,17 @@ func (provider *Marathon) getPort(task marathon.Task, applications []marathon.Ap
log.Errorf("Unable to get marathon application from task %s", task.AppID)
return ""
}
ports := processPorts(application, task)
if portIndexLabel, err := provider.getLabel(application, "traefik.portIndex"); err == nil {
if index, err := strconv.Atoi(portIndexLabel); err == nil {
return strconv.Itoa(task.Ports[index])
return strconv.Itoa(ports[index])
}
}
if portValueLabel, err := provider.getLabel(application, "traefik.port"); err == nil {
return portValueLabel
}
for _, port := range task.Ports {
for _, port := range ports {
return strconv.Itoa(port)
}
return ""
@ -488,3 +490,62 @@ func (provider *Marathon) getCircuitBreakerExpression(application marathon.Appli
}
return "NetworkErrorRatio() > 1"
}
func processPorts(application marathon.Application, task marathon.Task) []int {
// First using application ports
if len(application.Ports) > 0 {
return application.Ports
}
// Using default port configuration
if task.Ports != nil && len(task.Ports) > 0 {
return task.Ports
}
// Using port definition if available
if application.PortDefinitions != nil && len(*application.PortDefinitions) > 0 {
ports := make([]int, 0)
for _, def := range *application.PortDefinitions {
if def.Port != nil {
ports = append(ports, *def.Port)
}
}
return ports
}
// If using IP-per-task using this port definition
if application.IPAddressPerTask != nil && len(*((*application.IPAddressPerTask).Discovery).Ports) > 0 {
ports := make([]int, 0)
for _, def := range *((*application.IPAddressPerTask).Discovery).Ports {
ports = append(ports, def.Number)
}
return ports
}
return []int{}
}
func (provider *Marathon) getBackendServer(task marathon.Task, applications []marathon.Application) string {
application, err := getApplication(task, applications)
if err != nil {
log.Errorf("Unable to get marathon application from task %s", task.AppID)
return ""
}
if len(task.IPAddresses) == 0 {
return ""
} else if len(task.IPAddresses) == 1 {
return task.IPAddresses[0].IPAddress
} else {
ipAddressIdxStr, err := provider.getLabel(application, "traefik.ipAddressIdx")
if err != nil {
log.Errorf("Unable to get marathon IPAddress from task %s", task.AppID)
return ""
}
ipAddressIdx, err := strconv.Atoi(ipAddressIdxStr)
if err != nil {
log.Errorf("Invalid marathon IPAddress from task %s", task.AppID)
return ""
}
return task.IPAddresses[ipAddressIdx].IPAddress
}
}

View file

@ -80,8 +80,14 @@ func TestMarathonLoadConfig(t *testing.T) {
{
ID: "test",
AppID: "/test",
Host: "127.0.0.1",
Host: "localhost",
Ports: []int{80},
IPAddresses: []*marathon.IPAddress{
{
IPAddress: "127.0.0.1",
Protocol: "tcp",
},
},
},
},
},
@ -127,8 +133,14 @@ func TestMarathonLoadConfig(t *testing.T) {
{
ID: "testLoadBalancerAndCircuitBreaker.dot",
AppID: "/testLoadBalancerAndCircuitBreaker.dot",
Host: "127.0.0.1",
Host: "localhost",
Ports: []int{80},
IPAddresses: []*marathon.IPAddress{
{
IPAddress: "127.0.0.1",
Protocol: "tcp",
},
},
},
},
},
@ -179,8 +191,14 @@ func TestMarathonLoadConfig(t *testing.T) {
{
ID: "testMaxConn",
AppID: "/testMaxConn",
Host: "127.0.0.1",
Host: "localhost",
Ports: []int{80},
IPAddresses: []*marathon.IPAddress{
{
IPAddress: "127.0.0.1",
Protocol: "tcp",
},
},
},
},
},
@ -228,8 +246,14 @@ func TestMarathonLoadConfig(t *testing.T) {
{
ID: "testMaxConnOnlySpecifyAmount",
AppID: "/testMaxConnOnlySpecifyAmount",
Host: "127.0.0.1",
Host: "localhost",
Ports: []int{80},
IPAddresses: []*marathon.IPAddress{
{
IPAddress: "127.0.0.1",
Protocol: "tcp",
},
},
},
},
},
@ -274,8 +298,14 @@ func TestMarathonLoadConfig(t *testing.T) {
{
ID: "testMaxConnOnlyExtractorFunc",
AppID: "/testMaxConnOnlyExtractorFunc",
Host: "127.0.0.1",
Host: "localhost",
Ports: []int{80},
IPAddresses: []*marathon.IPAddress{
{
IPAddress: "127.0.0.1",
Protocol: "tcp",
},
},
},
},
},
@ -387,7 +417,89 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
task: marathon.Task{
AppID: "disable",
AppID: "ipAddressOnePort",
},
applications: &marathon.Applications{
Apps: []marathon.Application{
{
ID: "ipAddressOnePort",
IPAddressPerTask: &marathon.IPAddressPerTask{
Discovery: &marathon.Discovery{
Ports: &[]marathon.Port{
{
Number: 8880,
Name: "p1",
},
},
},
},
Labels: &map[string]string{},
},
},
},
expected: true,
exposedByDefault: true,
},
{
task: marathon.Task{
AppID: "ipAddressTwoPortsUseFirst",
},
applications: &marathon.Applications{
Apps: []marathon.Application{
{
ID: "ipAddressTwoPortsUseFirst",
IPAddressPerTask: &marathon.IPAddressPerTask{
Discovery: &marathon.Discovery{
Ports: &[]marathon.Port{
{
Number: 8898,
Name: "p1",
}, {
Number: 9999,
Name: "p1",
},
},
},
},
Labels: &map[string]string{},
},
},
},
expected: true,
exposedByDefault: true,
},
{
task: marathon.Task{
AppID: "ipAddressValidTwoPorts",
},
applications: &marathon.Applications{
Apps: []marathon.Application{
{
ID: "ipAddressValidTwoPorts",
IPAddressPerTask: &marathon.IPAddressPerTask{
Discovery: &marathon.Discovery{
Ports: &[]marathon.Port{
{
Number: 8898,
Name: "p1",
}, {
Number: 9999,
Name: "p2",
},
},
},
},
Labels: &map[string]string{
"traefik.portIndex": "0",
},
},
},
},
expected: true,
exposedByDefault: true,
},
{
task: marathon.Task{
Ports: []int{80},
},
applications: &marathon.Applications{

View file

@ -1,7 +1,7 @@
{{$apps := .Applications}}
[backends]{{range .Tasks}}
[backends."backend{{getBackend . $apps}}".servers."server-{{.ID | replace "." "-"}}"]
url = "{{getProtocol . $apps}}://{{.Host}}:{{getPort . $apps}}"
url = "{{getProtocol . $apps}}://{{getBackendServer . $apps}}:{{getPort . $apps}}"
weight = {{getWeight . $apps}}
{{end}}