Following up to the conversation on Slack & GitHub:

- Change the annotation to define the rule type in `traefik.frontend.rule.type`
 - Update tests
 - Add documentation
 - Add example
This commit is contained in:
AlmogBaku 2016-05-17 13:50:06 +03:00
parent 92abaa0d47
commit 71f160dddc
4 changed files with 211 additions and 31 deletions

View file

@ -619,7 +619,7 @@ Labels can be used on containers to override default behaviour:
- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). - `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`).
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. - `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
- `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.domain=traefik.localhost`: override the default domain - `traefik.domain=traefik.localhost`: override the default domain
## Kubernetes Ingress backend ## Kubernetes Ingress backend
@ -651,6 +651,10 @@ Træfɪk can be configured to use Kubernetes Ingress as a backend configuration:
# namespaces = ["default","production"] # namespaces = ["default","production"]
``` ```
Annotations can be used on containers to override default behaviour for the whole Ingress resource:
- `traefik.frontend.rule.type: PathPrefixStrip`: override the default frontend rule (Default: `Host:{containerName}.{domain}`).
You can find here an example [ingress](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s.ingress.yaml) and [replication controller](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s.rc.yaml). You can find here an example [ingress](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s.ingress.yaml) and [replication controller](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s.rc.yaml).
## Consul backend ## Consul backend

View file

@ -91,3 +91,21 @@ spec:
- backend: - backend:
serviceName: service3 serviceName: service3
servicePort: 80 servicePort: 80
---
# Another Ingress with PathPrefixStrip
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: whoami-ingress-stripped
annotations:
traefik.frontend.rule.type: "PathPrefixStrip"
spec:
rules:
- host: foo.localhost
http:
paths:
- path: /prefixWillBeStripped
backend:
serviceName: service1
servicePort: 80

View file

@ -165,14 +165,24 @@ func (provider *Kubernetes) loadIngresses(k8sClient k8s.Client) (*types.Configur
} }
} }
if len(pa.Path) > 0 { if len(pa.Path) > 0 {
if _, ok := i.Annotations["PathPrefixStrip"]; ok { var ruleType string = i.Annotations["traefik.frontend.rule.type"]
templateObjects.Frontends[r.Host+pa.Path].Routes[pa.Path] = types.Route{
Rule: "PathPrefixStrip:" + pa.Path, switch strings.ToLower(ruleType) {
} case "pathprefixstrip":
} else { ruleType = "PathPrefixStrip"
templateObjects.Frontends[r.Host+pa.Path].Routes[pa.Path] = types.Route{ case "pathstrip":
Rule: "PathPrefix:" + pa.Path, ruleType = "PathStrip"
} case "path":
ruleType = "Path"
case "pathprefix":
ruleType = "PathPrefix"
default:
log.Debugf("Unknown RuleType `%s`, falling back to `PathPrefix", ruleType)
ruleType = "PathPrefix"
}
templateObjects.Frontends[r.Host+pa.Path].Routes[pa.Path] = types.Route{
Rule: ruleType + ":" + pa.Path,
} }
} }
services, err := k8sClient.GetServices(func(service k8s.Service) bool { services, err := k8sClient.GetServices(func(service k8s.Service) bool {

View file

@ -169,20 +169,25 @@ func TestLoadIngresses(t *testing.T) {
} }
} }
func TestPathPrefixStrip(t *testing.T) { func TestRuleType(t *testing.T) {
ingresses := []k8s.Ingress{{ ingresses := []k8s.Ingress{
Spec: k8s.IngressSpec{ {
Rules: []k8s.IngressRule{ ObjectMeta: k8s.ObjectMeta{
{ Annotations: map[string]string{"traefik.frontend.rule.type": "PathPrefixStrip"}, //camel case
Host: "foo", },
IngressRuleValue: k8s.IngressRuleValue{ Spec: k8s.IngressSpec{
HTTP: &k8s.HTTPIngressRuleValue{ Rules: []k8s.IngressRule{
Paths: []k8s.HTTPIngressPath{ {
{ Host: "foo1",
Path: "/bar", IngressRuleValue: k8s.IngressRuleValue{
Backend: k8s.IngressBackend{ HTTP: &k8s.HTTPIngressRuleValue{
ServiceName: "service1", Paths: []k8s.HTTPIngressPath{
ServicePort: k8s.FromInt(801), {
Path: "/bar1",
Backend: k8s.IngressBackend{
ServiceName: "service1",
ServicePort: k8s.FromInt(801),
},
}, },
}, },
}, },
@ -191,8 +196,107 @@ func TestPathPrefixStrip(t *testing.T) {
}, },
}, },
}, },
}} {
ingresses[0].Annotations = map[string]string{"PathPrefixStrip": "true"} ObjectMeta: k8s.ObjectMeta{
Annotations: map[string]string{"traefik.frontend.rule.type": "path"}, //lower case
},
Spec: k8s.IngressSpec{
Rules: []k8s.IngressRule{
{
Host: "foo1",
IngressRuleValue: k8s.IngressRuleValue{
HTTP: &k8s.HTTPIngressRuleValue{
Paths: []k8s.HTTPIngressPath{
{
Path: "/bar2",
Backend: k8s.IngressBackend{
ServiceName: "service1",
ServicePort: k8s.FromInt(801),
},
},
},
},
},
},
},
},
},
{
ObjectMeta: k8s.ObjectMeta{
Annotations: map[string]string{"traefik.frontend.rule.type": "PathPrefix"}, //path prefix
},
Spec: k8s.IngressSpec{
Rules: []k8s.IngressRule{
{
Host: "foo2",
IngressRuleValue: k8s.IngressRuleValue{
HTTP: &k8s.HTTPIngressRuleValue{
Paths: []k8s.HTTPIngressPath{
{
Path: "/bar1",
Backend: k8s.IngressBackend{
ServiceName: "service1",
ServicePort: k8s.FromInt(801),
},
},
},
},
},
},
},
},
},
{
ObjectMeta: k8s.ObjectMeta{
Annotations: map[string]string{"traefik.frontend.rule.type": "PathStrip"}, //path strip
},
Spec: k8s.IngressSpec{
Rules: []k8s.IngressRule{
{
Host: "foo2",
IngressRuleValue: k8s.IngressRuleValue{
HTTP: &k8s.HTTPIngressRuleValue{
Paths: []k8s.HTTPIngressPath{
{
Path: "/bar2",
Backend: k8s.IngressBackend{
ServiceName: "service1",
ServicePort: k8s.FromInt(801),
},
},
},
},
},
},
},
},
},
{
ObjectMeta: k8s.ObjectMeta{
Annotations: map[string]string{"traefik.frontend.rule.type": "PathXXStrip"}, //wrong rule
},
Spec: k8s.IngressSpec{
Rules: []k8s.IngressRule{
{
Host: "foo1",
IngressRuleValue: k8s.IngressRuleValue{
HTTP: &k8s.HTTPIngressRuleValue{
Paths: []k8s.HTTPIngressPath{
{
Path: "/bar3",
Backend: k8s.IngressBackend{
ServiceName: "service1",
ServicePort: k8s.FromInt(801),
},
},
},
},
},
},
},
},
},
}
services := []k8s.Service{ services := []k8s.Service{
{ {
ObjectMeta: k8s.ObjectMeta{ ObjectMeta: k8s.ObjectMeta{
@ -224,14 +328,58 @@ func TestPathPrefixStrip(t *testing.T) {
} }
expected := map[string]*types.Frontend{ expected := map[string]*types.Frontend{
"foo/bar": { "foo1/bar1": {
Backend: "foo/bar", Backend: "foo1/bar1",
Routes: map[string]types.Route{ Routes: map[string]types.Route{
"/bar": { "/bar1": {
Rule: "PathPrefixStrip:/bar", Rule: "PathPrefixStrip:/bar1",
}, },
"foo": { "foo1": {
Rule: "Host:foo", Rule: "Host:foo1",
},
},
},
"foo1/bar2": {
Backend: "foo1/bar2",
Routes: map[string]types.Route{
"/bar2": {
Rule: "Path:/bar2",
},
"foo1": {
Rule: "Host:foo1",
},
},
},
"foo2/bar1": {
Backend: "foo2/bar1",
Routes: map[string]types.Route{
"/bar1": {
Rule: "PathPrefix:/bar1",
},
"foo2": {
Rule: "Host:foo2",
},
},
},
"foo2/bar2": {
Backend: "foo2/bar2",
Routes: map[string]types.Route{
"/bar2": {
Rule: "PathStrip:/bar2",
},
"foo2": {
Rule: "Host:foo2",
},
},
},
"foo1/bar3": {
Backend: "foo1/bar3",
Routes: map[string]types.Route{
"/bar3": {
Rule: "PathPrefix:/bar3",
},
"foo1": {
Rule: "Host:foo1",
}, },
}, },
}, },