1
0
Fork 0

Adding compatibility for marathon 1.5

This commit is contained in:
Trevin Teacutter 2018-07-03 16:42:03 -05:00 committed by Traefiker Bot
parent 461ebf6d88
commit 04d8b5d483
35 changed files with 2257 additions and 63 deletions

View file

@ -83,6 +83,24 @@ func portDefinition(port int) func(*marathon.Application) {
}
}
func bridgeNetwork() func(*marathon.Application) {
return func(app *marathon.Application) {
app.SetNetwork("bridge", marathon.BridgeNetworkMode)
}
}
func containerNetwork() func(*marathon.Application) {
return func(app *marathon.Application) {
app.SetNetwork("cni", marathon.ContainerNetworkMode)
}
}
func hostNetwork() func(*marathon.Application) {
return func(app *marathon.Application) {
app.SetNetwork("host", marathon.HostNetworkMode)
}
}
func ipAddrPerTask(port int) func(*marathon.Application) {
return func(app *marathon.Application) {
p := marathon.Port{

View file

@ -347,7 +347,16 @@ func (p *Provider) getServer(app appData, task marathon.Task) (string, *types.Se
}
func (p *Provider) getServerHost(task marathon.Task, app appData) (string, error) {
if app.IPAddressPerTask == nil || p.ForceTaskHostname {
networks := app.Networks
var hostFlag bool
if networks == nil {
hostFlag = app.IPAddressPerTask == nil
} else {
hostFlag = (*networks)[0].Mode != marathon.ContainerNetworkMode
}
if hostFlag || p.ForceTaskHostname {
if len(task.Host) == 0 {
return "", fmt.Errorf("host is undefined for task %q app %q", task.ID, app.ID)
}

View file

@ -1289,7 +1289,30 @@ func TestGetServers(t *testing.T) {
expected: nil,
},
{
desc: "with 3 tasks",
desc: "with 3 tasks and hosts set",
application: application(
withTasks(
task(ipAddresses("1.1.1.1"), host("2.2.2.2"), withTaskID("A"), taskPorts(80)),
task(ipAddresses("1.1.1.2"), host("2.2.2.2"), withTaskID("B"), taskPorts(81)),
task(ipAddresses("1.1.1.3"), host("2.2.2.2"), withTaskID("C"), taskPorts(82))),
),
expected: map[string]types.Server{
"server-A": {
URL: "http://2.2.2.2:80",
Weight: label.DefaultWeight,
},
"server-B": {
URL: "http://2.2.2.2:81",
Weight: label.DefaultWeight,
},
"server-C": {
URL: "http://2.2.2.2:82",
Weight: label.DefaultWeight,
},
},
},
{
desc: "with 3 tasks and ipAddrPerTask set",
application: application(
ipAddrPerTask(80),
withTasks(
@ -1312,20 +1335,66 @@ func TestGetServers(t *testing.T) {
},
},
},
{
desc: "with 3 tasks and bridge network",
application: application(
bridgeNetwork(),
withTasks(
task(ipAddresses("1.1.1.1"), host("2.2.2.2"), withTaskID("A"), taskPorts(80)),
task(ipAddresses("1.1.1.2"), host("2.2.2.2"), withTaskID("B"), taskPorts(81)),
task(ipAddresses("1.1.1.3"), host("2.2.2.2"), withTaskID("C"), taskPorts(82))),
),
expected: map[string]types.Server{
"server-A": {
URL: "http://2.2.2.2:80",
Weight: label.DefaultWeight,
},
"server-B": {
URL: "http://2.2.2.2:81",
Weight: label.DefaultWeight,
},
"server-C": {
URL: "http://2.2.2.2:82",
Weight: label.DefaultWeight,
},
},
},
{
desc: "with 3 tasks and cni set",
application: application(
containerNetwork(),
withTasks(
task(ipAddresses("1.1.1.1"), withTaskID("A"), taskPorts(80)),
task(ipAddresses("1.1.1.2"), withTaskID("B"), taskPorts(80)),
task(ipAddresses("1.1.1.3"), withTaskID("C"), taskPorts(80))),
),
expected: map[string]types.Server{
"server-A": {
URL: "http://1.1.1.1:80",
Weight: label.DefaultWeight,
},
"server-B": {
URL: "http://1.1.1.2:80",
Weight: label.DefaultWeight,
},
"server-C": {
URL: "http://1.1.1.3:80",
Weight: label.DefaultWeight,
},
},
},
}
p := &Provider{}
for _, test := range testCases {
test := test
if test.desc == "should return nil when all hosts are empty" {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
actual := p.getServers(withAppData(test.application, test.segmentName))
actual := p.getServers(withAppData(test.application, test.segmentName))
assert.Equal(t, test.expected, actual)
})
}
assert.Equal(t, test.expected, actual)
})
}
}

View file

@ -147,11 +147,21 @@ func (p *Provider) getFrontendRuleV1(application marathon.Application, serviceNa
// Deprecated
func (p *Provider) getBackendServerV1(task marathon.Task, application marathon.Application) string {
if application.IPAddressPerTask == nil || p.ForceTaskHostname {
networks := application.Networks
var hostFlag bool
if networks == nil {
hostFlag = application.IPAddressPerTask == nil
} else {
hostFlag = (*networks)[0].Mode != marathon.ContainerNetworkMode
}
if hostFlag || p.ForceTaskHostname {
return task.Host
}
numTaskIPAddresses := len(task.IPAddresses)
switch numTaskIPAddresses {
case 0:
log.Errorf("Missing IP address for Marathon application %s on task %s", application.ID, task.ID)

View file

@ -784,7 +784,30 @@ func TestGetServersV1(t *testing.T) {
expected: nil,
},
{
desc: "with 3 tasks",
desc: "with 3 tasks and hosts set",
application: application(
withTasks(
task(ipAddresses("1.1.1.1"), host("2.2.2.2"), withTaskID("A"), taskPorts(80)),
task(ipAddresses("1.1.1.2"), host("2.2.2.2"), withTaskID("B"), taskPorts(81)),
task(ipAddresses("1.1.1.3"), host("2.2.2.2"), withTaskID("C"), taskPorts(82))),
),
expected: map[string]types.Server{
"server-A": {
URL: "http://2.2.2.2:80",
Weight: label.DefaultWeight,
},
"server-B": {
URL: "http://2.2.2.2:81",
Weight: label.DefaultWeight,
},
"server-C": {
URL: "http://2.2.2.2:82",
Weight: label.DefaultWeight,
},
},
},
{
desc: "with 3 tasks and ipAddrPerTask set",
application: application(
ipAddrPerTask(80),
withTasks(
@ -807,20 +830,66 @@ func TestGetServersV1(t *testing.T) {
},
},
},
{
desc: "with 3 tasks and bridge network",
application: application(
bridgeNetwork(),
withTasks(
task(ipAddresses("1.1.1.1"), host("2.2.2.2"), withTaskID("A"), taskPorts(80)),
task(ipAddresses("1.1.1.2"), host("2.2.2.2"), withTaskID("B"), taskPorts(81)),
task(ipAddresses("1.1.1.3"), host("2.2.2.2"), withTaskID("C"), taskPorts(82))),
),
expected: map[string]types.Server{
"server-A": {
URL: "http://2.2.2.2:80",
Weight: label.DefaultWeight,
},
"server-B": {
URL: "http://2.2.2.2:81",
Weight: label.DefaultWeight,
},
"server-C": {
URL: "http://2.2.2.2:82",
Weight: label.DefaultWeight,
},
},
},
{
desc: "with 3 tasks and cni set",
application: application(
containerNetwork(),
withTasks(
task(ipAddresses("1.1.1.1"), withTaskID("A"), taskPorts(80)),
task(ipAddresses("1.1.1.2"), withTaskID("B"), taskPorts(80)),
task(ipAddresses("1.1.1.3"), withTaskID("C"), taskPorts(80))),
),
expected: map[string]types.Server{
"server-A": {
URL: "http://1.1.1.1:80",
Weight: label.DefaultWeight,
},
"server-B": {
URL: "http://1.1.1.2:80",
Weight: label.DefaultWeight,
},
"server-C": {
URL: "http://1.1.1.3:80",
Weight: label.DefaultWeight,
},
},
},
}
p := &Provider{}
for _, test := range testCases {
test := test
if test.desc == "should return nil when all hosts are empty" {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
actual := p.getServersV1(test.application, test.segmentName)
actual := p.getServersV1(test.application, test.segmentName)
assert.Equal(t, test.expected, actual)
})
}
assert.Equal(t, test.expected, actual)
})
}
}

View file

@ -1,4 +1,4 @@
// Package mocks Code generated by mockery v1.0.0
// Package mocks Code generated by mockery v1.0.0. DO NOT EDIT.
// mockery -recursive -dir=vendor/github.com/gambol99/ -name=Marathon -output=provider/marathon/mocks
package mocks
@ -278,6 +278,29 @@ func (_m *Marathon) CreateGroup(group *marathon.Group) error {
return r0
}
// CreatePod provides a mock function with given fields: pod
func (_m *Marathon) CreatePod(pod *marathon.Pod) (*marathon.Pod, error) {
ret := _m.Called(pod)
var r0 *marathon.Pod
if rf, ok := ret.Get(0).(func(*marathon.Pod) *marathon.Pod); ok {
r0 = rf(pod)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*marathon.Pod)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*marathon.Pod) error); ok {
r1 = rf(pod)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DeleteApplication provides a mock function with given fields: name, force
func (_m *Marathon) DeleteApplication(name string, force bool) (*marathon.DeploymentID, error) {
ret := _m.Called(name, force)
@ -347,6 +370,75 @@ func (_m *Marathon) DeleteGroup(name string, force bool) (*marathon.DeploymentID
return r0, r1
}
// DeletePod provides a mock function with given fields: name, force
func (_m *Marathon) DeletePod(name string, force bool) (*marathon.DeploymentID, error) {
ret := _m.Called(name, force)
var r0 *marathon.DeploymentID
if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok {
r0 = rf(name, force)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*marathon.DeploymentID)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, bool) error); ok {
r1 = rf(name, force)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DeletePodInstance provides a mock function with given fields: name, instance
func (_m *Marathon) DeletePodInstance(name string, instance string) (*marathon.PodInstance, error) {
ret := _m.Called(name, instance)
var r0 *marathon.PodInstance
if rf, ok := ret.Get(0).(func(string, string) *marathon.PodInstance); ok {
r0 = rf(name, instance)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*marathon.PodInstance)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(name, instance)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DeletePodInstances provides a mock function with given fields: name, instances
func (_m *Marathon) DeletePodInstances(name string, instances []string) ([]*marathon.PodInstance, error) {
ret := _m.Called(name, instances)
var r0 []*marathon.PodInstance
if rf, ok := ret.Get(0).(func(string, []string) []*marathon.PodInstance); ok {
r0 = rf(name, instances)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*marathon.PodInstance)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, []string) error); ok {
r1 = rf(name, instances)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DeleteQueueDelay provides a mock function with given fields: appID
func (_m *Marathon) DeleteQueueDelay(appID string) error {
ret := _m.Called(appID)
@ -701,6 +793,158 @@ func (_m *Marathon) Ping() (bool, error) {
return r0, r1
}
// Pod provides a mock function with given fields: name
func (_m *Marathon) Pod(name string) (*marathon.Pod, error) {
ret := _m.Called(name)
var r0 *marathon.Pod
if rf, ok := ret.Get(0).(func(string) *marathon.Pod); ok {
r0 = rf(name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*marathon.Pod)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// PodByVersion provides a mock function with given fields: name, version
func (_m *Marathon) PodByVersion(name string, version string) (*marathon.Pod, error) {
ret := _m.Called(name, version)
var r0 *marathon.Pod
if rf, ok := ret.Get(0).(func(string, string) *marathon.Pod); ok {
r0 = rf(name, version)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*marathon.Pod)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(name, version)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// PodIsRunning provides a mock function with given fields: name
func (_m *Marathon) PodIsRunning(name string) bool {
ret := _m.Called(name)
var r0 bool
if rf, ok := ret.Get(0).(func(string) bool); ok {
r0 = rf(name)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// PodStatus provides a mock function with given fields: name
func (_m *Marathon) PodStatus(name string) (*marathon.PodStatus, error) {
ret := _m.Called(name)
var r0 *marathon.PodStatus
if rf, ok := ret.Get(0).(func(string) *marathon.PodStatus); ok {
r0 = rf(name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*marathon.PodStatus)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// PodStatuses provides a mock function with given fields:
func (_m *Marathon) PodStatuses() ([]*marathon.PodStatus, error) {
ret := _m.Called()
var r0 []*marathon.PodStatus
if rf, ok := ret.Get(0).(func() []*marathon.PodStatus); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*marathon.PodStatus)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// PodVersions provides a mock function with given fields: name
func (_m *Marathon) PodVersions(name string) ([]string, error) {
ret := _m.Called(name)
var r0 []string
if rf, ok := ret.Get(0).(func(string) []string); ok {
r0 = rf(name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Pods provides a mock function with given fields:
func (_m *Marathon) Pods() ([]marathon.Pod, error) {
ret := _m.Called()
var r0 []marathon.Pod
if rf, ok := ret.Get(0).(func() []marathon.Pod); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]marathon.Pod)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Queue provides a mock function with given fields:
func (_m *Marathon) Queue() (*marathon.Queue, error) {
ret := _m.Called()
@ -835,6 +1079,27 @@ func (_m *Marathon) Subscriptions() (*marathon.Subscriptions, error) {
return r0, r1
}
// SupportsPods provides a mock function with given fields:
func (_m *Marathon) SupportsPods() (bool, error) {
ret := _m.Called()
var r0 bool
if rf, ok := ret.Get(0).(func() bool); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// TaskEndpoints provides a mock function with given fields: name, port, healthCheck
func (_m *Marathon) TaskEndpoints(name string, port int, healthCheck bool) ([]string, error) {
ret := _m.Called(name, port, healthCheck)
@ -941,6 +1206,29 @@ func (_m *Marathon) UpdateGroup(id string, group *marathon.Group, force bool) (*
return r0, r1
}
// UpdatePod provides a mock function with given fields: pod, force
func (_m *Marathon) UpdatePod(pod *marathon.Pod, force bool) (*marathon.Pod, error) {
ret := _m.Called(pod, force)
var r0 *marathon.Pod
if rf, ok := ret.Get(0).(func(*marathon.Pod, bool) *marathon.Pod); ok {
r0 = rf(pod, force)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*marathon.Pod)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*marathon.Pod, bool) error); ok {
r1 = rf(pod, force)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// WaitOnApplication provides a mock function with given fields: name, timeout
func (_m *Marathon) WaitOnApplication(name string, timeout time.Duration) error {
ret := _m.Called(name, timeout)
@ -982,3 +1270,17 @@ func (_m *Marathon) WaitOnGroup(name string, timeout time.Duration) error {
return r0
}
// WaitOnPod provides a mock function with given fields: name, timeout
func (_m *Marathon) WaitOnPod(name string, timeout time.Duration) error {
ret := _m.Called(name, timeout)
var r0 error
if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok {
r0 = rf(name, timeout)
} else {
r0 = ret.Error(0)
}
return r0
}