From dafb14ff378e45681af6daea670232c625b0dbc6 Mon Sep 17 00:00:00 2001 From: Romain Date: Tue, 28 Jul 2020 17:50:04 +0200 Subject: [PATCH] Support Kubernetes Ingress pathType Co-authored-by: jbdoumenjou Co-authored-by: kevinpollet --- docs/content/providers/kubernetes-ingress.md | 15 +- .../routing/providers/kubernetes-ingress.md | 20 ++- pkg/provider/kubernetes/ingress/client.go | 2 +- ...8-Ingress-with-empty-pathType_endpoint.yml | 11 ++ ...18-Ingress-with-empty-pathType_ingress.yml | 16 ++ ...18-Ingress-with-empty-pathType_service.yml | 10 ++ ...8-Ingress-with-exact-pathType_endpoint.yml | 11 ++ ...18-Ingress-with-exact-pathType_ingress.yml | 14 ++ ...18-Ingress-with-exact-pathType_service.yml | 10 ++ ...plementationSpecific-pathType_endpoint.yml | 11 ++ ...mplementationSpecific-pathType_ingress.yml | 16 ++ ...mplementationSpecific-pathType_service.yml | 10 ++ ...gress-with-ingress-annotation_endpoint.yml | 11 ++ ...ngress-with-ingress-annotation_ingress.yml | 15 ++ ...ngress-with-ingress-annotation_service.yml | 10 ++ .../v18-Ingress-with-no-pathType_endpoint.yml | 11 ++ .../v18-Ingress-with-no-pathType_ingress.yml | 15 ++ .../v18-Ingress-with-no-pathType_service.yml | 10 ++ ...-Ingress-with-prefix-pathType_endpoint.yml | 11 ++ ...8-Ingress-with-prefix-pathType_ingress.yml | 14 ++ ...8-Ingress-with-prefix-pathType_service.yml | 10 ++ pkg/provider/kubernetes/ingress/kubernetes.go | 25 +-- .../kubernetes/ingress/kubernetes_test.go | 169 ++++++++++++++++++ 23 files changed, 423 insertions(+), 24 deletions(-) create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_endpoint.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_ingress.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_service.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_endpoint.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_ingress.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_service.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_endpoint.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_ingress.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_service.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_endpoint.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_ingress.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_service.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_endpoint.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_ingress.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_service.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_endpoint.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_ingress.yml create mode 100644 pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_service.yml diff --git a/docs/content/providers/kubernetes-ingress.md b/docs/content/providers/kubernetes-ingress.md index b0dea1fdc..c5a855147 100644 --- a/docs/content/providers/kubernetes-ingress.md +++ b/docs/content/providers/kubernetes-ingress.md @@ -258,16 +258,13 @@ Value of `kubernetes.io/ingress.class` annotation that identifies Ingress object If the parameter is non-empty, only Ingresses containing an annotation with the same value are processed. Otherwise, Ingresses missing the annotation, having an empty value, or with the value `traefik` are processed. -#### ingressClass on Kubernetes 1.18+ +!!! info "Kubernetes 1.18+" -If you cluster is running kubernetes 1.18+, -you can also leverage the newly Introduced `IngressClass` resource to define which Ingress Objects to handle. -In that case, Traefik will look for an `IngressClass` in your cluster with the controller of *traefik.io/ingress-controller* inside the spec. - -!!! note "" - Please note, the ingressClass configuration on the provider is not used then anymore. - -Please see [this article](https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/) for more information. + If the Kubernetes cluster version is 1.18+, + the new `IngressClass` resource can be leveraged to identify Ingress objects that should be processed. + In that case, Traefik will look for an `IngressClass` in the cluster with the controller value equal to *traefik.io/ingress-controller*. + + Please see [this article](https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/) for more information. ### `ingressEndpoint` diff --git a/docs/content/routing/providers/kubernetes-ingress.md b/docs/content/routing/providers/kubernetes-ingress.md index 7b7ac27d0..83ef155b1 100644 --- a/docs/content/routing/providers/kubernetes-ingress.md +++ b/docs/content/routing/providers/kubernetes-ingress.md @@ -322,9 +322,23 @@ which in turn will create the resulting routers, services, handlers, etc. traefik.ingress.kubernetes.io/service.sticky.cookie.httponly: "true" ``` -### TLS +## Path Types on Kubernetes 1.18+ + +If the Kubernetes cluster version is 1.18+, +the new `pathType` property can be leveraged to define the rules matchers: -#### Communication Between Traefik and Pods +- `Exact`: This path type forces the rule matcher to `Path` +- `Prefix`: This path type forces the rule matcher to `PathPrefix` + +Please see [this documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types) for more information. + +!!! warning "Multiple Matches" + In the case of multiple matches, Traefik will not ensure the priority of a Path matcher over a PathPrefix matcher, + as stated in [this documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/#multiple-matches). + +## TLS + +### Communication Between Traefik and Pods Traefik automatically requests endpoint information based on the service provided in the ingress spec. Although Traefik will connect directly to the endpoints (pods), @@ -346,7 +360,7 @@ and will connect via TLS automatically. If this is not an option, you may need to skip TLS certificate verification. See the [insecureSkipVerify](../../routing/overview.md#insecureskipverify) setting for more details. -#### Certificates Management +### Certificates Management ??? example "Using a secret" diff --git a/pkg/provider/kubernetes/ingress/client.go b/pkg/provider/kubernetes/ingress/client.go index 84d6bb835..fc54c48d5 100644 --- a/pkg/provider/kubernetes/ingress/client.go +++ b/pkg/provider/kubernetes/ingress/client.go @@ -341,7 +341,7 @@ func (c *clientWrapper) GetIngressClass() (*networkingv1beta1.IngressClass, erro for _, ic := range ingressClasses { if ic.Spec.Controller == traefikDefaultIngressClassController { - return ic, err + return ic, nil } } diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_endpoint.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_endpoint.yml new file mode 100644 index 000000000..6ed60d79c --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_endpoint.yml @@ -0,0 +1,11 @@ +kind: Endpoints +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +subsets: +- addresses: + - ip: 10.10.0.1 + ports: + - port: 8080 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_ingress.yml new file mode 100644 index 000000000..b01a04d51 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_ingress.yml @@ -0,0 +1,16 @@ +kind: Ingress +apiVersion: networking.k8s.io/v1beta1 +metadata: + name: "" + namespace: testing + annotations: + traefik.ingress.kubernetes.io/router.pathmatcher: Path +spec: + rules: + - http: + paths: + - path: /bar + pathType: "" + backend: + serviceName: service1 + servicePort: 80 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_service.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_service.yml new file mode 100644 index 000000000..7c58aeed5 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-empty-pathType_service.yml @@ -0,0 +1,10 @@ +kind: Service +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +spec: + ports: + - port: 80 + clusterIp: 10.0.0.1 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_endpoint.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_endpoint.yml new file mode 100644 index 000000000..6ed60d79c --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_endpoint.yml @@ -0,0 +1,11 @@ +kind: Endpoints +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +subsets: +- addresses: + - ip: 10.10.0.1 + ports: + - port: 8080 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_ingress.yml new file mode 100644 index 000000000..d3f9848f6 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_ingress.yml @@ -0,0 +1,14 @@ +kind: Ingress +apiVersion: networking.k8s.io/v1beta1 +metadata: + name: "" + namespace: testing +spec: + rules: + - http: + paths: + - path: /bar + pathType: Exact + backend: + serviceName: service1 + servicePort: 80 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_service.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_service.yml new file mode 100644 index 000000000..7c58aeed5 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-exact-pathType_service.yml @@ -0,0 +1,10 @@ +kind: Service +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +spec: + ports: + - port: 80 + clusterIp: 10.0.0.1 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_endpoint.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_endpoint.yml new file mode 100644 index 000000000..6ed60d79c --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_endpoint.yml @@ -0,0 +1,11 @@ +kind: Endpoints +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +subsets: +- addresses: + - ip: 10.10.0.1 + ports: + - port: 8080 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_ingress.yml new file mode 100644 index 000000000..8b1cc9674 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_ingress.yml @@ -0,0 +1,16 @@ +kind: Ingress +apiVersion: networking.k8s.io/v1beta1 +metadata: + name: "" + namespace: testing + annotations: + traefik.ingress.kubernetes.io/router.pathmatcher: Path +spec: + rules: + - http: + paths: + - path: /bar + pathType: ImplementationSpecific + backend: + serviceName: service1 + servicePort: 80 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_service.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_service.yml new file mode 100644 index 000000000..7c58aeed5 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-implementationSpecific-pathType_service.yml @@ -0,0 +1,10 @@ +kind: Service +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +spec: + ports: + - port: 80 + clusterIp: 10.0.0.1 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_endpoint.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_endpoint.yml new file mode 100644 index 000000000..6ed60d79c --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_endpoint.yml @@ -0,0 +1,11 @@ +kind: Endpoints +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +subsets: +- addresses: + - ip: 10.10.0.1 + ports: + - port: 8080 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_ingress.yml new file mode 100644 index 000000000..e223946d0 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_ingress.yml @@ -0,0 +1,15 @@ +kind: Ingress +apiVersion: networking.k8s.io/v1beta1 +metadata: + name: "" + namespace: testing + annotations: + kubernetes.io/ingress.class: traefik +spec: + rules: + - http: + paths: + - path: /bar + backend: + serviceName: service1 + servicePort: 80 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_service.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_service.yml new file mode 100644 index 000000000..7c58aeed5 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-ingress-annotation_service.yml @@ -0,0 +1,10 @@ +kind: Service +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +spec: + ports: + - port: 80 + clusterIp: 10.0.0.1 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_endpoint.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_endpoint.yml new file mode 100644 index 000000000..6ed60d79c --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_endpoint.yml @@ -0,0 +1,11 @@ +kind: Endpoints +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +subsets: +- addresses: + - ip: 10.10.0.1 + ports: + - port: 8080 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_ingress.yml new file mode 100644 index 000000000..740d39d1c --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_ingress.yml @@ -0,0 +1,15 @@ +kind: Ingress +apiVersion: networking.k8s.io/v1beta1 +metadata: + name: "" + namespace: testing + annotations: + traefik.ingress.kubernetes.io/router.pathmatcher: Path +spec: + rules: + - http: + paths: + - path: /bar + backend: + serviceName: service1 + servicePort: 80 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_service.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_service.yml new file mode 100644 index 000000000..7c58aeed5 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-no-pathType_service.yml @@ -0,0 +1,10 @@ +kind: Service +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +spec: + ports: + - port: 80 + clusterIp: 10.0.0.1 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_endpoint.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_endpoint.yml new file mode 100644 index 000000000..6ed60d79c --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_endpoint.yml @@ -0,0 +1,11 @@ +kind: Endpoints +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +subsets: +- addresses: + - ip: 10.10.0.1 + ports: + - port: 8080 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_ingress.yml new file mode 100644 index 000000000..2ae20e2ef --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_ingress.yml @@ -0,0 +1,14 @@ +kind: Ingress +apiVersion: networking.k8s.io/v1beta1 +metadata: + name: "" + namespace: testing +spec: + rules: + - http: + paths: + - path: /bar + pathType: Prefix + backend: + serviceName: service1 + servicePort: 80 diff --git a/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_service.yml b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_service.yml new file mode 100644 index 000000000..7c58aeed5 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/v18-Ingress-with-prefix-pathType_service.yml @@ -0,0 +1,10 @@ +kind: Service +apiVersion: v1 +metadata: + name: service1 + namespace: testing + +spec: + ports: + - port: 80 + clusterIp: 10.0.0.1 diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index b67251548..119c0115e 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -194,13 +194,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl if supportsIngressClass(serverVersion) { ic, err := client.GetIngressClass() if err != nil { - log.FromContext(ctx).Errorf("Failed to find an ingress class: %v", err) - return conf - } - - if ic == nil { - log.FromContext(ctx).Errorf("No ingress class for the traefik-controller in the cluster") - return conf + log.FromContext(ctx).Warnf("Failed to find an ingress class: %v", err) } ingressClass = ic @@ -337,8 +331,12 @@ func (p *Provider) updateIngressStatus(ing *v1beta1.Ingress, k8sClient Client) e } func (p *Provider) shouldProcessIngress(providerIngressClass string, ingress *networkingv1beta1.Ingress, ingressClass *networkingv1beta1.IngressClass) bool { - return ingressClass != nil && ingress.Spec.IngressClassName != nil && ingressClass.ObjectMeta.Name == *ingress.Spec.IngressClassName || - providerIngressClass == ingress.Annotations[annotationKubernetesIngressClass] || + // configuration through the new kubernetes ingressClass + if ingress.Spec.IngressClassName != nil { + return ingressClass != nil && ingressClass.ObjectMeta.Name == *ingress.Spec.IngressClassName + } + + return providerIngressClass == ingress.Annotations[annotationKubernetesIngressClass] || len(providerIngressClass) == 0 && ingress.Annotations[annotationKubernetesIngressClass] == traefikDefaultIngressClass } @@ -549,8 +547,13 @@ func loadRouter(rule v1beta1.IngressRule, pa v1beta1.HTTPIngressPath, rtConfig * if len(pa.Path) > 0 { matcher := defaultPathMatcher - if rtConfig != nil && rtConfig.Router != nil && rtConfig.Router.PathMatcher != "" { - matcher = rtConfig.Router.PathMatcher + + if pa.PathType == nil || *pa.PathType == "" || *pa.PathType == v1beta1.PathTypeImplementationSpecific { + if rtConfig != nil && rtConfig.Router != nil && rtConfig.Router.PathMatcher != "" { + matcher = rtConfig.Router.PathMatcher + } + } else if *pa.PathType == v1beta1.PathTypeExact { + matcher = "Path" } rules = append(rules, fmt.Sprintf("%s(`%s`)", matcher, pa.Path)) diff --git a/pkg/provider/kubernetes/ingress/kubernetes_test.go b/pkg/provider/kubernetes/ingress/kubernetes_test.go index a819ce16e..f1daee211 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress/kubernetes_test.go @@ -952,6 +952,146 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, }, }, + { + desc: "v18 Ingress with no pathType", + serverVersion: "v1.18", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-bar": { + Rule: "Path(`/bar`)", + Service: "testing-service1-80", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, + { + desc: "v18 Ingress with empty pathType", + serverVersion: "v1.18", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-bar": { + Rule: "Path(`/bar`)", + Service: "testing-service1-80", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, + { + desc: "v18 Ingress with implementationSpecific pathType", + serverVersion: "v1.18", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-bar": { + Rule: "Path(`/bar`)", + Service: "testing-service1-80", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, + { + desc: "v18 Ingress with prefix pathType", + serverVersion: "v1.18", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-bar": { + Rule: "PathPrefix(`/bar`)", + Service: "testing-service1-80", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, + { + desc: "v18 Ingress with exact pathType", + serverVersion: "v1.18", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-bar": { + Rule: "Path(`/bar`)", + Service: "testing-service1-80", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, { desc: "v18 Ingress with missing ingressClass", serverVersion: "v1.18", @@ -964,10 +1104,39 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, }, }, + { + desc: "v18 Ingress with ingress annotation", + serverVersion: "v1.18", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-bar": { + Rule: "PathPrefix(`/bar`)", + Service: "testing-service1-80", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, } for _, test := range testCases { test := test + t.Run(test.desc, func(t *testing.T) { t.Parallel()