diff --git a/cmd.go b/cmd.go index 76e53d1cf..e0639197c 100644 --- a/cmd.go +++ b/cmd.go @@ -126,6 +126,7 @@ func init() { traefikCmd.PersistentFlags().StringVar(&arguments.Marathon.Filename, "marathon.filename", "", "Override default configuration template. For advanced users :)") traefikCmd.PersistentFlags().StringVar(&arguments.Marathon.Endpoint, "marathon.endpoint", "http://127.0.0.1:8080", "Marathon server endpoint. You can also specify multiple endpoint for Marathon") traefikCmd.PersistentFlags().StringVar(&arguments.Marathon.Domain, "marathon.domain", "", "Default domain used") + traefikCmd.PersistentFlags().BoolVar(&arguments.Marathon.ExposedByDefault, "marathon.exposedByDefault", true, "Expose Marathon apps by default") traefikCmd.PersistentFlags().BoolVar(&arguments.consul, "consul", false, "Enable Consul backend") traefikCmd.PersistentFlags().BoolVar(&arguments.Consul.Watch, "consul.watch", true, "Watch provider") diff --git a/provider/marathon.go b/provider/marathon.go index de6a3bef8..787b8e8fd 100644 --- a/provider/marathon.go +++ b/provider/marathon.go @@ -17,12 +17,13 @@ import ( // Marathon holds configuration of the Marathon provider. type Marathon struct { - BaseProvider `mapstructure:",squash"` - Endpoint string - Domain string - Basic *MarathonBasic - TLS *tls.Config - marathonClient marathon.Marathon + BaseProvider `mapstructure:",squash"` + Endpoint string + Domain string + ExposedByDefault bool + Basic *MarathonBasic + TLS *tls.Config + marathonClient marathon.Marathon } // MarathonBasic holds basic authentication specific configurations @@ -115,7 +116,7 @@ func (provider *Marathon) loadMarathonConfig() *types.Configuration { //filter tasks filteredTasks := fun.Filter(func(task marathon.Task) bool { - return taskFilter(task, applications) + return taskFilter(task, applications, provider.ExposedByDefault) }, tasks.Tasks).([]marathon.Task) //filter apps @@ -140,7 +141,7 @@ func (provider *Marathon) loadMarathonConfig() *types.Configuration { return configuration } -func taskFilter(task marathon.Task, applications *marathon.Applications) bool { +func 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 @@ -150,7 +151,8 @@ func taskFilter(task marathon.Task, applications *marathon.Applications) bool { log.Errorf("Unable to get marathon application from task %s", task.AppID) return false } - if application.Labels["traefik.enable"] == "false" { + + if !isApplicationEnabled(application, exposedByDefaultFlag) { log.Debugf("Filtering disabled marathon task %s", task.AppID) return false } @@ -227,6 +229,10 @@ func getApplication(task marathon.Task, apps []marathon.Application) (marathon.A return marathon.Application{}, errors.New("Application not found: " + task.AppID) } +func isApplicationEnabled(application marathon.Application, exposedByDefault bool) bool { + return exposedByDefault && application.Labels["traefik.enable"] != "false" || application.Labels["traefik.enable"] == "true" +} + func (provider *Marathon) getLabel(application marathon.Application, label string) (string, error) { for key, value := range application.Labels { if key == label { diff --git a/provider/marathon_test.go b/provider/marathon_test.go index 56958bfe3..32fd00698 100644 --- a/provider/marathon_test.go +++ b/provider/marathon_test.go @@ -110,8 +110,9 @@ func TestMarathonLoadConfig(t *testing.T) { for _, c := range cases { fakeClient := newFakeClient(c.applicationsError, c.applications, c.tasksError, c.tasks) provider := &Marathon{ - Domain: "docker.localhost", - marathonClient: fakeClient, + Domain: "docker.localhost", + ExposedByDefault: true, + marathonClient: fakeClient, } actualConfig := provider.loadMarathonConfig() if c.expectedNil { @@ -132,22 +133,25 @@ func TestMarathonLoadConfig(t *testing.T) { func TestMarathonTaskFilter(t *testing.T) { cases := []struct { - task marathon.Task - applications *marathon.Applications - expected bool + task marathon.Task + applications *marathon.Applications + expected bool + exposedByDefault bool }{ { - task: marathon.Task{}, - applications: &marathon.Applications{}, - expected: false, + task: marathon.Task{}, + applications: &marathon.Applications{}, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ AppID: "test", Ports: []int{80}, }, - applications: &marathon.Applications{}, - expected: false, + applications: &marathon.Applications{}, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -161,7 +165,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -176,7 +181,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -194,7 +200,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -212,7 +219,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: true, + expected: true, + exposedByDefault: true, }, { task: marathon.Task{ @@ -230,7 +238,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -248,7 +257,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: true, + expected: true, + exposedByDefault: true, }, { task: marathon.Task{ @@ -266,7 +276,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -285,7 +296,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -303,7 +315,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -326,7 +339,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -352,7 +366,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: false, + expected: false, + exposedByDefault: true, }, { task: marathon.Task{ @@ -367,7 +382,8 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: true, + expected: true, + exposedByDefault: true, }, { task: marathon.Task{ @@ -390,12 +406,67 @@ func TestMarathonTaskFilter(t *testing.T) { }, }, }, - expected: true, + expected: true, + exposedByDefault: true, + }, + { + task: marathon.Task{ + AppID: "disable-default-expose", + Ports: []int{80}, + }, + applications: &marathon.Applications{ + Apps: []marathon.Application{ + { + ID: "disable-default-expose", + Ports: []int{80}, + }, + }, + }, + expected: false, + exposedByDefault: false, + }, + { + task: marathon.Task{ + AppID: "disable-default-expose-disable-in-label", + Ports: []int{80}, + }, + applications: &marathon.Applications{ + Apps: []marathon.Application{ + { + ID: "disable-default-expose-disable-in-label", + Ports: []int{80}, + Labels: map[string]string{ + "traefik.enable": "false", + }, + }, + }, + }, + expected: false, + exposedByDefault: false, + }, + { + task: marathon.Task{ + AppID: "disable-default-expose-enable-in-label", + Ports: []int{80}, + }, + applications: &marathon.Applications{ + Apps: []marathon.Application{ + { + ID: "disable-default-expose-enable-in-label", + Ports: []int{80}, + Labels: map[string]string{ + "traefik.enable": "true", + }, + }, + }, + }, + expected: true, + exposedByDefault: false, }, } for _, c := range cases { - actual := taskFilter(c.task, c.applications) + actual := taskFilter(c.task, c.applications, c.exposedByDefault) if actual != c.expected { t.Fatalf("expected %v, got %v", c.expected, actual) }