diff --git a/docs/content/reference/install-configuration/configuration-options.md b/docs/content/reference/install-configuration/configuration-options.md
index 400ca6068..8b08b6bac 100644
--- a/docs/content/reference/install-configuration/configuration-options.md
+++ b/docs/content/reference/install-configuration/configuration-options.md
@@ -399,6 +399,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| providers.kubernetesingressnginx.endpoint | Kubernetes server endpoint (required for external cluster client). | |
| providers.kubernetesingressnginx.ingressclass | Name of the ingress class this controller satisfies. | nginx |
| providers.kubernetesingressnginx.ingressclassbyname | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false |
+| providers.kubernetesingressnginx.proxyconnecttimeout | Amount of time to wait until a connection to a server can be established. Timeout value is unitless and in seconds. | 60 |
| providers.kubernetesingressnginx.publishservice | Service fronting the Ingress controller. Takes the form 'namespace/name'. | |
| providers.kubernetesingressnginx.publishstatusaddress | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | |
| providers.kubernetesingressnginx.throttleduration | Ingress refresh throttle duration. | 0 |
diff --git a/docs/content/reference/install-configuration/providers/kubernetes/kubernetes-ingress-nginx.md b/docs/content/reference/install-configuration/providers/kubernetes/kubernetes-ingress-nginx.md
index aa42c8acb..0524f4d2b 100644
--- a/docs/content/reference/install-configuration/providers/kubernetes/kubernetes-ingress-nginx.md
+++ b/docs/content/reference/install-configuration/providers/kubernetes/kubernetes-ingress-nginx.md
@@ -114,23 +114,24 @@ This provider watches for incoming Ingress events and automatically translates N
## Configuration Options
-| Field | Description | Default | Required |
-|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------|:--------|:---------|
-| `providers.providers`
`ThrottleDuration` | Minimum amount of time to wait for, after a configuration reload, before taking into account any new configuration refresh event.
If multiple events occur within this time, only the most recent one is taken into account, and all others are discarded.
**This option cannot be set per provider, but the throttling algorithm applies to each of them independently.** | 2s | No |
-| `providers.`
`kubernetesIngressNGINX.`
`endpoint` | Server endpoint URL.
More information [here](#endpoint). | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`token` | Bearer token used for the Kubernetes client configuration. | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`certAuthFilePath` | Path to the certificate authority file.
Used for the Kubernetes client configuration. | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`throttleDuration` | Minimum amount of time to wait between two Kubernetes events before producing a new configuration.
This prevents a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.
If empty, every event is caught. | 0s | No |
-| `providers.`
`kubernetesIngressNGINX.`
`watchNamespace` | Namespace the controller watches for updates to Kubernetes objects. All namespaces are watched if this parameter is left empty. | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`watchNamespaceSelector` | Selector selects namespaces the controller watches for updates to Kubernetes objects. | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`ingressClass` | Name of the ingress class this controller satisfies. | "nginx" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`controllerClass` | Ingress Class Controller value this controller satisfies. | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`watchIngressWithoutClass` | Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified. | false | No |
-| `providers.`
`kubernetesIngressNGINX.`
`ingressClassByName` | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false | No |
-| `providers.`
`kubernetesIngressNGINX.`
`publishService` | Service fronting the Ingress controller. Takes the form `namespace/name`. | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`publishStatusAddress` | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`defaultBackendService` | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'. | "" | No |
-| `providers.`
`kubernetesIngressNGINX.`
`disableSvcExternalName` | Disable support for Services of type ExternalName. | false | No |
+| Field | Description | Default | Required |
+|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------|
+| `providers.providers`
`ThrottleDuration` | Minimum amount of time to wait for, after a configuration reload, before taking into account any new configuration refresh event.
If multiple events occur within this time, only the most recent one is taken into account, and all others are discarded.
**This option cannot be set per provider, but the throttling algorithm applies to each of them independently.** | 2s | No |
+| `providers.`
`kubernetesIngressNGINX.`
`endpoint` | Server endpoint URL.
More information [here](#endpoint). | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`token` | Bearer token used for the Kubernetes client configuration. | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`certAuthFilePath` | Path to the certificate authority file.
Used for the Kubernetes client configuration. | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`throttleDuration` | Minimum amount of time to wait between two Kubernetes events before producing a new configuration.
This prevents a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.
If empty, every event is caught. | 0s | No |
+| `providers.`
`kubernetesIngressNGINX.`
`watchNamespace` | Namespace the controller watches for updates to Kubernetes objects. All namespaces are watched if this parameter is left empty. | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`watchNamespaceSelector` | Selector selects namespaces the controller watches for updates to Kubernetes objects. | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`ingressClass` | Name of the ingress class this controller satisfies. | "nginx" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`controllerClass` | Ingress Class Controller value this controller satisfies. | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`watchIngressWithoutClass` | Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified. | false | No |
+| `providers.`
`kubernetesIngressNGINX.`
`ingressClassByName` | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false | No |
+| `providers.`
`kubernetesIngressNGINX.`
`publishService` | Service fronting the Ingress controller. Takes the form `namespace/name`. | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`publishStatusAddress` | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`defaultBackendService` | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'. | "" | No |
+| `providers.`
`kubernetesIngressNGINX.`
`disableSvcExternalName` | Disable support for Services of type ExternalName. | false | No |
+| `providers.`
`kubernetesIngressNGINX.`
`proxyConnectTimeout` | Amount of time to wait until a connection to a server can be established. The value is unitless and in seconds. This is used as the global connection timeout when no ingress-specific timeout is configured. An ingress-specific timeout can be configured using [`nginx.ingress.kubernetes.io/proxy-connect-timeout`](../../../../routing-configuration/kubernetes/ingress-nginx/#opt-nginx-ingress-kubernetes-ioproxy-connect-timeout) annotation. | 60 | No |
diff --git a/docs/content/reference/routing-configuration/kubernetes/ingress-nginx.md b/docs/content/reference/routing-configuration/kubernetes/ingress-nginx.md
index 4e210fd8d..d86fd9a32 100644
--- a/docs/content/reference/routing-configuration/kubernetes/ingress-nginx.md
+++ b/docs/content/reference/routing-configuration/kubernetes/ingress-nginx.md
@@ -331,6 +331,11 @@ The following annotations are organized by category for easier navigation.
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
| `nginx.ingress.kubernetes.io/whitelist-source-range` | |
+### Timeout
+
+| Annotation | Limitations / Notes |
+|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `nginx.ingress.kubernetes.io/proxy-connect-timeout` | Timeout can be defined globally at the provider level using the [`proxyConnectTimeout` option](../../../install-configuration/providers/kubernetes/kubernetes-ingress-nginx/#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout). |
## Limitations
@@ -399,8 +404,7 @@ The following annotations are organized by category for easier navigation.
| `nginx.ingress.kubernetes.io/global-rate-limit-ignored-cidrs` | |
| `nginx.ingress.kubernetes.io/preserve-trailing-slash` | Traefik preserves trailing slash by default. |
| `nginx.ingress.kubernetes.io/proxy-cookie-domain` | |
-| `nginx.ingress.kubernetes.io/proxy-cookie-path` | |
-| `nginx.ingress.kubernetes.io/proxy-connect-timeout` | |
+| `nginx.ingress.kubernetes.io/proxy-cookie-path` | | |
| `nginx.ingress.kubernetes.io/proxy-send-timeout` | |
| `nginx.ingress.kubernetes.io/proxy-read-timeout` | |
| `nginx.ingress.kubernetes.io/proxy-next-upstream` | |
diff --git a/pkg/provider/kubernetes/ingress-nginx/annotations.go b/pkg/provider/kubernetes/ingress-nginx/annotations.go
index 4d4b132c6..953cda9ed 100644
--- a/pkg/provider/kubernetes/ingress-nginx/annotations.go
+++ b/pkg/provider/kubernetes/ingress-nginx/annotations.go
@@ -46,10 +46,11 @@ type ingressConfig struct {
BackendProtocol *string `annotation:"nginx.ingress.kubernetes.io/backend-protocol"`
- ProxySSLSecret *string `annotation:"nginx.ingress.kubernetes.io/proxy-ssl-secret"`
- ProxySSLVerify *string `annotation:"nginx.ingress.kubernetes.io/proxy-ssl-verify"`
- ProxySSLName *string `annotation:"nginx.ingress.kubernetes.io/proxy-ssl-name"`
- ProxySSLServerName *string `annotation:"nginx.ingress.kubernetes.io/proxy-ssl-server-name"`
+ ProxySSLSecret *string `annotation:"nginx.ingress.kubernetes.io/proxy-ssl-secret"`
+ ProxySSLVerify *string `annotation:"nginx.ingress.kubernetes.io/proxy-ssl-verify"`
+ ProxySSLName *string `annotation:"nginx.ingress.kubernetes.io/proxy-ssl-name"`
+ ProxySSLServerName *string `annotation:"nginx.ingress.kubernetes.io/proxy-ssl-server-name"`
+ ProxyConnectTimeout *int `annotation:"nginx.ingress.kubernetes.io/proxy-connect-timeout"`
EnableCORS *bool `annotation:"nginx.ingress.kubernetes.io/enable-cors"`
EnableCORSAllowCredentials *bool `annotation:"nginx.ingress.kubernetes.io/cors-allow-credentials"`
diff --git a/pkg/provider/kubernetes/ingress-nginx/annotations_test.go b/pkg/provider/kubernetes/ingress-nginx/annotations_test.go
index 961b2b871..64ccb03a8 100644
--- a/pkg/provider/kubernetes/ingress-nginx/annotations_test.go
+++ b/pkg/provider/kubernetes/ingress-nginx/annotations_test.go
@@ -30,6 +30,7 @@ func Test_parseIngressConfig(t *testing.T) {
"nginx.ingress.kubernetes.io/cors-expose-headers": "foo, bar",
"nginx.ingress.kubernetes.io/auth-url": "http://auth.example.com/verify",
"nginx.ingress.kubernetes.io/auth-signin": "https://auth.example.com/oauth2/start?rd=foo",
+ "nginx.ingress.kubernetes.io/proxy-connect-timeout": "30",
},
expected: ingressConfig{
SSLPassthrough: ptr.To(true),
@@ -44,6 +45,7 @@ func Test_parseIngressConfig(t *testing.T) {
CORSExposeHeaders: ptr.To([]string{"foo", "bar"}),
AuthURL: ptr.To("http://auth.example.com/verify"),
AuthSignin: ptr.To("https://auth.example.com/oauth2/start?rd=foo"),
+ ProxyConnectTimeout: ptr.To(30),
},
},
{
@@ -60,6 +62,7 @@ func Test_parseIngressConfig(t *testing.T) {
annotations: map[string]string{
"nginx.ingress.kubernetes.io/ssl-passthrough": "notabool",
"nginx.ingress.kubernetes.io/session-cookie-max-age (in seconds)": "notanint",
+ "nginx.ingress.kubernetes.io/proxy-connect-timeout": "notanint",
},
},
}
diff --git a/pkg/provider/kubernetes/ingress-nginx/fixtures/ingresses/19-ingress-with-proxy-timeout.yml b/pkg/provider/kubernetes/ingress-nginx/fixtures/ingresses/19-ingress-with-proxy-timeout.yml
new file mode 100644
index 000000000..69cc4612e
--- /dev/null
+++ b/pkg/provider/kubernetes/ingress-nginx/fixtures/ingresses/19-ingress-with-proxy-timeout.yml
@@ -0,0 +1,22 @@
+---
+kind: Ingress
+apiVersion: networking.k8s.io/v1
+metadata:
+ name: ingress-with-proxy-timeout
+ namespace: default
+ annotations:
+ nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
+
+spec:
+ ingressClassName: nginx
+ rules:
+ - host: whoami.localhost
+ http:
+ paths:
+ - path: /
+ pathType: Exact
+ backend:
+ service:
+ name: whoami
+ port:
+ number: 80
diff --git a/pkg/provider/kubernetes/ingress-nginx/kubernetes.go b/pkg/provider/kubernetes/ingress-nginx/kubernetes.go
index 355d6c2b8..f27bffa1f 100644
--- a/pkg/provider/kubernetes/ingress-nginx/kubernetes.go
+++ b/pkg/provider/kubernetes/ingress-nginx/kubernetes.go
@@ -41,6 +41,8 @@ const (
defaultBackendName = "default-backend"
defaultBackendTLSName = "default-backend-tls"
+
+ defaultProxyConnectTimeout = 60
)
type backendAddress struct {
@@ -80,6 +82,8 @@ 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"`
+ ProxyConnectTimeout int `description:"Amount of time to wait until a connection to a server can be established. Timeout value is unitless and in seconds." json:"proxyConnectTimeout,omitempty" toml:"proxyConnectTimeout,omitempty" yaml:"proxyConnectTimeout,omitempty" export:"true"`
+
// NonTLSEntryPoints contains the names of entrypoints that are configured without TLS.
NonTLSEntryPoints []string `json:"-" toml:"-" yaml:"-" label:"-" file:"-"`
@@ -93,6 +97,7 @@ type Provider struct {
func (p *Provider) SetDefaults() {
p.IngressClass = defaultAnnotationValue
p.ControllerClass = defaultControllerName
+ p.ProxyConnectTimeout = defaultProxyConnectTimeout
}
// Init the provider.
@@ -503,19 +508,23 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
}
func (p *Provider) buildServersTransport(namespace, name string, cfg ingressConfig) (*namedServersTransport, error) {
- scheme := parseBackendProtocol(ptr.Deref(cfg.BackendProtocol, "HTTP"))
- if scheme != "https" {
- return nil, nil
- }
-
+ proxyConnectTimeout := ptr.Deref(cfg.ProxyConnectTimeout, p.ProxyConnectTimeout)
nst := &namedServersTransport{
Name: provider.Normalize(namespace + "-" + name),
ServersTransport: &dynamic.ServersTransport{
- ServerName: ptr.Deref(cfg.ProxySSLName, ptr.Deref(cfg.ProxySSLServerName, "")),
- InsecureSkipVerify: strings.ToLower(ptr.Deref(cfg.ProxySSLVerify, "off")) == "off",
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(time.Duration(proxyConnectTimeout) * time.Second),
+ },
},
}
+ if scheme := parseBackendProtocol(ptr.Deref(cfg.BackendProtocol, "HTTP")); scheme != "https" {
+ return nst, nil
+ }
+
+ nst.ServersTransport.ServerName = ptr.Deref(cfg.ProxySSLName, ptr.Deref(cfg.ProxySSLServerName, ""))
+ nst.ServersTransport.InsecureSkipVerify = strings.ToLower(ptr.Deref(cfg.ProxySSLVerify, "off")) == "off"
+
if sslSecret := ptr.Deref(cfg.ProxySSLSecret, ""); sslSecret != "" {
parts := strings.Split(sslSecret, "/")
if len(parts) != 2 {
diff --git a/pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go b/pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go
index 3839d8d94..3f76c203b 100644
--- a/pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go
+++ b/pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go
@@ -6,9 +6,11 @@ import (
"os"
"path/filepath"
"testing"
+ "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s"
"github.com/traefik/traefik/v3/pkg/tls"
@@ -86,15 +88,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-custom-headers",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-custom-headers": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -147,15 +156,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-no-annotation",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-no-annotation": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
@@ -211,15 +227,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-basicauth",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-basicauth": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -265,15 +288,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-forwardauth",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-forwardauth": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -350,8 +380,9 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-ssl-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
@@ -367,8 +398,9 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-without-ssl-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
@@ -384,15 +416,32 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-force-ssl-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-ssl-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ "default-ingress-without-ssl-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ "default-ingress-with-force-ssl-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
@@ -483,8 +532,9 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-sticky",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
@@ -503,7 +553,13 @@ func TestLoadIngresses(t *testing.T) {
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-sticky": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -555,6 +611,9 @@ func TestLoadIngresses(t *testing.T) {
ServerName: "whoami.localhost",
InsecureSkipVerify: false,
RootCAs: []types.FileOrContent{"-----BEGIN CERTIFICATE-----"},
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
},
},
},
@@ -605,15 +664,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-cors",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-cors": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -647,15 +713,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.10.1:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-service-upstream",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-service-upstream": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -704,10 +777,17 @@ func TestLoadIngresses(t *testing.T) {
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
+ ServersTransport: "default-ingress-with-upstream-vhost",
+ },
+ },
+ },
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-upstream-vhost": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -749,10 +829,17 @@ func TestLoadIngresses(t *testing.T) {
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
+ ServersTransport: "default-ingress-with-use-regex",
+ },
+ },
+ },
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-use-regex": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -802,10 +889,17 @@ func TestLoadIngresses(t *testing.T) {
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
+ ServersTransport: "default-ingress-with-rewrite-target",
+ },
+ },
+ },
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-rewrite-target": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -850,15 +944,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-app-root",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-app-root": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -895,15 +996,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-app-root",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-app-root": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1005,10 +1113,17 @@ func TestLoadIngresses(t *testing.T) {
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
+ ServersTransport: "default-ingress-with-whitelist-single-ip",
+ },
+ },
+ },
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-whitelist-single-ip": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1057,10 +1172,17 @@ func TestLoadIngresses(t *testing.T) {
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
+ ServersTransport: "default-ingress-with-whitelist-single-cidr",
+ },
+ },
+ },
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-whitelist-single-cidr": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1109,10 +1231,17 @@ func TestLoadIngresses(t *testing.T) {
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
+ ServersTransport: "default-ingress-with-whitelist-multiple-ip-and-cidr",
+ },
+ },
+ },
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-whitelist-multiple-ip-and-cidr": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1155,10 +1284,17 @@ func TestLoadIngresses(t *testing.T) {
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
+ ServersTransport: "default-ingress-with-whitelist-empty",
+ },
+ },
+ },
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-whitelist-empty": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1204,15 +1340,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-permanent-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-permanent-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1258,15 +1401,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-permanent-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-permanent-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1312,15 +1462,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-permanent-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-permanent-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1366,15 +1523,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1420,15 +1584,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-temporal-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-temporal-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1474,15 +1645,22 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-temporal-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-temporal-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},
@@ -1528,15 +1706,70 @@ func TestLoadIngresses(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
- Strategy: "wrr",
- PassHostHeader: ptr.To(true),
+ Strategy: "wrr",
+ PassHostHeader: ptr.To(true),
+ ServersTransport: "default-ingress-with-temporal-redirect",
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
},
- ServersTransports: map[string]*dynamic.ServersTransport{},
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-temporal-redirect": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(60 * time.Second),
+ },
+ },
+ },
+ },
+ TLS: &dynamic.TLSConfiguration{},
+ },
+ },
+ {
+ desc: "Proxy connect timeout",
+ paths: []string{
+ "services.yml",
+ "ingressclasses.yml",
+ "ingresses/19-ingress-with-proxy-timeout.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-proxy-timeout-rule-0-path-0": {
+ Rule: "Host(`whoami.localhost`) && Path(`/`)",
+ RuleSyntax: "default",
+ Service: "default-ingress-with-proxy-timeout-whoami-80",
+ },
+ },
+ Middlewares: map[string]*dynamic.Middleware{},
+ Services: map[string]*dynamic.Service{
+ "default-ingress-with-proxy-timeout-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,
+ },
+ ServersTransport: "default-ingress-with-proxy-timeout",
+ },
+ },
+ },
+ ServersTransports: map[string]*dynamic.ServersTransport{
+ "default-ingress-with-proxy-timeout": {
+ ForwardingTimeouts: &dynamic.ForwardingTimeouts{
+ DialTimeout: ptypes.Duration(30 * time.Second),
+ },
+ },
+ },
},
TLS: &dynamic.TLSConfiguration{},
},