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
|
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.
|
// 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.
|
// This allows the provider to adapt the matcher syntax to the desired rule syntax version.
|
||||||
if c.Core != nil && c.Providers.KubernetesIngress != nil {
|
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"`
|
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"`
|
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
|
defaultBackendServiceNamespace string
|
||||||
defaultBackendServiceName 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.
|
// Apply SSL redirect is mandatory to be applied after all other middlewares.
|
||||||
// TODO: check how to remove this, and create the HTTP router elsewhere.
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -934,7 +937,7 @@ func applyCORSConfiguration(routerName string, ingressConfig ingressConfig, rt *
|
||||||
rt.Middlewares = append(rt.Middlewares, corsMiddlewareName)
|
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
|
var forceSSLRedirect bool
|
||||||
if ingressConfig.ForceSSLRedirect != nil {
|
if ingressConfig.ForceSSLRedirect != nil {
|
||||||
forceSSLRedirect = *ingressConfig.ForceSSLRedirect
|
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,
|
// 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.
|
// so no Non-TLS router exists to handle HTTP traffic, and we should create it.
|
||||||
httpRouter := &dynamic.Router{
|
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.
|
// "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax.
|
||||||
RuleSyntax: "default",
|
RuleSyntax: "default",
|
||||||
Middlewares: rt.Middlewares,
|
Middlewares: rt.Middlewares,
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,76 @@ func TestLoadIngresses(t *testing.T) {
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
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",
|
desc: "Basic Auth",
|
||||||
paths: []string{
|
paths: []string{
|
||||||
|
|
@ -176,15 +246,17 @@ func TestLoadIngresses(t *testing.T) {
|
||||||
Service: "default-ingress-with-ssl-redirect-whoami-80",
|
Service: "default-ingress-with-ssl-redirect-whoami-80",
|
||||||
},
|
},
|
||||||
"default-ingress-with-ssl-redirect-rule-0-path-0-http": {
|
"default-ingress-with-ssl-redirect-rule-0-path-0-http": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
Rule: "Host(`sslredirect.localhost`) && Path(`/`)",
|
Rule: "Host(`sslredirect.localhost`) && Path(`/`)",
|
||||||
RuleSyntax: "default",
|
RuleSyntax: "default",
|
||||||
Middlewares: []string{"default-ingress-with-ssl-redirect-rule-0-path-0-redirect-scheme"},
|
Middlewares: []string{"default-ingress-with-ssl-redirect-rule-0-path-0-redirect-scheme"},
|
||||||
Service: "noop@internal",
|
Service: "noop@internal",
|
||||||
},
|
},
|
||||||
"default-ingress-without-ssl-redirect-rule-0-path-0-http": {
|
"default-ingress-without-ssl-redirect-rule-0-path-0-http": {
|
||||||
Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)",
|
EntryPoints: []string{"web"},
|
||||||
RuleSyntax: "default",
|
Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)",
|
||||||
Service: "default-ingress-without-ssl-redirect-whoami-80",
|
RuleSyntax: "default",
|
||||||
|
Service: "default-ingress-without-ssl-redirect-whoami-80",
|
||||||
},
|
},
|
||||||
"default-ingress-without-ssl-redirect-rule-0-path-0": {
|
"default-ingress-without-ssl-redirect-rule-0-path-0": {
|
||||||
Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)",
|
Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)",
|
||||||
|
|
@ -653,6 +725,7 @@ func TestLoadIngresses(t *testing.T) {
|
||||||
k8sClient: client,
|
k8sClient: client,
|
||||||
defaultBackendServiceName: test.defaultBackendServiceName,
|
defaultBackendServiceName: test.defaultBackendServiceName,
|
||||||
defaultBackendServiceNamespace: test.defaultBackendServiceNamespace,
|
defaultBackendServiceNamespace: test.defaultBackendServiceNamespace,
|
||||||
|
NonTLSEntryPoints: []string{"web"},
|
||||||
}
|
}
|
||||||
p.SetDefaults()
|
p.SetDefaults()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue