Added ability to override frontend priority for k8s ingress router
This commit is contained in:
parent
29390a3c4a
commit
94f922cd28
4 changed files with 163 additions and 1 deletions
|
@ -1242,6 +1242,7 @@ Træfik can be configured to use Kubernetes Ingress as a backend configuration:
|
||||||
Annotations can be used on containers to override default behaviour for the whole Ingress resource:
|
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 type (Default: `PathPrefix`).
|
- `traefik.frontend.rule.type: PathPrefixStrip`: override the default frontend rule type (Default: `PathPrefix`).
|
||||||
|
- `traefik.frontend.priority: 3`: override the default frontend rule priority (Default: `len(Path)`).
|
||||||
|
|
||||||
Annotations can be used on the Kubernetes service to override default behaviour:
|
Annotations can be used on the Kubernetes service to override default behaviour:
|
||||||
|
|
||||||
|
|
|
@ -604,6 +604,45 @@ You should now be able to visit the websites in your browser.
|
||||||
* [cheeses.minikube/cheddar](http://cheeses.minikube/cheddar/)
|
* [cheeses.minikube/cheddar](http://cheeses.minikube/cheddar/)
|
||||||
* [cheeses.minikube/wensleydale](http://cheeses.minikube/wensleydale/)
|
* [cheeses.minikube/wensleydale](http://cheeses.minikube/wensleydale/)
|
||||||
|
|
||||||
|
## Specifying priority for routing
|
||||||
|
|
||||||
|
Sometimes you need to specify priority for ingress route, especially when handling wildcard routes.
|
||||||
|
This can be done by adding annotation `traefik.frontend.priority`, i.e.:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: wildcard-cheeses
|
||||||
|
annotations:
|
||||||
|
traefik.frontend.priority: 1
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: *.minikube
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
backend:
|
||||||
|
serviceName: stilton
|
||||||
|
servicePort: http
|
||||||
|
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: specific-cheeses
|
||||||
|
annotations:
|
||||||
|
traefik.frontend.priority: 2
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: specific.minikube
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
backend:
|
||||||
|
serviceName: stilton
|
||||||
|
servicePort: http
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Forwarding to ExternalNames
|
## Forwarding to ExternalNames
|
||||||
|
|
||||||
When specifying an [ExternalName](https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors),
|
When specifying an [ExternalName](https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors),
|
||||||
|
|
|
@ -192,11 +192,14 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
log.Errorf("Failed to retrieve basic auth configuration for ingress %s/%s: %s", i.ObjectMeta.Namespace, i.ObjectMeta.Name, err)
|
log.Errorf("Failed to retrieve basic auth configuration for ingress %s/%s: %s", i.ObjectMeta.Namespace, i.ObjectMeta.Name, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priority := p.getPriority(pa, i)
|
||||||
|
|
||||||
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,
|
||||||
PassHostHeader: PassHostHeader,
|
PassHostHeader: PassHostHeader,
|
||||||
Routes: make(map[string]types.Route),
|
Routes: make(map[string]types.Route),
|
||||||
Priority: len(pa.Path),
|
Priority: priority,
|
||||||
BasicAuth: basicAuthCreds,
|
BasicAuth: basicAuthCreds,
|
||||||
WhitelistSourceRange: whitelistSourceRange,
|
WhitelistSourceRange: whitelistSourceRange,
|
||||||
}
|
}
|
||||||
|
@ -322,6 +325,23 @@ func getRuleForPath(pa v1beta1.HTTPIngressPath, i *v1beta1.Ingress) string {
|
||||||
return rule
|
return rule
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getPriority(path v1beta1.HTTPIngressPath, i *v1beta1.Ingress) int {
|
||||||
|
priority := len(path.Path)
|
||||||
|
|
||||||
|
priorityRaw, ok := i.Annotations[types.LabelFrontendPriority]
|
||||||
|
if ok {
|
||||||
|
priorityParsed, err := strconv.Atoi(priorityRaw)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
priority = priorityParsed
|
||||||
|
} else {
|
||||||
|
log.Errorf("Error in ingress: failed to parse %q value %q.", types.LabelFrontendPriority, priorityRaw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return priority
|
||||||
|
}
|
||||||
|
|
||||||
func handleBasicAuthConfig(i *v1beta1.Ingress, k8sClient Client) ([]string, error) {
|
func handleBasicAuthConfig(i *v1beta1.Ingress, k8sClient Client) ([]string, error) {
|
||||||
authType, exists := i.Annotations[annotationKubernetesAuthType]
|
authType, exists := i.Annotations[annotationKubernetesAuthType]
|
||||||
if !exists {
|
if !exists {
|
||||||
|
|
|
@ -1778,6 +1778,108 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPriorityHeaderValue(t *testing.T) {
|
||||||
|
ingresses := []*v1beta1.Ingress{
|
||||||
|
{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Namespace: "testing",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
types.LabelFrontendPriority: "1337",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: v1beta1.IngressSpec{
|
||||||
|
Rules: []v1beta1.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "foo",
|
||||||
|
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||||
|
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||||
|
Paths: []v1beta1.HTTPIngressPath{
|
||||||
|
{
|
||||||
|
Path: "/bar",
|
||||||
|
Backend: v1beta1.IngressBackend{
|
||||||
|
ServiceName: "service1",
|
||||||
|
ServicePort: intstr.FromInt(80),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
services := []*v1.Service{
|
||||||
|
{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Name: "service1",
|
||||||
|
UID: "1",
|
||||||
|
Namespace: "testing",
|
||||||
|
},
|
||||||
|
Spec: v1.ServiceSpec{
|
||||||
|
ClusterIP: "10.0.0.1",
|
||||||
|
Type: "ExternalName",
|
||||||
|
ExternalName: "example.com",
|
||||||
|
Ports: []v1.ServicePort{
|
||||||
|
{
|
||||||
|
Name: "http",
|
||||||
|
Port: 80,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoints := []*v1.Endpoints{}
|
||||||
|
watchChan := make(chan interface{})
|
||||||
|
client := clientMock{
|
||||||
|
ingresses: ingresses,
|
||||||
|
services: services,
|
||||||
|
endpoints: endpoints,
|
||||||
|
watchChan: watchChan,
|
||||||
|
}
|
||||||
|
provider := Provider{}
|
||||||
|
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{
|
||||||
|
"http://example.com": {
|
||||||
|
URL: "http://example.com",
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CircuitBreaker: nil,
|
||||||
|
LoadBalancer: &types.LoadBalancer{
|
||||||
|
Sticky: false,
|
||||||
|
Method: "wrr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Frontends: map[string]*types.Frontend{
|
||||||
|
"foo/bar": {
|
||||||
|
Backend: "foo/bar",
|
||||||
|
PassHostHeader: true,
|
||||||
|
Priority: 1337,
|
||||||
|
Routes: map[string]types.Route{
|
||||||
|
"/bar": {
|
||||||
|
Rule: "PathPrefix:/bar",
|
||||||
|
},
|
||||||
|
"foo": {
|
||||||
|
Rule: "Host:foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
func TestInvalidPassHostHeaderValue(t *testing.T) {
|
func TestInvalidPassHostHeaderValue(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{
|
ingresses := []*v1beta1.Ingress{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue