parent
4a4ba2791d
commit
be209ed30c
11 changed files with 142 additions and 33 deletions
|
@ -236,7 +236,8 @@ func TestConsulCatalogBuildConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
expectedFrontends: map[string]*types.Frontend{
|
expectedFrontends: map[string]*types.Frontend{
|
||||||
"frontend-test": {
|
"frontend-test": {
|
||||||
Backend: "backend-test",
|
Backend: "backend-test",
|
||||||
|
PassHostHeader: true,
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"route-host-test": {
|
"route-host-test": {
|
||||||
Rule: "Host:test.localhost",
|
Rule: "Host:test.localhost",
|
||||||
|
|
|
@ -279,7 +279,7 @@ func (provider *Docker) getPassHostHeader(container dockertypes.ContainerJSON) s
|
||||||
if passHostHeader, err := getLabel(container, "traefik.frontend.passHostHeader"); err == nil {
|
if passHostHeader, err := getLabel(container, "traefik.frontend.passHostHeader"); err == nil {
|
||||||
return passHostHeader
|
return passHostHeader
|
||||||
}
|
}
|
||||||
return "false"
|
return "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *Docker) getEntryPoints(container dockertypes.ContainerJSON) []string {
|
func (provider *Docker) getEntryPoints(container dockertypes.ContainerJSON) []string {
|
||||||
|
|
|
@ -401,7 +401,6 @@ func TestDockerGetProtocol(t *testing.T) {
|
||||||
|
|
||||||
func TestDockerGetPassHostHeader(t *testing.T) {
|
func TestDockerGetPassHostHeader(t *testing.T) {
|
||||||
provider := &Docker{}
|
provider := &Docker{}
|
||||||
|
|
||||||
containers := []struct {
|
containers := []struct {
|
||||||
container docker.ContainerJSON
|
container docker.ContainerJSON
|
||||||
expected string
|
expected string
|
||||||
|
@ -413,7 +412,7 @@ func TestDockerGetPassHostHeader(t *testing.T) {
|
||||||
},
|
},
|
||||||
Config: &container.Config{},
|
Config: &container.Config{},
|
||||||
},
|
},
|
||||||
expected: "false",
|
expected: "true",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
container: docker.ContainerJSON{
|
container: docker.ContainerJSON{
|
||||||
|
@ -422,11 +421,11 @@ func TestDockerGetPassHostHeader(t *testing.T) {
|
||||||
},
|
},
|
||||||
Config: &container.Config{
|
Config: &container.Config{
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"traefik.frontend.passHostHeader": "true",
|
"traefik.frontend.passHostHeader": "false",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: "true",
|
expected: "false",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,8 +743,9 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
expectedFrontends: map[string]*types.Frontend{
|
expectedFrontends: map[string]*types.Frontend{
|
||||||
"frontend-Host-test-docker-localhost": {
|
"frontend-Host-test-docker-localhost": {
|
||||||
Backend: "backend-test",
|
Backend: "backend-test",
|
||||||
EntryPoints: []string{},
|
PassHostHeader: true,
|
||||||
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"route-frontend-Host-test-docker-localhost": {
|
"route-frontend-Host-test-docker-localhost": {
|
||||||
Rule: "Host:test.docker.localhost",
|
Rule: "Host:test.docker.localhost",
|
||||||
|
@ -816,8 +816,9 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
expectedFrontends: map[string]*types.Frontend{
|
expectedFrontends: map[string]*types.Frontend{
|
||||||
"frontend-Host-test1-docker-localhost": {
|
"frontend-Host-test1-docker-localhost": {
|
||||||
Backend: "backend-foobar",
|
Backend: "backend-foobar",
|
||||||
EntryPoints: []string{"http", "https"},
|
PassHostHeader: true,
|
||||||
|
EntryPoints: []string{"http", "https"},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"route-frontend-Host-test1-docker-localhost": {
|
"route-frontend-Host-test1-docker-localhost": {
|
||||||
Rule: "Host:test1.docker.localhost",
|
Rule: "Host:test1.docker.localhost",
|
||||||
|
@ -825,8 +826,9 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"frontend-Host-test2-docker-localhost": {
|
"frontend-Host-test2-docker-localhost": {
|
||||||
Backend: "backend-foobar",
|
Backend: "backend-foobar",
|
||||||
EntryPoints: []string{},
|
PassHostHeader: true,
|
||||||
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"route-frontend-Host-test2-docker-localhost": {
|
"route-frontend-Host-test2-docker-localhost": {
|
||||||
Rule: "Host:test2.docker.localhost",
|
Rule: "Host:test2.docker.localhost",
|
||||||
|
|
|
@ -21,9 +21,10 @@ const (
|
||||||
|
|
||||||
// Kubernetes holds configurations of the Kubernetes provider.
|
// Kubernetes holds configurations of the Kubernetes provider.
|
||||||
type Kubernetes struct {
|
type Kubernetes struct {
|
||||||
BaseProvider `mapstructure:",squash"`
|
BaseProvider `mapstructure:",squash"`
|
||||||
Endpoint string
|
Endpoint string
|
||||||
Namespaces []string
|
disablePassHostHeaders bool
|
||||||
|
Namespaces []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *Kubernetes) createClient() (k8s.Client, error) {
|
func (provider *Kubernetes) createClient() (k8s.Client, error) {
|
||||||
|
@ -142,6 +143,7 @@ func (provider *Kubernetes) loadIngresses(k8sClient k8s.Client) (*types.Configur
|
||||||
map[string]*types.Backend{},
|
map[string]*types.Backend{},
|
||||||
map[string]*types.Frontend{},
|
map[string]*types.Frontend{},
|
||||||
}
|
}
|
||||||
|
PassHostHeader := provider.getPassHostHeader()
|
||||||
for _, i := range ingresses {
|
for _, i := range ingresses {
|
||||||
for _, r := range i.Spec.Rules {
|
for _, r := range i.Spec.Rules {
|
||||||
for _, pa := range r.HTTP.Paths {
|
for _, pa := range r.HTTP.Paths {
|
||||||
|
@ -152,8 +154,9 @@ func (provider *Kubernetes) loadIngresses(k8sClient k8s.Client) (*types.Configur
|
||||||
}
|
}
|
||||||
if _, exists := templateObjects.Frontends[r.Host+pa.Path]; !exists {
|
if _, exists := templateObjects.Frontends[r.Host+pa.Path]; !exists {
|
||||||
templateObjects.Frontends[r.Host+pa.Path] = &types.Frontend{
|
templateObjects.Frontends[r.Host+pa.Path] = &types.Frontend{
|
||||||
Backend: r.Host + pa.Path,
|
Backend: r.Host + pa.Path,
|
||||||
Routes: make(map[string]types.Route),
|
PassHostHeader: PassHostHeader,
|
||||||
|
Routes: make(map[string]types.Route),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, exists := templateObjects.Frontends[r.Host+pa.Path].Routes[r.Host]; !exists {
|
if _, exists := templateObjects.Frontends[r.Host+pa.Path].Routes[r.Host]; !exists {
|
||||||
|
@ -199,6 +202,13 @@ func (provider *Kubernetes) loadIngresses(k8sClient k8s.Client) (*types.Configur
|
||||||
return &templateObjects, nil
|
return &templateObjects, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (provider *Kubernetes) getPassHostHeader() bool {
|
||||||
|
if provider.disablePassHostHeaders {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (provider *Kubernetes) loadConfig(templateObjects types.Configuration) *types.Configuration {
|
func (provider *Kubernetes) loadConfig(templateObjects types.Configuration) *types.Configuration {
|
||||||
var FuncMap = template.FuncMap{}
|
var FuncMap = template.FuncMap{}
|
||||||
configuration, err := provider.getConfiguration("templates/kubernetes.tmpl", FuncMap, templateObjects)
|
configuration, err := provider.getConfiguration("templates/kubernetes.tmpl", FuncMap, templateObjects)
|
||||||
|
|
|
@ -139,7 +139,8 @@ func TestLoadIngresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
Frontends: map[string]*types.Frontend{
|
Frontends: map[string]*types.Frontend{
|
||||||
"foo/bar": {
|
"foo/bar": {
|
||||||
Backend: "foo/bar",
|
Backend: "foo/bar",
|
||||||
|
PassHostHeader: true,
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"/bar": {
|
"/bar": {
|
||||||
Rule: "PathPrefixStrip:/bar",
|
Rule: "PathPrefixStrip:/bar",
|
||||||
|
@ -150,7 +151,8 @@ func TestLoadIngresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"bar": {
|
"bar": {
|
||||||
Backend: "bar",
|
Backend: "bar",
|
||||||
|
PassHostHeader: true,
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"bar": {
|
"bar": {
|
||||||
Rule: "Host:bar",
|
Rule: "Host:bar",
|
||||||
|
@ -167,6 +169,93 @@ func TestLoadIngresses(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetPassHostHeader(t *testing.T) {
|
||||||
|
ingresses := []k8s.Ingress{{
|
||||||
|
Spec: k8s.IngressSpec{
|
||||||
|
Rules: []k8s.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "foo",
|
||||||
|
IngressRuleValue: k8s.IngressRuleValue{
|
||||||
|
HTTP: &k8s.HTTPIngressRuleValue{
|
||||||
|
Paths: []k8s.HTTPIngressPath{
|
||||||
|
{
|
||||||
|
Path: "/bar",
|
||||||
|
Backend: k8s.IngressBackend{
|
||||||
|
ServiceName: "service1",
|
||||||
|
ServicePort: k8s.FromInt(801),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
services := []k8s.Service{
|
||||||
|
{
|
||||||
|
ObjectMeta: k8s.ObjectMeta{
|
||||||
|
Name: "service1",
|
||||||
|
UID: "1",
|
||||||
|
},
|
||||||
|
Spec: k8s.ServiceSpec{
|
||||||
|
ClusterIP: "10.0.0.1",
|
||||||
|
Ports: []k8s.ServicePort{
|
||||||
|
{
|
||||||
|
Name: "http",
|
||||||
|
Port: 801,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
watchChan := make(chan interface{})
|
||||||
|
client := clientMock{
|
||||||
|
ingresses: ingresses,
|
||||||
|
services: services,
|
||||||
|
watchChan: watchChan,
|
||||||
|
}
|
||||||
|
provider := Kubernetes{disablePassHostHeaders: true}
|
||||||
|
actual, err := provider.loadIngresses(client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := &types.Configuration{
|
||||||
|
Backends: map[string]*types.Backend{
|
||||||
|
"foo/bar": {
|
||||||
|
Servers: map[string]types.Server{
|
||||||
|
"1": {
|
||||||
|
URL: "http://10.0.0.1:801",
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CircuitBreaker: nil,
|
||||||
|
LoadBalancer: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Frontends: map[string]*types.Frontend{
|
||||||
|
"foo/bar": {
|
||||||
|
Backend: "foo/bar",
|
||||||
|
Routes: map[string]types.Route{
|
||||||
|
"/bar": {
|
||||||
|
Rule: "PathPrefixStrip:/bar",
|
||||||
|
},
|
||||||
|
"foo": {
|
||||||
|
Rule: "Host:foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
actualJSON, _ := json.Marshal(actual)
|
||||||
|
expectedJSON, _ := json.Marshal(expected)
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(actual, expected) {
|
||||||
|
t.Fatalf("expected %+v, got %+v", string(expectedJSON), string(actualJSON))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoadNamespacedIngresses(t *testing.T) {
|
func TestLoadNamespacedIngresses(t *testing.T) {
|
||||||
ingresses := []k8s.Ingress{
|
ingresses := []k8s.Ingress{
|
||||||
{
|
{
|
||||||
|
@ -330,7 +419,8 @@ func TestLoadNamespacedIngresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
Frontends: map[string]*types.Frontend{
|
Frontends: map[string]*types.Frontend{
|
||||||
"foo/bar": {
|
"foo/bar": {
|
||||||
Backend: "foo/bar",
|
Backend: "foo/bar",
|
||||||
|
PassHostHeader: true,
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"/bar": {
|
"/bar": {
|
||||||
Rule: "PathPrefixStrip:/bar",
|
Rule: "PathPrefixStrip:/bar",
|
||||||
|
@ -341,7 +431,8 @@ func TestLoadNamespacedIngresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"bar": {
|
"bar": {
|
||||||
Backend: "bar",
|
Backend: "bar",
|
||||||
|
PassHostHeader: true,
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"bar": {
|
"bar": {
|
||||||
Rule: "Host:bar",
|
Rule: "Host:bar",
|
||||||
|
@ -556,7 +647,8 @@ func TestLoadMultipleNamespacedIngresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
Frontends: map[string]*types.Frontend{
|
Frontends: map[string]*types.Frontend{
|
||||||
"foo/bar": {
|
"foo/bar": {
|
||||||
Backend: "foo/bar",
|
Backend: "foo/bar",
|
||||||
|
PassHostHeader: true,
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"/bar": {
|
"/bar": {
|
||||||
Rule: "PathPrefixStrip:/bar",
|
Rule: "PathPrefixStrip:/bar",
|
||||||
|
@ -567,7 +659,8 @@ func TestLoadMultipleNamespacedIngresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"bar": {
|
"bar": {
|
||||||
Backend: "bar",
|
Backend: "bar",
|
||||||
|
PassHostHeader: true,
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"bar": {
|
"bar": {
|
||||||
Rule: "Host:bar",
|
Rule: "Host:bar",
|
||||||
|
@ -575,7 +668,8 @@ func TestLoadMultipleNamespacedIngresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"awesome/quix": {
|
"awesome/quix": {
|
||||||
Backend: "awesome/quix",
|
Backend: "awesome/quix",
|
||||||
|
PassHostHeader: true,
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"/quix": {
|
"/quix": {
|
||||||
Rule: "PathPrefixStrip:/quix",
|
Rule: "PathPrefixStrip:/quix",
|
||||||
|
|
|
@ -430,7 +430,7 @@ func TestKVLoadConfig(t *testing.T) {
|
||||||
Frontends: map[string]*types.Frontend{
|
Frontends: map[string]*types.Frontend{
|
||||||
"frontend.with.dot": {
|
"frontend.with.dot": {
|
||||||
Backend: "backend.with.dot.too",
|
Backend: "backend.with.dot.too",
|
||||||
PassHostHeader: false,
|
PassHostHeader: true,
|
||||||
EntryPoints: []string{},
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
"route.with.dot": {
|
"route.with.dot": {
|
||||||
|
|
|
@ -316,7 +316,7 @@ func (provider *Marathon) getPassHostHeader(application marathon.Application) st
|
||||||
if passHostHeader, err := provider.getLabel(application, "traefik.frontend.passHostHeader"); err == nil {
|
if passHostHeader, err := provider.getLabel(application, "traefik.frontend.passHostHeader"); err == nil {
|
||||||
return passHostHeader
|
return passHostHeader
|
||||||
}
|
}
|
||||||
return "false"
|
return "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *Marathon) getEntryPoints(application marathon.Application) []string {
|
func (provider *Marathon) getEntryPoints(application marathon.Application) []string {
|
||||||
|
|
|
@ -82,8 +82,9 @@ func TestMarathonLoadConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
expectedFrontends: map[string]*types.Frontend{
|
expectedFrontends: map[string]*types.Frontend{
|
||||||
`frontend-test`: {
|
`frontend-test`: {
|
||||||
Backend: "backend-test",
|
Backend: "backend-test",
|
||||||
EntryPoints: []string{},
|
PassHostHeader: true,
|
||||||
|
EntryPoints: []string{},
|
||||||
Routes: map[string]types.Route{
|
Routes: map[string]types.Route{
|
||||||
`route-host-test`: {
|
`route-host-test`: {
|
||||||
Rule: "Host:test.docker.localhost",
|
Rule: "Host:test.docker.localhost",
|
||||||
|
@ -780,15 +781,15 @@ func TestMarathonGetPassHostHeader(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
application: marathon.Application{},
|
application: marathon.Application{},
|
||||||
expected: "false",
|
expected: "true",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
application: marathon.Application{
|
application: marathon.Application{
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"traefik.frontend.passHostHeader": "true",
|
"traefik.frontend.passHostHeader": "false",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: "true",
|
expected: "false",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
{{range .Services}}
|
{{range .Services}}
|
||||||
[frontends.frontend-{{.ServiceName}}]
|
[frontends.frontend-{{.ServiceName}}]
|
||||||
backend = "backend-{{.ServiceName}}"
|
backend = "backend-{{.ServiceName}}"
|
||||||
passHostHeader = {{getAttribute "frontend.passHostHeader" .Attributes "false"}}
|
passHostHeader = {{getAttribute "frontend.passHostHeader" .Attributes "true"}}
|
||||||
{{$entryPoints := getAttribute "frontend.entrypoints" .Attributes ""}}
|
{{$entryPoints := getAttribute "frontend.entrypoints" .Attributes ""}}
|
||||||
{{with $entryPoints}}
|
{{with $entryPoints}}
|
||||||
entrypoints = [{{range getEntryPoints $entryPoints}}
|
entrypoints = [{{range getEntryPoints $entryPoints}}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[frontends]{{range $frontendName, $frontend := .Frontends}}
|
[frontends]{{range $frontendName, $frontend := .Frontends}}
|
||||||
[frontends."{{$frontendName}}"]
|
[frontends."{{$frontendName}}"]
|
||||||
backend = "{{$frontend.Backend}}"
|
backend = "{{$frontend.Backend}}"
|
||||||
|
passHostHeader = {{$frontend.PassHostHeader}}
|
||||||
{{range $routeName, $route := $frontend.Routes}}
|
{{range $routeName, $route := $frontend.Routes}}
|
||||||
[frontends."{{$frontendName}}".routes."{{$routeName}}"]
|
[frontends."{{$frontendName}}".routes."{{$routeName}}"]
|
||||||
rule = "{{$route.Rule}}"
|
rule = "{{$route.Rule}}"
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
{{$entryPoints := SplitGet . "/entrypoints"}}
|
{{$entryPoints := SplitGet . "/entrypoints"}}
|
||||||
[frontends."{{$frontend}}"]
|
[frontends."{{$frontend}}"]
|
||||||
backend = "{{Get "" . "/backend"}}"
|
backend = "{{Get "" . "/backend"}}"
|
||||||
passHostHeader = {{Get "false" . "/passHostHeader"}}
|
passHostHeader = {{Get "true" . "/passHostHeader"}}
|
||||||
entryPoints = [{{range $entryPoints}}
|
entryPoints = [{{range $entryPoints}}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{end}}]
|
{{end}}]
|
||||||
|
|
Loading…
Reference in a new issue