mirror of
https://github.com/traefik/traefik.git
synced 2026-02-03 20:39:51 -05:00
Merge 3698cc1e73 into a4a91344ed
This commit is contained in:
commit
25a0ec43b6
25 changed files with 1151 additions and 180 deletions
|
|
@ -90,6 +90,7 @@ linters:
|
|||
- github.com/mailgun/multibuf
|
||||
- github.com/jaguilar/vt100
|
||||
- github.com/cucumber/godog
|
||||
- github.com/vulcand/oxy/v2
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
|
|
|
|||
|
|
@ -393,13 +393,19 @@ THIS FILE MUST NOT BE EDITED BY HAND
|
|||
| <a id="opt-providers-kubernetesingress-token" href="#opt-providers-kubernetesingress-token" title="#opt-providers-kubernetesingress-token">providers.kubernetesingress.token</a> | Kubernetes bearer token (not needed for in-cluster client). It accepts either a token value or a file path to the token. | |
|
||||
| <a id="opt-providers-kubernetesingressnginx" href="#opt-providers-kubernetesingressnginx" title="#opt-providers-kubernetesingressnginx">providers.kubernetesingressnginx</a> | Enables Kubernetes Ingress NGINX provider. | false |
|
||||
| <a id="opt-providers-kubernetesingressnginx-certauthfilepath" href="#opt-providers-kubernetesingressnginx-certauthfilepath" title="#opt-providers-kubernetesingressnginx-certauthfilepath">providers.kubernetesingressnginx.certauthfilepath</a> | Kubernetes certificate authority file path (not needed for in-cluster client). | |
|
||||
| <a id="opt-providers-kubernetesingressnginx-clientbodybuffersize" href="#opt-providers-kubernetesingressnginx-clientbodybuffersize" title="#opt-providers-kubernetesingressnginx-clientbodybuffersize">providers.kubernetesingressnginx.clientbodybuffersize</a> | Default buffer size for reading client request body. | 16384 |
|
||||
| <a id="opt-providers-kubernetesingressnginx-controllerclass" href="#opt-providers-kubernetesingressnginx-controllerclass" title="#opt-providers-kubernetesingressnginx-controllerclass">providers.kubernetesingressnginx.controllerclass</a> | Ingress Class Controller value this controller satisfies. | k8s.io/ingress-nginx |
|
||||
| <a id="opt-providers-kubernetesingressnginx-defaultbackendservice" href="#opt-providers-kubernetesingressnginx-defaultbackendservice" title="#opt-providers-kubernetesingressnginx-defaultbackendservice">providers.kubernetesingressnginx.defaultbackendservice</a> | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'. | |
|
||||
| <a id="opt-providers-kubernetesingressnginx-disablesvcexternalname" href="#opt-providers-kubernetesingressnginx-disablesvcexternalname" title="#opt-providers-kubernetesingressnginx-disablesvcexternalname">providers.kubernetesingressnginx.disablesvcexternalname</a> | Disable support for Services of type ExternalName. | false |
|
||||
| <a id="opt-providers-kubernetesingressnginx-endpoint" href="#opt-providers-kubernetesingressnginx-endpoint" title="#opt-providers-kubernetesingressnginx-endpoint">providers.kubernetesingressnginx.endpoint</a> | Kubernetes server endpoint (required for external cluster client). | |
|
||||
| <a id="opt-providers-kubernetesingressnginx-ingressclass" href="#opt-providers-kubernetesingressnginx-ingressclass" title="#opt-providers-kubernetesingressnginx-ingressclass">providers.kubernetesingressnginx.ingressclass</a> | Name of the ingress class this controller satisfies. | nginx |
|
||||
| <a id="opt-providers-kubernetesingressnginx-ingressclassbyname" href="#opt-providers-kubernetesingressnginx-ingressclassbyname" title="#opt-providers-kubernetesingressnginx-ingressclassbyname">providers.kubernetesingressnginx.ingressclassbyname</a> | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false |
|
||||
| <a id="opt-providers-kubernetesingressnginx-proxybodysize" href="#opt-providers-kubernetesingressnginx-proxybodysize" title="#opt-providers-kubernetesingressnginx-proxybodysize">providers.kubernetesingressnginx.proxybodysize</a> | Default maximum size of a client request body in bytes. | 1048576 |
|
||||
| <a id="opt-providers-kubernetesingressnginx-proxybuffering" href="#opt-providers-kubernetesingressnginx-proxybuffering" title="#opt-providers-kubernetesingressnginx-proxybuffering">providers.kubernetesingressnginx.proxybuffering</a> | Defines whether to enable response buffering. | false |
|
||||
| <a id="opt-providers-kubernetesingressnginx-proxybuffersize" href="#opt-providers-kubernetesingressnginx-proxybuffersize" title="#opt-providers-kubernetesingressnginx-proxybuffersize">providers.kubernetesingressnginx.proxybuffersize</a> | Default buffer size for reading the response body. | 8192 |
|
||||
| <a id="opt-providers-kubernetesingressnginx-proxybuffersnumber" href="#opt-providers-kubernetesingressnginx-proxybuffersnumber" title="#opt-providers-kubernetesingressnginx-proxybuffersnumber">providers.kubernetesingressnginx.proxybuffersnumber</a> | Default number of buffers for reading a response. | 4 |
|
||||
| <a id="opt-providers-kubernetesingressnginx-proxyconnecttimeout" href="#opt-providers-kubernetesingressnginx-proxyconnecttimeout" title="#opt-providers-kubernetesingressnginx-proxyconnecttimeout">providers.kubernetesingressnginx.proxyconnecttimeout</a> | Amount of time to wait until a connection to a server can be established. Timeout value is unitless and in seconds. | 60 |
|
||||
| <a id="opt-providers-kubernetesingressnginx-proxyrequestbuffering" href="#opt-providers-kubernetesingressnginx-proxyrequestbuffering" title="#opt-providers-kubernetesingressnginx-proxyrequestbuffering">providers.kubernetesingressnginx.proxyrequestbuffering</a> | Defines whether to enable request buffering. | false |
|
||||
| <a id="opt-providers-kubernetesingressnginx-publishservice" href="#opt-providers-kubernetesingressnginx-publishservice" title="#opt-providers-kubernetesingressnginx-publishservice">providers.kubernetesingressnginx.publishservice</a> | Service fronting the Ingress controller. Takes the form 'namespace/name'. | |
|
||||
| <a id="opt-providers-kubernetesingressnginx-publishstatusaddress" href="#opt-providers-kubernetesingressnginx-publishstatusaddress" title="#opt-providers-kubernetesingressnginx-publishstatusaddress">providers.kubernetesingressnginx.publishstatusaddress</a> | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | |
|
||||
| <a id="opt-providers-kubernetesingressnginx-throttleduration" href="#opt-providers-kubernetesingressnginx-throttleduration" title="#opt-providers-kubernetesingressnginx-throttleduration">providers.kubernetesingressnginx.throttleduration</a> | Ingress refresh throttle duration. | 0 |
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ It also supports many of the [ingress-nginx](https://kubernetes.github.io/ingres
|
|||
|
||||
## Requirements
|
||||
|
||||
When you install Traefik without using the Helm Chart,
|
||||
ensure that you add/update the [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for the Traefik Kubernetes Ingress NGINX provider.
|
||||
When you install Traefik without using the Helm Chart,
|
||||
ensure that you add/update the [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for the Traefik Kubernetes Ingress NGINX provider.
|
||||
|
||||
!!! note "Additional RBAC for Namespace Selector"
|
||||
|
||||
|
|
@ -59,6 +59,13 @@ providers:
|
|||
controllerClass: "k8s.io/ingress-nginx"
|
||||
watchIngressWithoutClass: false
|
||||
ingressClassByName: false
|
||||
proxyConnectTimeout: 60
|
||||
proxyRequestBuffering: false
|
||||
clientBodyBufferSize: "16384" # 16k
|
||||
proxyBuffering: false
|
||||
proxyBodySize: "1048576" # 1m
|
||||
proxyBufferSize: "8192" # 8k
|
||||
proxyBuffersNumber: 8
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
|
|
@ -73,6 +80,12 @@ providers:
|
|||
controllerClass = "k8s.io/ingress-nginx"
|
||||
watchIngressWithoutClass = false
|
||||
ingressClassByName = false
|
||||
proxyConnectTimeout = 60
|
||||
clientBodyBufferSize = "16384" # 16k
|
||||
proxyBuffering = false
|
||||
proxyBodySize = "1048576" # 1m
|
||||
proxyBufferSize = "8192" # 8k
|
||||
proxyBuffersNumber = 8
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
|
|
@ -82,6 +95,13 @@ providers:
|
|||
--providers.kubernetesingressnginx.controllerclass=k8s.io/ingress-nginx
|
||||
--providers.kubernetesingressnginx.watchingresswithoutclass=false
|
||||
--providers.kubernetesingressnginx.ingressclassbyname=false
|
||||
--providers.kubernetesingressnginx.proxyconnecttimeout=60
|
||||
--providers.kubernetesingressnginx.proxyrequestbuffering=false
|
||||
--providers.kubernetesingressnginx.clientbodybuffersize=16384 # 16k
|
||||
--providers.kubernetesingressnginx.proxybuffering=false
|
||||
--providers.kubernetesingressnginx.proxybodysize=1048576 # 1m
|
||||
--providers.kubernetesingressnginx.proxybuffersize=8192 # 8k
|
||||
--providers.kubernetesingressnginx.proxybuffersnumber=8
|
||||
```
|
||||
|
||||
```yaml tab="Helm Chart Values"
|
||||
|
|
@ -114,24 +134,30 @@ This provider watches for incoming Ingress events and automatically translates N
|
|||
## Configuration Options
|
||||
<!-- markdownlint-disable MD013 -->
|
||||
|
||||
| Field | Description | Default | Required |
|
||||
|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------|
|
||||
| <a id="opt-providers-providers-ThrottleDuration" href="#opt-providers-providers-ThrottleDuration" title="#opt-providers-providers-ThrottleDuration">`providers.providers`<br/>`ThrottleDuration`</a> | Minimum amount of time to wait for, after a configuration reload, before taking into account any new configuration refresh event.<br />If multiple events occur within this time, only the most recent one is taken into account, and all others are discarded.<br />**This option cannot be set per provider, but the throttling algorithm applies to each of them independently.** | 2s | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-endpoint" href="#opt-providers-kubernetesIngressNGINX-endpoint" title="#opt-providers-kubernetesIngressNGINX-endpoint">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`endpoint`</a> | Server endpoint URL.<br />More information [here](#endpoint). | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-token" href="#opt-providers-kubernetesIngressNGINX-token" title="#opt-providers-kubernetesIngressNGINX-token">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`token`</a> | Bearer token used for the Kubernetes client configuration. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-certAuthFilePath" href="#opt-providers-kubernetesIngressNGINX-certAuthFilePath" title="#opt-providers-kubernetesIngressNGINX-certAuthFilePath">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`certAuthFilePath`</a> | Path to the certificate authority file.<br />Used for the Kubernetes client configuration. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-throttleDuration" href="#opt-providers-kubernetesIngressNGINX-throttleDuration" title="#opt-providers-kubernetesIngressNGINX-throttleDuration">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`throttleDuration`</a> | Minimum amount of time to wait between two Kubernetes events before producing a new configuration.<br />This prevents a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.<br />If empty, every event is caught. | 0s | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespace" href="#opt-providers-kubernetesIngressNGINX-watchNamespace" title="#opt-providers-kubernetesIngressNGINX-watchNamespace">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespace`</a> | Namespace the controller watches for updates to Kubernetes objects. All namespaces are watched if this parameter is left empty. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" href="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" title="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespaceSelector`</a> | Selector selects namespaces the controller watches for updates to Kubernetes objects. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-ingressClass" href="#opt-providers-kubernetesIngressNGINX-ingressClass" title="#opt-providers-kubernetesIngressNGINX-ingressClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClass`</a> | Name of the ingress class this controller satisfies. | "nginx" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-controllerClass" href="#opt-providers-kubernetesIngressNGINX-controllerClass" title="#opt-providers-kubernetesIngressNGINX-controllerClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`controllerClass`</a> | Ingress Class Controller value this controller satisfies. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass" href="#opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass" title="#opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchIngressWithoutClass`</a> | Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified. | false | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-ingressClassByName" href="#opt-providers-kubernetesIngressNGINX-ingressClassByName" title="#opt-providers-kubernetesIngressNGINX-ingressClassByName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClassByName`</a> | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-publishService" href="#opt-providers-kubernetesIngressNGINX-publishService" title="#opt-providers-kubernetesIngressNGINX-publishService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`publishService`</a> | Service fronting the Ingress controller. Takes the form `namespace/name`. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-publishStatusAddress" href="#opt-providers-kubernetesIngressNGINX-publishStatusAddress" title="#opt-providers-kubernetesIngressNGINX-publishStatusAddress">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`publishStatusAddress`</a> | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-defaultBackendService" href="#opt-providers-kubernetesIngressNGINX-defaultBackendService" title="#opt-providers-kubernetesIngressNGINX-defaultBackendService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`defaultBackendService`</a> | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-disableSvcExternalName" href="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName" title="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`disableSvcExternalName`</a> | Disable support for Services of type ExternalName. | false | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-proxyConnectTimeout" href="#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout" title="#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyConnectTimeout`</a> | 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 |
|
||||
| Field | Description | Default | Required |
|
||||
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------|
|
||||
| <a id="opt-providers-providers-ThrottleDuration" href="#opt-providers-providers-ThrottleDuration" title="#opt-providers-providers-ThrottleDuration">`providers.providers`<br/>`ThrottleDuration`</a> | Minimum amount of time to wait for, after a configuration reload, before taking into account any new configuration refresh event.<br />If multiple events occur within this time, only the most recent one is taken into account, and all others are discarded.<br />**This option cannot be set per provider, but the throttling algorithm applies to each of them independently.** | 2s | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-endpoint" href="#opt-providers-kubernetesIngressNGINX-endpoint" title="#opt-providers-kubernetesIngressNGINX-endpoint">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`endpoint`</a> | Server endpoint URL.<br />More information [here](#endpoint). | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-token" href="#opt-providers-kubernetesIngressNGINX-token" title="#opt-providers-kubernetesIngressNGINX-token">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`token`</a> | Bearer token used for the Kubernetes client configuration. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-certAuthFilePath" href="#opt-providers-kubernetesIngressNGINX-certAuthFilePath" title="#opt-providers-kubernetesIngressNGINX-certAuthFilePath">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`certAuthFilePath`</a> | Path to the certificate authority file.<br />Used for the Kubernetes client configuration. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-throttleDuration" href="#opt-providers-kubernetesIngressNGINX-throttleDuration" title="#opt-providers-kubernetesIngressNGINX-throttleDuration">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`throttleDuration`</a> | Minimum amount of time to wait between two Kubernetes events before producing a new configuration.<br />This prevents a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.<br />If empty, every event is caught. | 0s | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespace" href="#opt-providers-kubernetesIngressNGINX-watchNamespace" title="#opt-providers-kubernetesIngressNGINX-watchNamespace">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespace`</a> | Namespace the controller watches for updates to Kubernetes objects. All namespaces are watched if this parameter is left empty. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" href="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" title="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespaceSelector`</a> | Selector selects namespaces the controller watches for updates to Kubernetes objects. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-ingressClass" href="#opt-providers-kubernetesIngressNGINX-ingressClass" title="#opt-providers-kubernetesIngressNGINX-ingressClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClass`</a> | Name of the ingress class this controller satisfies. | "nginx" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-controllerClass" href="#opt-providers-kubernetesIngressNGINX-controllerClass" title="#opt-providers-kubernetesIngressNGINX-controllerClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`controllerClass`</a> | Ingress Class Controller value this controller satisfies. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass" href="#opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass" title="#opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchIngressWithoutClass`</a> | Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified. | false | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-ingressClassByName" href="#opt-providers-kubernetesIngressNGINX-ingressClassByName" title="#opt-providers-kubernetesIngressNGINX-ingressClassByName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClassByName`</a> | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-publishService" href="#opt-providers-kubernetesIngressNGINX-publishService" title="#opt-providers-kubernetesIngressNGINX-publishService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`publishService`</a> | Service fronting the Ingress controller. Takes the form `namespace/name`. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-publishStatusAddress" href="#opt-providers-kubernetesIngressNGINX-publishStatusAddress" title="#opt-providers-kubernetesIngressNGINX-publishStatusAddress">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`publishStatusAddress`</a> | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-defaultBackendService" href="#opt-providers-kubernetesIngressNGINX-defaultBackendService" title="#opt-providers-kubernetesIngressNGINX-defaultBackendService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`defaultBackendService`</a> | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'. | "" | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-disableSvcExternalName" href="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName" title="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`disableSvcExternalName`</a> | Disable support for Services of type ExternalName. | false | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-proxyConnectTimeout" href="#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout" title="#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyConnectTimeout`</a> | 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 |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-proxyrequestbuffering" href="#opt-providers-kubernetesIngressNGINX-proxyrequestbuffering" title="#opt-providers-kubernetesIngressNGINX-proxyrequestbuffering">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyrequestbuffering`</a> | Defines whether request buffering is enabled by default for all ingresses. | false | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-clientBodyBufferSize" href="#opt-providers-kubernetesIngressNGINX-clientBodyBufferSize" title="#opt-providers-kubernetesIngressNGINX-clientBodyBufferSize">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`clientBodyBufferSize`</a> | Default buffer size for reading client request body in bytes. | 16384 | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-proxybuffering" href="#opt-providers-kubernetesIngressNGINX-proxybuffering" title="#opt-providers-kubernetesIngressNGINX-proxybuffering">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxybuffering`</a> | Defines whether response buffering is enabled by default for all ingresses. | false | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-proxyBodySize" href="#opt-providers-kubernetesIngressNGINX-proxyBodySize" title="#opt-providers-kubernetesIngressNGINX-proxyBodySize">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyBodySize`</a> | Default maximum size of a client request body in bytes. | 1048576 | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-proxyBufferSize" href="#opt-providers-kubernetesIngressNGINX-proxyBufferSize" title="#opt-providers-kubernetesIngressNGINX-proxyBufferSize">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyBufferSize`</a> | Default buffer size for reading the response body in bytes. | 8192 | No |
|
||||
| <a id="opt-providers-kubernetesIngressNGINX-proxyBuffersNumber" href="#opt-providers-kubernetesIngressNGINX-proxyBuffersNumber" title="#opt-providers-kubernetesIngressNGINX-proxyBuffersNumber">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyBuffersNumber`</a> | Default number of buffers for reading a response. | 8 | No |
|
||||
|
||||
<!-- markdownlint-enable MD013 -->
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ Enable seamless migration from NGINX Ingress Controller to Traefik with NGINX an
|
|||
|
||||
## Ingress Discovery
|
||||
|
||||
This provider discovers all Ingresses in the cluster by default, which may lead to duplicated routers if you are also using the standard Kubernetes Ingress provider.
|
||||
This provider discovers all Ingresses in the cluster by default,
|
||||
which may lead to duplicated routers if you are also using the standard Kubernetes Ingress provider.
|
||||
|
||||
**Best Practices:**
|
||||
|
||||
|
|
@ -29,7 +30,21 @@ This provider discovers all Ingresses in the cluster by default, which may lead
|
|||
|
||||
## Routing Configuration
|
||||
|
||||
This provider watches for incoming Ingress events and automatically translates NGINX annotations into Traefik's dynamic configuration, creating the corresponding routers, services, middlewares, and other components needed to handle your traffic.
|
||||
This provider watches for incoming Ingress events and automatically translates NGINX annotations into Traefik's dynamic configuration,
|
||||
creating the corresponding routers, services, middlewares, and other components needed to handle your traffic.
|
||||
|
||||
!!! warning "ConfigMap Configuration and Default Behaviors"
|
||||
|
||||
Routing annotations take precedence over provider-level defaults,
|
||||
but they don't control all behaviors that NGINX Ingress Controller's ConfigMap configuration would handle globally.
|
||||
|
||||
Important differences in default behaviors:
|
||||
|
||||
- **Request buffering**: NGINX enables `proxy-request-buffering` by default, while Traefik requires explicit opt-in via the provider's `proxyRequestBuffering` option.
|
||||
|
||||
To ensure consistent behavior during migration,
|
||||
review and configure Traefik's provider-level options to match your current NGINX ConfigMap settings.
|
||||
See the [provider configuration options](../../install-configuration/providers/kubernetes/kubernetes-ingress-nginx.md) for available settings.
|
||||
|
||||
## Configuration Example
|
||||
|
||||
|
|
@ -334,6 +349,18 @@ The following annotations are organized by category for easier navigation.
|
|||
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
|
||||
| <a id="opt-nginx-ingress-kubernetes-iowhitelist-source-range" href="#opt-nginx-ingress-kubernetes-iowhitelist-source-range" title="#opt-nginx-ingress-kubernetes-iowhitelist-source-range">`nginx.ingress.kubernetes.io/whitelist-source-range`</a> | |
|
||||
|
||||
### Buffering
|
||||
|
||||
| Annotation | Limitations / Notes |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-request-buffering" href="#opt-nginx-ingress-kubernetes-ioproxy-request-buffering" title="#opt-nginx-ingress-kubernetes-ioproxy-request-buffering">`nginx.ingress.kubernetes.io/proxy-request-buffering`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-body-size" href="#opt-nginx-ingress-kubernetes-ioproxy-body-size" title="#opt-nginx-ingress-kubernetes-ioproxy-body-size">`nginx.ingress.kubernetes.io/proxy-body-size`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioclient-body-buffer-size" href="#opt-nginx-ingress-kubernetes-ioclient-body-buffer-size" title="#opt-nginx-ingress-kubernetes-ioclient-body-buffer-size">`nginx.ingress.kubernetes.io/client-body-buffer-size`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffering" href="#opt-nginx-ingress-kubernetes-ioproxy-buffering" title="#opt-nginx-ingress-kubernetes-ioproxy-buffering">`nginx.ingress.kubernetes.io/proxy-buffering`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffer-size" href="#opt-nginx-ingress-kubernetes-ioproxy-buffer-size" title="#opt-nginx-ingress-kubernetes-ioproxy-buffer-size">`nginx.ingress.kubernetes.io/proxy-buffer-size`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffers-number" href="#opt-nginx-ingress-kubernetes-ioproxy-buffers-number" title="#opt-nginx-ingress-kubernetes-ioproxy-buffers-number">`nginx.ingress.kubernetes.io/proxy-buffers-number`</a> | With Traefik, `proxy-buffer-numbers` is actually used to compute the size of a single buffer (size * number). |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-max-temp-file-size" href="#opt-nginx-ingress-kubernetes-ioproxy-max-temp-file-size" title="#opt-nginx-ingress-kubernetes-ioproxy-max-temp-file-size">`nginx.ingress.kubernetes.io/proxy-max-temp-file-size`</a> | |
|
||||
|
||||
### Timeout
|
||||
|
||||
| Annotation | Limitations / Notes |
|
||||
|
|
@ -387,7 +414,6 @@ The following annotations are organized by category for easier navigation.
|
|||
| <a id="opt-nginx-ingress-kubernetes-iocanary-by-cookie" href="#opt-nginx-ingress-kubernetes-iocanary-by-cookie" title="#opt-nginx-ingress-kubernetes-iocanary-by-cookie">`nginx.ingress.kubernetes.io/canary-by-cookie`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-iocanary-weight" href="#opt-nginx-ingress-kubernetes-iocanary-weight" title="#opt-nginx-ingress-kubernetes-iocanary-weight">`nginx.ingress.kubernetes.io/canary-weight`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-iocanary-weight-total" href="#opt-nginx-ingress-kubernetes-iocanary-weight-total" title="#opt-nginx-ingress-kubernetes-iocanary-weight-total">`nginx.ingress.kubernetes.io/canary-weight-total`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioclient-body-buffer-size" href="#opt-nginx-ingress-kubernetes-ioclient-body-buffer-size" title="#opt-nginx-ingress-kubernetes-ioclient-body-buffer-size">`nginx.ingress.kubernetes.io/client-body-buffer-size`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioconfiguration-snippet" href="#opt-nginx-ingress-kubernetes-ioconfiguration-snippet" title="#opt-nginx-ingress-kubernetes-ioconfiguration-snippet">`nginx.ingress.kubernetes.io/configuration-snippet`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-iocustom-http-errors" href="#opt-nginx-ingress-kubernetes-iocustom-http-errors" title="#opt-nginx-ingress-kubernetes-iocustom-http-errors">`nginx.ingress.kubernetes.io/custom-http-errors`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-iodisable-proxy-intercept-errors" href="#opt-nginx-ingress-kubernetes-iodisable-proxy-intercept-errors" title="#opt-nginx-ingress-kubernetes-iodisable-proxy-intercept-errors">`nginx.ingress.kubernetes.io/disable-proxy-intercept-errors`</a> | |
|
||||
|
|
@ -411,7 +437,6 @@ The following annotations are organized by category for easier navigation.
|
|||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-next-upstream" href="#opt-nginx-ingress-kubernetes-ioproxy-next-upstream" title="#opt-nginx-ingress-kubernetes-ioproxy-next-upstream">`nginx.ingress.kubernetes.io/proxy-next-upstream`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-next-upstream-timeout" href="#opt-nginx-ingress-kubernetes-ioproxy-next-upstream-timeout" title="#opt-nginx-ingress-kubernetes-ioproxy-next-upstream-timeout">`nginx.ingress.kubernetes.io/proxy-next-upstream-timeout`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-next-upstream-tries" href="#opt-nginx-ingress-kubernetes-ioproxy-next-upstream-tries" title="#opt-nginx-ingress-kubernetes-ioproxy-next-upstream-tries">`nginx.ingress.kubernetes.io/proxy-next-upstream-tries`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-request-buffering" href="#opt-nginx-ingress-kubernetes-ioproxy-request-buffering" title="#opt-nginx-ingress-kubernetes-ioproxy-request-buffering">`nginx.ingress.kubernetes.io/proxy-request-buffering`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-redirect-from" href="#opt-nginx-ingress-kubernetes-ioproxy-redirect-from" title="#opt-nginx-ingress-kubernetes-ioproxy-redirect-from">`nginx.ingress.kubernetes.io/proxy-redirect-from`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-redirect-to" href="#opt-nginx-ingress-kubernetes-ioproxy-redirect-to" title="#opt-nginx-ingress-kubernetes-ioproxy-redirect-to">`nginx.ingress.kubernetes.io/proxy-redirect-to`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-http-version" href="#opt-nginx-ingress-kubernetes-ioproxy-http-version" title="#opt-nginx-ingress-kubernetes-ioproxy-http-version">`nginx.ingress.kubernetes.io/proxy-http-version`</a> | |
|
||||
|
|
@ -442,11 +467,7 @@ The following annotations are organized by category for easier navigation.
|
|||
| <a id="opt-nginx-ingress-kubernetes-iox-forwarded-prefix" href="#opt-nginx-ingress-kubernetes-iox-forwarded-prefix" title="#opt-nginx-ingress-kubernetes-iox-forwarded-prefix">`nginx.ingress.kubernetes.io/x-forwarded-prefix`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioupstream-hash-by" href="#opt-nginx-ingress-kubernetes-ioupstream-hash-by" title="#opt-nginx-ingress-kubernetes-ioupstream-hash-by">`nginx.ingress.kubernetes.io/upstream-hash-by`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-iodenylist-source-range" href="#opt-nginx-ingress-kubernetes-iodenylist-source-range" title="#opt-nginx-ingress-kubernetes-iodenylist-source-range">`nginx.ingress.kubernetes.io/denylist-source-range`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffering" href="#opt-nginx-ingress-kubernetes-ioproxy-buffering" title="#opt-nginx-ingress-kubernetes-ioproxy-buffering">`nginx.ingress.kubernetes.io/proxy-buffering`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffers-number" href="#opt-nginx-ingress-kubernetes-ioproxy-buffers-number" title="#opt-nginx-ingress-kubernetes-ioproxy-buffers-number">`nginx.ingress.kubernetes.io/proxy-buffers-number`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffer-size" href="#opt-nginx-ingress-kubernetes-ioproxy-buffer-size" title="#opt-nginx-ingress-kubernetes-ioproxy-buffer-size">`nginx.ingress.kubernetes.io/proxy-buffer-size`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-max-temp-file-size" href="#opt-nginx-ingress-kubernetes-ioproxy-max-temp-file-size" title="#opt-nginx-ingress-kubernetes-ioproxy-max-temp-file-size">`nginx.ingress.kubernetes.io/proxy-max-temp-file-size`</a> | |
|
||||
| <a id="opt-nginx-ingress-kubernetes-iostream-snippet" href="#opt-nginx-ingress-kubernetes-iostream-snippet" title="#opt-nginx-ingress-kubernetes-iostream-snippet">`nginx.ingress.kubernetes.io/stream-snippet`</a> | |
|
||||
<a id="opt-nginx-ingress-kubernetes-iostream-snippet" href="#opt-nginx-ingress-kubernetes-iostream-snippet" title="#opt-nginx-ingress-kubernetes-iostream-snippet">`nginx.ingress.kubernetes.io/stream-snippet`</a> | |
|
||||
|
||||
### Global Configuration
|
||||
|
||||
|
|
|
|||
6
go.mod
6
go.mod
|
|
@ -78,7 +78,7 @@ require (
|
|||
github.com/unrolled/secure v1.0.9
|
||||
github.com/valyala/fasthttp v1.58.0
|
||||
github.com/vulcand/oxy/v2 v2.0.3
|
||||
github.com/vulcand/predicate v1.2.0
|
||||
github.com/vulcand/predicate v1.3.0
|
||||
github.com/yuin/gopher-lua v1.1.1
|
||||
go.opentelemetry.io/collector/pdata v1.41.0
|
||||
go.opentelemetry.io/contrib/bridges/otellogrus v0.13.0
|
||||
|
|
@ -244,7 +244,7 @@ require (
|
|||
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
||||
github.com/gophercloud/gophercloud v1.14.1 // indirect
|
||||
github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 // indirect
|
||||
github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect
|
||||
github.com/gravitational/trace v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
|
||||
github.com/hashicorp/cronexpr v1.1.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
|
|
@ -260,7 +260,6 @@ require (
|
|||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
|
||||
github.com/infobloxopen/infoblox-go-client/v2 v2.10.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.5.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect
|
||||
|
|
@ -420,6 +419,7 @@ replace (
|
|||
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e
|
||||
github.com/gorilla/mux => github.com/containous/mux v0.0.0-20250523120546-41b6ec3aed59
|
||||
github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595
|
||||
github.com/vulcand/oxy/v2 => github.com/traefik/oxy/v2 v2.0.0-20260126093803-fb11d60e0fdf
|
||||
)
|
||||
|
||||
// ambiguous import: found package github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http in multiple modules
|
||||
|
|
|
|||
16
go.sum
16
go.sum
|
|
@ -644,8 +644,8 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
|
|||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf h1:C1GPyPJrOlJlIrcaBBiBpDsqZena2Ks8spa5xZqr1XQ=
|
||||
github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf/go.mod h1:zXqxTI6jXDdKnlf8s+nT+3c8LrwUEy3yNpO4XJL90lA=
|
||||
github.com/gravitational/trace v1.5.0 h1:JbeL2HDGyzgy7G72Z2hP2gExEyA6Y2p7fCiSjyZwCJw=
|
||||
github.com/gravitational/trace v1.5.0/go.mod h1:dxezSkKm880IIDx+czWG8fq+pLnXjETBewMgN3jOBlg=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
|
|
@ -762,9 +762,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC
|
|||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
|
||||
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
|
|
@ -1286,6 +1283,8 @@ github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XV
|
|||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/traefik/grpc-web v0.16.0 h1:eeUWZaFg6ZU0I9dWOYE2D5qkNzRBmXzzuRlxdltascY=
|
||||
github.com/traefik/grpc-web v0.16.0/go.mod h1:2ttniSv7pTgBWIU2HZLokxRfFX3SA60c/DTmQQgVml4=
|
||||
github.com/traefik/oxy/v2 v2.0.0-20260126093803-fb11d60e0fdf h1:qOjmGqgXvycy0+tda6rWhTPulgQxnImwRrM1AROIvJ4=
|
||||
github.com/traefik/oxy/v2 v2.0.0-20260126093803-fb11d60e0fdf/go.mod h1:as06A23Znc9S/ilJpKqJ/UhO3Zu5JztlxVwQuKl+iZs=
|
||||
github.com/traefik/paerser v0.2.2 h1:cpzW/ZrQrBh3mdwD/jnp6aXASiUFKOVr6ldP+keJTcQ=
|
||||
github.com/traefik/paerser v0.2.2/go.mod h1:7BBDd4FANoVgaTZG+yh26jI6CA2nds7D/4VTEdIsh24=
|
||||
github.com/traefik/yaegi v0.16.1 h1:f1De3DVJqIDKmnasUF6MwmWv1dSEEat0wcpXhD2On3E=
|
||||
|
|
@ -1321,10 +1320,8 @@ github.com/vinyldns/go-vinyldns v0.9.17 h1:hfPZfCaxcRBX6Gsgl42rLCeoal58/BH8kkvJS
|
|||
github.com/vinyldns/go-vinyldns v0.9.17/go.mod h1:pwWhE9K/leGDOIduVhRGvQ3ecVMHWRfEnKYUTEU3gB4=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.233 h1:Hh2pzwu/Wq19rsZgNo3HdpjQB28D/F0+m6EjLVggmhM=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.233/go.mod h1:zHJlaqiMbIB+0mcrsZPTwOb3FB7S/0MCfqlnO8R7hlM=
|
||||
github.com/vulcand/oxy/v2 v2.0.3 h1:CPWVPfW4hVZXzwwiQzpFidbnJKpahjPHezM+7TkZRNw=
|
||||
github.com/vulcand/oxy/v2 v2.0.3/go.mod h1:k3t+xjyqmXVh88FdFDbYmUKMEvNpaejvBW14es6H70A=
|
||||
github.com/vulcand/predicate v1.2.0 h1:uFsW1gcnnR7R+QTID+FVcs0sSYlIGntoGOTb3rQJt50=
|
||||
github.com/vulcand/predicate v1.2.0/go.mod h1:VipoNYXny6c8N381zGUWkjuuNHiRbeAZhE7Qm9c+2GA=
|
||||
github.com/vulcand/predicate v1.3.0 h1:jtNe4PHbLJ649dR7Gl+MSAzUhLGtLspAkWlSjoOiXg8=
|
||||
github.com/vulcand/predicate v1.3.0/go.mod h1:opzv9MetRuMNnuoPeTSWtwzjcXsxQC00/fuWzkPTn4s=
|
||||
github.com/vultr/govultr/v3 v3.26.1 h1:G/M0rMQKwVSmL+gb0UgETbW5mcQi0Vf/o/ZSGdBCxJw=
|
||||
github.com/vultr/govultr/v3 v3.26.1/go.mod h1:9WwnWGCKnwDlNjHjtt+j+nP+0QWq6hQXzaHgddqrLWY=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
|
|
@ -1593,7 +1590,6 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
|
|||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
|
|
|
|||
|
|
@ -134,6 +134,10 @@ type Buffering struct {
|
|||
// It is a logical combination of functions with operators AND (&&) and OR (||).
|
||||
// More info: https://doc.traefik.io/traefik/v3.6/middlewares/http/buffering/#retryexpression
|
||||
RetryExpression string `json:"retryExpression,omitempty" toml:"retryExpression,omitempty" yaml:"retryExpression,omitempty" export:"true"`
|
||||
|
||||
// Only configurable via code, not via configuration files.
|
||||
DisableRequestBuffer bool `json:"disableRequestBuffer,omitempty" toml:"-" yaml:"-" label:"-" file:"-" kv:"-" export:"true"`
|
||||
DisableResponseBuffer bool `json:"disableResponseBuffer,omitempty" toml:"-" yaml:"-" label:"-" file:"-" kv:"-" export:"true"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ func New(ctx context.Context, next http.Handler, config dynamic.Buffering, name
|
|||
logger.Debug().Msgf("Setting up buffering: request limits: %d (mem), %d (max), response limits: %d (mem), %d (max) with retry: '%s'",
|
||||
config.MemRequestBodyBytes, config.MaxRequestBodyBytes, config.MemResponseBodyBytes, config.MaxResponseBodyBytes, config.RetryExpression)
|
||||
|
||||
oxyBuffer, err := oxybuffer.New(
|
||||
next,
|
||||
options := []oxybuffer.Option{
|
||||
oxybuffer.MemRequestBodyBytes(config.MemRequestBodyBytes),
|
||||
oxybuffer.MaxRequestBodyBytes(config.MaxRequestBodyBytes),
|
||||
oxybuffer.MemResponseBodyBytes(config.MemResponseBodyBytes),
|
||||
|
|
@ -36,6 +35,19 @@ func New(ctx context.Context, next http.Handler, config dynamic.Buffering, name
|
|||
oxybuffer.Logger(logs.NewOxyWrapper(*logger)),
|
||||
oxybuffer.Verbose(logger.GetLevel() == zerolog.TraceLevel),
|
||||
oxybuffer.Cond(len(config.RetryExpression) > 0, oxybuffer.Retry(config.RetryExpression)),
|
||||
}
|
||||
|
||||
if config.DisableRequestBuffer {
|
||||
options = append(options, oxybuffer.DisableRequestBuffer())
|
||||
}
|
||||
|
||||
if config.DisableResponseBuffer {
|
||||
options = append(options, oxybuffer.DisableResponseBuffer())
|
||||
}
|
||||
|
||||
oxyBuffer, err := oxybuffer.New(
|
||||
next,
|
||||
options...,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// BufferingApplyConfiguration represents a declarative configuration of the Buffering type for use
|
||||
// with apply.
|
||||
type BufferingApplyConfiguration struct {
|
||||
MaxRequestBodyBytes *int64 `json:"maxRequestBodyBytes,omitempty"`
|
||||
MemRequestBodyBytes *int64 `json:"memRequestBodyBytes,omitempty"`
|
||||
MaxResponseBodyBytes *int64 `json:"maxResponseBodyBytes,omitempty"`
|
||||
MemResponseBodyBytes *int64 `json:"memResponseBodyBytes,omitempty"`
|
||||
RetryExpression *string `json:"retryExpression,omitempty"`
|
||||
}
|
||||
|
||||
// BufferingApplyConfiguration constructs a declarative configuration of the Buffering type for use with
|
||||
// apply.
|
||||
func Buffering() *BufferingApplyConfiguration {
|
||||
return &BufferingApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithMaxRequestBodyBytes sets the MaxRequestBodyBytes field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the MaxRequestBodyBytes field is set to the value of the last call.
|
||||
func (b *BufferingApplyConfiguration) WithMaxRequestBodyBytes(value int64) *BufferingApplyConfiguration {
|
||||
b.MaxRequestBodyBytes = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithMemRequestBodyBytes sets the MemRequestBodyBytes field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the MemRequestBodyBytes field is set to the value of the last call.
|
||||
func (b *BufferingApplyConfiguration) WithMemRequestBodyBytes(value int64) *BufferingApplyConfiguration {
|
||||
b.MemRequestBodyBytes = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithMaxResponseBodyBytes sets the MaxResponseBodyBytes field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the MaxResponseBodyBytes field is set to the value of the last call.
|
||||
func (b *BufferingApplyConfiguration) WithMaxResponseBodyBytes(value int64) *BufferingApplyConfiguration {
|
||||
b.MaxResponseBodyBytes = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithMemResponseBodyBytes sets the MemResponseBodyBytes field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the MemResponseBodyBytes field is set to the value of the last call.
|
||||
func (b *BufferingApplyConfiguration) WithMemResponseBodyBytes(value int64) *BufferingApplyConfiguration {
|
||||
b.MemResponseBodyBytes = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithRetryExpression sets the RetryExpression field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the RetryExpression field is set to the value of the last call.
|
||||
func (b *BufferingApplyConfiguration) WithRetryExpression(value string) *BufferingApplyConfiguration {
|
||||
b.RetryExpression = &value
|
||||
return b
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ type MiddlewareSpecApplyConfiguration struct {
|
|||
DigestAuth *DigestAuthApplyConfiguration `json:"digestAuth,omitempty"`
|
||||
ForwardAuth *ForwardAuthApplyConfiguration `json:"forwardAuth,omitempty"`
|
||||
InFlightReq *dynamic.InFlightReq `json:"inFlightReq,omitempty"`
|
||||
Buffering *dynamic.Buffering `json:"buffering,omitempty"`
|
||||
Buffering *BufferingApplyConfiguration `json:"buffering,omitempty"`
|
||||
CircuitBreaker *CircuitBreakerApplyConfiguration `json:"circuitBreaker,omitempty"`
|
||||
Compress *CompressApplyConfiguration `json:"compress,omitempty"`
|
||||
PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty"`
|
||||
|
|
@ -215,8 +215,8 @@ func (b *MiddlewareSpecApplyConfiguration) WithInFlightReq(value dynamic.InFligh
|
|||
// WithBuffering sets the Buffering field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Buffering field is set to the value of the last call.
|
||||
func (b *MiddlewareSpecApplyConfiguration) WithBuffering(value dynamic.Buffering) *MiddlewareSpecApplyConfiguration {
|
||||
b.Buffering = &value
|
||||
func (b *MiddlewareSpecApplyConfiguration) WithBuffering(value *BufferingApplyConfiguration) *MiddlewareSpecApplyConfiguration {
|
||||
b.Buffering = value
|
||||
return b
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
|
|||
// Group=traefik.io, Version=v1alpha1
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("BasicAuth"):
|
||||
return &traefikiov1alpha1.BasicAuthApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("Buffering"):
|
||||
return &traefikiov1alpha1.BufferingApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("Certificate"):
|
||||
return &traefikiov1alpha1.CertificateApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("Chain"):
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
|||
DigestAuth: digestAuth,
|
||||
ForwardAuth: forwardAuth,
|
||||
InFlightReq: middleware.Spec.InFlightReq,
|
||||
Buffering: middleware.Spec.Buffering,
|
||||
Buffering: createBufferingMiddleware(middleware.Spec.Buffering),
|
||||
CircuitBreaker: circuitBreaker,
|
||||
Compress: createCompressMiddleware(middleware.Spec.Compress),
|
||||
PassTLSClientCert: middleware.Spec.PassTLSClientCert,
|
||||
|
|
@ -1196,6 +1196,20 @@ func createDigestAuthMiddleware(client Client, namespace string, digestAuth *tra
|
|||
}, nil
|
||||
}
|
||||
|
||||
func createBufferingMiddleware(buffering *traefikv1alpha1.Buffering) *dynamic.Buffering {
|
||||
if buffering == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &dynamic.Buffering{
|
||||
MemRequestBodyBytes: buffering.MemRequestBodyBytes,
|
||||
MaxRequestBodyBytes: buffering.MaxRequestBodyBytes,
|
||||
MemResponseBodyBytes: buffering.MemResponseBodyBytes,
|
||||
MaxResponseBodyBytes: buffering.MaxResponseBodyBytes,
|
||||
RetryExpression: buffering.RetryExpression,
|
||||
}
|
||||
}
|
||||
|
||||
func loadBasicAuthCredentials(secret *corev1.Secret) ([]string, error) {
|
||||
username, usernameExists := secret.Data["username"]
|
||||
password, passwordExists := secret.Data["password"]
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ type MiddlewareSpec struct {
|
|||
DigestAuth *DigestAuth `json:"digestAuth,omitempty"`
|
||||
ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty"`
|
||||
InFlightReq *dynamic.InFlightReq `json:"inFlightReq,omitempty"`
|
||||
Buffering *dynamic.Buffering `json:"buffering,omitempty"`
|
||||
Buffering *Buffering `json:"buffering,omitempty"`
|
||||
CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty"`
|
||||
Compress *Compress `json:"compress,omitempty"`
|
||||
PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty"`
|
||||
|
|
@ -59,6 +59,32 @@ type MiddlewareSpec struct {
|
|||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// Buffering holds the buffering middleware configuration.
|
||||
// This middleware retries or limits the size of requests that can be forwarded to backends.
|
||||
// More info: https://doc.traefik.io/traefik/v3.6/middlewares/http/buffering/#maxrequestbodybytes
|
||||
type Buffering struct {
|
||||
// MaxRequestBodyBytes defines the maximum allowed body size for the request (in bytes).
|
||||
// If the request exceeds the allowed size, it is not forwarded to the service, and the client gets a 413 (Request Entity Too Large) response.
|
||||
// Default: 0 (no maximum).
|
||||
MaxRequestBodyBytes int64 `json:"maxRequestBodyBytes,omitempty" toml:"maxRequestBodyBytes,omitempty" yaml:"maxRequestBodyBytes,omitempty" export:"true"`
|
||||
// MemRequestBodyBytes defines the threshold (in bytes) from which the request will be buffered on disk instead of in memory.
|
||||
// Default: 1048576 (1Mi).
|
||||
MemRequestBodyBytes int64 `json:"memRequestBodyBytes,omitempty" toml:"memRequestBodyBytes,omitempty" yaml:"memRequestBodyBytes,omitempty" export:"true"`
|
||||
// MaxResponseBodyBytes defines the maximum allowed response size from the service (in bytes).
|
||||
// If the response exceeds the allowed size, it is not forwarded to the client. The client gets a 500 (Internal Server Error) response instead.
|
||||
// Default: 0 (no maximum).
|
||||
MaxResponseBodyBytes int64 `json:"maxResponseBodyBytes,omitempty" toml:"maxResponseBodyBytes,omitempty" yaml:"maxResponseBodyBytes,omitempty" export:"true"`
|
||||
// MemResponseBodyBytes defines the threshold (in bytes) from which the response will be buffered on disk instead of in memory.
|
||||
// Default: 1048576 (1Mi).
|
||||
MemResponseBodyBytes int64 `json:"memResponseBodyBytes,omitempty" toml:"memResponseBodyBytes,omitempty" yaml:"memResponseBodyBytes,omitempty" export:"true"`
|
||||
// RetryExpression defines the retry conditions.
|
||||
// It is a logical combination of functions with operators AND (&&) and OR (||).
|
||||
// More info: https://doc.traefik.io/traefik/v3.6/middlewares/http/buffering/#retryexpression
|
||||
RetryExpression string `json:"retryExpression,omitempty" toml:"retryExpression,omitempty" yaml:"retryExpression,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// ErrorPage holds the custom error middleware configuration.
|
||||
// This middleware returns a custom page in lieu of the default, according to configured ranges of HTTP Status codes.
|
||||
// More info: https://doc.traefik.io/traefik/v3.6/reference/routing-configuration/http/middlewares/errorpages/
|
||||
|
|
|
|||
|
|
@ -54,6 +54,22 @@ func (in *BasicAuth) DeepCopy() *BasicAuth {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Buffering) DeepCopyInto(out *Buffering) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Buffering.
|
||||
func (in *Buffering) DeepCopy() *Buffering {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Buffering)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Certificate) DeepCopyInto(out *Certificate) {
|
||||
*out = *in
|
||||
|
|
@ -910,7 +926,7 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) {
|
|||
}
|
||||
if in.Buffering != nil {
|
||||
in, out := &in.Buffering, &out.Buffering
|
||||
*out = new(dynamic.Buffering)
|
||||
*out = new(Buffering)
|
||||
**out = **in
|
||||
}
|
||||
if in.CircuitBreaker != nil {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package ingressnginx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -69,10 +68,26 @@ type ingressConfig struct {
|
|||
|
||||
CustomHeaders *string `annotation:"nginx.ingress.kubernetes.io/custom-headers"`
|
||||
UpstreamVhost *string `annotation:"nginx.ingress.kubernetes.io/upstream-vhost"`
|
||||
|
||||
// ProxyRequestBuffering controls whether request buffering is enabled.
|
||||
ProxyRequestBuffering *string `annotation:"nginx.ingress.kubernetes.io/proxy-request-buffering"`
|
||||
// ClientBodyBufferSize sets the size of the buffer used for reading request body.
|
||||
ClientBodyBufferSize *string `annotation:"nginx.ingress.kubernetes.io/client-body-buffer-size"`
|
||||
// ProxyBodySize sets the maximum allowed size of the client request body.
|
||||
ProxyBodySize *string `annotation:"nginx.ingress.kubernetes.io/proxy-body-size"`
|
||||
|
||||
// ProxyBuffering controls whether response buffering is enabled.
|
||||
ProxyBuffering *string `annotation:"nginx.ingress.kubernetes.io/proxy-buffering"`
|
||||
// ProxyBufferSize sets the size of the memory buffer used for reading the response.
|
||||
ProxyBufferSize *string `annotation:"nginx.ingress.kubernetes.io/proxy-buffer-size"`
|
||||
// ProxyBuffersNumber sets the number of memory buffers used for reading the response.
|
||||
ProxyBuffersNumber *int `annotation:"nginx.ingress.kubernetes.io/proxy-buffers-number"`
|
||||
// ProxyMaxTempFileSize sets the maximum size of a temporary file used to buffer responses.
|
||||
ProxyMaxTempFileSize *string `annotation:"nginx.ingress.kubernetes.io/proxy-max-temp-file-size"`
|
||||
}
|
||||
|
||||
// parseIngressConfig parses the annotations from an Ingress object into an ingressConfig struct.
|
||||
func parseIngressConfig(ing *netv1.Ingress) (ingressConfig, error) {
|
||||
func parseIngressConfig(ing *netv1.Ingress) ingressConfig {
|
||||
cfg := ingressConfig{}
|
||||
cfgType := reflect.TypeFor[ingressConfig]()
|
||||
cfgValue := reflect.ValueOf(&cfg).Elem()
|
||||
|
|
@ -93,10 +108,8 @@ func parseIngressConfig(ing *netv1.Ingress) (ingressConfig, error) {
|
|||
case reflect.String:
|
||||
cfgValue.Field(i).Set(reflect.ValueOf(&val))
|
||||
case reflect.Bool:
|
||||
parsed, err := strconv.ParseBool(val)
|
||||
if err == nil {
|
||||
cfgValue.Field(i).Set(reflect.ValueOf(&parsed))
|
||||
}
|
||||
b := val == "true"
|
||||
cfgValue.Field(i).Set(reflect.ValueOf(&b))
|
||||
case reflect.Int:
|
||||
parsed, err := strconv.Atoi(val)
|
||||
if err == nil {
|
||||
|
|
@ -110,15 +123,13 @@ func parseIngressConfig(ing *netv1.Ingress) (ingressConfig, error) {
|
|||
slice = append(slice, strings.TrimSpace(elt))
|
||||
}
|
||||
cfgValue.Field(i).Set(reflect.ValueOf(&slice))
|
||||
} else {
|
||||
return cfg, errors.New("unsupported slice type in annotations")
|
||||
}
|
||||
default:
|
||||
return cfg, errors.New("unsupported kind")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
return cfg
|
||||
}
|
||||
|
||||
// parseBackendProtocol parses the backend protocol annotation and returns the corresponding protocol string.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
netv1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
|
@ -18,19 +17,26 @@ func Test_parseIngressConfig(t *testing.T) {
|
|||
{
|
||||
desc: "all fields set",
|
||||
annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/ssl-passthrough": "true",
|
||||
"nginx.ingress.kubernetes.io/affinity": "cookie",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-name": "mycookie",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-secure": "true",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-path": "/foo",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-domain": "example.com",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-samesite": "Strict",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-max-age": "3600",
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "HTTPS",
|
||||
"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",
|
||||
"nginx.ingress.kubernetes.io/ssl-passthrough": "true",
|
||||
"nginx.ingress.kubernetes.io/affinity": "cookie",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-name": "mycookie",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-secure": "true",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-path": "/foo",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-domain": "example.com",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-samesite": "Strict",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-max-age": "3600",
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "HTTPS",
|
||||
"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",
|
||||
"nginx.ingress.kubernetes.io/proxy-request-buffering": "on",
|
||||
"nginx.ingress.kubernetes.io/client-body-buffer-size": "16k",
|
||||
"nginx.ingress.kubernetes.io/proxy-body-size": "16k",
|
||||
"nginx.ingress.kubernetes.io/proxy-buffering": "on",
|
||||
"nginx.ingress.kubernetes.io/proxy-buffer-size": "16k",
|
||||
"nginx.ingress.kubernetes.io/proxy-buffers-number": "8",
|
||||
"nginx.ingress.kubernetes.io/proxy-max-temp-file-size": "100m",
|
||||
},
|
||||
expected: ingressConfig{
|
||||
SSLPassthrough: ptr.To(true),
|
||||
|
|
@ -46,6 +52,13 @@ func Test_parseIngressConfig(t *testing.T) {
|
|||
AuthURL: ptr.To("http://auth.example.com/verify"),
|
||||
AuthSignin: ptr.To("https://auth.example.com/oauth2/start?rd=foo"),
|
||||
ProxyConnectTimeout: ptr.To(30),
|
||||
ProxyRequestBuffering: ptr.To("on"),
|
||||
ClientBodyBufferSize: ptr.To("16k"),
|
||||
ProxyBodySize: ptr.To("16k"),
|
||||
ProxyBuffering: ptr.To("on"),
|
||||
ProxyBufferSize: ptr.To("16k"),
|
||||
ProxyBuffersNumber: ptr.To(8),
|
||||
ProxyMaxTempFileSize: ptr.To("100m"),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -62,7 +75,9 @@ 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",
|
||||
},
|
||||
expected: ingressConfig{
|
||||
SSLPassthrough: ptr.To(false),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -74,10 +89,7 @@ func Test_parseIngressConfig(t *testing.T) {
|
|||
var ing netv1.Ingress
|
||||
ing.SetAnnotations(test.annotations)
|
||||
|
||||
cfg, err := parseIngressConfig(&ing)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expected, cfg)
|
||||
assert.Equal(t, test.expected, parseIngressConfig(&ing))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-client-body-buffer-size
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-request-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/client-body-buffer-size: "10M"
|
||||
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: hostname.localhost
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Exact
|
||||
backend:
|
||||
service:
|
||||
name: whoami
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-proxy-body-size-and-client-body-buffer-size
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-request-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "10M"
|
||||
nginx.ingress.kubernetes.io/client-body-buffer-size: "10K"
|
||||
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: hostname.localhost
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Exact
|
||||
backend:
|
||||
service:
|
||||
name: whoami
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-proxy-body-size
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-request-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "10M"
|
||||
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: hostname.localhost
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Exact
|
||||
backend:
|
||||
service:
|
||||
name: whoami
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-proxy-buffer-size-and-number
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
|
||||
nginx.ingress.kubernetes.io/proxy-buffers-number: "8"
|
||||
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: hostname.localhost
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Exact
|
||||
backend:
|
||||
service:
|
||||
name: whoami
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-proxy-buffer-size
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
|
||||
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: hostname.localhost
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Exact
|
||||
backend:
|
||||
service:
|
||||
name: whoami
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-proxy-buffers-number
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/proxy-buffers-number: "8"
|
||||
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: hostname.localhost
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Exact
|
||||
backend:
|
||||
service:
|
||||
name: whoami
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-proxy-max-temp-file-size
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "100m"
|
||||
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: hostname.localhost
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Exact
|
||||
backend:
|
||||
service:
|
||||
name: whoami
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -43,8 +43,20 @@ const (
|
|||
defaultBackendTLSName = "default-backend-tls"
|
||||
|
||||
defaultProxyConnectTimeout = 60
|
||||
// https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
|
||||
defaultProxyBodySize = int64(1024 * 1024) // 1MB
|
||||
// https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
|
||||
defaultClientBodyBufferSize = int64(16 * 1024) // 16KB
|
||||
// https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size
|
||||
defaultProxyBufferSize = int64(8 * 1024) // 8KB
|
||||
// https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#proxy-buffers-number
|
||||
defaultProxyBuffersNumber = 4
|
||||
// https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_max_temp_file_size
|
||||
defaultProxyMaxTempFileSize = int64(1024 * 1024 * 1024) // 1GB
|
||||
)
|
||||
|
||||
var nginxSizeRegexp = regexp.MustCompile(`^(?i)\s*([0-9]+)\s*([b|k|m|g]?)\s*$`)
|
||||
|
||||
type backendAddress struct {
|
||||
Address string
|
||||
Fenced bool
|
||||
|
|
@ -84,6 +96,14 @@ type Provider struct {
|
|||
|
||||
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"`
|
||||
|
||||
// Configuration options available within the NGINX Ingress Controller ConfigMap.
|
||||
ProxyRequestBuffering bool `description:"Defines whether to enable request buffering." json:"proxyRequestBuffering,omitempty" toml:"proxyRequestBuffering,omitempty" yaml:"proxyRequestBuffering,omitempty" export:"true"`
|
||||
ClientBodyBufferSize int64 `description:"Default buffer size for reading client request body." json:"clientBodyBufferSize,omitempty" toml:"clientBodyBufferSize,omitempty" yaml:"clientBodyBufferSize,omitempty" export:"true"`
|
||||
ProxyBodySize int64 `description:"Default maximum size of a client request body in bytes." json:"proxyBodySize,omitempty" toml:"proxyBodySize,omitempty" yaml:"proxyBodySize,omitempty" export:"true"`
|
||||
ProxyBuffering bool `description:"Defines whether to enable response buffering." json:"proxyBuffering,omitempty" toml:"proxyBuffering,omitempty" yaml:"proxyBuffering,omitempty" export:"true"`
|
||||
ProxyBufferSize int64 `description:"Default buffer size for reading the response body." json:"proxyBufferSize,omitempty" toml:"proxyBufferSize,omitempty" yaml:"proxyBufferSize,omitempty" export:"true"`
|
||||
ProxyBuffersNumber int `description:"Default number of buffers for reading a response." json:"proxyBuffersNumber,omitempty" toml:"proxyBuffersNumber,omitempty" yaml:"proxyBuffersNumber,omitempty" export:"true"`
|
||||
|
||||
// NonTLSEntryPoints contains the names of entrypoints that are configured without TLS.
|
||||
NonTLSEntryPoints []string `json:"-" toml:"-" yaml:"-" label:"-" file:"-"`
|
||||
|
||||
|
|
@ -98,6 +118,10 @@ func (p *Provider) SetDefaults() {
|
|||
p.IngressClass = defaultAnnotationValue
|
||||
p.ControllerClass = defaultControllerName
|
||||
p.ProxyConnectTimeout = defaultProxyConnectTimeout
|
||||
p.ClientBodyBufferSize = defaultClientBodyBufferSize
|
||||
p.ProxyBodySize = defaultProxyBodySize
|
||||
p.ProxyBufferSize = defaultProxyBufferSize
|
||||
p.ProxyBuffersNumber = defaultProxyBuffersNumber
|
||||
}
|
||||
|
||||
// Init the provider.
|
||||
|
|
@ -289,12 +313,6 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||
continue
|
||||
}
|
||||
|
||||
ingressConfig, err := parseIngressConfig(ingress)
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("Error parsing ingress configuration")
|
||||
continue
|
||||
}
|
||||
|
||||
if err := p.updateIngressStatus(ingress); err != nil {
|
||||
logger.Error().Err(err).Msg("Error while updating ingress status")
|
||||
}
|
||||
|
|
@ -308,6 +326,8 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||
}
|
||||
}
|
||||
|
||||
ingressConfig := parseIngressConfig(ingress)
|
||||
|
||||
var clientAuthTLSOptionName string
|
||||
if ingressConfig.AuthTLSSecret != nil {
|
||||
tlsOptName := provider.Normalize(ingress.Namespace + "-" + ingress.Name + "-" + *ingressConfig.AuthTLSSecret)
|
||||
|
|
@ -543,7 +563,10 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||
|
||||
conf.TLS = &dynamic.TLSConfiguration{
|
||||
Certificates: slices.Collect(maps.Values(uniqCerts)),
|
||||
Options: tlsOptions,
|
||||
}
|
||||
|
||||
if len(tlsOptions) > 0 {
|
||||
conf.TLS.Options = tlsOptions
|
||||
}
|
||||
|
||||
return conf
|
||||
|
|
@ -856,12 +879,16 @@ func (p *Provider) applyMiddlewares(namespace, routerKey, rulePath, ruleHost str
|
|||
return fmt.Errorf("applying basic auth configuration: %w", err)
|
||||
}
|
||||
|
||||
applyWhitelistSourceRangeConfiguration(routerKey, ingressConfig, rt, conf)
|
||||
|
||||
if err := p.applyBufferingConfiguration(routerKey, ingressConfig, rt, conf); err != nil {
|
||||
return fmt.Errorf("applying buffering: %w", err)
|
||||
}
|
||||
|
||||
if err := applyForwardAuthConfiguration(routerKey, ingressConfig, rt, conf); err != nil {
|
||||
return fmt.Errorf("applying forward auth configuration: %w", err)
|
||||
}
|
||||
|
||||
applyWhitelistSourceRangeConfiguration(routerKey, ingressConfig, rt, conf)
|
||||
|
||||
applyCORSConfiguration(routerKey, ingressConfig, rt, conf)
|
||||
|
||||
applyRewriteTargetConfiguration(rulePath, routerKey, ingressConfig, rt, conf)
|
||||
|
|
@ -1188,6 +1215,83 @@ func applyWhitelistSourceRangeConfiguration(routerName string, ingressConfig ing
|
|||
rt.Middlewares = append(rt.Middlewares, whitelistSourceRangeMiddlewareName)
|
||||
}
|
||||
|
||||
func (p *Provider) applyBufferingConfiguration(routerName string, ingressConfig ingressConfig, rt *dynamic.Router, conf *dynamic.Configuration) error {
|
||||
disableRequestBuffering := !p.ProxyRequestBuffering
|
||||
if ingressConfig.ProxyRequestBuffering != nil {
|
||||
// Without value validation, lean on disabling by checking for "on", which is more likely to satisfy user input.
|
||||
disableRequestBuffering = *ingressConfig.ProxyRequestBuffering != "on"
|
||||
}
|
||||
|
||||
disableResponseBuffering := !p.ProxyBuffering
|
||||
if ingressConfig.ProxyBuffering != nil {
|
||||
// Without value validation, lean on disabling by checking for "on", which is more likely to satisfy user input.
|
||||
disableResponseBuffering = *ingressConfig.ProxyBuffering != "on"
|
||||
}
|
||||
|
||||
if disableRequestBuffering && disableResponseBuffering {
|
||||
return nil
|
||||
}
|
||||
|
||||
buffering := &dynamic.Buffering{
|
||||
DisableRequestBuffer: disableRequestBuffering,
|
||||
DisableResponseBuffer: disableResponseBuffering,
|
||||
MemRequestBodyBytes: p.ClientBodyBufferSize,
|
||||
MaxRequestBodyBytes: p.ProxyBodySize,
|
||||
MemResponseBodyBytes: p.ProxyBufferSize * int64(p.ProxyBuffersNumber),
|
||||
}
|
||||
|
||||
if !disableRequestBuffering {
|
||||
if clientBodyBufferSize := ptr.Deref(ingressConfig.ClientBodyBufferSize, ""); clientBodyBufferSize != "" {
|
||||
memRequestBodySize, err := nginxSizeToBytes(clientBodyBufferSize)
|
||||
if err != nil {
|
||||
return fmt.Errorf("client-body-buffer-size annotation has invalid value: %w", err)
|
||||
}
|
||||
buffering.MemRequestBodyBytes = memRequestBodySize
|
||||
}
|
||||
|
||||
if proxyBodySize := ptr.Deref(ingressConfig.ProxyBodySize, ""); proxyBodySize != "" {
|
||||
maxRequestBody, err := nginxSizeToBytes(proxyBodySize)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proxy-body-size annotation has invalid value: %w", err)
|
||||
}
|
||||
|
||||
buffering.MaxRequestBodyBytes = maxRequestBody
|
||||
}
|
||||
}
|
||||
|
||||
if !disableResponseBuffering {
|
||||
if ingressConfig.ProxyBufferSize != nil || ingressConfig.ProxyBuffersNumber != nil {
|
||||
bufferSize := p.ProxyBufferSize
|
||||
if proxyBufferSize := ptr.Deref(ingressConfig.ProxyBufferSize, ""); proxyBufferSize != "" {
|
||||
var err error
|
||||
if bufferSize, err = nginxSizeToBytes(proxyBufferSize); err != nil {
|
||||
return fmt.Errorf("proxy-buffer-size annotation has invalid value: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
buffering.MemResponseBodyBytes = bufferSize * int64(ptr.Deref(ingressConfig.ProxyBuffersNumber, p.ProxyBuffersNumber))
|
||||
}
|
||||
|
||||
proxyMaxTempFileSize := defaultProxyMaxTempFileSize
|
||||
if ingressConfig.ProxyMaxTempFileSize != nil {
|
||||
var err error
|
||||
if proxyMaxTempFileSize, err = nginxSizeToBytes(*ingressConfig.ProxyMaxTempFileSize); err != nil {
|
||||
return fmt.Errorf("proxy-body-size annotation has invalid value: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
buffering.MaxResponseBodyBytes = buffering.MemResponseBodyBytes + proxyMaxTempFileSize
|
||||
}
|
||||
|
||||
bufferingMiddlewareName := routerName + "-buffering"
|
||||
conf.HTTP.Middlewares[bufferingMiddlewareName] = &dynamic.Middleware{
|
||||
Buffering: buffering,
|
||||
}
|
||||
rt.Middlewares = append(rt.Middlewares, bufferingMiddlewareName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) applySSLRedirectConfiguration(routerName string, ingressConfig ingressConfig, hasTLS bool, rt *dynamic.Router, conf *dynamic.Configuration) {
|
||||
var forceSSLRedirect bool
|
||||
if ingressConfig.ForceSSLRedirect != nil {
|
||||
|
|
@ -1441,3 +1545,24 @@ func (p *Provider) buildClientAuthTLSOption(ingressNamespace string, config ingr
|
|||
|
||||
return tlsOpt, nil
|
||||
}
|
||||
|
||||
// nginxSizeToBytes convert nginx size to memory bytes as defined in https://nginx.org/en/docs/syntax.html.
|
||||
func nginxSizeToBytes(nginxSize string) (int64, error) {
|
||||
units := map[string]int64{
|
||||
"g": 1024 * 1024 * 1024,
|
||||
"m": 1024 * 1024,
|
||||
"k": 1024,
|
||||
"b": 1,
|
||||
"": 1,
|
||||
}
|
||||
|
||||
if !nginxSizeRegexp.MatchString(nginxSize) {
|
||||
return 0, fmt.Errorf("unable to parse number %s", nginxSize)
|
||||
}
|
||||
size := nginxSizeRegexp.FindStringSubmatch(nginxSize)
|
||||
bytes, err := strconv.ParseInt(size[1], 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return bytes * units[strings.ToLower(size[2])], nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package ingressnginx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -47,9 +48,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -108,9 +107,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -187,7 +184,6 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -250,9 +246,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -313,9 +307,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -462,7 +454,6 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -507,9 +498,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -574,9 +563,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -632,9 +619,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -698,9 +683,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -749,9 +732,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -810,9 +791,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -864,9 +843,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -926,9 +903,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -988,9 +963,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1042,9 +1015,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1110,9 +1081,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1178,9 +1147,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1260,9 +1227,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1315,9 +1280,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1376,9 +1339,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1437,9 +1398,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1498,9 +1457,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1553,9 +1510,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1616,9 +1571,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1679,9 +1632,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1742,9 +1693,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1805,9 +1754,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1868,9 +1815,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1931,9 +1876,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1994,9 +1937,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -2044,9 +1985,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Options: map[string]tls.Options{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -2256,6 +2195,444 @@ func TestLoadIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Buffering with proxy body size of 10MB",
|
||||
paths: []string{
|
||||
"services.yml",
|
||||
"ingressclasses.yml",
|
||||
"ingresses/ingress-with-proxy-body-size.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-body-size-rule-0-path-0": {
|
||||
Rule: "Host(`hostname.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-proxy-body-size-rule-0-path-0-buffering"},
|
||||
Service: "default-ingress-with-proxy-body-size-whoami-80",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-ingress-with-proxy-body-size-rule-0-path-0-buffering": {
|
||||
Buffering: &dynamic.Buffering{
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
MemRequestBodyBytes: defaultClientBodyBufferSize,
|
||||
MemResponseBodyBytes: defaultProxyBufferSize * int64(defaultProxyBuffersNumber),
|
||||
DisableResponseBuffer: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-ingress-with-proxy-body-size-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-body-size",
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||
"default-ingress-with-proxy-body-size": {
|
||||
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Buffering with client body buffer size of 10MB",
|
||||
paths: []string{
|
||||
"services.yml",
|
||||
"ingressclasses.yml",
|
||||
"ingresses/ingress-with-client-body-buffer-size.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-client-body-buffer-size-rule-0-path-0": {
|
||||
Rule: "Host(`hostname.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-client-body-buffer-size-rule-0-path-0-buffering"},
|
||||
Service: "default-ingress-with-client-body-buffer-size-whoami-80",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-ingress-with-client-body-buffer-size-rule-0-path-0-buffering": {
|
||||
Buffering: &dynamic.Buffering{
|
||||
MemRequestBodyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: defaultProxyBodySize,
|
||||
MemResponseBodyBytes: defaultProxyBufferSize * int64(defaultProxyBuffersNumber),
|
||||
DisableResponseBuffer: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-ingress-with-client-body-buffer-size-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-client-body-buffer-size",
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||
"default-ingress-with-client-body-buffer-size": {
|
||||
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Buffering with proxy body size and client body buffer",
|
||||
paths: []string{
|
||||
"services.yml",
|
||||
"ingressclasses.yml",
|
||||
"ingresses/ingress-with-proxy-body-size-and-client-body-buffer-size.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-body-size-and-client-body-buffer-size-rule-0-path-0": {
|
||||
Rule: "Host(`hostname.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-proxy-body-size-and-client-body-buffer-size-rule-0-path-0-buffering"},
|
||||
Service: "default-ingress-with-proxy-body-size-and-client-body-buffer-size-whoami-80",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-ingress-with-proxy-body-size-and-client-body-buffer-size-rule-0-path-0-buffering": {
|
||||
Buffering: &dynamic.Buffering{
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
MemRequestBodyBytes: 10 * 1024,
|
||||
MemResponseBodyBytes: defaultProxyBufferSize * int64(defaultProxyBuffersNumber),
|
||||
DisableResponseBuffer: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-ingress-with-proxy-body-size-and-client-body-buffer-size-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-body-size-and-client-body-buffer-size",
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||
"default-ingress-with-proxy-body-size-and-client-body-buffer-size": {
|
||||
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Buffering with proxy buffer size",
|
||||
paths: []string{
|
||||
"services.yml",
|
||||
"ingressclasses.yml",
|
||||
"ingresses/ingress-with-proxy-buffer-size.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-buffer-size-rule-0-path-0": {
|
||||
Rule: "Host(`hostname.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-proxy-buffer-size-rule-0-path-0-buffering"},
|
||||
Service: "default-ingress-with-proxy-buffer-size-whoami-80",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-ingress-with-proxy-buffer-size-rule-0-path-0-buffering": {
|
||||
Buffering: &dynamic.Buffering{
|
||||
DisableRequestBuffer: true,
|
||||
MaxRequestBodyBytes: defaultProxyBodySize,
|
||||
MemRequestBodyBytes: defaultClientBodyBufferSize,
|
||||
MemResponseBodyBytes: 16 * 1024 * int64(defaultProxyBuffersNumber),
|
||||
MaxResponseBodyBytes: defaultProxyMaxTempFileSize + (defaultProxyBufferSize * 8),
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-ingress-with-proxy-buffer-size-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-buffer-size",
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||
"default-ingress-with-proxy-buffer-size": {
|
||||
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Buffering with proxy buffers number",
|
||||
paths: []string{
|
||||
"services.yml",
|
||||
"ingressclasses.yml",
|
||||
"ingresses/ingress-with-proxy-buffers-number.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-buffers-number-rule-0-path-0": {
|
||||
Rule: "Host(`hostname.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-proxy-buffers-number-rule-0-path-0-buffering"},
|
||||
Service: "default-ingress-with-proxy-buffers-number-whoami-80",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-ingress-with-proxy-buffers-number-rule-0-path-0-buffering": {
|
||||
Buffering: &dynamic.Buffering{
|
||||
DisableRequestBuffer: true,
|
||||
MaxRequestBodyBytes: defaultProxyBodySize,
|
||||
MemRequestBodyBytes: defaultClientBodyBufferSize,
|
||||
MemResponseBodyBytes: defaultProxyBufferSize * 8,
|
||||
MaxResponseBodyBytes: defaultProxyMaxTempFileSize + (defaultProxyBufferSize * 8),
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-ingress-with-proxy-buffers-number-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-buffers-number",
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||
"default-ingress-with-proxy-buffers-number": {
|
||||
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Buffering with proxy buffer size and proxy buffers number",
|
||||
paths: []string{
|
||||
"services.yml",
|
||||
"ingressclasses.yml",
|
||||
"ingresses/ingress-with-proxy-buffer-size-and-number.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-buffer-size-and-number-rule-0-path-0": {
|
||||
Rule: "Host(`hostname.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-proxy-buffer-size-and-number-rule-0-path-0-buffering"},
|
||||
Service: "default-ingress-with-proxy-buffer-size-and-number-whoami-80",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-ingress-with-proxy-buffer-size-and-number-rule-0-path-0-buffering": {
|
||||
Buffering: &dynamic.Buffering{
|
||||
DisableRequestBuffer: true,
|
||||
MaxRequestBodyBytes: defaultProxyBodySize,
|
||||
MemRequestBodyBytes: defaultClientBodyBufferSize,
|
||||
MemResponseBodyBytes: 16 * 1024 * 8,
|
||||
MaxResponseBodyBytes: defaultProxyMaxTempFileSize + (16 * 1024 * 8),
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-ingress-with-proxy-buffer-size-and-number-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-buffer-size-and-number",
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||
"default-ingress-with-proxy-buffer-size-and-number": {
|
||||
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Buffering with proxy max temp file size",
|
||||
paths: []string{
|
||||
"services.yml",
|
||||
"ingressclasses.yml",
|
||||
"ingresses/ingress-with-proxy-max-temp-file-size.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-max-temp-file-size-rule-0-path-0": {
|
||||
Rule: "Host(`hostname.localhost`) && Path(`/`)",
|
||||
RuleSyntax: "default",
|
||||
Middlewares: []string{"default-ingress-with-proxy-max-temp-file-size-rule-0-path-0-buffering"},
|
||||
Service: "default-ingress-with-proxy-max-temp-file-size-whoami-80",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-ingress-with-proxy-max-temp-file-size-rule-0-path-0-buffering": {
|
||||
Buffering: &dynamic.Buffering{
|
||||
DisableRequestBuffer: true,
|
||||
MaxRequestBodyBytes: defaultProxyBodySize,
|
||||
MemRequestBodyBytes: defaultClientBodyBufferSize,
|
||||
MemResponseBodyBytes: defaultProxyBufferSize * int64(defaultProxyBuffersNumber),
|
||||
MaxResponseBodyBytes: (defaultProxyBufferSize * int64(defaultProxyBuffersNumber)) + (100 * 1024 * 1024),
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-ingress-with-proxy-max-temp-file-size-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-max-temp-file-size",
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||
"default-ingress-with-proxy-max-temp-file-size": {
|
||||
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
|
@ -2288,6 +2665,82 @@ func TestLoadIngresses(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNginxSizeToBytes(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
value string
|
||||
err error
|
||||
expected int64
|
||||
}{
|
||||
{
|
||||
desc: "Testing no unit",
|
||||
expected: 100,
|
||||
value: "100",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit b",
|
||||
expected: 100,
|
||||
value: "100b",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit B",
|
||||
expected: 100,
|
||||
value: "100B",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit KB",
|
||||
expected: 100 * 1024,
|
||||
value: "100k",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit MB",
|
||||
expected: 100 * 1024 * 1024,
|
||||
value: "100m",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit GB",
|
||||
expected: 100 * 1024 * 1024 * 1024,
|
||||
value: "100g",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit GB with whitespaces",
|
||||
expected: 100 * 1024 * 1024 * 1024,
|
||||
value: " 100 g ",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit KB uppercase",
|
||||
expected: 100 * 1024,
|
||||
value: "100K",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit MB uppercase",
|
||||
expected: 100 * 1024 * 1024,
|
||||
value: "100M",
|
||||
},
|
||||
{
|
||||
desc: "Testing unit GB uppercase",
|
||||
expected: 100 * 1024 * 1024 * 1024,
|
||||
value: "100G",
|
||||
},
|
||||
{
|
||||
desc: "Testing invalid input",
|
||||
expected: 0,
|
||||
value: "100A",
|
||||
err: errors.New("unable to parse number 100A"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
size, err := nginxSizeToBytes(test.value)
|
||||
assert.Equal(t, test.err, err)
|
||||
assert.Equal(t, test.expected, size)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func readResources(t *testing.T, paths []string) []runtime.Object {
|
||||
t.Helper()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue