Add marathon label to configure basic auth, similar to docker and rancher providers
This commit is contained in:
parent
c31b4c55c2
commit
4dfbb6d489
4 changed files with 62 additions and 5 deletions
|
@ -607,7 +607,6 @@ If you want Træfik to watch file changes automatically, just add:
|
||||||
watch = true
|
watch = true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## API backend
|
## API backend
|
||||||
|
|
||||||
Træfik can be configured using a RESTful api.
|
Træfik can be configured using a RESTful api.
|
||||||
|
@ -912,8 +911,9 @@ Labels can be used on containers to override default behaviour:
|
||||||
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
|
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
|
||||||
- `traefik.frontend.priority=10`: override default frontend priority
|
- `traefik.frontend.priority=10`: override default frontend priority
|
||||||
- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`.
|
- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`.
|
||||||
- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets a Basic Auth for that frontend with the users test:test and test2:test2
|
- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively
|
||||||
- `traefik.frontend.whitelistSourceRange: "1.2.3.0/24, fe80::/16"`: List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access.- `traefik.docker.network`: Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with docker inspect <container_id>) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name.
|
- `traefik.frontend.whitelistSourceRange: "1.2.3.0/24, fe80::/16"`: List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access.
|
||||||
|
- `traefik.docker.network`: Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with docker inspect <container_id>) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name.
|
||||||
|
|
||||||
If several ports need to be exposed from a container, the services labels can be used
|
If several ports need to be exposed from a container, the services labels can be used
|
||||||
- `traefik.<service-name>.port=443`: create a service binding with frontend/backend using this port. Overrides `traefik.port`.
|
- `traefik.<service-name>.port=443`: create a service binding with frontend/backend using this port. Overrides `traefik.port`.
|
||||||
|
@ -1068,6 +1068,7 @@ Labels can be used on containers to override default behaviour:
|
||||||
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
|
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
|
||||||
- `traefik.frontend.priority=10`: override default frontend priority
|
- `traefik.frontend.priority=10`: override default frontend priority
|
||||||
- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`.
|
- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`.
|
||||||
|
- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively
|
||||||
|
|
||||||
|
|
||||||
## Mesos generic backend
|
## Mesos generic backend
|
||||||
|
@ -1768,7 +1769,7 @@ Labels can be used on task containers to override default behaviour:
|
||||||
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
|
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
|
||||||
- `traefik.frontend.priority=10`: override default frontend priority
|
- `traefik.frontend.priority=10`: override default frontend priority
|
||||||
- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`.
|
- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`.
|
||||||
- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets a Basic Auth for that frontend with the users test:test and test2:test2
|
- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively
|
||||||
|
|
||||||
|
|
||||||
## DynamoDB backend
|
## DynamoDB backend
|
||||||
|
|
|
@ -163,6 +163,7 @@ func (p *Provider) loadMarathonConfig() *types.Configuration {
|
||||||
"hasHealthCheckLabels": p.hasHealthCheckLabels,
|
"hasHealthCheckLabels": p.hasHealthCheckLabels,
|
||||||
"getHealthCheckPath": p.getHealthCheckPath,
|
"getHealthCheckPath": p.getHealthCheckPath,
|
||||||
"getHealthCheckInterval": p.getHealthCheckInterval,
|
"getHealthCheckInterval": p.getHealthCheckInterval,
|
||||||
|
"getBasicAuth": p.getBasicAuth,
|
||||||
}
|
}
|
||||||
|
|
||||||
applications, err := p.marathonClient.Applications(nil)
|
applications, err := p.marathonClient.Applications(nil)
|
||||||
|
@ -485,6 +486,14 @@ func (p *Provider) getHealthCheckInterval(application marathon.Application) stri
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getBasicAuth(application marathon.Application) []string {
|
||||||
|
if basicAuth, ok := p.getLabel(application, "traefik.frontend.auth.basic"); ok {
|
||||||
|
return strings.Split(basicAuth, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
func processPorts(application marathon.Application, task marathon.Task) (int, error) {
|
func processPorts(application marathon.Application, task marathon.Task) (int, error) {
|
||||||
if portLabel, ok := (*application.Labels)[labelPort]; ok {
|
if portLabel, ok := (*application.Labels)[labelPort]; ok {
|
||||||
port, err := strconv.Atoi(portLabel)
|
port, err := strconv.Atoi(portLabel)
|
||||||
|
|
|
@ -98,6 +98,7 @@ func TestMarathonLoadConfig(t *testing.T) {
|
||||||
`frontend-test`: {
|
`frontend-test`: {
|
||||||
Backend: "backend-test",
|
Backend: "backend-test",
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
|
BasicAuth: []string{},
|
||||||
EntryPoints: []string{},
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
`route-host-test`: {
|
`route-host-test`: {
|
||||||
|
@ -151,6 +152,7 @@ func TestMarathonLoadConfig(t *testing.T) {
|
||||||
`frontend-testLoadBalancerAndCircuitBreaker.dot`: {
|
`frontend-testLoadBalancerAndCircuitBreaker.dot`: {
|
||||||
Backend: "backend-testLoadBalancerAndCircuitBreaker.dot",
|
Backend: "backend-testLoadBalancerAndCircuitBreaker.dot",
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
|
BasicAuth: []string{},
|
||||||
EntryPoints: []string{},
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
`route-host-testLoadBalancerAndCircuitBreaker.dot`: {
|
`route-host-testLoadBalancerAndCircuitBreaker.dot`: {
|
||||||
|
@ -209,6 +211,7 @@ func TestMarathonLoadConfig(t *testing.T) {
|
||||||
`frontend-testMaxConn`: {
|
`frontend-testMaxConn`: {
|
||||||
Backend: "backend-testMaxConn",
|
Backend: "backend-testMaxConn",
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
|
BasicAuth: []string{},
|
||||||
EntryPoints: []string{},
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
`route-host-testMaxConn`: {
|
`route-host-testMaxConn`: {
|
||||||
|
@ -264,6 +267,7 @@ func TestMarathonLoadConfig(t *testing.T) {
|
||||||
`frontend-testMaxConnOnlySpecifyAmount`: {
|
`frontend-testMaxConnOnlySpecifyAmount`: {
|
||||||
Backend: "backend-testMaxConnOnlySpecifyAmount",
|
Backend: "backend-testMaxConnOnlySpecifyAmount",
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
|
BasicAuth: []string{},
|
||||||
EntryPoints: []string{},
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
`route-host-testMaxConnOnlySpecifyAmount`: {
|
`route-host-testMaxConnOnlySpecifyAmount`: {
|
||||||
|
@ -316,6 +320,7 @@ func TestMarathonLoadConfig(t *testing.T) {
|
||||||
`frontend-testMaxConnOnlyExtractorFunc`: {
|
`frontend-testMaxConnOnlyExtractorFunc`: {
|
||||||
Backend: "backend-testMaxConnOnlyExtractorFunc",
|
Backend: "backend-testMaxConnOnlyExtractorFunc",
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
|
BasicAuth: []string{},
|
||||||
EntryPoints: []string{},
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
`route-host-testMaxConnOnlyExtractorFunc`: {
|
`route-host-testMaxConnOnlyExtractorFunc`: {
|
||||||
|
@ -369,6 +374,7 @@ func TestMarathonLoadConfig(t *testing.T) {
|
||||||
"frontend-testHealthCheck": {
|
"frontend-testHealthCheck": {
|
||||||
Backend: "backend-testHealthCheck",
|
Backend: "backend-testHealthCheck",
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
|
BasicAuth: []string{},
|
||||||
EntryPoints: []string{},
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"route-host-testHealthCheck": {
|
"route-host-testHealthCheck": {
|
||||||
|
@ -1368,7 +1374,7 @@ func TestMarathonGetEntryPoints(t *testing.T) {
|
||||||
for _, a := range applications {
|
for _, a := range applications {
|
||||||
actual := provider.getEntryPoints(a.application)
|
actual := provider.getEntryPoints(a.application)
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, a.expected) {
|
if !reflect.DeepEqual(a.expected, actual) {
|
||||||
t.Fatalf("expected %#v, got %#v", a.expected, actual)
|
t.Fatalf("expected %#v, got %#v", a.expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1800,3 +1806,41 @@ func TestParseIndex(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMarathonGetBasicAuth(t *testing.T) {
|
||||||
|
provider := &Provider{}
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
desc string
|
||||||
|
application marathon.Application
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "basic auth label is empty",
|
||||||
|
application: marathon.Application{
|
||||||
|
Labels: &map[string]string{}},
|
||||||
|
expected: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "basic auth label is set with user:password",
|
||||||
|
application: marathon.Application{
|
||||||
|
Labels: &map[string]string{
|
||||||
|
"traefik.frontend.auth.basic": "user:password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{"user:password"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
c := c
|
||||||
|
t.Run(c.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
actual := provider.getBasicAuth(c.application)
|
||||||
|
if !reflect.DeepEqual(c.expected, actual) {
|
||||||
|
t.Errorf("expected %q, got %q", c.expected, actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,9 @@
|
||||||
priority = {{getPriority .}}
|
priority = {{getPriority .}}
|
||||||
entryPoints = [{{range getEntryPoints .}}
|
entryPoints = [{{range getEntryPoints .}}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
|
{{end}}]
|
||||||
|
basicAuth = [{{range getBasicAuth .}}
|
||||||
|
"{{.}}",
|
||||||
{{end}}]
|
{{end}}]
|
||||||
[frontends."frontend{{.ID | replace "/" "-"}}".routes."route-host{{.ID | replace "/" "-"}}"]
|
[frontends."frontend{{.ID | replace "/" "-"}}".routes."route-host{{.ID | replace "/" "-"}}"]
|
||||||
rule = "{{getFrontendRule .}}"
|
rule = "{{getFrontendRule .}}"
|
||||||
|
|
Loading…
Reference in a new issue