Merge pull request #686 from tuier/marathon_constraints
feat(constraints): Supports constraints for Marathon provider
This commit is contained in:
commit
5d0f82ffbd
2 changed files with 127 additions and 7 deletions
|
@ -153,12 +153,12 @@ func (provider *Marathon) loadMarathonConfig() *types.Configuration {
|
|||
|
||||
//filter tasks
|
||||
filteredTasks := fun.Filter(func(task marathon.Task) bool {
|
||||
return taskFilter(task, applications, provider.ExposedByDefault)
|
||||
return provider.taskFilter(task, applications, provider.ExposedByDefault)
|
||||
}, tasks.Tasks).([]marathon.Task)
|
||||
|
||||
//filter apps
|
||||
filteredApps := fun.Filter(func(app marathon.Application) bool {
|
||||
return applicationFilter(app, filteredTasks)
|
||||
return provider.applicationFilter(app, filteredTasks)
|
||||
}, applications.Apps).([]marathon.Application)
|
||||
|
||||
templateObjects := struct {
|
||||
|
@ -178,7 +178,7 @@ func (provider *Marathon) loadMarathonConfig() *types.Configuration {
|
|||
return configuration
|
||||
}
|
||||
|
||||
func taskFilter(task marathon.Task, applications *marathon.Applications, exposedByDefaultFlag bool) bool {
|
||||
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
|
||||
|
@ -188,6 +188,15 @@ func taskFilter(task marathon.Task, applications *marathon.Applications, exposed
|
|||
log.Errorf("Unable to get marathon application from task %s", task.AppID)
|
||||
return false
|
||||
}
|
||||
if label, err := provider.getLabel(application, "traefik.tags"); err == nil {
|
||||
constraintTags := strings.Split(label, ",")
|
||||
if ok, failingConstraint := provider.MatchConstraints(constraintTags); !ok {
|
||||
if failingConstraint != nil {
|
||||
log.Debugf("Application %v pruned by '%v' constraint", application.ID, failingConstraint.String())
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if !isApplicationEnabled(application, exposedByDefaultFlag) {
|
||||
log.Debugf("Filtering disabled marathon task %s", task.AppID)
|
||||
|
@ -248,7 +257,15 @@ func taskFilter(task marathon.Task, applications *marathon.Applications, exposed
|
|||
return true
|
||||
}
|
||||
|
||||
func applicationFilter(app marathon.Application, filteredTasks []marathon.Task) bool {
|
||||
func (provider *Marathon) applicationFilter(app marathon.Application, filteredTasks []marathon.Task) bool {
|
||||
constraintTags := strings.Split((*app.Labels)["traefik.tags"], ",")
|
||||
if ok, failingConstraint := provider.MatchConstraints(constraintTags); !ok {
|
||||
if failingConstraint != nil {
|
||||
log.Debugf("Application %v pruned by '%v' constraint", app.ID, failingConstraint.String())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return fun.Exists(func(task marathon.Task) bool {
|
||||
return task.AppID == app.ID
|
||||
}, filteredTasks)
|
||||
|
|
|
@ -674,14 +674,114 @@ func TestMarathonTaskFilter(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
provider := &Marathon{}
|
||||
for _, c := range cases {
|
||||
actual := taskFilter(c.task, c.applications, c.exposedByDefault)
|
||||
actual := provider.taskFilter(c.task, c.applications, c.exposedByDefault)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("expected %v, got %v", c.expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarathonAppConstraints(t *testing.T) {
|
||||
cases := []struct {
|
||||
application marathon.Application
|
||||
filteredTasks []marathon.Task
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
application: marathon.Application{
|
||||
ID: "foo1",
|
||||
Labels: &map[string]string{},
|
||||
},
|
||||
filteredTasks: []marathon.Task{
|
||||
{
|
||||
AppID: "foo1",
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
application: marathon.Application{
|
||||
ID: "foo",
|
||||
Labels: &map[string]string{
|
||||
"traefik.tags": "valid",
|
||||
},
|
||||
},
|
||||
filteredTasks: []marathon.Task{
|
||||
{
|
||||
AppID: "foo",
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
provider := &Marathon{}
|
||||
constraint, _ := types.NewConstraint("tag==valid")
|
||||
provider.Constraints = []types.Constraint{*constraint}
|
||||
for _, c := range cases {
|
||||
actual := provider.applicationFilter(c.application, c.filteredTasks)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("expected %v, got %v: %v", c.expected, actual, c.application)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
func TestMarathonTaskConstraints(t *testing.T) {
|
||||
cases := []struct {
|
||||
applications []marathon.Application
|
||||
filteredTask marathon.Task
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
applications: []marathon.Application{
|
||||
{
|
||||
ID: "bar1",
|
||||
Labels: &map[string]string{},
|
||||
}, {
|
||||
ID: "foo1",
|
||||
Labels: &map[string]string{
|
||||
"traefik.tags": "other",
|
||||
},
|
||||
},
|
||||
},
|
||||
filteredTask: marathon.Task{
|
||||
AppID: "foo1",
|
||||
Ports: []int{80},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
applications: []marathon.Application{
|
||||
{
|
||||
ID: "foo2",
|
||||
Labels: &map[string]string{
|
||||
"traefik.tags": "valid",
|
||||
},
|
||||
},
|
||||
},
|
||||
filteredTask: marathon.Task{
|
||||
AppID: "foo2",
|
||||
Ports: []int{80},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
provider := &Marathon{}
|
||||
constraint, _ := types.NewConstraint("tag==valid")
|
||||
provider.Constraints = []types.Constraint{*constraint}
|
||||
for _, c := range cases {
|
||||
apps := new(marathon.Applications)
|
||||
apps.Apps = c.applications
|
||||
actual := provider.taskFilter(c.filteredTask, apps, true)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("expected %v, got %v: %v", c.expected, actual, c.filteredTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarathonApplicationFilter(t *testing.T) {
|
||||
cases := []struct {
|
||||
application marathon.Application
|
||||
|
@ -689,7 +789,9 @@ func TestMarathonApplicationFilter(t *testing.T) {
|
|||
expected bool
|
||||
}{
|
||||
{
|
||||
application: marathon.Application{},
|
||||
application: marathon.Application{
|
||||
Labels: &map[string]string{},
|
||||
},
|
||||
filteredTasks: []marathon.Task{},
|
||||
expected: false,
|
||||
},
|
||||
|
@ -727,8 +829,9 @@ func TestMarathonApplicationFilter(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
provider := &Marathon{}
|
||||
for _, c := range cases {
|
||||
actual := applicationFilter(c.application, c.filteredTasks)
|
||||
actual := provider.applicationFilter(c.application, c.filteredTasks)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("expected %v, got %v", c.expected, actual)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue