Fix wildcard hostname issue
This commit is contained in:
parent
c4fa96c41e
commit
d4f0a9ff62
8 changed files with 193 additions and 1 deletions
|
@ -0,0 +1,15 @@
|
|||
kind: Endpoints
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 10.10.0.1
|
||||
ports:
|
||||
- port: 8080
|
||||
- addresses:
|
||||
- ip: 10.21.0.1
|
||||
ports:
|
||||
- port: 8080
|
|
@ -0,0 +1,23 @@
|
|||
kind: Ingress
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: ""
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
rules:
|
||||
- host: "*.bar"
|
||||
http:
|
||||
paths:
|
||||
- path: /bar
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
||||
|
||||
- host: "bar"
|
||||
http:
|
||||
paths:
|
||||
- path: /bar
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
|
@ -0,0 +1,10 @@
|
|||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
|
@ -0,0 +1,15 @@
|
|||
kind: Endpoints
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 10.10.0.1
|
||||
ports:
|
||||
- port: 8080
|
||||
- addresses:
|
||||
- ip: 10.21.0.1
|
||||
ports:
|
||||
- port: 8080
|
|
@ -0,0 +1,19 @@
|
|||
kind: Ingress
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: ""
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /foo/bar
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
||||
|
||||
- path: /foo-bar
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
|
@ -0,0 +1,10 @@
|
|||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
|
@ -2,6 +2,7 @@ package ingress
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
@ -253,6 +254,8 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
conf.HTTP.Services["default-backend"] = service
|
||||
}
|
||||
|
||||
routers := map[string][]*dynamic.Router{}
|
||||
|
||||
for _, rule := range ingress.Spec.Rules {
|
||||
if err := p.updateIngressStatus(ingress, client); err != nil {
|
||||
log.FromContext(ctx).Errorf("Error while updating ingress status: %v", err)
|
||||
|
@ -276,8 +279,26 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
conf.HTTP.Services[serviceName] = service
|
||||
|
||||
routerKey := strings.TrimPrefix(provider.Normalize(ingress.Name+"-"+ingress.Namespace+"-"+rule.Host+pa.Path), "-")
|
||||
routers[routerKey] = append(routers[routerKey], loadRouter(rule, pa, rtConfig, serviceName))
|
||||
}
|
||||
}
|
||||
|
||||
conf.HTTP.Routers[routerKey] = loadRouter(rule, pa, rtConfig, serviceName)
|
||||
for routerKey, conflictingRouters := range routers {
|
||||
if len(conflictingRouters) == 1 {
|
||||
conf.HTTP.Routers[routerKey] = conflictingRouters[0]
|
||||
continue
|
||||
}
|
||||
|
||||
log.FromContext(ctx).Debugf("Multiple routers are defined with the same key %q, generating hashes to avoid conflicts", routerKey)
|
||||
|
||||
for _, router := range conflictingRouters {
|
||||
key, err := makeRouterKeyWithHash(routerKey, router.Rule)
|
||||
if err != nil {
|
||||
log.FromContext(ctx).Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
conf.HTTP.Routers[key] = router
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -543,6 +564,17 @@ func getProtocol(portSpec corev1.ServicePort, portName string, svcConfig *Servic
|
|||
return protocol
|
||||
}
|
||||
|
||||
func makeRouterKeyWithHash(key, rule string) (string, error) {
|
||||
h := sha256.New()
|
||||
if _, err := h.Write([]byte(rule)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
dupKey := fmt.Sprintf("%s-%.10x", key, h.Sum(nil))
|
||||
|
||||
return dupKey, nil
|
||||
}
|
||||
|
||||
func loadRouter(rule networkingv1beta1.IngressRule, pa networkingv1beta1.HTTPIngressPath, rtConfig *RouterConfig, serviceName string) *dynamic.Router {
|
||||
var rules []string
|
||||
if len(rule.Host) > 0 {
|
||||
|
|
|
@ -169,6 +169,74 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Ingress with conflicting routers on host",
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"testing-bar-bar-3be6cfd7daba66cf2fdd": {
|
||||
Rule: "HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.bar`) && PathPrefix(`/bar`)",
|
||||
Service: "testing-service1-80",
|
||||
},
|
||||
"testing-bar-bar-636bf36c00fedaab3d44": {
|
||||
Rule: "Host(`bar`) && 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",
|
||||
},
|
||||
{
|
||||
URL: "http://10.21.0.1:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Ingress with conflicting routers on path",
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"testing-foo-bar-d0b30949e54d6a7515ca": {
|
||||
Rule: "PathPrefix(`/foo/bar`)",
|
||||
Service: "testing-service1-80",
|
||||
},
|
||||
"testing-foo-bar-dcd54bae39a6d7557f48": {
|
||||
Rule: "PathPrefix(`/foo-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",
|
||||
},
|
||||
{
|
||||
URL: "http://10.21.0.1:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Ingress one rule with two paths",
|
||||
expected: &dynamic.Configuration{
|
||||
|
|
Loading…
Reference in a new issue