Refactor frontends rules
Signed-off-by: Emile Vauge <emile@vauge.com>
This commit is contained in:
parent
dd160dc342
commit
8737530a7d
24 changed files with 198 additions and 222 deletions
|
@ -89,7 +89,7 @@ func (provider *ConsulCatalog) getBackend(node *api.ServiceEntry) string {
|
|||
}
|
||||
|
||||
func (provider *ConsulCatalog) getFrontendValue(service string) string {
|
||||
return service + "." + provider.Domain
|
||||
return "Host:" + service + "." + provider.Domain
|
||||
}
|
||||
|
||||
func (provider *ConsulCatalog) buildConfig(catalog []catalogUpdate) *types.Configuration {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
func TestConsulCatalogGetFrontendValue(t *testing.T) {
|
||||
func TestConsulCatalogGetFrontendRule(t *testing.T) {
|
||||
provider := &ConsulCatalog{
|
||||
Domain: "localhost",
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func TestConsulCatalogGetFrontendValue(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
service: "foo",
|
||||
expected: "foo.localhost",
|
||||
expected: "Host:foo.localhost",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,7 @@ func TestConsulCatalogBuildConfig(t *testing.T) {
|
|||
Backend: "backend-test",
|
||||
Routes: map[string]types.Route{
|
||||
"route-host-test": {
|
||||
Rule: "Host",
|
||||
Value: "test.localhost",
|
||||
Rule: "Host:test.localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2,7 +2,6 @@ package provider
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
@ -108,7 +107,6 @@ func (provider *Docker) loadDockerConfig(containersInspected []docker.Container)
|
|||
"getProtocol": provider.getProtocol,
|
||||
"getPassHostHeader": provider.getPassHostHeader,
|
||||
"getEntryPoints": provider.getEntryPoints,
|
||||
"getFrontendValue": provider.getFrontendValue,
|
||||
"getFrontendRule": provider.getFrontendRule,
|
||||
"replace": replace,
|
||||
}
|
||||
|
@ -154,31 +152,18 @@ func containerFilter(container docker.Container) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
labels, err := getLabels(container, []string{"traefik.frontend.rule", "traefik.frontend.value"})
|
||||
if len(labels) != 0 && err != nil {
|
||||
log.Debugf("Filtering bad labeled container %s", container.Name)
|
||||
return false
|
||||
}
|
||||
// labels, err := getLabels(container, []string{"traefik.frontend.rule"})
|
||||
// if len(labels) != 0 && err != nil {
|
||||
// log.Debugf("Filtering bad labeled container %s", container.Name)
|
||||
// return false
|
||||
// }
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (provider *Docker) getFrontendName(container docker.Container) string {
|
||||
// Replace '.' with '-' in quoted keys because of this issue https://github.com/BurntSushi/toml/issues/78
|
||||
frontendName := fmt.Sprintf("%s-%s", provider.getFrontendRule(container), provider.getFrontendValue(container))
|
||||
frontendName = strings.Replace(frontendName, "[", "", -1)
|
||||
frontendName = strings.Replace(frontendName, "]", "", -1)
|
||||
|
||||
return strings.Replace(frontendName, ".", "-", -1)
|
||||
}
|
||||
|
||||
// GetFrontendValue returns the frontend value for the specified container, using
|
||||
// it's label. It returns a default one if the label is not present.
|
||||
func (provider *Docker) getFrontendValue(container docker.Container) string {
|
||||
if label, err := getLabel(container, "traefik.frontend.value"); err == nil {
|
||||
return label
|
||||
}
|
||||
return getEscapedName(container.Name) + "." + provider.Domain
|
||||
return normalize(provider.getFrontendRule(container))
|
||||
}
|
||||
|
||||
// GetFrontendRule returns the frontend rule for the specified container, using
|
||||
|
@ -187,14 +172,14 @@ func (provider *Docker) getFrontendRule(container docker.Container) string {
|
|||
if label, err := getLabel(container, "traefik.frontend.rule"); err == nil {
|
||||
return label
|
||||
}
|
||||
return "Host"
|
||||
return "Host:" + getEscapedName(container.Name) + "." + provider.Domain
|
||||
}
|
||||
|
||||
func (provider *Docker) getBackend(container docker.Container) string {
|
||||
if label, err := getLabel(container, "traefik.backend"); err == nil {
|
||||
return label
|
||||
}
|
||||
return getEscapedName(container.Name)
|
||||
return normalize(container.Name)
|
||||
}
|
||||
|
||||
func (provider *Docker) getPort(container docker.Container) string {
|
||||
|
@ -211,7 +196,7 @@ func (provider *Docker) getWeight(container docker.Container) string {
|
|||
if label, err := getLabel(container, "traefik.weight"); err == nil {
|
||||
return label
|
||||
}
|
||||
return "0"
|
||||
return "1"
|
||||
}
|
||||
|
||||
func (provider *Docker) getDomain(container docker.Container) string {
|
||||
|
|
|
@ -30,18 +30,18 @@ func TestDockerGetFrontendName(t *testing.T) {
|
|||
Name: "bar",
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.rule": "Header",
|
||||
"traefik.frontend.rule": "Headers:User-Agent,bat/0.1.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "Header-bar-docker-localhost",
|
||||
expected: "Headers-User-Agent-bat-0-1-0",
|
||||
},
|
||||
{
|
||||
container: docker.Container{
|
||||
Name: "test",
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.value": "foo.bar",
|
||||
"traefik.frontend.rule": "Host:foo.bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -52,24 +52,22 @@ func TestDockerGetFrontendName(t *testing.T) {
|
|||
Name: "test",
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.value": "foo.bar",
|
||||
"traefik.frontend.rule": "Header",
|
||||
"traefik.frontend.rule": "Path:/test",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "Header-foo-bar",
|
||||
expected: "Path-test",
|
||||
},
|
||||
{
|
||||
container: docker.Container{
|
||||
Name: "test",
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.value": "[foo.bar]",
|
||||
"traefik.frontend.rule": "Header",
|
||||
"traefik.frontend.rule": "PathPrefix:/test2",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "Header-foo-bar",
|
||||
expected: "PathPrefix-test2",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -81,7 +79,7 @@ func TestDockerGetFrontendName(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDockerGetFrontendValue(t *testing.T) {
|
||||
func TestDockerGetFrontendRule(t *testing.T) {
|
||||
provider := &Docker{
|
||||
Domain: "docker.localhost",
|
||||
}
|
||||
|
@ -95,60 +93,36 @@ func TestDockerGetFrontendValue(t *testing.T) {
|
|||
Name: "foo",
|
||||
Config: &docker.Config{},
|
||||
},
|
||||
expected: "foo.docker.localhost",
|
||||
expected: "Host:foo.docker.localhost",
|
||||
},
|
||||
{
|
||||
container: docker.Container{
|
||||
Name: "bar",
|
||||
Config: &docker.Config{},
|
||||
},
|
||||
expected: "bar.docker.localhost",
|
||||
expected: "Host:bar.docker.localhost",
|
||||
},
|
||||
{
|
||||
container: docker.Container{
|
||||
Name: "test",
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.value": "foo.bar",
|
||||
"traefik.frontend.rule": "Host:foo.bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "foo.bar",
|
||||
},
|
||||
}
|
||||
|
||||
for _, e := range containers {
|
||||
actual := provider.getFrontendValue(e.container)
|
||||
if actual != e.expected {
|
||||
t.Fatalf("expected %q, got %q", e.expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDockerGetFrontendRule(t *testing.T) {
|
||||
provider := &Docker{}
|
||||
|
||||
containers := []struct {
|
||||
container docker.Container
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
container: docker.Container{
|
||||
Name: "foo",
|
||||
Config: &docker.Config{},
|
||||
},
|
||||
expected: "Host",
|
||||
expected: "Host:foo.bar",
|
||||
},
|
||||
{
|
||||
container: docker.Container{
|
||||
Name: "test",
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.rule": "foo",
|
||||
"traefik.frontend.rule": "Path:/test",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "foo",
|
||||
expected: "Path:/test",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -281,7 +255,7 @@ func TestDockerGetWeight(t *testing.T) {
|
|||
Name: "foo",
|
||||
Config: &docker.Config{},
|
||||
},
|
||||
expected: "0",
|
||||
expected: "1",
|
||||
},
|
||||
{
|
||||
container: docker.Container{
|
||||
|
@ -535,7 +509,7 @@ func TestDockerTraefikFilter(t *testing.T) {
|
|||
container: docker.Container{
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.rule": "Host",
|
||||
"traefik.frontend.rule": "Host:foo.bar",
|
||||
},
|
||||
},
|
||||
NetworkSettings: &docker.NetworkSettings{
|
||||
|
@ -544,22 +518,7 @@ func TestDockerTraefikFilter(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
container: docker.Container{
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.value": "foo.bar",
|
||||
},
|
||||
},
|
||||
NetworkSettings: &docker.NetworkSettings{
|
||||
Ports: map[docker.Port][]docker.PortBinding{
|
||||
"80/tcp": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
container: docker.Container{
|
||||
|
@ -634,8 +593,7 @@ func TestDockerTraefikFilter(t *testing.T) {
|
|||
container: docker.Container{
|
||||
Config: &docker.Config{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.rule": "Host",
|
||||
"traefik.frontend.value": "foo.bar",
|
||||
"traefik.frontend.rule": "Host:foo.bar",
|
||||
},
|
||||
},
|
||||
NetworkSettings: &docker.NetworkSettings{
|
||||
|
@ -651,7 +609,7 @@ func TestDockerTraefikFilter(t *testing.T) {
|
|||
for _, e := range containers {
|
||||
actual := containerFilter(e.container)
|
||||
if actual != e.expected {
|
||||
t.Fatalf("expected %v, got %v", e.expected, actual)
|
||||
t.Fatalf("expected %v for %+v, got %+v", e.expected, e, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -690,8 +648,7 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
|||
EntryPoints: []string{},
|
||||
Routes: map[string]types.Route{
|
||||
`"route-frontend-Host-test-docker-localhost"`: {
|
||||
Rule: "Host",
|
||||
Value: "test.docker.localhost",
|
||||
Rule: "Host:test.docker.localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -700,7 +657,8 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
|||
"backend-test": {
|
||||
Servers: map[string]types.Server{
|
||||
"server-test": {
|
||||
URL: "http://127.0.0.1:80",
|
||||
URL: "http://127.0.0.1:80",
|
||||
Weight: 1,
|
||||
},
|
||||
},
|
||||
CircuitBreaker: nil,
|
||||
|
@ -741,7 +699,7 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
|||
"80/tcp": {},
|
||||
},
|
||||
Networks: map[string]docker.ContainerNetwork{
|
||||
"bridgde": {
|
||||
"bridge": {
|
||||
IPAddress: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
|
@ -754,8 +712,7 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
|||
EntryPoints: []string{"http", "https"},
|
||||
Routes: map[string]types.Route{
|
||||
`"route-frontend-Host-test1-docker-localhost"`: {
|
||||
Rule: "Host",
|
||||
Value: "test1.docker.localhost",
|
||||
Rule: "Host:test1.docker.localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -764,8 +721,7 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
|||
EntryPoints: []string{},
|
||||
Routes: map[string]types.Route{
|
||||
`"route-frontend-Host-test2-docker-localhost"`: {
|
||||
Rule: "Host",
|
||||
Value: "test2.docker.localhost",
|
||||
Rule: "Host:test2.docker.localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -774,10 +730,12 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
|||
"backend-foobar": {
|
||||
Servers: map[string]types.Server{
|
||||
"server-test1": {
|
||||
URL: "http://127.0.0.1:80",
|
||||
URL: "http://127.0.0.1:80",
|
||||
Weight: 1,
|
||||
},
|
||||
"server-test2": {
|
||||
URL: "http://127.0.0.1:80",
|
||||
URL: "http://127.0.0.1:80",
|
||||
Weight: 1,
|
||||
},
|
||||
},
|
||||
CircuitBreaker: nil,
|
||||
|
|
|
@ -96,7 +96,6 @@ func (provider *Marathon) loadMarathonConfig() *types.Configuration {
|
|||
"getProtocol": provider.getProtocol,
|
||||
"getPassHostHeader": provider.getPassHostHeader,
|
||||
"getEntryPoints": provider.getEntryPoints,
|
||||
"getFrontendValue": provider.getFrontendValue,
|
||||
"getFrontendRule": provider.getFrontendRule,
|
||||
"getFrontendBackend": provider.getFrontendBackend,
|
||||
"replace": replace,
|
||||
|
@ -309,22 +308,13 @@ func (provider *Marathon) getEntryPoints(application marathon.Application) []str
|
|||
return []string{}
|
||||
}
|
||||
|
||||
// getFrontendValue returns the frontend value for the specified application, using
|
||||
// it's label. It returns a default one if the label is not present.
|
||||
func (provider *Marathon) getFrontendValue(application marathon.Application) string {
|
||||
if label, err := provider.getLabel(application, "traefik.frontend.value"); err == nil {
|
||||
return label
|
||||
}
|
||||
return getEscapedName(application.ID) + "." + provider.Domain
|
||||
}
|
||||
|
||||
// getFrontendRule returns the frontend rule for the specified application, using
|
||||
// it's label. It returns a default one (Host) if the label is not present.
|
||||
func (provider *Marathon) getFrontendRule(application marathon.Application) string {
|
||||
if label, err := provider.getLabel(application, "traefik.frontend.rule"); err == nil {
|
||||
return label
|
||||
}
|
||||
return "Host"
|
||||
return "Host:" + getEscapedName(application.ID) + "." + provider.Domain
|
||||
}
|
||||
|
||||
func (provider *Marathon) getBackend(task marathon.Task, applications []marathon.Application) string {
|
||||
|
|
|
@ -86,8 +86,7 @@ func TestMarathonLoadConfig(t *testing.T) {
|
|||
EntryPoints: []string{},
|
||||
Routes: map[string]types.Route{
|
||||
`route-host-test`: {
|
||||
Rule: "Host",
|
||||
Value: "test.docker.localhost",
|
||||
Rule: "Host:test.docker.localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -831,7 +830,7 @@ func TestMarathonGetEntryPoints(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMarathonGetFrontendValue(t *testing.T) {
|
||||
func TestMarathonGetFrontendRule(t *testing.T) {
|
||||
provider := &Marathon{
|
||||
Domain: "docker.localhost",
|
||||
}
|
||||
|
@ -842,50 +841,21 @@ func TestMarathonGetFrontendValue(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
application: marathon.Application{},
|
||||
expected: ".docker.localhost",
|
||||
expected: "Host:.docker.localhost",
|
||||
},
|
||||
{
|
||||
application: marathon.Application{
|
||||
ID: "test",
|
||||
},
|
||||
expected: "test.docker.localhost",
|
||||
expected: "Host:test.docker.localhost",
|
||||
},
|
||||
{
|
||||
application: marathon.Application{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.value": "foo.bar",
|
||||
"traefik.frontend.rule": "Host:foo.bar",
|
||||
},
|
||||
},
|
||||
expected: "foo.bar",
|
||||
},
|
||||
}
|
||||
|
||||
for _, a := range applications {
|
||||
actual := provider.getFrontendValue(a.application)
|
||||
if actual != a.expected {
|
||||
t.Fatalf("expected %q, got %q", a.expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarathonGetFrontendRule(t *testing.T) {
|
||||
provider := &Marathon{}
|
||||
|
||||
applications := []struct {
|
||||
application marathon.Application
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
application: marathon.Application{},
|
||||
expected: "Host",
|
||||
},
|
||||
{
|
||||
application: marathon.Application{
|
||||
Labels: map[string]string{
|
||||
"traefik.frontend.rule": "Header",
|
||||
},
|
||||
},
|
||||
expected: "Header",
|
||||
expected: "Host:foo.bar",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/BurntSushi/toml"
|
||||
"github.com/containous/traefik/autogen"
|
||||
"github.com/containous/traefik/types"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Provider defines methods of a provider.
|
||||
|
@ -67,3 +68,11 @@ func replace(s1 string, s2 string, s3 string) string {
|
|||
func getEscapedName(name string) string {
|
||||
return strings.Replace(strings.TrimPrefix(name, "/"), "/", "-", -1)
|
||||
}
|
||||
|
||||
func normalize(name string) string {
|
||||
fargs := func(c rune) bool {
|
||||
return !unicode.IsLetter(c) && !unicode.IsNumber(c)
|
||||
}
|
||||
// get function
|
||||
return strings.Join(strings.FieldsFunc(name, fargs), "-")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue