Merge pull request #426 from containous/fix-marathon-directory-subdomain
Fix marathon groups subdomain
This commit is contained in:
commit
c5ac563e74
6 changed files with 86 additions and 16 deletions
11
docs/toml.md
11
docs/toml.md
|
@ -636,7 +636,16 @@ domain = "marathon.localhost"
|
||||||
# Optional
|
# Optional
|
||||||
# Default: false
|
# Default: false
|
||||||
#
|
#
|
||||||
# ExposedByDefault = true
|
# exposedByDefault = true
|
||||||
|
|
||||||
|
# Convert Marathon groups to subdomains
|
||||||
|
# Default behavior: /foo/bar/myapp => foo-bar-myapp.{defaultDomain}
|
||||||
|
# with groupsAsSubDomains enabled: /foo/bar/myapp => myapp.bar.foo.{defaultDomain}
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
# Default: false
|
||||||
|
#
|
||||||
|
# groupsAsSubDomains = true
|
||||||
|
|
||||||
# Enable Marathon basic authentication
|
# Enable Marathon basic authentication
|
||||||
#
|
#
|
||||||
|
|
40
examples/whoami-group.json
Normal file
40
examples/whoami-group.json
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"id": "/foo",
|
||||||
|
"groups": [
|
||||||
|
{
|
||||||
|
"id": "/foo/bar",
|
||||||
|
"apps": [
|
||||||
|
{
|
||||||
|
"id": "whoami",
|
||||||
|
"cpus": 0.1,
|
||||||
|
"mem": 64.0,
|
||||||
|
"instances": 3,
|
||||||
|
"container": {
|
||||||
|
"type": "DOCKER",
|
||||||
|
"docker": {
|
||||||
|
"image": "emilevauge/whoami",
|
||||||
|
"network": "BRIDGE",
|
||||||
|
"portMappings": [
|
||||||
|
{
|
||||||
|
"containerPort": 80,
|
||||||
|
"hostPort": 0,
|
||||||
|
"protocol": "tcp"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthChecks": [
|
||||||
|
{
|
||||||
|
"protocol": "HTTP",
|
||||||
|
"portIndex": 0,
|
||||||
|
"path": "/",
|
||||||
|
"gracePeriodSeconds": 5,
|
||||||
|
"intervalSeconds": 20,
|
||||||
|
"maxConsecutiveFailures": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -236,7 +236,7 @@ func (provider *Docker) getFrontendRule(container dockertypes.ContainerJSON) str
|
||||||
if label, err := getLabel(container, "traefik.frontend.rule"); err == nil {
|
if label, err := getLabel(container, "traefik.frontend.rule"); err == nil {
|
||||||
return label
|
return label
|
||||||
}
|
}
|
||||||
return "Host:" + getEscapedName(container.Name) + "." + provider.Domain
|
return "Host:" + provider.getSubDomain(container.Name) + "." + provider.Domain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *Docker) getBackend(container dockertypes.ContainerJSON) string {
|
func (provider *Docker) getBackend(container dockertypes.ContainerJSON) string {
|
||||||
|
@ -349,3 +349,8 @@ func listContainers(dockerClient client.APIClient) ([]dockertypes.ContainerJSON,
|
||||||
}
|
}
|
||||||
return containersInspected, nil
|
return containersInspected, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Escape beginning slash "/", convert all others to dash "-"
|
||||||
|
func (provider *Docker) getSubDomain(name string) string {
|
||||||
|
return strings.Replace(strings.TrimPrefix(name, "/"), "/", "-", -1)
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package provider
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
@ -20,13 +21,14 @@ import (
|
||||||
|
|
||||||
// Marathon holds configuration of the Marathon provider.
|
// Marathon holds configuration of the Marathon provider.
|
||||||
type Marathon struct {
|
type Marathon struct {
|
||||||
BaseProvider `mapstructure:",squash" description:"go through"`
|
BaseProvider
|
||||||
Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon"`
|
Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon"`
|
||||||
Domain string `description:"Default domain used"`
|
Domain string `description:"Default domain used"`
|
||||||
ExposedByDefault bool `description:"Expose Marathon apps by default"`
|
ExposedByDefault bool `description:"Expose Marathon apps by default"`
|
||||||
Basic *MarathonBasic
|
GroupsAsSubDomains bool `description:"Convert Marathon groups to subdomains"`
|
||||||
TLS *tls.Config
|
Basic *MarathonBasic
|
||||||
marathonClient marathon.Marathon
|
TLS *tls.Config
|
||||||
|
marathonClient marathon.Marathon
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarathonBasic holds basic authentication specific configurations
|
// MarathonBasic holds basic authentication specific configurations
|
||||||
|
@ -341,7 +343,7 @@ func (provider *Marathon) getFrontendRule(application marathon.Application) stri
|
||||||
if label, err := provider.getLabel(application, "traefik.frontend.rule"); err == nil {
|
if label, err := provider.getLabel(application, "traefik.frontend.rule"); err == nil {
|
||||||
return label
|
return label
|
||||||
}
|
}
|
||||||
return "Host:" + getEscapedName(application.ID) + "." + provider.Domain
|
return "Host:" + provider.getSubDomain(application.ID) + "." + provider.Domain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *Marathon) getBackend(task marathon.Task, applications []marathon.Application) string {
|
func (provider *Marathon) getBackend(task marathon.Task, applications []marathon.Application) string {
|
||||||
|
@ -359,3 +361,13 @@ func (provider *Marathon) getFrontendBackend(application marathon.Application) s
|
||||||
}
|
}
|
||||||
return replace("/", "-", application.ID)
|
return replace("/", "-", application.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (provider *Marathon) getSubDomain(name string) string {
|
||||||
|
if provider.GroupsAsSubDomains {
|
||||||
|
splitedName := strings.Split(strings.TrimPrefix(name, "/"), "/")
|
||||||
|
sort.Sort(sort.Reverse(sort.StringSlice(splitedName)))
|
||||||
|
reverseName := strings.Join(splitedName, ".")
|
||||||
|
return reverseName
|
||||||
|
}
|
||||||
|
return strings.Replace(strings.TrimPrefix(name, "/"), "/", "-", -1)
|
||||||
|
}
|
||||||
|
|
|
@ -85,11 +85,6 @@ func replace(s1 string, s2 string, s3 string) string {
|
||||||
return strings.Replace(s3, s1, s2, -1)
|
return strings.Replace(s3, s1, s2, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Escape beginning slash "/", convert all others to dash "-"
|
|
||||||
func getEscapedName(name string) string {
|
|
||||||
return strings.Replace(strings.TrimPrefix(name, "/"), "/", "-", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func normalize(name string) string {
|
func normalize(name string) string {
|
||||||
fargs := func(c rune) bool {
|
fargs := func(c rune) bool {
|
||||||
return !unicode.IsLetter(c) && !unicode.IsNumber(c)
|
return !unicode.IsLetter(c) && !unicode.IsNumber(c)
|
||||||
|
|
|
@ -306,7 +306,16 @@
|
||||||
# Optional
|
# Optional
|
||||||
# Default: false
|
# Default: false
|
||||||
#
|
#
|
||||||
# ExposedByDefault = true
|
# exposedByDefault = true
|
||||||
|
|
||||||
|
# Convert Marathon groups to subdomains
|
||||||
|
# Default behavior: /foo/bar/myapp => foo-bar-myapp.{defaultDomain}
|
||||||
|
# with groupsAsSubDomains enabled: /foo/bar/myapp => myapp.bar.foo.{defaultDomain}
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
# Default: false
|
||||||
|
#
|
||||||
|
# groupsAsSubDomains = true
|
||||||
|
|
||||||
# Enable Marathon basic authentication
|
# Enable Marathon basic authentication
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in a new issue