Prevent Ingress Nginx provider http router to attach to an entrypoint with TLS
Co-authored-by: Gina A. <70909035+gndz07@users.noreply.github.com>
This commit is contained in:
parent
1881434ac6
commit
26f4a669b8
4 changed files with 119 additions and 6 deletions
|
|
@ -314,6 +314,18 @@ func (c *Configuration) SetEffectiveConfiguration() {
|
|||
c.Providers.KubernetesGateway.EntryPoints = entryPoints
|
||||
}
|
||||
|
||||
// Configure Ingress NGINX provider.
|
||||
if c.Providers.KubernetesIngressNGINX != nil {
|
||||
var nonTLSEntryPoints []string
|
||||
for epName, entryPoint := range c.EntryPoints {
|
||||
if entryPoint.HTTP.TLS == nil {
|
||||
nonTLSEntryPoints = append(nonTLSEntryPoints, epName)
|
||||
}
|
||||
}
|
||||
|
||||
c.Providers.KubernetesIngressNGINX.NonTLSEntryPoints = nonTLSEntryPoints
|
||||
}
|
||||
|
||||
// Defines the default rule syntax for the Kubernetes Ingress Provider.
|
||||
// This allows the provider to adapt the matcher syntax to the desired rule syntax version.
|
||||
if c.Core != nil && c.Providers.KubernetesIngress != nil {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-no-annotation
|
||||
namespace: default
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: whoami.localhost
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
service:
|
||||
name: whoami
|
||||
port:
|
||||
number: 80
|
||||
path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- hosts:
|
||||
- whoami.localhost
|
||||
secretName: whoami-tls
|
||||
|
|
@ -80,6 +80,9 @@ type Provider struct {
|
|||
DefaultBackendService string `description:"Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'." json:"defaultBackendService,omitempty" toml:"defaultBackendService,omitempty" yaml:"defaultBackendService,omitempty" export:"true"`
|
||||
DisableSvcExternalName bool `description:"Disable support for Services of type ExternalName." json:"disableSvcExternalName,omitempty" toml:"disableSvcExternalName,omitempty" yaml:"disableSvcExternalName,omitempty" export:"true"`
|
||||
|
||||
// NonTLSEntryPoints contains the names of entrypoints that are configured without TLS.
|
||||
NonTLSEntryPoints []string `json:"-" toml:"-" yaml:"-" label:"-" file:"-"`
|
||||
|
||||
defaultBackendServiceNamespace string
|
||||
defaultBackendServiceName string
|
||||
|
||||
|
|
@ -798,7 +801,7 @@ func (p *Provider) applyMiddlewares(namespace, routerKey string, ingressConfig i
|
|||
|
||||
// Apply SSL redirect is mandatory to be applied after all other middlewares.
|
||||
// TODO: check how to remove this, and create the HTTP router elsewhere.
|
||||
applySSLRedirectConfiguration(routerKey, ingressConfig, hasTLS, rt, conf)
|
||||
p.applySSLRedirectConfiguration(routerKey, ingressConfig, hasTLS, rt, conf)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -934,7 +937,7 @@ func applyCORSConfiguration(routerName string, ingressConfig ingressConfig, rt *
|
|||
rt.Middlewares = append(rt.Middlewares, corsMiddlewareName)
|
||||
}
|
||||
|
||||
func applySSLRedirectConfiguration(routerName string, ingressConfig ingressConfig, hasTLS bool, rt *dynamic.Router, conf *dynamic.Configuration) {
|
||||
func (p *Provider) applySSLRedirectConfiguration(routerName string, ingressConfig ingressConfig, hasTLS bool, rt *dynamic.Router, conf *dynamic.Configuration) {
|
||||
var forceSSLRedirect bool
|
||||
if ingressConfig.ForceSSLRedirect != nil {
|
||||
forceSSLRedirect = *ingressConfig.ForceSSLRedirect
|
||||
|
|
@ -946,7 +949,9 @@ func applySSLRedirectConfiguration(routerName string, ingressConfig ingressConfi
|
|||
// An Ingress with TLS configuration creates only a Traefik router with a TLS configuration,
|
||||
// so no Non-TLS router exists to handle HTTP traffic, and we should create it.
|
||||
httpRouter := &dynamic.Router{
|
||||
Rule: rt.Rule,
|
||||
// Only attach to entryPoint which do not activate TLS.
|
||||
EntryPoints: p.NonTLSEntryPoints,
|
||||
Rule: rt.Rule,
|
||||
// "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax.
|
||||
RuleSyntax: "default",
|
||||
Middlewares: rt.Middlewares,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,76 @@ func TestLoadIngresses(t *testing.T) {
|
|||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "No annotation",
|
||||
paths: []string{
|
||||
"ingresses/00-ingress-with-no-annotation.yml",
|
||||
"ingressclasses.yml",
|
||||
"services.yml",
|
||||
"secrets.yml",
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"default-ingress-with-no-annotation-rule-0-path-0": {
|
||||
Rule: "Host(`whoami.localhost`) && PathPrefix(`/`)",
|
||||
RuleSyntax: "default",
|
||||
TLS: &dynamic.RouterTLSConfig{},
|
||||
Service: "default-ingress-with-no-annotation-whoami-80",
|
||||
},
|
||||
"default-ingress-with-no-annotation-rule-0-path-0-http": {
|
||||
EntryPoints: []string{"web"},
|
||||
Rule: "Host(`whoami.localhost`) && PathPrefix(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-no-annotation-rule-0-path-0-redirect-scheme"},
|
||||
Service: "noop@internal",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-ingress-with-no-annotation-rule-0-path-0-redirect-scheme": {
|
||||
RedirectScheme: &dynamic.RedirectScheme{
|
||||
Scheme: "https",
|
||||
ForcePermanentRedirect: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-ingress-with-no-annotation-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.2:80",
|
||||
},
|
||||
},
|
||||
Strategy: "wrr",
|
||||
PassHostHeader: ptr.To(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: dynamic.DefaultFlushInterval,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: "-----BEGIN CERTIFICATE-----",
|
||||
KeyFile: "-----BEGIN CERTIFICATE-----",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Basic Auth",
|
||||
paths: []string{
|
||||
|
|
@ -176,15 +246,17 @@ func TestLoadIngresses(t *testing.T) {
|
|||
Service: "default-ingress-with-ssl-redirect-whoami-80",
|
||||
},
|
||||
"default-ingress-with-ssl-redirect-rule-0-path-0-http": {
|
||||
EntryPoints: []string{"web"},
|
||||
Rule: "Host(`sslredirect.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-ssl-redirect-rule-0-path-0-redirect-scheme"},
|
||||
Service: "noop@internal",
|
||||
},
|
||||
"default-ingress-without-ssl-redirect-rule-0-path-0-http": {
|
||||
Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Service: "default-ingress-without-ssl-redirect-whoami-80",
|
||||
EntryPoints: []string{"web"},
|
||||
Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Service: "default-ingress-without-ssl-redirect-whoami-80",
|
||||
},
|
||||
"default-ingress-without-ssl-redirect-rule-0-path-0": {
|
||||
Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)",
|
||||
|
|
@ -653,6 +725,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
k8sClient: client,
|
||||
defaultBackendServiceName: test.defaultBackendServiceName,
|
||||
defaultBackendServiceNamespace: test.defaultBackendServiceNamespace,
|
||||
NonTLSEntryPoints: []string{"web"},
|
||||
}
|
||||
p.SetDefaults()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue