add ServersTransport on services
This commit is contained in:
parent
6075f7e8fd
commit
76f42a3013
64 changed files with 2359 additions and 242 deletions
|
@ -213,7 +213,8 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
||||||
metricsRegistry := metrics.NewMultiRegistry(metricRegistries)
|
metricsRegistry := metrics.NewMultiRegistry(metricRegistries)
|
||||||
accessLog := setupAccessLog(staticConfiguration.AccessLog)
|
accessLog := setupAccessLog(staticConfiguration.AccessLog)
|
||||||
chainBuilder := middleware.NewChainBuilder(*staticConfiguration, metricsRegistry, accessLog)
|
chainBuilder := middleware.NewChainBuilder(*staticConfiguration, metricsRegistry, accessLog)
|
||||||
managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry)
|
roundTripperManager := service.NewRoundTripperManager()
|
||||||
|
managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry, roundTripperManager)
|
||||||
|
|
||||||
client, plgs, devPlugin, err := initPlugins(staticConfiguration)
|
client, plgs, devPlugin, err := initPlugins(staticConfiguration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -259,6 +260,10 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
||||||
metricsRegistry.LastConfigReloadSuccessGauge().Set(float64(time.Now().Unix()))
|
metricsRegistry.LastConfigReloadSuccessGauge().Set(float64(time.Now().Unix()))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||||
|
roundTripperManager.Update(conf.HTTP.ServersTransports)
|
||||||
|
})
|
||||||
|
|
||||||
watcher.AddListener(switchRouter(routerFactory, acmeProviders, serverEntryPointsTCP, serverEntryPointsUDP, aviator))
|
watcher.AddListener(switchRouter(routerFactory, acmeProviders, serverEntryPointsTCP, serverEntryPointsUDP, aviator))
|
||||||
|
|
||||||
watcher.AddListener(func(conf dynamic.Configuration) {
|
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ Previous versions of Traefik used a [KV store](https://docs.traefik.io/v1.7/conf
|
||||||
|
|
||||||
If you require LetsEncrypt with HA in a kubernetes environment, we recommend using [TraefikEE](https://containo.us/traefikee/) where distributed LetsEncrypt is a supported feature.
|
If you require LetsEncrypt with HA in a kubernetes environment, we recommend using [TraefikEE](https://containo.us/traefikee/) where distributed LetsEncrypt is a supported feature.
|
||||||
|
|
||||||
If you are wanting to continue to run Traefik Community Edition, LetsEncrypt HA can be achieved by using a Certificate Controller such as [Cert-Manager](https://docs.cert-manager.io/en/latest/index.html).
|
If you want to continue to run Traefik Community Edition, LetsEncrypt HA can be achieved by using a Certificate Controller such as [Cert-Manager](https://docs.cert-manager.io/en/latest/index.html).
|
||||||
When using Cert-Manager to manage certificates, it will create secrets in your namespaces that can be referenced as TLS secrets in your [ingress objects](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).
|
When using Cert-Manager to manage certificates, it will create secrets in your namespaces that can be referenced as TLS secrets in your [ingress objects](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).
|
||||||
When using the Traefik Kubernetes CRD Provider, unfortunately Cert-Manager cannot interface directly with the CRDs _yet_, but this is being worked on by our team.
|
When using the Traefik Kubernetes CRD Provider, unfortunately Cert-Manager cannot interface directly with the CRDs _yet_, but this is being worked on by our team.
|
||||||
A workaround is to enable the [Kubernetes Ingress provider](./kubernetes-ingress.md) to allow Cert-Manager to create ingress objects to complete the challenges.
|
A workaround is to enable the [Kubernetes Ingress provider](./kubernetes-ingress.md) to allow Cert-Manager to create ingress objects to complete the challenges.
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
[http.services.Service01]
|
[http.services.Service01]
|
||||||
[http.services.Service01.loadBalancer]
|
[http.services.Service01.loadBalancer]
|
||||||
passHostHeader = true
|
passHostHeader = true
|
||||||
|
serversTransport = "foobar"
|
||||||
[http.services.Service01.loadBalancer.sticky]
|
[http.services.Service01.loadBalancer.sticky]
|
||||||
[http.services.Service01.loadBalancer.sticky.cookie]
|
[http.services.Service01.loadBalancer.sticky.cookie]
|
||||||
name = "foobar"
|
name = "foobar"
|
||||||
|
@ -264,6 +265,41 @@
|
||||||
[http.middlewares.Middleware22]
|
[http.middlewares.Middleware22]
|
||||||
[http.middlewares.Middleware22.stripPrefixRegex]
|
[http.middlewares.Middleware22.stripPrefixRegex]
|
||||||
regex = ["foobar", "foobar"]
|
regex = ["foobar", "foobar"]
|
||||||
|
[http.serversTransports]
|
||||||
|
[http.serversTransports.ServersTransport0]
|
||||||
|
serverName = "foobar"
|
||||||
|
insecureSkipVerify = true
|
||||||
|
rootCAs = ["foobar", "foobar"]
|
||||||
|
maxIdleConnsPerHost = 42
|
||||||
|
|
||||||
|
[[http.serversTransports.ServersTransport0.certificates]]
|
||||||
|
certFile = "foobar"
|
||||||
|
keyFile = "foobar"
|
||||||
|
|
||||||
|
[[http.serversTransports.ServersTransport0.certificates]]
|
||||||
|
certFile = "foobar"
|
||||||
|
keyFile = "foobar"
|
||||||
|
[http.serversTransports.ServersTransport0.forwardingTimeouts]
|
||||||
|
dialTimeout = "42s"
|
||||||
|
responseHeaderTimeout = "42s"
|
||||||
|
idleConnTimeout = "42s"
|
||||||
|
[http.serversTransports.ServersTransport1]
|
||||||
|
serverName = "foobar"
|
||||||
|
insecureSkipVerify = true
|
||||||
|
rootCAs = ["foobar", "foobar"]
|
||||||
|
maxIdleConnsPerHost = 42
|
||||||
|
|
||||||
|
[[http.serversTransports.ServersTransport1.certificates]]
|
||||||
|
certFile = "foobar"
|
||||||
|
keyFile = "foobar"
|
||||||
|
|
||||||
|
[[http.serversTransports.ServersTransport1.certificates]]
|
||||||
|
certFile = "foobar"
|
||||||
|
keyFile = "foobar"
|
||||||
|
[http.serversTransports.ServersTransport1.forwardingTimeouts]
|
||||||
|
dialTimeout = "42s"
|
||||||
|
responseHeaderTimeout = "42s"
|
||||||
|
idleConnTimeout = "42s"
|
||||||
|
|
||||||
[tcp]
|
[tcp]
|
||||||
[tcp.routers]
|
[tcp.routers]
|
||||||
|
|
|
@ -70,6 +70,7 @@ http:
|
||||||
passHostHeader: true
|
passHostHeader: true
|
||||||
responseForwarding:
|
responseForwarding:
|
||||||
flushInterval: foobar
|
flushInterval: foobar
|
||||||
|
serversTransport: foobar
|
||||||
Service02:
|
Service02:
|
||||||
mirroring:
|
mirroring:
|
||||||
service: foobar
|
service: foobar
|
||||||
|
@ -301,6 +302,39 @@ http:
|
||||||
regex:
|
regex:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
serversTransports:
|
||||||
|
ServersTransport0:
|
||||||
|
serverName: foobar
|
||||||
|
insecureSkipVerify: true
|
||||||
|
rootCAs:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
|
certificates:
|
||||||
|
- certFile: foobar
|
||||||
|
keyFile: foobar
|
||||||
|
- certFile: foobar
|
||||||
|
keyFile: foobar
|
||||||
|
maxIdleConnsPerHost: 42
|
||||||
|
forwardingTimeouts:
|
||||||
|
dialTimeout: 42s
|
||||||
|
responseHeaderTimeout: 42s
|
||||||
|
idleConnTimeout: 42s
|
||||||
|
ServersTransport1:
|
||||||
|
serverName: foobar
|
||||||
|
insecureSkipVerify: true
|
||||||
|
rootCAs:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
|
certificates:
|
||||||
|
- certFile: foobar
|
||||||
|
keyFile: foobar
|
||||||
|
- certFile: foobar
|
||||||
|
keyFile: foobar
|
||||||
|
maxIdleConnsPerHost: 42
|
||||||
|
forwardingTimeouts:
|
||||||
|
dialTimeout: 42s
|
||||||
|
responseHeaderTimeout: 42s
|
||||||
|
idleConnTimeout: 42s
|
||||||
tcp:
|
tcp:
|
||||||
routers:
|
routers:
|
||||||
TCPRouter0:
|
TCPRouter0:
|
||||||
|
|
|
@ -101,3 +101,18 @@ spec:
|
||||||
plural: traefikservices
|
plural: traefikservices
|
||||||
singular: traefikservice
|
singular: traefikservice
|
||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
name: serverstransports.traefik.containo.us
|
||||||
|
|
||||||
|
spec:
|
||||||
|
group: traefik.containo.us
|
||||||
|
version: v1alpha1
|
||||||
|
names:
|
||||||
|
kind: ServersTransport
|
||||||
|
plural: serverstransports
|
||||||
|
singular: serverstransport
|
||||||
|
scope: Namespaced
|
||||||
|
|
|
@ -40,6 +40,7 @@ rules:
|
||||||
- ingressrouteudps
|
- ingressrouteudps
|
||||||
- tlsoptions
|
- tlsoptions
|
||||||
- tlsstores
|
- tlsstores
|
||||||
|
- serverstransports
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
|
|
|
@ -186,3 +186,25 @@ spec:
|
||||||
clientAuthType: foobar
|
clientAuthType: foobar
|
||||||
sniStrict: true
|
sniStrict: true
|
||||||
preferServerCipherSuites: true
|
preferServerCipherSuites: true
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
serverName: foobar
|
||||||
|
insecureSkipVerify: true
|
||||||
|
rootCAsSecrets:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
|
certificatesSecrets:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
|
maxIdleConnsPerHost: 1
|
||||||
|
forwardingTimeouts:
|
||||||
|
dialTimeout: 42s
|
||||||
|
responseHeaderTimeout: 42s
|
||||||
|
idleConnTimeout: 42s
|
||||||
|
|
|
@ -159,6 +159,30 @@
|
||||||
| `traefik/http/routers/Router1/tls/domains/1/sans/0` | `foobar` |
|
| `traefik/http/routers/Router1/tls/domains/1/sans/0` | `foobar` |
|
||||||
| `traefik/http/routers/Router1/tls/domains/1/sans/1` | `foobar` |
|
| `traefik/http/routers/Router1/tls/domains/1/sans/1` | `foobar` |
|
||||||
| `traefik/http/routers/Router1/tls/options` | `foobar` |
|
| `traefik/http/routers/Router1/tls/options` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/certificates/0/certFile` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/certificates/0/keyFile` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/certificates/1/certFile` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/certificates/1/keyFile` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/dialTimeout` | `42s` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/idleConnTimeout` | `42s` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/responseHeaderTimeout` | `42s` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/insecureSkipVerify` | `true` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/maxIdleConnsPerHost` | `42` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/rootCAs/0` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/rootCAs/1` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport0/serverName` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/certificates/0/certFile` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/certificates/0/keyFile` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/certificates/1/certFile` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/certificates/1/keyFile` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/dialTimeout` | `42s` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/idleConnTimeout` | `42s` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/responseHeaderTimeout` | `42s` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/insecureSkipVerify` | `true` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/maxIdleConnsPerHost` | `42` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/rootCAs/0` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/rootCAs/1` | `foobar` |
|
||||||
|
| `traefik/http/serversTransports/ServersTransport1/serverName` | `foobar` |
|
||||||
| `traefik/http/services/Service01/loadBalancer/healthCheck/followRedirects` | `true` |
|
| `traefik/http/services/Service01/loadBalancer/healthCheck/followRedirects` | `true` |
|
||||||
| `traefik/http/services/Service01/loadBalancer/healthCheck/headers/name0` | `foobar` |
|
| `traefik/http/services/Service01/loadBalancer/healthCheck/headers/name0` | `foobar` |
|
||||||
| `traefik/http/services/Service01/loadBalancer/healthCheck/headers/name1` | `foobar` |
|
| `traefik/http/services/Service01/loadBalancer/healthCheck/headers/name1` | `foobar` |
|
||||||
|
@ -172,6 +196,7 @@
|
||||||
| `traefik/http/services/Service01/loadBalancer/responseForwarding/flushInterval` | `foobar` |
|
| `traefik/http/services/Service01/loadBalancer/responseForwarding/flushInterval` | `foobar` |
|
||||||
| `traefik/http/services/Service01/loadBalancer/servers/0/url` | `foobar` |
|
| `traefik/http/services/Service01/loadBalancer/servers/0/url` | `foobar` |
|
||||||
| `traefik/http/services/Service01/loadBalancer/servers/1/url` | `foobar` |
|
| `traefik/http/services/Service01/loadBalancer/servers/1/url` | `foobar` |
|
||||||
|
| `traefik/http/services/Service01/loadBalancer/serversTransport` | `foobar` |
|
||||||
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/httpOnly` | `true` |
|
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/httpOnly` | `true` |
|
||||||
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/name` | `foobar` |
|
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/name` | `foobar` |
|
||||||
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/sameSite` | `foobar` |
|
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/sameSite` | `foobar` |
|
||||||
|
|
|
@ -1488,9 +1488,9 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres
|
||||||
secretName: mySecret # [1]
|
secretName: mySecret # [1]
|
||||||
```
|
```
|
||||||
|
|
||||||
| Ref | Attribute | Purpose |
|
| Ref | Attribute | Purpose |
|
||||||
|-----|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [1] | `secretName` | The name of the referenced Kubernetes [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) that holds the default certificate for the store. |
|
| [1] | `secretName` | The name of the referenced Kubernetes [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) that holds the default certificate for the store. |
|
||||||
|
|
||||||
??? example "Declaring and referencing a TLSStore"
|
??? example "Declaring and referencing a TLSStore"
|
||||||
|
|
||||||
|
@ -1537,6 +1537,84 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres
|
||||||
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Kind: `ServersTransport`
|
||||||
|
|
||||||
|
`ServersTransport` is the CRD implementation of a [ServersTransport](../services/index.md#serverstransport).
|
||||||
|
|
||||||
|
!!! important "Default serversTransport"
|
||||||
|
If no `serversTransport` is specified, the `default@internal` will be used.
|
||||||
|
The `default@internal` serversTransport is created from the [static configuration](../overview.md#transport-configuration).
|
||||||
|
|
||||||
|
!!! info "ServersTransport Attributes"
|
||||||
|
|
||||||
|
```yaml tab="TLSStore"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
serverName: foobar # [1]
|
||||||
|
insecureSkipVerify: true # [2]
|
||||||
|
rootCAsSecrets: # [3]
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
|
certificatesSecrets: # [4]
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
|
maxIdleConnsPerHost: 1 # [5]
|
||||||
|
forwardingTimeouts: # [6]
|
||||||
|
dialTimeout: 42s # [7]
|
||||||
|
responseHeaderTimeout: 42s # [8]
|
||||||
|
idleConnTimeout: 42s # [9]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ref | Attribute | Purpose |
|
||||||
|
|-----|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| [1] | `serverName` | ServerName used to contact the server. |
|
||||||
|
| [2] | `insecureSkipVerify` | Disable SSL certificate verification. |
|
||||||
|
| [3] | `rootCAsSecrets` | Add cert file for self-signed certificate. |
|
||||||
|
| [4] | `certificatesSecrets` | Certificates for mTLS. |
|
||||||
|
| [5] | `maxIdleConnsPerHost` | If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, `defaultMaxIdleConnsPerHost` is used. |
|
||||||
|
| [6] | `forwardingTimeouts` | Timeouts for requests forwarded to the backend servers. |
|
||||||
|
| [7] | `dialTimeout` | The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists. |
|
||||||
|
| [8] | `responseHeaderTimeout` | The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. |
|
||||||
|
| [9] | `idleConnTimeout` | The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself. |
|
||||||
|
|
||||||
|
??? example "Declaring and referencing a ServersTransport"
|
||||||
|
|
||||||
|
```yaml tab="ServersTransport"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
serverName: example.org
|
||||||
|
insecureSkipVerify: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="IngressRoute"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: testroute
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- web
|
||||||
|
routes:
|
||||||
|
- match: Host(`example.com`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: whoami
|
||||||
|
port: 80
|
||||||
|
serversTransport: mytransport
|
||||||
|
```
|
||||||
|
|
||||||
## Further
|
## Further
|
||||||
|
|
||||||
Also see the [full example](../../user-guides/crd-acme/index.md) with Let's Encrypt.
|
Also see the [full example](../../user-guides/crd-acme/index.md) with Let's Encrypt.
|
||||||
|
|
|
@ -460,6 +460,33 @@ By default, `passHostHeader` is true.
|
||||||
passHostHeader: false
|
passHostHeader: false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### ServersTransport
|
||||||
|
|
||||||
|
`serversTransport` allows to reference a ServersTransport configuration for the communication between Traefik and your servers.
|
||||||
|
|
||||||
|
??? example "Specify a transport -- Using the [File Provider](../../providers/file.md)"
|
||||||
|
|
||||||
|
```toml tab="TOML"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.services]
|
||||||
|
[http.services.Service01]
|
||||||
|
[http.services.Service01.loadBalancer]
|
||||||
|
serversTransport = "mytransport"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="YAML"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
services:
|
||||||
|
Service01:
|
||||||
|
loadBalancer:
|
||||||
|
serversTransport = "mytransport"
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! info default serversTransport
|
||||||
|
If no serversTransport is specified, the `default@internal` will be used.
|
||||||
|
The `default@internal` serversTransport is created from the [static configuration](../overview.md#transport-configuration).
|
||||||
|
|
||||||
#### Response Forwarding
|
#### Response Forwarding
|
||||||
|
|
||||||
This section is about configuring how Traefik forwards the response from the backend server to the client.
|
This section is about configuring how Traefik forwards the response from the backend server to the client.
|
||||||
|
@ -492,6 +519,301 @@ Below are the available options for the Response Forwarding mechanism:
|
||||||
flushInterval: 1s
|
flushInterval: 1s
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### ServersTransport
|
||||||
|
|
||||||
|
ServersTransport allows to configure the transport between Traefik and your servers.
|
||||||
|
|
||||||
|
#### `ServerName`
|
||||||
|
|
||||||
|
_Optional_
|
||||||
|
|
||||||
|
`serverName` configure the server name that will be used for SNI.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.serversTransports.mytransport]
|
||||||
|
serverName = "myhost"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
mytransport:
|
||||||
|
serverName: "myhost"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
serverName: "test"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `Certificates`
|
||||||
|
|
||||||
|
_Optional_
|
||||||
|
|
||||||
|
`certificates` is the list of certificates (as file paths, or data bytes)
|
||||||
|
that will be set as client certificates for mTLS.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[[http.serversTransports.mytransport.certificates]]
|
||||||
|
certFile = "foo.crt"
|
||||||
|
keyFile = "bar.crt"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
mytransport:
|
||||||
|
certficates:
|
||||||
|
- certFile: foo.crt
|
||||||
|
keyFile: bar.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
certificatesSecrets:
|
||||||
|
- mycert
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: mycert
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||||
|
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `insecureSkipVerify`
|
||||||
|
|
||||||
|
_Optional_
|
||||||
|
|
||||||
|
`insecureSkipVerify` disables SSL certificate verification.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.serversTransports.mytransport]
|
||||||
|
insecureSkipVerify = true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
mytransport:
|
||||||
|
insecureSkipVerify: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
insecureSkipVerify: true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `rootCAs`
|
||||||
|
|
||||||
|
_Optional_
|
||||||
|
|
||||||
|
`rootCAs` is the list of certificates (as file paths, or data bytes)
|
||||||
|
that will be set as Root Certificate Authorities when using a self-signed TLS certificate.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.serversTransports.mytransport]
|
||||||
|
rootCAs = ["foo.crt", "bar.crt"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
mytransport:
|
||||||
|
rootCAs:
|
||||||
|
- foo.crt
|
||||||
|
- bar.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
rootCAsSecrets:
|
||||||
|
- myca
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: myca
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `maxIdleConnsPerHost`
|
||||||
|
|
||||||
|
_Optional, Default=2_
|
||||||
|
|
||||||
|
If non-zero, `maxIdleConnsPerHost` controls the maximum idle (keep-alive) connections to keep per-host.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.serversTransports.mytransport]
|
||||||
|
maxIdleConnsPerHost = 7
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
mytransport:
|
||||||
|
maxIdleConnsPerHost: 7
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
maxIdleConnsPerHost: 7
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `forwardingTimeouts`
|
||||||
|
|
||||||
|
`forwardingTimeouts` is about a number of timeouts relevant to when forwarding requests to the backend servers.
|
||||||
|
|
||||||
|
##### `forwardingTimeouts.dialTimeout`
|
||||||
|
|
||||||
|
_Optional, Default=30s_
|
||||||
|
|
||||||
|
`dialTimeout` is the maximum duration allowed for a connection to a backend server to be established.
|
||||||
|
Zero means no timeout.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.serversTransports.mytransport.forwardingTimeouts]
|
||||||
|
dialTimeout = "1s"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
mytransport:
|
||||||
|
forwardingTimeouts:
|
||||||
|
dialTimeout: "1s"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
forwardingTimeouts:
|
||||||
|
dialTimeout: "1s"
|
||||||
|
```
|
||||||
|
|
||||||
|
##### `forwardingTimeouts.responseHeaderTimeout`
|
||||||
|
|
||||||
|
_Optional, Default=0s_
|
||||||
|
|
||||||
|
`responseHeaderTimeout`, if non-zero, specifies the amount of time to wait for a server's response headers
|
||||||
|
after fully writing the request (including its body, if any).
|
||||||
|
This time does not include the time to read the response body.
|
||||||
|
Zero means no timeout.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.serversTransports.mytransport.forwardingTimeouts]
|
||||||
|
responseHeaderTimeout = "1s"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
mytransport:
|
||||||
|
forwardingTimeouts:
|
||||||
|
responseHeaderTimeout: "1s"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
forwardingTimeouts:
|
||||||
|
responseHeaderTimeout: "1s"
|
||||||
|
```
|
||||||
|
|
||||||
|
##### `forwardingTimeouts.idleConnTimeout`
|
||||||
|
|
||||||
|
_Optional, Default=90s_
|
||||||
|
|
||||||
|
`idleConnTimeout`, is the maximum amount of time an idle (keep-alive) connection
|
||||||
|
will remain idle before closing itself.
|
||||||
|
Zero means no limit.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.serversTransports.mytransport.forwardingTimeouts]
|
||||||
|
idleConnTimeout = "1s"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
mytransport:
|
||||||
|
forwardingTimeouts:
|
||||||
|
idleConnTimeout: "1s"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
forwardingTimeouts:
|
||||||
|
idleConnTimeout: "1s"
|
||||||
|
```
|
||||||
|
|
||||||
### Weighted Round Robin (service)
|
### Weighted Round Robin (service)
|
||||||
|
|
||||||
The WRR is able to load balance the requests between multiple services based on weights.
|
The WRR is able to load balance the requests between multiple services based on weights.
|
||||||
|
|
|
@ -72,6 +72,21 @@ spec:
|
||||||
singular: tlsoption
|
singular: tlsoption
|
||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
name: serverstransports.traefik.containo.us
|
||||||
|
|
||||||
|
spec:
|
||||||
|
group: traefik.containo.us
|
||||||
|
version: v1alpha1
|
||||||
|
names:
|
||||||
|
kind: ServersTransport
|
||||||
|
plural: serverstransports
|
||||||
|
singular: serverstransport
|
||||||
|
scope: Namespaced
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1beta1
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: testst.route
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- web
|
||||||
|
routes:
|
||||||
|
- match: Host(`foo.com`) && PathPrefix(`/serverstransport`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: whoami
|
||||||
|
port: 80
|
||||||
|
serversTransport: mytransport
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: mytransport
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
serverName: "test"
|
||||||
|
insecureSkipVerify: true
|
|
@ -97,6 +97,10 @@ func (s *KeepAliveSuite) TestShouldRespectConfiguredBackendHttpKeepAliveTime(c *
|
||||||
c.Check(err, checker.IsNil)
|
c.Check(err, checker.IsNil)
|
||||||
defer cmd.Process.Kill()
|
defer cmd.Process.Kill()
|
||||||
|
|
||||||
|
// Wait for Traefik
|
||||||
|
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Duration(1)*time.Second, try.StatusCodeIs(200), try.BodyContains("PathPrefix(`/keepalive`)"))
|
||||||
|
c.Check(err, checker.IsNil)
|
||||||
|
|
||||||
err = try.GetRequest("http://127.0.0.1:8000/keepalive", time.Duration(1)*time.Second, try.StatusCodeIs(200))
|
err = try.GetRequest("http://127.0.0.1:8000/keepalive", time.Duration(1)*time.Second, try.StatusCodeIs(200))
|
||||||
c.Check(err, checker.IsNil)
|
c.Check(err, checker.IsNil)
|
||||||
|
|
||||||
|
|
61
integration/testdata/rawdata-crd.json
vendored
61
integration/testdata/rawdata-crd.json
vendored
|
@ -50,6 +50,17 @@
|
||||||
"using": [
|
"using": [
|
||||||
"web"
|
"web"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"default-testst-route-60ad45fcb5fc1f5f3629@kubernetescrd": {
|
||||||
|
"entryPoints": [
|
||||||
|
"web"
|
||||||
|
],
|
||||||
|
"service": "default-testst-route-60ad45fcb5fc1f5f3629",
|
||||||
|
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/serverstransport`)",
|
||||||
|
"status": "enabled",
|
||||||
|
"using": [
|
||||||
|
"web"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"middlewares": {
|
"middlewares": {
|
||||||
|
@ -98,10 +109,10 @@
|
||||||
"loadBalancer": {
|
"loadBalancer": {
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.2:80"
|
"url": "http://10.42.0.6:80"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.3:80"
|
"url": "http://10.42.0.7:80"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"passHostHeader": true
|
"passHostHeader": true
|
||||||
|
@ -111,18 +122,18 @@
|
||||||
"default-test-route-6b204d94623b3df4370c@kubernetescrd"
|
"default-test-route-6b204d94623b3df4370c@kubernetescrd"
|
||||||
],
|
],
|
||||||
"serverStatus": {
|
"serverStatus": {
|
||||||
"http://10.42.0.2:80": "UP",
|
"http://10.42.0.6:80": "UP",
|
||||||
"http://10.42.0.3:80": "UP"
|
"http://10.42.0.7:80": "UP"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"default-test2-route-23c7f4c450289ee29016@kubernetescrd": {
|
"default-test2-route-23c7f4c450289ee29016@kubernetescrd": {
|
||||||
"loadBalancer": {
|
"loadBalancer": {
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.2:80"
|
"url": "http://10.42.0.6:80"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.3:80"
|
"url": "http://10.42.0.7:80"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"passHostHeader": true
|
"passHostHeader": true
|
||||||
|
@ -132,26 +143,48 @@
|
||||||
"default-test2-route-23c7f4c450289ee29016@kubernetescrd"
|
"default-test2-route-23c7f4c450289ee29016@kubernetescrd"
|
||||||
],
|
],
|
||||||
"serverStatus": {
|
"serverStatus": {
|
||||||
"http://10.42.0.2:80": "UP",
|
"http://10.42.0.6:80": "UP",
|
||||||
"http://10.42.0.3:80": "UP"
|
"http://10.42.0.7:80": "UP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default-testst-route-60ad45fcb5fc1f5f3629@kubernetescrd": {
|
||||||
|
"loadBalancer": {
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "http://10.42.0.6:80"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://10.42.0.7:80"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"passHostHeader": true,
|
||||||
|
"serversTransport": "mytransport@kubernetescrd"
|
||||||
|
},
|
||||||
|
"status": "enabled",
|
||||||
|
"usedBy": [
|
||||||
|
"default-testst-route-60ad45fcb5fc1f5f3629@kubernetescrd"
|
||||||
|
],
|
||||||
|
"serverStatus": {
|
||||||
|
"http://10.42.0.6:80": "UP",
|
||||||
|
"http://10.42.0.7:80": "UP"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"default-whoami-80@kubernetescrd": {
|
"default-whoami-80@kubernetescrd": {
|
||||||
"loadBalancer": {
|
"loadBalancer": {
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.2:80"
|
"url": "http://10.42.0.6:80"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.3:80"
|
"url": "http://10.42.0.7:80"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"passHostHeader": true
|
"passHostHeader": true
|
||||||
},
|
},
|
||||||
"status": "enabled",
|
"status": "enabled",
|
||||||
"serverStatus": {
|
"serverStatus": {
|
||||||
"http://10.42.0.2:80": "UP",
|
"http://10.42.0.6:80": "UP",
|
||||||
"http://10.42.0.3:80": "UP"
|
"http://10.42.0.7:80": "UP"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"default-wrr1@kubernetescrd": {
|
"default-wrr1@kubernetescrd": {
|
||||||
|
@ -210,7 +243,7 @@
|
||||||
"terminationDelay": 100,
|
"terminationDelay": 100,
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"address": "10.42.0.3:8080"
|
"address": "10.42.0.10:8080"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "10.42.0.8:8080"
|
"address": "10.42.0.8:8080"
|
||||||
|
@ -255,7 +288,7 @@
|
||||||
"loadBalancer": {
|
"loadBalancer": {
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"address": "10.42.0.10:8090"
|
"address": "10.42.0.4:8090"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "10.42.0.9:8090"
|
"address": "10.42.0.9:8090"
|
||||||
|
|
8
integration/testdata/rawdata-ingress.json
vendored
8
integration/testdata/rawdata-ingress.json
vendored
|
@ -93,10 +93,10 @@
|
||||||
"loadBalancer": {
|
"loadBalancer": {
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.3:80"
|
"url": "http://10.42.0.10:80"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.5:80"
|
"url": "http://10.42.0.8:80"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"passHostHeader": true
|
"passHostHeader": true
|
||||||
|
@ -107,8 +107,8 @@
|
||||||
"test-ingress-https-default-whoami-test-https-whoami@kubernetes"
|
"test-ingress-https-default-whoami-test-https-whoami@kubernetes"
|
||||||
],
|
],
|
||||||
"serverStatus": {
|
"serverStatus": {
|
||||||
"http://10.42.0.3:80": "UP",
|
"http://10.42.0.10:80": "UP",
|
||||||
"http://10.42.0.5:80": "UP"
|
"http://10.42.0.8:80": "UP"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"noop@internal": {
|
"noop@internal": {
|
||||||
|
|
|
@ -2,18 +2,22 @@ package dynamic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/containous/traefik/v2/pkg/tls"
|
||||||
"github.com/containous/traefik/v2/pkg/types"
|
"github.com/containous/traefik/v2/pkg/types"
|
||||||
|
ptypes "github.com/traefik/paerser/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
// HTTPConfiguration contains all the HTTP configuration parameters.
|
// HTTPConfiguration contains all the HTTP configuration parameters.
|
||||||
type HTTPConfiguration struct {
|
type HTTPConfiguration struct {
|
||||||
Routers map[string]*Router `json:"routers,omitempty" toml:"routers,omitempty" yaml:"routers,omitempty"`
|
Routers map[string]*Router `json:"routers,omitempty" toml:"routers,omitempty" yaml:"routers,omitempty"`
|
||||||
Services map[string]*Service `json:"services,omitempty" toml:"services,omitempty" yaml:"services,omitempty"`
|
Services map[string]*Service `json:"services,omitempty" toml:"services,omitempty" yaml:"services,omitempty"`
|
||||||
Middlewares map[string]*Middleware `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty"`
|
Middlewares map[string]*Middleware `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty"`
|
||||||
Models map[string]*Model `json:"models,omitempty" toml:"models,omitempty" yaml:"models,omitempty"`
|
Models map[string]*Model `json:"models,omitempty" toml:"models,omitempty" yaml:"models,omitempty"`
|
||||||
|
ServersTransports map[string]*ServersTransport `json:"serversTransports,omitempty" toml:"serversTransports,omitempty" yaml:"serversTransports,omitempty" label:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
@ -125,6 +129,7 @@ type ServersLoadBalancer struct {
|
||||||
HealthCheck *HealthCheck `json:"healthCheck,omitempty" toml:"healthCheck,omitempty" yaml:"healthCheck,omitempty"`
|
HealthCheck *HealthCheck `json:"healthCheck,omitempty" toml:"healthCheck,omitempty" yaml:"healthCheck,omitempty"`
|
||||||
PassHostHeader *bool `json:"passHostHeader" toml:"passHostHeader" yaml:"passHostHeader"`
|
PassHostHeader *bool `json:"passHostHeader" toml:"passHostHeader" yaml:"passHostHeader"`
|
||||||
ResponseForwarding *ResponseForwarding `json:"responseForwarding,omitempty" toml:"responseForwarding,omitempty" yaml:"responseForwarding,omitempty"`
|
ResponseForwarding *ResponseForwarding `json:"responseForwarding,omitempty" toml:"responseForwarding,omitempty" yaml:"responseForwarding,omitempty"`
|
||||||
|
ServersTransport string `json:"serversTransport,omitempty" toml:"serversTransport,omitempty" yaml:"serversTransport,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mergeable tells if the given service is mergeable.
|
// Mergeable tells if the given service is mergeable.
|
||||||
|
@ -192,3 +197,30 @@ func (h *HealthCheck) SetDefaults() {
|
||||||
fr := true
|
fr := true
|
||||||
h.FollowRedirects = &fr
|
h.FollowRedirects = &fr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
|
// ServersTransport options to configure communication between Traefik and the servers.
|
||||||
|
type ServersTransport struct {
|
||||||
|
ServerName string `description:"ServerName used to contact the server" json:"serverName,omitempty" toml:"serverName,omitempty" yaml:"serverName,omitempty" export:"true"`
|
||||||
|
InsecureSkipVerify bool `description:"Disable SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"`
|
||||||
|
RootCAs []tls.FileOrContent `description:"Add cert file for self-signed certificate." json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"`
|
||||||
|
Certificates tls.Certificates `description:"Certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty"`
|
||||||
|
MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" json:"maxIdleConnsPerHost,omitempty" toml:"maxIdleConnsPerHost,omitempty" yaml:"maxIdleConnsPerHost,omitempty" export:"true"`
|
||||||
|
ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
|
// ForwardingTimeouts contains timeout configurations for forwarding requests to the backend servers.
|
||||||
|
type ForwardingTimeouts struct {
|
||||||
|
DialTimeout ptypes.Duration `description:"The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." json:"dialTimeout,omitempty" toml:"dialTimeout,omitempty" yaml:"dialTimeout,omitempty" export:"true"`
|
||||||
|
ResponseHeaderTimeout ptypes.Duration `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"`
|
||||||
|
IdleConnTimeout ptypes.Duration `description:"The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself" json:"idleConnTimeout,omitempty" toml:"idleConnTimeout,omitempty" yaml:"idleConnTimeout,omitempty" export:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaults sets the default values.
|
||||||
|
func (f *ForwardingTimeouts) SetDefaults() {
|
||||||
|
f.DialTimeout = ptypes.Duration(30 * time.Second)
|
||||||
|
f.IdleConnTimeout = ptypes.Duration(90 * time.Second)
|
||||||
|
}
|
||||||
|
|
|
@ -357,6 +357,22 @@ func (in *ForwardAuth) DeepCopy() *ForwardAuth {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ForwardingTimeouts) DeepCopyInto(out *ForwardingTimeouts) {
|
||||||
|
*out = *in
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ForwardingTimeouts.
|
||||||
|
func (in *ForwardingTimeouts) DeepCopy() *ForwardingTimeouts {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ForwardingTimeouts)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *HTTPConfiguration) DeepCopyInto(out *HTTPConfiguration) {
|
func (in *HTTPConfiguration) DeepCopyInto(out *HTTPConfiguration) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@ -420,6 +436,21 @@ func (in *HTTPConfiguration) DeepCopyInto(out *HTTPConfiguration) {
|
||||||
(*out)[key] = outVal
|
(*out)[key] = outVal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if in.ServersTransports != nil {
|
||||||
|
in, out := &in.ServersTransports, &out.ServersTransports
|
||||||
|
*out = make(map[string]*ServersTransport, len(*in))
|
||||||
|
for key, val := range *in {
|
||||||
|
var outVal *ServersTransport
|
||||||
|
if val == nil {
|
||||||
|
(*out)[key] = nil
|
||||||
|
} else {
|
||||||
|
in, out := &val, &outVal
|
||||||
|
*out = new(ServersTransport)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
(*out)[key] = outVal
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,6 +1121,37 @@ func (in *ServersLoadBalancer) DeepCopy() *ServersLoadBalancer {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ServersTransport) DeepCopyInto(out *ServersTransport) {
|
||||||
|
*out = *in
|
||||||
|
if in.RootCAs != nil {
|
||||||
|
in, out := &in.RootCAs, &out.RootCAs
|
||||||
|
*out = make([]tls.FileOrContent, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
if in.Certificates != nil {
|
||||||
|
in, out := &in.Certificates, &out.Certificates
|
||||||
|
*out = make(tls.Certificates, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
if in.ForwardingTimeouts != nil {
|
||||||
|
in, out := &in.ForwardingTimeouts, &out.ForwardingTimeouts
|
||||||
|
*out = new(ForwardingTimeouts)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransport.
|
||||||
|
func (in *ServersTransport) DeepCopy() *ServersTransport {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ServersTransport)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Service) DeepCopyInto(out *Service) {
|
func (in *Service) DeepCopyInto(out *Service) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|
|
@ -2,15 +2,16 @@ package log
|
||||||
|
|
||||||
// Log entry names.
|
// Log entry names.
|
||||||
const (
|
const (
|
||||||
EntryPointName = "entryPointName"
|
EntryPointName = "entryPointName"
|
||||||
RouterName = "routerName"
|
RouterName = "routerName"
|
||||||
Rule = "rule"
|
Rule = "rule"
|
||||||
MiddlewareName = "middlewareName"
|
MiddlewareName = "middlewareName"
|
||||||
MiddlewareType = "middlewareType"
|
MiddlewareType = "middlewareType"
|
||||||
ProviderName = "providerName"
|
ProviderName = "providerName"
|
||||||
ServiceName = "serviceName"
|
ServiceName = "serviceName"
|
||||||
MetricsProviderName = "metricsProviderName"
|
MetricsProviderName = "metricsProviderName"
|
||||||
TracingProviderName = "tracingProviderName"
|
TracingProviderName = "tracingProviderName"
|
||||||
ServerName = "serverName"
|
ServerName = "serverName"
|
||||||
TLSStoreName = "tlsStoreName"
|
TLSStoreName = "tlsStoreName"
|
||||||
|
ServersTransportName = "serversTransport"
|
||||||
)
|
)
|
||||||
|
|
|
@ -205,9 +205,10 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
|
||||||
if configuration == nil {
|
if configuration == nil {
|
||||||
configuration = &dynamic.Configuration{
|
configuration = &dynamic.Configuration{
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.Router),
|
Routers: make(map[string]*dynamic.Router),
|
||||||
Middlewares: make(map[string]*dynamic.Middleware),
|
Middlewares: make(map[string]*dynamic.Middleware),
|
||||||
Services: make(map[string]*dynamic.Service),
|
Services: make(map[string]*dynamic.Service),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.TCPRouter),
|
Routers: make(map[string]*dynamic.TCPRouter),
|
||||||
|
@ -274,6 +275,14 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for name, conf := range c.HTTP.ServersTransports {
|
||||||
|
if _, exists := configuration.HTTP.ServersTransports[name]; exists {
|
||||||
|
logger.WithField(log.ServersTransportName, name).Warn("HTTP servers transport already configured, skipping")
|
||||||
|
} else {
|
||||||
|
configuration.HTTP.ServersTransports[name] = conf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for name, conf := range c.TCP.Routers {
|
for name, conf := range c.TCP.Routers {
|
||||||
if _, exists := configuration.TCP.Routers[name]; exists {
|
if _, exists := configuration.TCP.Routers[name]; exists {
|
||||||
logger.WithField(log.RouterName, name).Warn("TCP router already configured, skipping")
|
logger.WithField(log.RouterName, name).Warn("TCP router already configured, skipping")
|
||||||
|
@ -398,9 +407,10 @@ func (p *Provider) DecodeConfiguration(filename string) (*dynamic.Configuration,
|
||||||
func (p *Provider) decodeConfiguration(filePath, content string) (*dynamic.Configuration, error) {
|
func (p *Provider) decodeConfiguration(filePath, content string) (*dynamic.Configuration, error) {
|
||||||
configuration := &dynamic.Configuration{
|
configuration := &dynamic.Configuration{
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.Router),
|
Routers: make(map[string]*dynamic.Router),
|
||||||
Middlewares: make(map[string]*dynamic.Middleware),
|
Middlewares: make(map[string]*dynamic.Middleware),
|
||||||
Services: make(map[string]*dynamic.Service),
|
Services: make(map[string]*dynamic.Service),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.TCPRouter),
|
Routers: make(map[string]*dynamic.TCPRouter),
|
||||||
|
|
|
@ -146,9 +146,10 @@ func (p *Provider) fetchConfigurationData() ([]byte, error) {
|
||||||
func decodeConfiguration(data []byte) (*dynamic.Configuration, error) {
|
func decodeConfiguration(data []byte) (*dynamic.Configuration, error) {
|
||||||
configuration := &dynamic.Configuration{
|
configuration := &dynamic.Configuration{
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.Router),
|
Routers: make(map[string]*dynamic.Router),
|
||||||
Middlewares: make(map[string]*dynamic.Middleware),
|
Middlewares: make(map[string]*dynamic.Middleware),
|
||||||
Services: make(map[string]*dynamic.Service),
|
Services: make(map[string]*dynamic.Service),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.TCPRouter),
|
Routers: make(map[string]*dynamic.TCPRouter),
|
||||||
|
|
|
@ -134,9 +134,10 @@ func TestProvider_decodeConfiguration(t *testing.T) {
|
||||||
configData: []byte("{\"tcp\":{\"routers\":{\"foo\":{}}}}"),
|
configData: []byte("{\"tcp\":{\"routers\":{\"foo\":{}}}}"),
|
||||||
expConfig: &dynamic.Configuration{
|
expConfig: &dynamic.Configuration{
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.Router),
|
Routers: make(map[string]*dynamic.Router),
|
||||||
Middlewares: make(map[string]*dynamic.Middleware),
|
Middlewares: make(map[string]*dynamic.Middleware),
|
||||||
Services: make(map[string]*dynamic.Service),
|
Services: make(map[string]*dynamic.Service),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
Routers: map[string]*dynamic.TCPRouter{
|
||||||
|
@ -192,9 +193,10 @@ func TestProvider_Provide(t *testing.T) {
|
||||||
|
|
||||||
expConfiguration := &dynamic.Configuration{
|
expConfiguration := &dynamic.Configuration{
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.Router),
|
Routers: make(map[string]*dynamic.Router),
|
||||||
Middlewares: make(map[string]*dynamic.Middleware),
|
Middlewares: make(map[string]*dynamic.Middleware),
|
||||||
Services: make(map[string]*dynamic.Service),
|
Services: make(map[string]*dynamic.Service),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.TCPRouter),
|
Routers: make(map[string]*dynamic.TCPRouter),
|
||||||
|
|
|
@ -52,6 +52,7 @@ type Client interface {
|
||||||
GetTraefikService(namespace, name string) (*v1alpha1.TraefikService, bool, error)
|
GetTraefikService(namespace, name string) (*v1alpha1.TraefikService, bool, error)
|
||||||
GetTraefikServices() []*v1alpha1.TraefikService
|
GetTraefikServices() []*v1alpha1.TraefikService
|
||||||
GetTLSOptions() []*v1alpha1.TLSOption
|
GetTLSOptions() []*v1alpha1.TLSOption
|
||||||
|
GetServersTransports() []*v1alpha1.ServersTransport
|
||||||
GetTLSStores() []*v1alpha1.TLSStore
|
GetTLSStores() []*v1alpha1.TLSStore
|
||||||
|
|
||||||
GetService(namespace, name string) (*corev1.Service, bool, error)
|
GetService(namespace, name string) (*corev1.Service, bool, error)
|
||||||
|
@ -162,6 +163,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
|
||||||
factoryCrd.Traefik().V1alpha1().IngressRouteTCPs().Informer().AddEventHandler(eventHandler)
|
factoryCrd.Traefik().V1alpha1().IngressRouteTCPs().Informer().AddEventHandler(eventHandler)
|
||||||
factoryCrd.Traefik().V1alpha1().IngressRouteUDPs().Informer().AddEventHandler(eventHandler)
|
factoryCrd.Traefik().V1alpha1().IngressRouteUDPs().Informer().AddEventHandler(eventHandler)
|
||||||
factoryCrd.Traefik().V1alpha1().TLSOptions().Informer().AddEventHandler(eventHandler)
|
factoryCrd.Traefik().V1alpha1().TLSOptions().Informer().AddEventHandler(eventHandler)
|
||||||
|
factoryCrd.Traefik().V1alpha1().ServersTransports().Informer().AddEventHandler(eventHandler)
|
||||||
factoryCrd.Traefik().V1alpha1().TLSStores().Informer().AddEventHandler(eventHandler)
|
factoryCrd.Traefik().V1alpha1().TLSStores().Informer().AddEventHandler(eventHandler)
|
||||||
factoryCrd.Traefik().V1alpha1().TraefikServices().Informer().AddEventHandler(eventHandler)
|
factoryCrd.Traefik().V1alpha1().TraefikServices().Informer().AddEventHandler(eventHandler)
|
||||||
|
|
||||||
|
@ -279,6 +281,21 @@ func (c *clientWrapper) GetTraefikServices() []*v1alpha1.TraefikService {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetServersTransport returns all ServersTransport.
|
||||||
|
func (c *clientWrapper) GetServersTransports() []*v1alpha1.ServersTransport {
|
||||||
|
var result []*v1alpha1.ServersTransport
|
||||||
|
|
||||||
|
for ns, factory := range c.factoriesCrd {
|
||||||
|
serversTransports, err := factory.Traefik().V1alpha1().ServersTransports().Lister().List(c.labelSelector)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to list servers transport in namespace %s: %v", ns, err)
|
||||||
|
}
|
||||||
|
result = append(result, serversTransports...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// GetTLSOptions returns all TLS options.
|
// GetTLSOptions returns all TLS options.
|
||||||
func (c *clientWrapper) GetTLSOptions() []*v1alpha1.TLSOption {
|
func (c *clientWrapper) GetTLSOptions() []*v1alpha1.TLSOption {
|
||||||
var result []*v1alpha1.TLSOption
|
var result []*v1alpha1.TLSOption
|
||||||
|
|
|
@ -37,6 +37,7 @@ type clientMock struct {
|
||||||
tlsOptions []*v1alpha1.TLSOption
|
tlsOptions []*v1alpha1.TLSOption
|
||||||
tlsStores []*v1alpha1.TLSStore
|
tlsStores []*v1alpha1.TLSStore
|
||||||
traefikServices []*v1alpha1.TraefikService
|
traefikServices []*v1alpha1.TraefikService
|
||||||
|
serversTransport []*v1alpha1.ServersTransport
|
||||||
|
|
||||||
watchChan chan interface{}
|
watchChan chan interface{}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +70,8 @@ func newClientMock(paths ...string) clientMock {
|
||||||
c.traefikServices = append(c.traefikServices, o)
|
c.traefikServices = append(c.traefikServices, o)
|
||||||
case *v1alpha1.TLSOption:
|
case *v1alpha1.TLSOption:
|
||||||
c.tlsOptions = append(c.tlsOptions, o)
|
c.tlsOptions = append(c.tlsOptions, o)
|
||||||
|
case *v1alpha1.ServersTransport:
|
||||||
|
c.serversTransport = append(c.serversTransport, o)
|
||||||
case *v1alpha1.TLSStore:
|
case *v1alpha1.TLSStore:
|
||||||
c.tlsStores = append(c.tlsStores, o)
|
c.tlsStores = append(c.tlsStores, o)
|
||||||
case *corev1.Secret:
|
case *corev1.Secret:
|
||||||
|
@ -120,6 +123,10 @@ func (c clientMock) GetTLSStores() []*v1alpha1.TLSStore {
|
||||||
return c.tlsStores
|
return c.tlsStores
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c clientMock) GetServersTransports() []*v1alpha1.ServersTransport {
|
||||||
|
return c.serversTransport
|
||||||
|
}
|
||||||
|
|
||||||
func (c clientMock) GetTLSOption(namespace, name string) (*v1alpha1.TLSOption, bool, error) {
|
func (c clientMock) GetTLSOption(namespace, name string) (*v1alpha1.TLSOption, bool, error) {
|
||||||
for _, option := range c.tlsOptions {
|
for _, option := range c.tlsOptions {
|
||||||
if option.Namespace == namespace && option.Name == name {
|
if option.Namespace == namespace && option.Name == name {
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: rootCas1
|
||||||
|
namespace: foo
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.ca: VEVTVFJPT1RDQVM=
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: rootCas2
|
||||||
|
namespace: foo
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.ca: VEVTVFJPT1RDQVMy
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: mtls1
|
||||||
|
namespace: foo
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.crt: VEVTVENFUlQx
|
||||||
|
tls.key: VEVTVEtFWTE=
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: mtls2
|
||||||
|
namespace: foo
|
||||||
|
|
||||||
|
data:
|
||||||
|
tls.crt: VEVTVENFUlQy
|
||||||
|
tls.key: VEVTVEtFWTI=
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: ServersTransport
|
||||||
|
metadata:
|
||||||
|
name: test
|
||||||
|
namespace: foo
|
||||||
|
|
||||||
|
spec:
|
||||||
|
serverName: "test"
|
||||||
|
insecureSkipVerify: true
|
||||||
|
maxIdleConnsPerHost: 42
|
||||||
|
rootCAsSecrets:
|
||||||
|
- rootCas1
|
||||||
|
- rootCas2
|
||||||
|
certificatesSecrets:
|
||||||
|
- mtls1
|
||||||
|
- mtls2
|
||||||
|
forwardingTimeouts:
|
||||||
|
dialTimeout: 42
|
||||||
|
responseHeaderTimeout: 42s
|
||||||
|
idleConnTimeout: 42ms
|
|
@ -35,14 +35,12 @@ import (
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var scheme = runtime.NewScheme()
|
||||||
scheme = runtime.NewScheme()
|
var codecs = serializer.NewCodecFactory(scheme)
|
||||||
codecs = serializer.NewCodecFactory(scheme)
|
var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||||
parameterCodec = runtime.NewParameterCodec(scheme)
|
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||||
localSchemeBuilder = runtime.SchemeBuilder{
|
traefikv1alpha1.AddToScheme,
|
||||||
traefikv1alpha1.AddToScheme,
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||||
// of clientsets, like in:
|
// of clientsets, like in:
|
||||||
|
|
|
@ -35,14 +35,12 @@ import (
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var Scheme = runtime.NewScheme()
|
||||||
Scheme = runtime.NewScheme()
|
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||||
Codecs = serializer.NewCodecFactory(Scheme)
|
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||||
ParameterCodec = runtime.NewParameterCodec(Scheme)
|
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||||
localSchemeBuilder = runtime.SchemeBuilder{
|
traefikv1alpha1.AddToScheme,
|
||||||
traefikv1alpha1.AddToScheme,
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||||
// of clientsets, like in:
|
// of clientsets, like in:
|
||||||
|
|
|
@ -85,6 +85,7 @@ func (c *FakeIngressRoutes) List(ctx context.Context, opts v1.ListOptions) (resu
|
||||||
func (c *FakeIngressRoutes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
func (c *FakeIngressRoutes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
return c.Fake.
|
return c.Fake.
|
||||||
InvokesWatch(testing.NewWatchAction(ingressroutesResource, c.ns, opts))
|
InvokesWatch(testing.NewWatchAction(ingressroutesResource, c.ns, opts))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create takes the representation of a ingressRoute and creates it. Returns the server's representation of the ingressRoute, and an error, if there is any.
|
// Create takes the representation of a ingressRoute and creates it. Returns the server's representation of the ingressRoute, and an error, if there is any.
|
||||||
|
|
|
@ -85,6 +85,7 @@ func (c *FakeIngressRouteTCPs) List(ctx context.Context, opts v1.ListOptions) (r
|
||||||
func (c *FakeIngressRouteTCPs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
func (c *FakeIngressRouteTCPs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
return c.Fake.
|
return c.Fake.
|
||||||
InvokesWatch(testing.NewWatchAction(ingressroutetcpsResource, c.ns, opts))
|
InvokesWatch(testing.NewWatchAction(ingressroutetcpsResource, c.ns, opts))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create takes the representation of a ingressRouteTCP and creates it. Returns the server's representation of the ingressRouteTCP, and an error, if there is any.
|
// Create takes the representation of a ingressRouteTCP and creates it. Returns the server's representation of the ingressRouteTCP, and an error, if there is any.
|
||||||
|
|
|
@ -85,6 +85,7 @@ func (c *FakeIngressRouteUDPs) List(ctx context.Context, opts v1.ListOptions) (r
|
||||||
func (c *FakeIngressRouteUDPs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
func (c *FakeIngressRouteUDPs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
return c.Fake.
|
return c.Fake.
|
||||||
InvokesWatch(testing.NewWatchAction(ingressrouteudpsResource, c.ns, opts))
|
InvokesWatch(testing.NewWatchAction(ingressrouteudpsResource, c.ns, opts))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create takes the representation of a ingressRouteUDP and creates it. Returns the server's representation of the ingressRouteUDP, and an error, if there is any.
|
// Create takes the representation of a ingressRouteUDP and creates it. Returns the server's representation of the ingressRouteUDP, and an error, if there is any.
|
||||||
|
|
|
@ -85,6 +85,7 @@ func (c *FakeMiddlewares) List(ctx context.Context, opts v1.ListOptions) (result
|
||||||
func (c *FakeMiddlewares) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
func (c *FakeMiddlewares) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
return c.Fake.
|
return c.Fake.
|
||||||
InvokesWatch(testing.NewWatchAction(middlewaresResource, c.ns, opts))
|
InvokesWatch(testing.NewWatchAction(middlewaresResource, c.ns, opts))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create takes the representation of a middleware and creates it. Returns the server's representation of the middleware, and an error, if there is any.
|
// Create takes the representation of a middleware and creates it. Returns the server's representation of the middleware, and an error, if there is any.
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016-2020 Containous SAS
|
||||||
|
|
||||||
|
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 client-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package fake
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
v1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
||||||
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
|
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
|
testing "k8s.io/client-go/testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FakeServersTransports implements ServersTransportInterface
|
||||||
|
type FakeServersTransports struct {
|
||||||
|
Fake *FakeTraefikV1alpha1
|
||||||
|
ns string
|
||||||
|
}
|
||||||
|
|
||||||
|
var serverstransportsResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "serverstransports"}
|
||||||
|
|
||||||
|
var serverstransportsKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "ServersTransport"}
|
||||||
|
|
||||||
|
// Get takes name of the serversTransport, and returns the corresponding serversTransport object, and an error if there is any.
|
||||||
|
func (c *FakeServersTransports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
obj, err := c.Fake.
|
||||||
|
Invokes(testing.NewGetAction(serverstransportsResource, c.ns, name), &v1alpha1.ServersTransport{})
|
||||||
|
|
||||||
|
if obj == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return obj.(*v1alpha1.ServersTransport), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List takes label and field selectors, and returns the list of ServersTransports that match those selectors.
|
||||||
|
func (c *FakeServersTransports) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ServersTransportList, err error) {
|
||||||
|
obj, err := c.Fake.
|
||||||
|
Invokes(testing.NewListAction(serverstransportsResource, serverstransportsKind, c.ns, opts), &v1alpha1.ServersTransportList{})
|
||||||
|
|
||||||
|
if obj == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||||
|
if label == nil {
|
||||||
|
label = labels.Everything()
|
||||||
|
}
|
||||||
|
list := &v1alpha1.ServersTransportList{ListMeta: obj.(*v1alpha1.ServersTransportList).ListMeta}
|
||||||
|
for _, item := range obj.(*v1alpha1.ServersTransportList).Items {
|
||||||
|
if label.Matches(labels.Set(item.Labels)) {
|
||||||
|
list.Items = append(list.Items, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch returns a watch.Interface that watches the requested serversTransports.
|
||||||
|
func (c *FakeServersTransports) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
|
return c.Fake.
|
||||||
|
InvokesWatch(testing.NewWatchAction(serverstransportsResource, c.ns, opts))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create takes the representation of a serversTransport and creates it. Returns the server's representation of the serversTransport, and an error, if there is any.
|
||||||
|
func (c *FakeServersTransports) Create(ctx context.Context, serversTransport *v1alpha1.ServersTransport, opts v1.CreateOptions) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
obj, err := c.Fake.
|
||||||
|
Invokes(testing.NewCreateAction(serverstransportsResource, c.ns, serversTransport), &v1alpha1.ServersTransport{})
|
||||||
|
|
||||||
|
if obj == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return obj.(*v1alpha1.ServersTransport), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update takes the representation of a serversTransport and updates it. Returns the server's representation of the serversTransport, and an error, if there is any.
|
||||||
|
func (c *FakeServersTransports) Update(ctx context.Context, serversTransport *v1alpha1.ServersTransport, opts v1.UpdateOptions) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
obj, err := c.Fake.
|
||||||
|
Invokes(testing.NewUpdateAction(serverstransportsResource, c.ns, serversTransport), &v1alpha1.ServersTransport{})
|
||||||
|
|
||||||
|
if obj == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return obj.(*v1alpha1.ServersTransport), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete takes name of the serversTransport and deletes it. Returns an error if one occurs.
|
||||||
|
func (c *FakeServersTransports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
|
_, err := c.Fake.
|
||||||
|
Invokes(testing.NewDeleteAction(serverstransportsResource, c.ns, name), &v1alpha1.ServersTransport{})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteCollection deletes a collection of objects.
|
||||||
|
func (c *FakeServersTransports) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||||
|
action := testing.NewDeleteCollectionAction(serverstransportsResource, c.ns, listOpts)
|
||||||
|
|
||||||
|
_, err := c.Fake.Invokes(action, &v1alpha1.ServersTransportList{})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch applies the patch and returns the patched serversTransport.
|
||||||
|
func (c *FakeServersTransports) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
obj, err := c.Fake.
|
||||||
|
Invokes(testing.NewPatchSubresourceAction(serverstransportsResource, c.ns, name, pt, data, subresources...), &v1alpha1.ServersTransport{})
|
||||||
|
|
||||||
|
if obj == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return obj.(*v1alpha1.ServersTransport), err
|
||||||
|
}
|
|
@ -85,6 +85,7 @@ func (c *FakeTLSOptions) List(ctx context.Context, opts v1.ListOptions) (result
|
||||||
func (c *FakeTLSOptions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
func (c *FakeTLSOptions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
return c.Fake.
|
return c.Fake.
|
||||||
InvokesWatch(testing.NewWatchAction(tlsoptionsResource, c.ns, opts))
|
InvokesWatch(testing.NewWatchAction(tlsoptionsResource, c.ns, opts))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create takes the representation of a tLSOption and creates it. Returns the server's representation of the tLSOption, and an error, if there is any.
|
// Create takes the representation of a tLSOption and creates it. Returns the server's representation of the tLSOption, and an error, if there is any.
|
||||||
|
|
|
@ -85,6 +85,7 @@ func (c *FakeTLSStores) List(ctx context.Context, opts v1.ListOptions) (result *
|
||||||
func (c *FakeTLSStores) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
func (c *FakeTLSStores) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
return c.Fake.
|
return c.Fake.
|
||||||
InvokesWatch(testing.NewWatchAction(tlsstoresResource, c.ns, opts))
|
InvokesWatch(testing.NewWatchAction(tlsstoresResource, c.ns, opts))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create takes the representation of a tLSStore and creates it. Returns the server's representation of the tLSStore, and an error, if there is any.
|
// Create takes the representation of a tLSStore and creates it. Returns the server's representation of the tLSStore, and an error, if there is any.
|
||||||
|
|
|
@ -52,6 +52,10 @@ func (c *FakeTraefikV1alpha1) Middlewares(namespace string) v1alpha1.MiddlewareI
|
||||||
return &FakeMiddlewares{c, namespace}
|
return &FakeMiddlewares{c, namespace}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FakeTraefikV1alpha1) ServersTransports(namespace string) v1alpha1.ServersTransportInterface {
|
||||||
|
return &FakeServersTransports{c, namespace}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FakeTraefikV1alpha1) TLSOptions(namespace string) v1alpha1.TLSOptionInterface {
|
func (c *FakeTraefikV1alpha1) TLSOptions(namespace string) v1alpha1.TLSOptionInterface {
|
||||||
return &FakeTLSOptions{c, namespace}
|
return &FakeTLSOptions{c, namespace}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ func (c *FakeTraefikServices) List(ctx context.Context, opts v1.ListOptions) (re
|
||||||
func (c *FakeTraefikServices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
func (c *FakeTraefikServices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
return c.Fake.
|
return c.Fake.
|
||||||
InvokesWatch(testing.NewWatchAction(traefikservicesResource, c.ns, opts))
|
InvokesWatch(testing.NewWatchAction(traefikservicesResource, c.ns, opts))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create takes the representation of a traefikService and creates it. Returns the server's representation of the traefikService, and an error, if there is any.
|
// Create takes the representation of a traefikService and creates it. Returns the server's representation of the traefikService, and an error, if there is any.
|
||||||
|
|
|
@ -34,6 +34,8 @@ type IngressRouteUDPExpansion interface{}
|
||||||
|
|
||||||
type MiddlewareExpansion interface{}
|
type MiddlewareExpansion interface{}
|
||||||
|
|
||||||
|
type ServersTransportExpansion interface{}
|
||||||
|
|
||||||
type TLSOptionExpansion interface{}
|
type TLSOptionExpansion interface{}
|
||||||
|
|
||||||
type TLSStoreExpansion interface{}
|
type TLSStoreExpansion interface{}
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016-2020 Containous SAS
|
||||||
|
|
||||||
|
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 client-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
scheme "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme"
|
||||||
|
v1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
||||||
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
|
rest "k8s.io/client-go/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ServersTransportsGetter has a method to return a ServersTransportInterface.
|
||||||
|
// A group's client should implement this interface.
|
||||||
|
type ServersTransportsGetter interface {
|
||||||
|
ServersTransports(namespace string) ServersTransportInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServersTransportInterface has methods to work with ServersTransport resources.
|
||||||
|
type ServersTransportInterface interface {
|
||||||
|
Create(ctx context.Context, serversTransport *v1alpha1.ServersTransport, opts v1.CreateOptions) (*v1alpha1.ServersTransport, error)
|
||||||
|
Update(ctx context.Context, serversTransport *v1alpha1.ServersTransport, opts v1.UpdateOptions) (*v1alpha1.ServersTransport, error)
|
||||||
|
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||||
|
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||||
|
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ServersTransport, error)
|
||||||
|
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ServersTransportList, error)
|
||||||
|
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||||
|
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ServersTransport, err error)
|
||||||
|
ServersTransportExpansion
|
||||||
|
}
|
||||||
|
|
||||||
|
// serversTransports implements ServersTransportInterface
|
||||||
|
type serversTransports struct {
|
||||||
|
client rest.Interface
|
||||||
|
ns string
|
||||||
|
}
|
||||||
|
|
||||||
|
// newServersTransports returns a ServersTransports
|
||||||
|
func newServersTransports(c *TraefikV1alpha1Client, namespace string) *serversTransports {
|
||||||
|
return &serversTransports{
|
||||||
|
client: c.RESTClient(),
|
||||||
|
ns: namespace,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get takes name of the serversTransport, and returns the corresponding serversTransport object, and an error if there is any.
|
||||||
|
func (c *serversTransports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
result = &v1alpha1.ServersTransport{}
|
||||||
|
err = c.client.Get().
|
||||||
|
Namespace(c.ns).
|
||||||
|
Resource("serverstransports").
|
||||||
|
Name(name).
|
||||||
|
VersionedParams(&options, scheme.ParameterCodec).
|
||||||
|
Do(ctx).
|
||||||
|
Into(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// List takes label and field selectors, and returns the list of ServersTransports that match those selectors.
|
||||||
|
func (c *serversTransports) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ServersTransportList, err error) {
|
||||||
|
var timeout time.Duration
|
||||||
|
if opts.TimeoutSeconds != nil {
|
||||||
|
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||||
|
}
|
||||||
|
result = &v1alpha1.ServersTransportList{}
|
||||||
|
err = c.client.Get().
|
||||||
|
Namespace(c.ns).
|
||||||
|
Resource("serverstransports").
|
||||||
|
VersionedParams(&opts, scheme.ParameterCodec).
|
||||||
|
Timeout(timeout).
|
||||||
|
Do(ctx).
|
||||||
|
Into(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch returns a watch.Interface that watches the requested serversTransports.
|
||||||
|
func (c *serversTransports) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||||
|
var timeout time.Duration
|
||||||
|
if opts.TimeoutSeconds != nil {
|
||||||
|
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||||
|
}
|
||||||
|
opts.Watch = true
|
||||||
|
return c.client.Get().
|
||||||
|
Namespace(c.ns).
|
||||||
|
Resource("serverstransports").
|
||||||
|
VersionedParams(&opts, scheme.ParameterCodec).
|
||||||
|
Timeout(timeout).
|
||||||
|
Watch(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create takes the representation of a serversTransport and creates it. Returns the server's representation of the serversTransport, and an error, if there is any.
|
||||||
|
func (c *serversTransports) Create(ctx context.Context, serversTransport *v1alpha1.ServersTransport, opts v1.CreateOptions) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
result = &v1alpha1.ServersTransport{}
|
||||||
|
err = c.client.Post().
|
||||||
|
Namespace(c.ns).
|
||||||
|
Resource("serverstransports").
|
||||||
|
VersionedParams(&opts, scheme.ParameterCodec).
|
||||||
|
Body(serversTransport).
|
||||||
|
Do(ctx).
|
||||||
|
Into(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update takes the representation of a serversTransport and updates it. Returns the server's representation of the serversTransport, and an error, if there is any.
|
||||||
|
func (c *serversTransports) Update(ctx context.Context, serversTransport *v1alpha1.ServersTransport, opts v1.UpdateOptions) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
result = &v1alpha1.ServersTransport{}
|
||||||
|
err = c.client.Put().
|
||||||
|
Namespace(c.ns).
|
||||||
|
Resource("serverstransports").
|
||||||
|
Name(serversTransport.Name).
|
||||||
|
VersionedParams(&opts, scheme.ParameterCodec).
|
||||||
|
Body(serversTransport).
|
||||||
|
Do(ctx).
|
||||||
|
Into(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete takes name of the serversTransport and deletes it. Returns an error if one occurs.
|
||||||
|
func (c *serversTransports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
|
return c.client.Delete().
|
||||||
|
Namespace(c.ns).
|
||||||
|
Resource("serverstransports").
|
||||||
|
Name(name).
|
||||||
|
Body(&opts).
|
||||||
|
Do(ctx).
|
||||||
|
Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteCollection deletes a collection of objects.
|
||||||
|
func (c *serversTransports) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||||
|
var timeout time.Duration
|
||||||
|
if listOpts.TimeoutSeconds != nil {
|
||||||
|
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||||
|
}
|
||||||
|
return c.client.Delete().
|
||||||
|
Namespace(c.ns).
|
||||||
|
Resource("serverstransports").
|
||||||
|
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||||
|
Timeout(timeout).
|
||||||
|
Body(&opts).
|
||||||
|
Do(ctx).
|
||||||
|
Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch applies the patch and returns the patched serversTransport.
|
||||||
|
func (c *serversTransports) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
result = &v1alpha1.ServersTransport{}
|
||||||
|
err = c.client.Patch(pt).
|
||||||
|
Namespace(c.ns).
|
||||||
|
Resource("serverstransports").
|
||||||
|
Name(name).
|
||||||
|
SubResource(subresources...).
|
||||||
|
VersionedParams(&opts, scheme.ParameterCodec).
|
||||||
|
Body(data).
|
||||||
|
Do(ctx).
|
||||||
|
Into(result)
|
||||||
|
return
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ type TraefikV1alpha1Interface interface {
|
||||||
IngressRouteTCPsGetter
|
IngressRouteTCPsGetter
|
||||||
IngressRouteUDPsGetter
|
IngressRouteUDPsGetter
|
||||||
MiddlewaresGetter
|
MiddlewaresGetter
|
||||||
|
ServersTransportsGetter
|
||||||
TLSOptionsGetter
|
TLSOptionsGetter
|
||||||
TLSStoresGetter
|
TLSStoresGetter
|
||||||
TraefikServicesGetter
|
TraefikServicesGetter
|
||||||
|
@ -64,6 +65,10 @@ func (c *TraefikV1alpha1Client) Middlewares(namespace string) MiddlewareInterfac
|
||||||
return newMiddlewares(c, namespace)
|
return newMiddlewares(c, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *TraefikV1alpha1Client) ServersTransports(namespace string) ServersTransportInterface {
|
||||||
|
return newServersTransports(c, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *TraefikV1alpha1Client) TLSOptions(namespace string) TLSOptionInterface {
|
func (c *TraefikV1alpha1Client) TLSOptions(namespace string) TLSOptionInterface {
|
||||||
return newTLSOptions(c, namespace)
|
return newTLSOptions(c, namespace)
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().IngressRouteUDPs().Informer()}, nil
|
return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().IngressRouteUDPs().Informer()}, nil
|
||||||
case v1alpha1.SchemeGroupVersion.WithResource("middlewares"):
|
case v1alpha1.SchemeGroupVersion.WithResource("middlewares"):
|
||||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().Middlewares().Informer()}, nil
|
return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().Middlewares().Informer()}, nil
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithResource("serverstransports"):
|
||||||
|
return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().ServersTransports().Informer()}, nil
|
||||||
case v1alpha1.SchemeGroupVersion.WithResource("tlsoptions"):
|
case v1alpha1.SchemeGroupVersion.WithResource("tlsoptions"):
|
||||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().TLSOptions().Informer()}, nil
|
return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().TLSOptions().Informer()}, nil
|
||||||
case v1alpha1.SchemeGroupVersion.WithResource("tlsstores"):
|
case v1alpha1.SchemeGroupVersion.WithResource("tlsstores"):
|
||||||
|
|
|
@ -40,6 +40,8 @@ type Interface interface {
|
||||||
IngressRouteUDPs() IngressRouteUDPInformer
|
IngressRouteUDPs() IngressRouteUDPInformer
|
||||||
// Middlewares returns a MiddlewareInformer.
|
// Middlewares returns a MiddlewareInformer.
|
||||||
Middlewares() MiddlewareInformer
|
Middlewares() MiddlewareInformer
|
||||||
|
// ServersTransports returns a ServersTransportInformer.
|
||||||
|
ServersTransports() ServersTransportInformer
|
||||||
// TLSOptions returns a TLSOptionInformer.
|
// TLSOptions returns a TLSOptionInformer.
|
||||||
TLSOptions() TLSOptionInformer
|
TLSOptions() TLSOptionInformer
|
||||||
// TLSStores returns a TLSStoreInformer.
|
// TLSStores returns a TLSStoreInformer.
|
||||||
|
@ -79,6 +81,11 @@ func (v *version) Middlewares() MiddlewareInformer {
|
||||||
return &middlewareInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
return &middlewareInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServersTransports returns a ServersTransportInformer.
|
||||||
|
func (v *version) ServersTransports() ServersTransportInformer {
|
||||||
|
return &serversTransportInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||||
|
}
|
||||||
|
|
||||||
// TLSOptions returns a TLSOptionInformer.
|
// TLSOptions returns a TLSOptionInformer.
|
||||||
func (v *version) TLSOptions() TLSOptionInformer {
|
func (v *version) TLSOptions() TLSOptionInformer {
|
||||||
return &tLSOptionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
return &tLSOptionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016-2020 Containous SAS
|
||||||
|
|
||||||
|
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 informer-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
time "time"
|
||||||
|
|
||||||
|
versioned "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned"
|
||||||
|
internalinterfaces "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces"
|
||||||
|
v1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1"
|
||||||
|
traefikv1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
||||||
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
|
cache "k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ServersTransportInformer provides access to a shared informer and lister for
|
||||||
|
// ServersTransports.
|
||||||
|
type ServersTransportInformer interface {
|
||||||
|
Informer() cache.SharedIndexInformer
|
||||||
|
Lister() v1alpha1.ServersTransportLister
|
||||||
|
}
|
||||||
|
|
||||||
|
type serversTransportInformer struct {
|
||||||
|
factory internalinterfaces.SharedInformerFactory
|
||||||
|
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||||
|
namespace string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServersTransportInformer constructs a new informer for ServersTransport type.
|
||||||
|
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||||
|
// one. This reduces memory footprint and number of connections to the server.
|
||||||
|
func NewServersTransportInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||||
|
return NewFilteredServersTransportInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFilteredServersTransportInformer constructs a new informer for ServersTransport type.
|
||||||
|
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||||
|
// one. This reduces memory footprint and number of connections to the server.
|
||||||
|
func NewFilteredServersTransportInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||||
|
return cache.NewSharedIndexInformer(
|
||||||
|
&cache.ListWatch{
|
||||||
|
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||||
|
if tweakListOptions != nil {
|
||||||
|
tweakListOptions(&options)
|
||||||
|
}
|
||||||
|
return client.TraefikV1alpha1().ServersTransports(namespace).List(context.TODO(), options)
|
||||||
|
},
|
||||||
|
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||||
|
if tweakListOptions != nil {
|
||||||
|
tweakListOptions(&options)
|
||||||
|
}
|
||||||
|
return client.TraefikV1alpha1().ServersTransports(namespace).Watch(context.TODO(), options)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&traefikv1alpha1.ServersTransport{},
|
||||||
|
resyncPeriod,
|
||||||
|
indexers,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *serversTransportInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||||
|
return NewFilteredServersTransportInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *serversTransportInformer) Informer() cache.SharedIndexInformer {
|
||||||
|
return f.factory.InformerFor(&traefikv1alpha1.ServersTransport{}, f.defaultInformer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *serversTransportInformer) Lister() v1alpha1.ServersTransportLister {
|
||||||
|
return v1alpha1.NewServersTransportLister(f.Informer().GetIndexer())
|
||||||
|
}
|
|
@ -58,6 +58,14 @@ type MiddlewareListerExpansion interface{}
|
||||||
// MiddlewareNamespaceLister.
|
// MiddlewareNamespaceLister.
|
||||||
type MiddlewareNamespaceListerExpansion interface{}
|
type MiddlewareNamespaceListerExpansion interface{}
|
||||||
|
|
||||||
|
// ServersTransportListerExpansion allows custom methods to be added to
|
||||||
|
// ServersTransportLister.
|
||||||
|
type ServersTransportListerExpansion interface{}
|
||||||
|
|
||||||
|
// ServersTransportNamespaceListerExpansion allows custom methods to be added to
|
||||||
|
// ServersTransportNamespaceLister.
|
||||||
|
type ServersTransportNamespaceListerExpansion interface{}
|
||||||
|
|
||||||
// TLSOptionListerExpansion allows custom methods to be added to
|
// TLSOptionListerExpansion allows custom methods to be added to
|
||||||
// TLSOptionLister.
|
// TLSOptionLister.
|
||||||
type TLSOptionListerExpansion interface{}
|
type TLSOptionListerExpansion interface{}
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016-2020 Containous SAS
|
||||||
|
|
||||||
|
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 lister-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ServersTransportLister helps list ServersTransports.
|
||||||
|
type ServersTransportLister interface {
|
||||||
|
// List lists all ServersTransports in the indexer.
|
||||||
|
List(selector labels.Selector) (ret []*v1alpha1.ServersTransport, err error)
|
||||||
|
// ServersTransports returns an object that can list and get ServersTransports.
|
||||||
|
ServersTransports(namespace string) ServersTransportNamespaceLister
|
||||||
|
ServersTransportListerExpansion
|
||||||
|
}
|
||||||
|
|
||||||
|
// serversTransportLister implements the ServersTransportLister interface.
|
||||||
|
type serversTransportLister struct {
|
||||||
|
indexer cache.Indexer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServersTransportLister returns a new ServersTransportLister.
|
||||||
|
func NewServersTransportLister(indexer cache.Indexer) ServersTransportLister {
|
||||||
|
return &serversTransportLister{indexer: indexer}
|
||||||
|
}
|
||||||
|
|
||||||
|
// List lists all ServersTransports in the indexer.
|
||||||
|
func (s *serversTransportLister) List(selector labels.Selector) (ret []*v1alpha1.ServersTransport, err error) {
|
||||||
|
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||||
|
ret = append(ret, m.(*v1alpha1.ServersTransport))
|
||||||
|
})
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServersTransports returns an object that can list and get ServersTransports.
|
||||||
|
func (s *serversTransportLister) ServersTransports(namespace string) ServersTransportNamespaceLister {
|
||||||
|
return serversTransportNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServersTransportNamespaceLister helps list and get ServersTransports.
|
||||||
|
type ServersTransportNamespaceLister interface {
|
||||||
|
// List lists all ServersTransports in the indexer for a given namespace.
|
||||||
|
List(selector labels.Selector) (ret []*v1alpha1.ServersTransport, err error)
|
||||||
|
// Get retrieves the ServersTransport from the indexer for a given namespace and name.
|
||||||
|
Get(name string) (*v1alpha1.ServersTransport, error)
|
||||||
|
ServersTransportNamespaceListerExpansion
|
||||||
|
}
|
||||||
|
|
||||||
|
// serversTransportNamespaceLister implements the ServersTransportNamespaceLister
|
||||||
|
// interface.
|
||||||
|
type serversTransportNamespaceLister struct {
|
||||||
|
indexer cache.Indexer
|
||||||
|
namespace string
|
||||||
|
}
|
||||||
|
|
||||||
|
// List lists all ServersTransports in the indexer for a given namespace.
|
||||||
|
func (s serversTransportNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ServersTransport, err error) {
|
||||||
|
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||||
|
ret = append(ret, m.(*v1alpha1.ServersTransport))
|
||||||
|
})
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves the ServersTransport from the indexer for a given namespace and name.
|
||||||
|
func (s serversTransportNamespaceLister) Get(name string) (*v1alpha1.ServersTransport, error) {
|
||||||
|
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.NewNotFound(v1alpha1.Resource("serverstransport"), name)
|
||||||
|
}
|
||||||
|
return obj.(*v1alpha1.ServersTransport), nil
|
||||||
|
}
|
|
@ -237,6 +237,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
cb := configBuilder{client}
|
cb := configBuilder{client}
|
||||||
|
|
||||||
for _, service := range client.GetTraefikServices() {
|
for _, service := range client.GetTraefikServices() {
|
||||||
err := cb.buildTraefikService(ctx, service, conf.HTTP.Services)
|
err := cb.buildTraefikService(ctx, service, conf.HTTP.Services)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -246,6 +247,70 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, serversTransport := range client.GetServersTransports() {
|
||||||
|
logger := log.FromContext(ctx).WithField(log.ServersTransportName, serversTransport.Name)
|
||||||
|
|
||||||
|
var rootCAs []tls.FileOrContent
|
||||||
|
for _, secret := range serversTransport.Spec.RootCAsSecrets {
|
||||||
|
caSecret, err := loadCASecret(serversTransport.Namespace, secret, client)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error while loading rootCAs %s: %v", secret, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
rootCAs = append(rootCAs, tls.FileOrContent(caSecret))
|
||||||
|
}
|
||||||
|
|
||||||
|
var certs tls.Certificates
|
||||||
|
for _, secret := range serversTransport.Spec.CertificatesSecrets {
|
||||||
|
tlsSecret, tlsKey, err := loadAuthTLSSecret(serversTransport.Namespace, secret, client)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error while loading certificates %s: %v", secret, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
certs = append(certs, tls.Certificate{
|
||||||
|
CertFile: tls.FileOrContent(tlsSecret),
|
||||||
|
KeyFile: tls.FileOrContent(tlsKey),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
forwardingTimeout := &dynamic.ForwardingTimeouts{}
|
||||||
|
forwardingTimeout.SetDefaults()
|
||||||
|
|
||||||
|
if serversTransport.Spec.ForwardingTimeouts != nil {
|
||||||
|
if serversTransport.Spec.ForwardingTimeouts.DialTimeout != nil {
|
||||||
|
err := forwardingTimeout.DialTimeout.Set(serversTransport.Spec.ForwardingTimeouts.DialTimeout.String())
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error while reading DialTimeout: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if serversTransport.Spec.ForwardingTimeouts.ResponseHeaderTimeout != nil {
|
||||||
|
err := forwardingTimeout.ResponseHeaderTimeout.Set(serversTransport.Spec.ForwardingTimeouts.ResponseHeaderTimeout.String())
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error while reading ResponseHeaderTimeout: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if serversTransport.Spec.ForwardingTimeouts.IdleConnTimeout != nil {
|
||||||
|
err := forwardingTimeout.IdleConnTimeout.Set(serversTransport.Spec.ForwardingTimeouts.IdleConnTimeout.String())
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error while reading IdleConnTimeout: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conf.HTTP.ServersTransports[serversTransport.Name] = &dynamic.ServersTransport{
|
||||||
|
ServerName: serversTransport.Spec.ServerName,
|
||||||
|
InsecureSkipVerify: serversTransport.Spec.InsecureSkipVerify,
|
||||||
|
RootCAs: rootCAs,
|
||||||
|
Certificates: certs,
|
||||||
|
MaxIdleConnsPerHost: serversTransport.Spec.MaxIdleConnsPerHost,
|
||||||
|
ForwardingTimeouts: forwardingTimeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return conf
|
return conf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,10 @@ const (
|
||||||
|
|
||||||
func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores) *dynamic.HTTPConfiguration {
|
func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores) *dynamic.HTTPConfiguration {
|
||||||
conf := &dynamic.HTTPConfiguration{
|
conf := &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Services: map[string]*dynamic.Service{},
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ingressRoute := range client.GetIngressRoutes() {
|
for _, ingressRoute := range client.GetIngressRoutes() {
|
||||||
|
@ -264,6 +265,7 @@ func (c configBuilder) buildServersLB(namespace string, svc v1alpha1.LoadBalance
|
||||||
lb.ResponseForwarding = conf.ResponseForwarding
|
lb.ResponseForwarding = conf.ResponseForwarding
|
||||||
|
|
||||||
lb.Sticky = svc.Sticky
|
lb.Sticky = svc.Sticky
|
||||||
|
lb.ServersTransport = svc.ServersTransport
|
||||||
|
|
||||||
return &dynamic.Service{LoadBalancer: lb}, nil
|
return &dynamic.Service{LoadBalancer: lb}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@ package crd
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
"github.com/containous/traefik/v2/pkg/provider"
|
"github.com/containous/traefik/v2/pkg/provider"
|
||||||
"github.com/containous/traefik/v2/pkg/tls"
|
"github.com/containous/traefik/v2/pkg/tls"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/traefik/paerser/types"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +37,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -51,9 +54,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.UDPService{},
|
Services: map[string]*dynamic.UDPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
Routers: map[string]*dynamic.TCPRouter{
|
||||||
|
@ -136,9 +140,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -177,9 +182,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -242,9 +248,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -323,9 +330,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -344,9 +352,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -364,9 +373,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -416,9 +426,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -459,9 +470,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -523,9 +535,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -585,9 +598,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -646,9 +660,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -696,9 +711,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -746,9 +762,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -787,9 +804,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -830,9 +848,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -881,9 +900,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.UDPService{},
|
Services: map[string]*dynamic.UDPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -917,9 +937,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -954,9 +975,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -980,9 +1002,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -1025,9 +1048,10 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -1045,6 +1069,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"foo"},
|
EntryPoints: []string{"foo"},
|
||||||
|
@ -1086,6 +1111,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test2-route-23c7f4c450289ee29016": {
|
"default-test2-route-23c7f4c450289ee29016": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1140,6 +1166,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test2-route-23c7f4c450289ee29016": {
|
"default-test2-route-23c7f4c450289ee29016": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1192,6 +1219,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1253,6 +1281,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1321,6 +1350,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1372,8 +1402,9 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
Services: map[string]*dynamic.Service{
|
Services: map[string]*dynamic.Service{
|
||||||
"default-wrr1": {
|
"default-wrr1": {
|
||||||
Weighted: &dynamic.WeightedRoundRobin{
|
Weighted: &dynamic.WeightedRoundRobin{
|
||||||
|
@ -1416,6 +1447,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1538,6 +1570,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1603,6 +1636,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1693,6 +1727,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1869,6 +1904,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -1931,6 +1967,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2013,6 +2050,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-77c62dfe9517144aeeaa": {
|
"default-test-route-77c62dfe9517144aeeaa": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2082,9 +2120,10 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2102,9 +2141,10 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2122,9 +2162,10 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2151,6 +2192,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2212,6 +2254,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2258,6 +2301,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2321,6 +2365,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2383,6 +2428,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2444,6 +2490,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2494,6 +2541,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2544,6 +2592,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2588,6 +2637,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2630,6 +2680,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"foo"},
|
EntryPoints: []string{"foo"},
|
||||||
|
@ -2671,6 +2722,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"foo"},
|
EntryPoints: []string{"foo"},
|
||||||
|
@ -2712,7 +2764,8 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
|
Routers: map[string]*dynamic.Router{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
"default-basicauth": {
|
"default-basicauth": {
|
||||||
BasicAuth: &dynamic.BasicAuth{
|
BasicAuth: &dynamic.BasicAuth{
|
||||||
|
@ -2753,7 +2806,8 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
|
Routers: map[string]*dynamic.Router{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
"default-errorpage": {
|
"default-errorpage": {
|
||||||
Errors: &dynamic.ErrorPage{
|
Errors: &dynamic.ErrorPage{
|
||||||
|
@ -2794,6 +2848,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"foo"},
|
EntryPoints: []string{"foo"},
|
||||||
|
@ -2846,6 +2901,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2890,6 +2946,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6b204d94623b3df4370c": {
|
"default-test-route-6b204d94623b3df4370c": {
|
||||||
EntryPoints: []string{"web"},
|
EntryPoints: []string{"web"},
|
||||||
|
@ -2934,6 +2991,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6f97418635c7e18853da": {
|
"default-test-route-6f97418635c7e18853da": {
|
||||||
EntryPoints: []string{"foo"},
|
EntryPoints: []string{"foo"},
|
||||||
|
@ -2971,6 +3029,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6f97418635c7e18853da": {
|
"default-test-route-6f97418635c7e18853da": {
|
||||||
EntryPoints: []string{"foo"},
|
EntryPoints: []string{"foo"},
|
||||||
|
@ -3008,6 +3067,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"default-test-route-6f97418635c7e18853da": {
|
"default-test-route-6f97418635c7e18853da": {
|
||||||
EntryPoints: []string{"foo"},
|
EntryPoints: []string{"foo"},
|
||||||
|
@ -3045,6 +3105,44 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
|
Routers: map[string]*dynamic.Router{},
|
||||||
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
|
},
|
||||||
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "ServersTransport",
|
||||||
|
paths: []string{"services.yml", "with_servers_transport.yml"},
|
||||||
|
expected: &dynamic.Configuration{
|
||||||
|
UDP: &dynamic.UDPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.UDPRouter{},
|
||||||
|
Services: map[string]*dynamic.UDPService{},
|
||||||
|
},
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{},
|
||||||
|
Services: map[string]*dynamic.TCPService{},
|
||||||
|
},
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||||
|
"test": {
|
||||||
|
ServerName: "test",
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
RootCAs: []tls.FileOrContent{"TESTROOTCAS", "TESTROOTCAS2"},
|
||||||
|
Certificates: tls.Certificates{
|
||||||
|
{CertFile: "TESTCERT1", KeyFile: "TESTKEY1"},
|
||||||
|
{CertFile: "TESTCERT2", KeyFile: "TESTKEY2"},
|
||||||
|
},
|
||||||
|
MaxIdleConnsPerHost: 42,
|
||||||
|
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||||
|
DialTimeout: types.Duration(42 * time.Second),
|
||||||
|
ResponseHeaderTimeout: types.Duration(42 * time.Second),
|
||||||
|
IdleConnTimeout: types.Duration(42 * time.Millisecond),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
Routers: map[string]*dynamic.Router{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Services: map[string]*dynamic.Service{},
|
||||||
|
@ -3056,7 +3154,6 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
test := test
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -3090,9 +3187,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -3126,9 +3224,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: map[string]*dynamic.TCPRouter{},
|
Routers: map[string]*dynamic.TCPRouter{},
|
||||||
|
@ -3188,9 +3287,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -3252,9 +3352,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -3332,9 +3433,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
@ -3353,9 +3455,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) {
|
||||||
Services: map[string]*dynamic.TCPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Routers: map[string]*dynamic.Router{},
|
||||||
Services: map[string]*dynamic.Service{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
Services: map[string]*dynamic.Service{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{},
|
||||||
},
|
},
|
||||||
|
|
|
@ -72,6 +72,7 @@ type LoadBalancerSpec struct {
|
||||||
Strategy string `json:"strategy,omitempty"`
|
Strategy string `json:"strategy,omitempty"`
|
||||||
PassHostHeader *bool `json:"passHostHeader,omitempty"`
|
PassHostHeader *bool `json:"passHostHeader,omitempty"`
|
||||||
ResponseForwarding *dynamic.ResponseForwarding `json:"responseForwarding,omitempty"`
|
ResponseForwarding *dynamic.ResponseForwarding `json:"responseForwarding,omitempty"`
|
||||||
|
ServersTransport string `json:"serversTransport,omitempty"`
|
||||||
|
|
||||||
// Weight should only be specified when Name references a TraefikService object
|
// Weight should only be specified when Name references a TraefikService object
|
||||||
// (and to be precise, one that embeds a Weighted Round Robin).
|
// (and to be precise, one that embeds a Weighted Round Robin).
|
||||||
|
|
|
@ -47,6 +47,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||||
&TLSStoreList{},
|
&TLSStoreList{},
|
||||||
&TraefikService{},
|
&TraefikService{},
|
||||||
&TraefikServiceList{},
|
&TraefikServiceList{},
|
||||||
|
&ServersTransport{},
|
||||||
|
&ServersTransportList{},
|
||||||
)
|
)
|
||||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// +genclient
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// ServersTransport is a specification for a ServersTransport resource.
|
||||||
|
type ServersTransport struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata"`
|
||||||
|
|
||||||
|
Spec ServersTransportSpec `json:"spec"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
|
// ServersTransportSpec options to configure communication between Traefik and the servers.
|
||||||
|
type ServersTransportSpec struct {
|
||||||
|
ServerName string `description:"ServerName used to contact the server" json:"serverName,omitempty" toml:"serverName,omitempty" yaml:"serverName,omitempty" export:"true"`
|
||||||
|
InsecureSkipVerify bool `description:"Disable SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"`
|
||||||
|
RootCAsSecrets []string `description:"Add cert file for self-signed certificate." json:"rootCAsSecrets,omitempty" toml:"rootCAsSecrets,omitempty" yaml:"rootCAsSecrets,omitempty"`
|
||||||
|
CertificatesSecrets []string `description:"Certificates for mTLS." json:"certificatesSecrets,omitempty" toml:"certificatesSecrets,omitempty" yaml:"certificatesSecrets,omitempty"`
|
||||||
|
MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" json:"maxIdleConnsPerHost,omitempty" toml:"maxIdleConnsPerHost,omitempty" yaml:"maxIdleConnsPerHost,omitempty" export:"true"`
|
||||||
|
ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
|
// ForwardingTimeouts contains timeout configurations for forwarding requests to the backend servers.
|
||||||
|
type ForwardingTimeouts struct {
|
||||||
|
DialTimeout *intstr.IntOrString `description:"The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." json:"dialTimeout,omitempty" toml:"dialTimeout,omitempty" yaml:"dialTimeout,omitempty" export:"true"`
|
||||||
|
ResponseHeaderTimeout *intstr.IntOrString `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"`
|
||||||
|
IdleConnTimeout *intstr.IntOrString `description:"The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself" json:"idleConnTimeout,omitempty" toml:"idleConnTimeout,omitempty" yaml:"idleConnTimeout,omitempty" export:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
|
// ServersTransportList is a list of ServersTransport resources.
|
||||||
|
type ServersTransportList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata"`
|
||||||
|
|
||||||
|
Items []ServersTransport `json:"items"`
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ import (
|
||||||
dynamic "github.com/containous/traefik/v2/pkg/config/dynamic"
|
dynamic "github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
types "github.com/containous/traefik/v2/pkg/types"
|
types "github.com/containous/traefik/v2/pkg/types"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
intstr "k8s.io/apimachinery/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
@ -188,6 +189,37 @@ func (in *ForwardAuth) DeepCopy() *ForwardAuth {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ForwardingTimeouts) DeepCopyInto(out *ForwardingTimeouts) {
|
||||||
|
*out = *in
|
||||||
|
if in.DialTimeout != nil {
|
||||||
|
in, out := &in.DialTimeout, &out.DialTimeout
|
||||||
|
*out = new(intstr.IntOrString)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.ResponseHeaderTimeout != nil {
|
||||||
|
in, out := &in.ResponseHeaderTimeout, &out.ResponseHeaderTimeout
|
||||||
|
*out = new(intstr.IntOrString)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.IdleConnTimeout != nil {
|
||||||
|
in, out := &in.IdleConnTimeout, &out.IdleConnTimeout
|
||||||
|
*out = new(intstr.IntOrString)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ForwardingTimeouts.
|
||||||
|
func (in *ForwardingTimeouts) DeepCopy() *ForwardingTimeouts {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ForwardingTimeouts)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *IngressRoute) DeepCopyInto(out *IngressRoute) {
|
func (in *IngressRoute) DeepCopyInto(out *IngressRoute) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@ -827,6 +859,97 @@ func (in *RouteUDP) DeepCopy() *RouteUDP {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ServersTransport) DeepCopyInto(out *ServersTransport) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransport.
|
||||||
|
func (in *ServersTransport) DeepCopy() *ServersTransport {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ServersTransport)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *ServersTransport) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ServersTransportList) DeepCopyInto(out *ServersTransportList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]ServersTransport, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransportList.
|
||||||
|
func (in *ServersTransportList) DeepCopy() *ServersTransportList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ServersTransportList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *ServersTransportList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ServersTransportSpec) DeepCopyInto(out *ServersTransportSpec) {
|
||||||
|
*out = *in
|
||||||
|
if in.RootCAsSecrets != nil {
|
||||||
|
in, out := &in.RootCAsSecrets, &out.RootCAsSecrets
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
if in.CertificatesSecrets != nil {
|
||||||
|
in, out := &in.CertificatesSecrets, &out.CertificatesSecrets
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
if in.ForwardingTimeouts != nil {
|
||||||
|
in, out := &in.ForwardingTimeouts, &out.ForwardingTimeouts
|
||||||
|
*out = new(ForwardingTimeouts)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransportSpec.
|
||||||
|
func (in *ServersTransportSpec) DeepCopy() *ServersTransportSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ServersTransportSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Service) DeepCopyInto(out *Service) {
|
func (in *Service) DeepCopyInto(out *Service) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
// MustParseYaml parses a YAML to objects.
|
// MustParseYaml parses a YAML to objects.
|
||||||
func MustParseYaml(content []byte) []runtime.Object {
|
func MustParseYaml(content []byte) []runtime.Object {
|
||||||
acceptedK8sTypes := regexp.MustCompile(`^(Deployment|Endpoints|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|Secret|TLSOption|TLSStore|TraefikService|IngressClass)$`)
|
acceptedK8sTypes := regexp.MustCompile(`^(Deployment|Endpoints|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport)$`)
|
||||||
|
|
||||||
files := strings.Split(string(content), "---")
|
files := strings.Split(string(content), "---")
|
||||||
retVal := make([]runtime.Object, 0, len(files))
|
retVal := make([]runtime.Object, 0, len(files))
|
||||||
|
|
|
@ -49,10 +49,11 @@ func (i *Provider) Init() error {
|
||||||
func (i *Provider) createConfiguration(ctx context.Context) *dynamic.Configuration {
|
func (i *Provider) createConfiguration(ctx context.Context) *dynamic.Configuration {
|
||||||
cfg := &dynamic.Configuration{
|
cfg := &dynamic.Configuration{
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.Router),
|
Routers: make(map[string]*dynamic.Router),
|
||||||
Middlewares: make(map[string]*dynamic.Middleware),
|
Middlewares: make(map[string]*dynamic.Middleware),
|
||||||
Services: make(map[string]*dynamic.Service),
|
Services: make(map[string]*dynamic.Service),
|
||||||
Models: make(map[string]*dynamic.Model),
|
Models: make(map[string]*dynamic.Model),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.TCPRouter),
|
Routers: make(map[string]*dynamic.TCPRouter),
|
||||||
|
@ -70,6 +71,7 @@ func (i *Provider) createConfiguration(ctx context.Context) *dynamic.Configurati
|
||||||
i.prometheusConfiguration(cfg)
|
i.prometheusConfiguration(cfg)
|
||||||
i.entryPointModels(cfg)
|
i.entryPointModels(cfg)
|
||||||
i.redirection(ctx, cfg)
|
i.redirection(ctx, cfg)
|
||||||
|
i.serverTransport(cfg)
|
||||||
|
|
||||||
cfg.HTTP.Services["noop"] = &dynamic.Service{}
|
cfg.HTTP.Services["noop"] = &dynamic.Service{}
|
||||||
|
|
||||||
|
@ -274,3 +276,25 @@ func (i *Provider) prometheusConfiguration(cfg *dynamic.Configuration) {
|
||||||
|
|
||||||
cfg.HTTP.Services["prometheus"] = &dynamic.Service{}
|
cfg.HTTP.Services["prometheus"] = &dynamic.Service{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Provider) serverTransport(cfg *dynamic.Configuration) {
|
||||||
|
if i.staticCfg.ServersTransport == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
st := &dynamic.ServersTransport{
|
||||||
|
InsecureSkipVerify: i.staticCfg.ServersTransport.InsecureSkipVerify,
|
||||||
|
RootCAs: i.staticCfg.ServersTransport.RootCAs,
|
||||||
|
MaxIdleConnsPerHost: i.staticCfg.ServersTransport.MaxIdleConnsPerHost,
|
||||||
|
}
|
||||||
|
|
||||||
|
if i.staticCfg.ServersTransport.ForwardingTimeouts != nil {
|
||||||
|
st.ForwardingTimeouts = &dynamic.ForwardingTimeouts{
|
||||||
|
DialTimeout: i.staticCfg.ServersTransport.ForwardingTimeouts.DialTimeout,
|
||||||
|
ResponseHeaderTimeout: i.staticCfg.ServersTransport.ForwardingTimeouts.ResponseHeaderTimeout,
|
||||||
|
IdleConnTimeout: i.staticCfg.ServersTransport.ForwardingTimeouts.IdleConnTimeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.HTTP.ServersTransports["default"] = st
|
||||||
|
}
|
||||||
|
|
|
@ -10,10 +10,11 @@ import (
|
||||||
func mergeConfiguration(configurations dynamic.Configurations, defaultEntryPoints []string) dynamic.Configuration {
|
func mergeConfiguration(configurations dynamic.Configurations, defaultEntryPoints []string) dynamic.Configuration {
|
||||||
conf := dynamic.Configuration{
|
conf := dynamic.Configuration{
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.Router),
|
Routers: make(map[string]*dynamic.Router),
|
||||||
Middlewares: make(map[string]*dynamic.Middleware),
|
Middlewares: make(map[string]*dynamic.Middleware),
|
||||||
Services: make(map[string]*dynamic.Service),
|
Services: make(map[string]*dynamic.Service),
|
||||||
Models: make(map[string]*dynamic.Model),
|
Models: make(map[string]*dynamic.Model),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
TCP: &dynamic.TCPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.TCPRouter),
|
Routers: make(map[string]*dynamic.TCPRouter),
|
||||||
|
@ -52,6 +53,9 @@ func mergeConfiguration(configurations dynamic.Configurations, defaultEntryPoint
|
||||||
for modelName, model := range configuration.HTTP.Models {
|
for modelName, model := range configuration.HTTP.Models {
|
||||||
conf.HTTP.Models[provider.MakeQualifiedName(pvd, modelName)] = model
|
conf.HTTP.Models[provider.MakeQualifiedName(pvd, modelName)] = model
|
||||||
}
|
}
|
||||||
|
for serversTransportName, serversTransport := range configuration.HTTP.ServersTransports {
|
||||||
|
conf.HTTP.ServersTransports[provider.MakeQualifiedName(pvd, serversTransportName)] = serversTransport
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.TCP != nil {
|
if configuration.TCP != nil {
|
||||||
|
|
|
@ -18,10 +18,11 @@ func Test_mergeConfiguration(t *testing.T) {
|
||||||
desc: "Nil returns an empty configuration",
|
desc: "Nil returns an empty configuration",
|
||||||
given: nil,
|
given: nil,
|
||||||
expected: &dynamic.HTTPConfiguration{
|
expected: &dynamic.HTTPConfiguration{
|
||||||
Routers: make(map[string]*dynamic.Router),
|
Routers: make(map[string]*dynamic.Router),
|
||||||
Middlewares: make(map[string]*dynamic.Middleware),
|
Middlewares: make(map[string]*dynamic.Middleware),
|
||||||
Services: make(map[string]*dynamic.Service),
|
Services: make(map[string]*dynamic.Service),
|
||||||
Models: make(map[string]*dynamic.Model),
|
Models: make(map[string]*dynamic.Model),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -53,7 +54,8 @@ func Test_mergeConfiguration(t *testing.T) {
|
||||||
Services: map[string]*dynamic.Service{
|
Services: map[string]*dynamic.Service{
|
||||||
"service-1@provider-1": {},
|
"service-1@provider-1": {},
|
||||||
},
|
},
|
||||||
Models: make(map[string]*dynamic.Model),
|
Models: make(map[string]*dynamic.Model),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -103,7 +105,8 @@ func Test_mergeConfiguration(t *testing.T) {
|
||||||
"service-1@provider-1": {},
|
"service-1@provider-1": {},
|
||||||
"service-1@provider-2": {},
|
"service-1@provider-2": {},
|
||||||
},
|
},
|
||||||
Models: make(map[string]*dynamic.Model),
|
Models: make(map[string]*dynamic.Model),
|
||||||
|
ServersTransports: make(map[string]*dynamic.ServersTransport),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,7 +287,9 @@ func TestRouterManager_Get(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
serviceManager := service.NewManager(rtConf.Services, http.DefaultTransport, nil, nil)
|
roundTripperManager := service.NewRoundTripperManager()
|
||||||
|
roundTripperManager.Update(map[string]*dynamic.ServersTransport{"default@internal": {}})
|
||||||
|
serviceManager := service.NewManager(rtConf.Services, nil, nil, roundTripperManager)
|
||||||
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
||||||
chainBuilder := middleware.NewChainBuilder(static.Configuration{}, nil, nil)
|
chainBuilder := middleware.NewChainBuilder(static.Configuration{}, nil, nil)
|
||||||
|
|
||||||
|
@ -391,7 +393,9 @@ func TestAccessLog(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
serviceManager := service.NewManager(rtConf.Services, http.DefaultTransport, nil, nil)
|
roundTripperManager := service.NewRoundTripperManager()
|
||||||
|
roundTripperManager.Update(map[string]*dynamic.ServersTransport{"default@internal": {}})
|
||||||
|
serviceManager := service.NewManager(rtConf.Services, nil, nil, roundTripperManager)
|
||||||
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
||||||
chainBuilder := middleware.NewChainBuilder(static.Configuration{}, nil, nil)
|
chainBuilder := middleware.NewChainBuilder(static.Configuration{}, nil, nil)
|
||||||
|
|
||||||
|
@ -678,7 +682,9 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
serviceManager := service.NewManager(rtConf.Services, http.DefaultTransport, nil, nil)
|
roundTripperManager := service.NewRoundTripperManager()
|
||||||
|
roundTripperManager.Update(map[string]*dynamic.ServersTransport{"default@internal": {}})
|
||||||
|
serviceManager := service.NewManager(rtConf.Services, nil, nil, roundTripperManager)
|
||||||
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
||||||
chainBuilder := middleware.NewChainBuilder(static.Configuration{}, nil, nil)
|
chainBuilder := middleware.NewChainBuilder(static.Configuration{}, nil, nil)
|
||||||
|
|
||||||
|
@ -759,7 +765,9 @@ func TestProviderOnMiddlewares(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
serviceManager := service.NewManager(rtConf.Services, http.DefaultTransport, nil, nil)
|
roundTripperManager := service.NewRoundTripperManager()
|
||||||
|
roundTripperManager.Update(map[string]*dynamic.ServersTransport{"default@internal": {}})
|
||||||
|
serviceManager := service.NewManager(rtConf.Services, nil, nil, roundTripperManager)
|
||||||
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
||||||
chainBuilder := middleware.NewChainBuilder(staticCfg, nil, nil)
|
chainBuilder := middleware.NewChainBuilder(staticCfg, nil, nil)
|
||||||
|
|
||||||
|
@ -773,6 +781,14 @@ func TestProviderOnMiddlewares(t *testing.T) {
|
||||||
assert.Equal(t, []string{"m1@docker", "m2@docker", "m1@file"}, rtConf.Middlewares["chain@docker"].Chain.Middlewares)
|
assert.Equal(t, []string{"m1@docker", "m2@docker", "m1@file"}, rtConf.Middlewares["chain@docker"].Chain.Middlewares)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type staticRoundTripperGetter struct {
|
||||||
|
res *http.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s staticRoundTripperGetter) Get(name string) (http.RoundTripper, error) {
|
||||||
|
return &staticTransport{res: s.res}, nil
|
||||||
|
}
|
||||||
|
|
||||||
type staticTransport struct {
|
type staticTransport struct {
|
||||||
res *http.Response
|
res *http.Response
|
||||||
}
|
}
|
||||||
|
@ -819,7 +835,7 @@ func BenchmarkRouterServe(b *testing.B) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
serviceManager := service.NewManager(rtConf.Services, &staticTransport{res}, nil, nil)
|
serviceManager := service.NewManager(rtConf.Services, nil, nil, staticRoundTripperGetter{res})
|
||||||
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, nil)
|
||||||
chainBuilder := middleware.NewChainBuilder(static.Configuration{}, nil, nil)
|
chainBuilder := middleware.NewChainBuilder(static.Configuration{}, nil, nil)
|
||||||
|
|
||||||
|
@ -861,7 +877,7 @@ func BenchmarkService(b *testing.B) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
serviceManager := service.NewManager(rtConf.Services, &staticTransport{res}, nil, nil)
|
serviceManager := service.NewManager(rtConf.Services, nil, nil, staticRoundTripperGetter{res})
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
req := testhelpers.MustNewRequest(http.MethodGet, "http://foo.bar/", nil)
|
req := testhelpers.MustNewRequest(http.MethodGet, "http://foo.bar/", nil)
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,9 @@ func TestReuseService(t *testing.T) {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
managerFactory := service.NewManagerFactory(staticConfig, nil, metrics.NewVoidRegistry())
|
roundTripperManager := service.NewRoundTripperManager()
|
||||||
|
roundTripperManager.Update(map[string]*dynamic.ServersTransport{"default@internal": {}})
|
||||||
|
managerFactory := service.NewManagerFactory(staticConfig, nil, metrics.NewVoidRegistry(), roundTripperManager)
|
||||||
tlsManager := tls.NewManager()
|
tlsManager := tls.NewManager()
|
||||||
|
|
||||||
factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(staticConfig, metrics.NewVoidRegistry(), nil), nil)
|
factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(staticConfig, metrics.NewVoidRegistry(), nil), nil)
|
||||||
|
@ -182,7 +184,9 @@ func TestServerResponseEmptyBackend(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
managerFactory := service.NewManagerFactory(staticConfig, nil, metrics.NewVoidRegistry())
|
roundTripperManager := service.NewRoundTripperManager()
|
||||||
|
roundTripperManager.Update(map[string]*dynamic.ServersTransport{"default@internal": {}})
|
||||||
|
managerFactory := service.NewManagerFactory(staticConfig, nil, metrics.NewVoidRegistry(), roundTripperManager)
|
||||||
tlsManager := tls.NewManager()
|
tlsManager := tls.NewManager()
|
||||||
|
|
||||||
factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(staticConfig, metrics.NewVoidRegistry(), nil), nil)
|
factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(staticConfig, metrics.NewVoidRegistry(), nil), nil)
|
||||||
|
@ -221,7 +225,9 @@ func TestInternalServices(t *testing.T) {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
managerFactory := service.NewManagerFactory(staticConfig, nil, metrics.NewVoidRegistry())
|
roundTripperManager := service.NewRoundTripperManager()
|
||||||
|
roundTripperManager.Update(map[string]*dynamic.ServersTransport{"default@internal": {}})
|
||||||
|
managerFactory := service.NewManagerFactory(staticConfig, nil, metrics.NewVoidRegistry(), roundTripperManager)
|
||||||
tlsManager := tls.NewManager()
|
tlsManager := tls.NewManager()
|
||||||
|
|
||||||
factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(staticConfig, metrics.NewVoidRegistry(), nil), nil)
|
factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(staticConfig, metrics.NewVoidRegistry(), nil), nil)
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
type ManagerFactory struct {
|
type ManagerFactory struct {
|
||||||
metricsRegistry metrics.Registry
|
metricsRegistry metrics.Registry
|
||||||
|
|
||||||
defaultRoundTripper http.RoundTripper
|
roundTripperManager *RoundTripperManager
|
||||||
|
|
||||||
api func(configuration *runtime.Configuration) http.Handler
|
api func(configuration *runtime.Configuration) http.Handler
|
||||||
restHandler http.Handler
|
restHandler http.Handler
|
||||||
|
@ -26,11 +26,11 @@ type ManagerFactory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManagerFactory creates a new ManagerFactory.
|
// NewManagerFactory creates a new ManagerFactory.
|
||||||
func NewManagerFactory(staticConfiguration static.Configuration, routinesPool *safe.Pool, metricsRegistry metrics.Registry) *ManagerFactory {
|
func NewManagerFactory(staticConfiguration static.Configuration, routinesPool *safe.Pool, metricsRegistry metrics.Registry, roundTripperManager *RoundTripperManager) *ManagerFactory {
|
||||||
factory := &ManagerFactory{
|
factory := &ManagerFactory{
|
||||||
metricsRegistry: metricsRegistry,
|
metricsRegistry: metricsRegistry,
|
||||||
defaultRoundTripper: setupDefaultRoundTripper(staticConfiguration.ServersTransport),
|
|
||||||
routinesPool: routinesPool,
|
routinesPool: routinesPool,
|
||||||
|
roundTripperManager: roundTripperManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
if staticConfiguration.API != nil {
|
if staticConfiguration.API != nil {
|
||||||
|
@ -61,6 +61,6 @@ func NewManagerFactory(staticConfiguration static.Configuration, routinesPool *s
|
||||||
|
|
||||||
// Build creates a service manager.
|
// Build creates a service manager.
|
||||||
func (f *ManagerFactory) Build(configuration *runtime.Configuration) *InternalHandlers {
|
func (f *ManagerFactory) Build(configuration *runtime.Configuration) *InternalHandlers {
|
||||||
svcManager := NewManager(configuration.Services, f.defaultRoundTripper, f.metricsRegistry, f.routinesPool)
|
svcManager := NewManager(configuration.Services, f.metricsRegistry, f.routinesPool, f.roundTripperManager)
|
||||||
return NewInternalHandlers(f.api, configuration, f.restHandler, f.metricsHandler, f.pingHandler, f.dashboardHandler, svcManager)
|
return NewInternalHandlers(f.api, configuration, f.restHandler, f.metricsHandler, f.pingHandler, f.dashboardHandler, svcManager)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ const StatusClientClosedRequest = 499
|
||||||
// StatusClientClosedRequestText non-standard HTTP status for client disconnection.
|
// StatusClientClosedRequestText non-standard HTTP status for client disconnection.
|
||||||
const StatusClientClosedRequestText = "Client Closed Request"
|
const StatusClientClosedRequestText = "Client Closed Request"
|
||||||
|
|
||||||
func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwarding, defaultRoundTripper http.RoundTripper, bufferPool httputil.BufferPool) (http.Handler, error) {
|
func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwarding, roundTripper http.RoundTripper, bufferPool httputil.BufferPool) (http.Handler, error) {
|
||||||
var flushInterval ptypes.Duration
|
var flushInterval ptypes.Duration
|
||||||
if responseForwarding != nil {
|
if responseForwarding != nil {
|
||||||
err := flushInterval.Set(responseForwarding.FlushInterval)
|
err := flushInterval.Set(responseForwarding.FlushInterval)
|
||||||
|
@ -76,7 +76,7 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar
|
||||||
delete(outReq.Header, "Sec-Websocket-Protocol")
|
delete(outReq.Header, "Sec-Websocket-Protocol")
|
||||||
delete(outReq.Header, "Sec-Websocket-Version")
|
delete(outReq.Header, "Sec-Websocket-Version")
|
||||||
},
|
},
|
||||||
Transport: defaultRoundTripper,
|
Transport: roundTripper,
|
||||||
FlushInterval: time.Duration(flushInterval),
|
FlushInterval: time.Duration(flushInterval),
|
||||||
BufferPool: bufferPool,
|
BufferPool: bufferPool,
|
||||||
ErrorHandler: func(w http.ResponseWriter, request *http.Request, err error) {
|
ErrorHandler: func(w http.ResponseWriter, request *http.Request, err error) {
|
||||||
|
|
|
@ -4,11 +4,14 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/pkg/config/static"
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
"github.com/containous/traefik/v2/pkg/log"
|
"github.com/containous/traefik/v2/pkg/log"
|
||||||
traefiktls "github.com/containous/traefik/v2/pkg/tls"
|
traefiktls "github.com/containous/traefik/v2/pkg/tls"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
|
@ -23,30 +26,100 @@ func (t *h2cTransportWrapper) RoundTrip(req *http.Request) (*http.Response, erro
|
||||||
return t.Transport.RoundTrip(req)
|
return t.Transport.RoundTrip(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createRoundtripper creates an http.Roundtripper configured with the Transport configuration settings.
|
// NewRoundTripperManager creates a new RoundTripperManager.
|
||||||
|
func NewRoundTripperManager() *RoundTripperManager {
|
||||||
|
return &RoundTripperManager{
|
||||||
|
roundTrippers: make(map[string]http.RoundTripper),
|
||||||
|
configs: make(map[string]*dynamic.ServersTransport),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundTripperManager handles roundtripper for the reverse proxy.
|
||||||
|
type RoundTripperManager struct {
|
||||||
|
rtLock sync.RWMutex
|
||||||
|
roundTrippers map[string]http.RoundTripper
|
||||||
|
configs map[string]*dynamic.ServersTransport
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates the roundtrippers configurations.
|
||||||
|
func (r *RoundTripperManager) Update(newConfigs map[string]*dynamic.ServersTransport) {
|
||||||
|
r.rtLock.Lock()
|
||||||
|
defer r.rtLock.Unlock()
|
||||||
|
|
||||||
|
for configName, config := range r.configs {
|
||||||
|
newConfig, ok := newConfigs[configName]
|
||||||
|
if !ok {
|
||||||
|
delete(r.configs, configName)
|
||||||
|
delete(r.roundTrippers, configName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if reflect.DeepEqual(newConfig, config) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
r.roundTrippers[configName], err = createRoundTripper(newConfig)
|
||||||
|
if err != nil {
|
||||||
|
log.WithoutContext().Errorf("Could not configure HTTP Transport %s, fallback on default transport: %v", configName, err)
|
||||||
|
r.roundTrippers[configName] = http.DefaultTransport
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for newConfigName, newConfig := range newConfigs {
|
||||||
|
if _, ok := r.configs[newConfigName]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
r.roundTrippers[newConfigName], err = createRoundTripper(newConfig)
|
||||||
|
if err != nil {
|
||||||
|
log.WithoutContext().Errorf("Could not configure HTTP Transport %s, fallback on default transport: %v", newConfigName, err)
|
||||||
|
r.roundTrippers[newConfigName] = http.DefaultTransport
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.configs = newConfigs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get get a roundtripper by name.
|
||||||
|
func (r *RoundTripperManager) Get(name string) (http.RoundTripper, error) {
|
||||||
|
if len(name) == 0 {
|
||||||
|
name = "default@internal"
|
||||||
|
}
|
||||||
|
|
||||||
|
r.rtLock.RLock()
|
||||||
|
defer r.rtLock.RUnlock()
|
||||||
|
|
||||||
|
if rt, ok := r.roundTrippers[name]; ok {
|
||||||
|
return rt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("servers transport not found %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// createRoundTripper creates an http.RoundTripper configured with the Transport configuration settings.
|
||||||
// For the settings that can't be configured in Traefik it uses the default http.Transport settings.
|
// For the settings that can't be configured in Traefik it uses the default http.Transport settings.
|
||||||
// An exception to this is the MaxIdleConns setting as we only provide the option MaxIdleConnsPerHost
|
// An exception to this is the MaxIdleConns setting as we only provide the option MaxIdleConnsPerHostin Traefik at this point in time.
|
||||||
// in Traefik at this point in time. Setting this value to the default of 100 could lead to confusing
|
// Setting this value to the default of 100 could lead to confusing behavior and backwards compatibility issues.
|
||||||
// behavior and backwards compatibility issues.
|
func createRoundTripper(cfg *dynamic.ServersTransport) (http.RoundTripper, error) {
|
||||||
func createRoundtripper(transportConfiguration *static.ServersTransport) (http.RoundTripper, error) {
|
if cfg == nil {
|
||||||
if transportConfiguration == nil {
|
|
||||||
return nil, errors.New("no transport configuration given")
|
return nil, errors.New("no transport configuration given")
|
||||||
}
|
}
|
||||||
|
|
||||||
dialer := &net.Dialer{
|
dialer := &net.Dialer{
|
||||||
Timeout: 30 * time.Second,
|
Timeout: 30 * time.Second,
|
||||||
KeepAlive: 30 * time.Second,
|
KeepAlive: 30 * time.Second,
|
||||||
DualStack: true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if transportConfiguration.ForwardingTimeouts != nil {
|
if cfg.ForwardingTimeouts != nil {
|
||||||
dialer.Timeout = time.Duration(transportConfiguration.ForwardingTimeouts.DialTimeout)
|
dialer.Timeout = time.Duration(cfg.ForwardingTimeouts.DialTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
DialContext: dialer.DialContext,
|
DialContext: dialer.DialContext,
|
||||||
MaxIdleConnsPerHost: transportConfiguration.MaxIdleConnsPerHost,
|
MaxIdleConnsPerHost: cfg.MaxIdleConnsPerHost,
|
||||||
IdleConnTimeout: 90 * time.Second,
|
IdleConnTimeout: 90 * time.Second,
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
|
@ -61,24 +134,21 @@ func createRoundtripper(transportConfiguration *static.ServersTransport) (http.R
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
if transportConfiguration.ForwardingTimeouts != nil {
|
if cfg.ForwardingTimeouts != nil {
|
||||||
transport.ResponseHeaderTimeout = time.Duration(transportConfiguration.ForwardingTimeouts.ResponseHeaderTimeout)
|
transport.ResponseHeaderTimeout = time.Duration(cfg.ForwardingTimeouts.ResponseHeaderTimeout)
|
||||||
transport.IdleConnTimeout = time.Duration(transportConfiguration.ForwardingTimeouts.IdleConnTimeout)
|
transport.IdleConnTimeout = time.Duration(cfg.ForwardingTimeouts.IdleConnTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
if transportConfiguration.InsecureSkipVerify || len(transportConfiguration.RootCAs) > 0 {
|
if cfg.InsecureSkipVerify || len(cfg.RootCAs) > 0 || len(cfg.ServerName) > 0 || len(cfg.Certificates) > 0 {
|
||||||
transport.TLSClientConfig = &tls.Config{
|
transport.TLSClientConfig = &tls.Config{
|
||||||
InsecureSkipVerify: transportConfiguration.InsecureSkipVerify,
|
ServerName: cfg.ServerName,
|
||||||
RootCAs: createRootCACertPool(transportConfiguration.RootCAs),
|
InsecureSkipVerify: cfg.InsecureSkipVerify,
|
||||||
|
RootCAs: createRootCACertPool(cfg.RootCAs),
|
||||||
|
Certificates: cfg.Certificates.GetCertificates(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
smartTransport, err := newSmartRoundTripper(transport)
|
return newSmartRoundTripper(transport)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return smartTransport, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool {
|
func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool {
|
||||||
|
@ -99,13 +169,3 @@ func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool {
|
||||||
|
|
||||||
return roots
|
return roots
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupDefaultRoundTripper(conf *static.ServersTransport) http.RoundTripper {
|
|
||||||
transport, err := createRoundtripper(conf)
|
|
||||||
if err != nil {
|
|
||||||
log.WithoutContext().Errorf("Could not configure HTTP Transport, fallbacking on default transport: %v", err)
|
|
||||||
return http.DefaultTransport
|
|
||||||
}
|
|
||||||
|
|
||||||
return transport
|
|
||||||
}
|
|
||||||
|
|
229
pkg/server/service/roundtripper_test.go
Normal file
229
pkg/server/service/roundtripper_test.go
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"sync/atomic"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
|
traefiktls "github.com/containous/traefik/v2/pkg/tls"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Int32(i int32) *int32 {
|
||||||
|
return &i
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocalhostCert is a PEM-encoded TLS cert
|
||||||
|
// for host example.com, www.example.com
|
||||||
|
// expiring at Jan 29 16:00:00 2084 GMT.
|
||||||
|
// go run $GOROOT/src/crypto/tls/generate_cert.go --rsa-bits 1024 --host example.com,www.example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
|
||||||
|
var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIICDDCCAXWgAwIBAgIQH20JmcOlcRWHNuf62SYwszANBgkqhkiG9w0BAQsFADAS
|
||||||
|
MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
|
||||||
|
MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
|
||||||
|
iQKBgQC0qINy3F4oq6viDnlpDDE5J08iSRGggg6EylJKBKZfphEG2ufgK78Dufl3
|
||||||
|
+7b0LlEY2AeZHwviHODqC9a6ihj1ZYQk0/djAh+OeOhFEWu+9T/VP8gVFarFqT8D
|
||||||
|
Opy+hrG7YJivUIzwb4fmJQRI7FajzsnGyM6LiXLU+0qzb7ZO/QIDAQABo2EwXzAO
|
||||||
|
BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw
|
||||||
|
AwEB/zAnBgNVHREEIDAeggtleGFtcGxlLmNvbYIPd3d3LmV4YW1wbGUuY29tMA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4GBAB+eluoQYzyyMfeEEAOtlldevx5MtDENT05NB0WI+91R
|
||||||
|
we7mX8lv763u0XuCWPxbHszhclI6FFjoQef0Z1NYLRm8ZRq58QqWDFZ3E6wdDK+B
|
||||||
|
+OWvkW+hRavo6R9LzIZPfbv8yBo4M9PK/DXw8hLqH7VkkI+Gh793iH7Ugd4A7wvT
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
// LocalhostKey is the private key for localhostCert.
|
||||||
|
var LocalhostKey = []byte(`-----BEGIN PRIVATE KEY-----
|
||||||
|
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALSog3LcXiirq+IO
|
||||||
|
eWkMMTknTyJJEaCCDoTKUkoEpl+mEQba5+ArvwO5+Xf7tvQuURjYB5kfC+Ic4OoL
|
||||||
|
1rqKGPVlhCTT92MCH4546EURa771P9U/yBUVqsWpPwM6nL6GsbtgmK9QjPBvh+Yl
|
||||||
|
BEjsVqPOycbIzouJctT7SrNvtk79AgMBAAECgYB1wMT1MBgbkFIXpXGTfAP1id61
|
||||||
|
rUTVBxCpkypx3ngHLjo46qRq5Hi72BN4FlTY8fugIudI8giP2FztkMvkiLDc4m0p
|
||||||
|
Gn+QMJzjlBjjTuNLvLy4aSmNRLIC3mtbx9PdU71DQswEpJHFj/vmsxbuSrG1I1YE
|
||||||
|
r1reuSo2ow6fOAjXLQJBANpz+RkOiPSPuvl+gi1sp2pLuynUJVDVqWZi386YRpfg
|
||||||
|
DiKCLpqwqYDkOozm/fwFALvwXKGmsyyL43HO8eI+2NsCQQDTtY32V+02GPecdsyq
|
||||||
|
msK06EPVTSaYwj9Mm+q709KsmYFHLXDqXjcKV4UgKYKRPz7my1fXodMmGmfuh1a3
|
||||||
|
/HMHAkEAmOQKN0tA90mRJwUvvvMIyRBv0fq0kzq28P3KfiF9ZtZdjjFmxMVYHOmf
|
||||||
|
QPZ6VGR7+w1jB5BQXqEZcpHQIPSzeQJBAIy9tZJ/AYNlNbcegxEnsSjy/6VdlLsY
|
||||||
|
51vWi0Yym2uC4R6gZuBnoc+OP0ISVmqY0Qg9RjhjrCs4gr9f2ZaWjSECQCxqZMq1
|
||||||
|
3viJ8BGCC0m/5jv1EHur3YgwphYCkf4Li6DKwIdMLk1WXkTcPIY3V2Jqj8rPEB5V
|
||||||
|
rqPRSAtd/h6oZbs=
|
||||||
|
-----END PRIVATE KEY-----`)
|
||||||
|
|
||||||
|
// openssl req -newkey rsa:2048 \
|
||||||
|
// -new -nodes -x509 \
|
||||||
|
// -days 3650 \
|
||||||
|
// -out cert.pem \
|
||||||
|
// -keyout key.pem \
|
||||||
|
// -subj "/CN=example.com"
|
||||||
|
// -addext "subjectAltName = DNS:example.com"
|
||||||
|
var mTLSCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDJTCCAg2gAwIBAgIUYKnGcLnmMosOSKqTn4ydAMURE4gwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wHhcNMjAwODEzMDkyNzIwWhcNMzAw
|
||||||
|
ODExMDkyNzIwWjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
|
||||||
|
AQEBBQADggEPADCCAQoCggEBAOAe+QM1c9lZ2TPRgoiuPAq2A3Pfu+i82lmqrTJ0
|
||||||
|
PR2Cx1fPbccCUTFJPlxSDiaMrwtvqw1yP9L2Pu/vJK5BY4YDVDtFGKjpRBau1otJ
|
||||||
|
iY50O5qMo3sfLqR4/1VsQGlLVZYLD3dyc4ZTmOp8+7tJ2SyGorojbIKfimZT7XD7
|
||||||
|
dzrVr4h4Gn+SzzOnoKyx29uaNRP+XuMYHmHyQcJE03pUGhkTOvMwBlF96QdQ9WG0
|
||||||
|
D+1CxRciEsZXE+imKBHoaTgrTkpnFHzsrIEw+OHQYf30zuT/k/lkgv1vqEwINHjz
|
||||||
|
W2VeTur5eqVvA7zZdoEXMRy7BUvh/nZk5AXkXAmZLn0eUg8CAwEAAaNrMGkwHQYD
|
||||||
|
VR0OBBYEFEDrbhPDt+hi3ZOzk6S/CFAVHwk0MB8GA1UdIwQYMBaAFEDrbhPDt+hi
|
||||||
|
3ZOzk6S/CFAVHwk0MA8GA1UdEwEB/wQFMAMBAf8wFgYDVR0RBA8wDYILZXhhbXBs
|
||||||
|
ZS5jb20wDQYJKoZIhvcNAQELBQADggEBAG/JRJWeUNx2mDJAk8W7Syq3gmQB7s9f
|
||||||
|
+yY/XVRJZGahOPilABqFpC6GVn2HWuvuOqy8/RGk9ja5abKVXqE6YKrljqo3XfzB
|
||||||
|
KQcOz4SFirpkHvNCiEcK3kggN3wJWqL2QyXAxWldBBBCO9yx7a3cux31C//sTUOG
|
||||||
|
xq4JZDg171U1UOpfN1t0BFMdt05XZFEM247N7Dcf7HoXwAa7eyLKgtKWqPDqGrFa
|
||||||
|
fvGDDKK9X/KVsU2x9V3pG+LsJg7ogUnSyD2r5G1F3Y8OVs2T/783PaN0M35fDL38
|
||||||
|
09VbsxA2GasOHZrghUzT4UvZWWZbWEmG975hFYvdj6DlK9K0s5TdKIs=
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
|
var mTLSKey = []byte(`-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDgHvkDNXPZWdkz
|
||||||
|
0YKIrjwKtgNz37vovNpZqq0ydD0dgsdXz23HAlExST5cUg4mjK8Lb6sNcj/S9j7v
|
||||||
|
7ySuQWOGA1Q7RRio6UQWrtaLSYmOdDuajKN7Hy6keP9VbEBpS1WWCw93cnOGU5jq
|
||||||
|
fPu7SdkshqK6I2yCn4pmU+1w+3c61a+IeBp/ks8zp6CssdvbmjUT/l7jGB5h8kHC
|
||||||
|
RNN6VBoZEzrzMAZRfekHUPVhtA/tQsUXIhLGVxPopigR6Gk4K05KZxR87KyBMPjh
|
||||||
|
0GH99M7k/5P5ZIL9b6hMCDR481tlXk7q+XqlbwO82XaBFzEcuwVL4f52ZOQF5FwJ
|
||||||
|
mS59HlIPAgMBAAECggEAAKLV3hZ2v7UrkqQTlMO50+X0WI3YAK8Yh4yedTgzPDQ0
|
||||||
|
0KD8FMaC6HrmvGhXNfDMRmIIwD8Ew1qDjzbEieIRoD2+LXTivwf6c34HidmplEfs
|
||||||
|
K2IezKin/zuArgNio2ndUlGxt4sRnN373x5/sGZjQWcYayLSmgRN5kByuhFco0Qa
|
||||||
|
oSrXcXNUlb+KgRQXPDU4+M35tPHvLdyg+tko/m/5uK9dc9MNvGZHOMBKg0VNURJb
|
||||||
|
V1l3dR+evwvpqHzBvWiqN/YOiUUvIxlFKA35hJkfCl7ivFs4CLqqFNCKDao95fWe
|
||||||
|
s0UR9iMakT48jXV76IfwZnyX10OhIWzKls5trjDL8QKBgQD3thQJ8e0FL9y1W+Ph
|
||||||
|
mCdEaoffSPkgSn64wIsQ9bMmv4y+KYBK5AhqaHgYm4LgW4x1+CURNFu+YFEyaNNA
|
||||||
|
kNCXFyRX3Em3vxcShP5jIqg+f07mtXPKntWP/zBeKQWgdHX371oFTfaAlNuKX/7S
|
||||||
|
n0jBYjr4Iof1bnquMQvUoHCYWwKBgQDnntFU9/AQGaQIvhfeU1XKFkQ/BfhIsd27
|
||||||
|
RlmiCi0ee9Ce74cMAhWr/9yg0XUxzrh+Ui1xnkMVTZ5P8tWIxROokznLUTGJA5rs
|
||||||
|
zB+ovCPFZcquTwNzn7SBnpHTR0OqJd8sd89P5ST2SqufeSF/gGi5sTs4EocOLCpZ
|
||||||
|
EPVIfm47XQKBgB4d5RHQeCDJUOw739jtxthqm1pqZN+oLwAHaOEG/mEXqOT15sM0
|
||||||
|
NlG5oeBcB+1/M/Sj1t3gn8blrvmSBR00fifgiGqmPdA5S3TU9pjW/d2bXNxv80QP
|
||||||
|
S6fWPusz0ZtQjYc3cppygCXh808/nJu/AfmBF+pTSHRumjvTery/RPFBAoGBAMi/
|
||||||
|
zCta4cTylEvHhqR5kiefePMu120aTFYeuV1KeKStJ7o5XNE5lVMIZk80e+D5jMpf
|
||||||
|
q2eIhhgWuBoPHKh4N3uqbzMbYlWgvEx09xOmTVKv0SWW8iTqzOZza2y1nZ4BSRcf
|
||||||
|
mJ1ku86EFZAYysHZp+saA3usA0ZzXRjpK87zVdM5AoGBAOSqI+t48PnPtaUDFdpd
|
||||||
|
taNNVDbcecJatm3w8VDWnarahfWe66FIqc9wUkqekqAgwZLa0AGdUalvXfGrHfNs
|
||||||
|
PtvuNc5EImfSkuPBYLBslNxtjbBvAYgacEdY+gRhn2TeIUApnND58lCWsKbNHLFZ
|
||||||
|
ajIPbTY+Fe9OTOFTN48ujXNn
|
||||||
|
-----END PRIVATE KEY-----`)
|
||||||
|
|
||||||
|
func TestKeepConnectionWhenSameConfiguration(t *testing.T) {
|
||||||
|
srv := httptest.NewUnstartedServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
}))
|
||||||
|
|
||||||
|
connCount := Int32(0)
|
||||||
|
srv.Config.ConnState = func(conn net.Conn, state http.ConnState) {
|
||||||
|
if state == http.StateNew {
|
||||||
|
atomic.AddInt32(connCount, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cert, err := tls.X509KeyPair(LocalhostCert, LocalhostKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
srv.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
|
||||||
|
srv.StartTLS()
|
||||||
|
|
||||||
|
rtManager := NewRoundTripperManager()
|
||||||
|
|
||||||
|
dynamicConf := map[string]*dynamic.ServersTransport{
|
||||||
|
"test": {
|
||||||
|
ServerName: "example.com",
|
||||||
|
RootCAs: []traefiktls.FileOrContent{traefiktls.FileOrContent(LocalhostCert)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
rtManager.Update(dynamicConf)
|
||||||
|
|
||||||
|
tr, err := rtManager.Get("test")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
client := http.Client{Transport: tr}
|
||||||
|
|
||||||
|
resp, err := client.Get(srv.URL)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
count := atomic.LoadInt32(connCount)
|
||||||
|
require.EqualValues(t, 1, count)
|
||||||
|
|
||||||
|
dynamicConf = map[string]*dynamic.ServersTransport{
|
||||||
|
"test": {
|
||||||
|
ServerName: "www.example.com",
|
||||||
|
RootCAs: []traefiktls.FileOrContent{traefiktls.FileOrContent(LocalhostCert)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
rtManager.Update(dynamicConf)
|
||||||
|
|
||||||
|
tr, err := rtManager.Get("test")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
client := http.Client{Transport: tr}
|
||||||
|
|
||||||
|
resp, err := client.Get(srv.URL)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
|
count = atomic.LoadInt32(connCount)
|
||||||
|
assert.EqualValues(t, 2, count)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMTLS(t *testing.T) {
|
||||||
|
srv := httptest.NewUnstartedServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
}))
|
||||||
|
|
||||||
|
cert, err := tls.X509KeyPair(LocalhostCert, LocalhostKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
clientPool := x509.NewCertPool()
|
||||||
|
clientPool.AppendCertsFromPEM(mTLSCert)
|
||||||
|
|
||||||
|
srv.TLS = &tls.Config{
|
||||||
|
// For TLS
|
||||||
|
Certificates: []tls.Certificate{cert},
|
||||||
|
|
||||||
|
// For mTLS
|
||||||
|
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||||
|
ClientCAs: clientPool,
|
||||||
|
}
|
||||||
|
srv.StartTLS()
|
||||||
|
|
||||||
|
rtManager := NewRoundTripperManager()
|
||||||
|
|
||||||
|
dynamicConf := map[string]*dynamic.ServersTransport{
|
||||||
|
"test": {
|
||||||
|
ServerName: "example.com",
|
||||||
|
// For TLS
|
||||||
|
RootCAs: []traefiktls.FileOrContent{traefiktls.FileOrContent(LocalhostCert)},
|
||||||
|
|
||||||
|
// For mTLS
|
||||||
|
Certificates: traefiktls.Certificates{
|
||||||
|
traefiktls.Certificate{
|
||||||
|
CertFile: traefiktls.FileOrContent(mTLSCert),
|
||||||
|
KeyFile: traefiktls.FileOrContent(mTLSKey),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
rtManager.Update(dynamicConf)
|
||||||
|
|
||||||
|
tr, err := rtManager.Get("test")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
client := http.Client{Transport: tr}
|
||||||
|
|
||||||
|
resp, err := client.Get(srv.URL)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
}
|
|
@ -35,13 +35,18 @@ const (
|
||||||
|
|
||||||
const defaultMaxBodySize int64 = -1
|
const defaultMaxBodySize int64 = -1
|
||||||
|
|
||||||
|
// RoundTripperGetter is a roundtripper getter interface.
|
||||||
|
type RoundTripperGetter interface {
|
||||||
|
Get(name string) (http.RoundTripper, error)
|
||||||
|
}
|
||||||
|
|
||||||
// NewManager creates a new Manager.
|
// NewManager creates a new Manager.
|
||||||
func NewManager(configs map[string]*runtime.ServiceInfo, defaultRoundTripper http.RoundTripper, metricsRegistry metrics.Registry, routinePool *safe.Pool) *Manager {
|
func NewManager(configs map[string]*runtime.ServiceInfo, metricsRegistry metrics.Registry, routinePool *safe.Pool, roundTripperManager RoundTripperGetter) *Manager {
|
||||||
return &Manager{
|
return &Manager{
|
||||||
routinePool: routinePool,
|
routinePool: routinePool,
|
||||||
metricsRegistry: metricsRegistry,
|
metricsRegistry: metricsRegistry,
|
||||||
bufferPool: newBufferPool(),
|
bufferPool: newBufferPool(),
|
||||||
defaultRoundTripper: defaultRoundTripper,
|
roundTripperManager: roundTripperManager,
|
||||||
balancers: make(map[string]healthcheck.Balancers),
|
balancers: make(map[string]healthcheck.Balancers),
|
||||||
configs: configs,
|
configs: configs,
|
||||||
}
|
}
|
||||||
|
@ -52,7 +57,7 @@ type Manager struct {
|
||||||
routinePool *safe.Pool
|
routinePool *safe.Pool
|
||||||
metricsRegistry metrics.Registry
|
metricsRegistry metrics.Registry
|
||||||
bufferPool httputil.BufferPool
|
bufferPool httputil.BufferPool
|
||||||
defaultRoundTripper http.RoundTripper
|
roundTripperManager RoundTripperGetter
|
||||||
// balancers is the map of all Balancers, keyed by service name.
|
// balancers is the map of all Balancers, keyed by service name.
|
||||||
// There is one Balancer per service handler, and there is one service handler per reference to a service
|
// There is one Balancer per service handler, and there is one service handler per reference to a service
|
||||||
// (e.g. if 2 routers refer to the same service name, 2 service handlers are created),
|
// (e.g. if 2 routers refer to the same service name, 2 service handlers are created),
|
||||||
|
@ -168,7 +173,16 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName
|
||||||
service.PassHostHeader = &defaultPassHostHeader
|
service.PassHostHeader = &defaultPassHostHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
fwd, err := buildProxy(service.PassHostHeader, service.ResponseForwarding, m.defaultRoundTripper, m.bufferPool)
|
if len(service.ServersTransport) > 0 {
|
||||||
|
service.ServersTransport = provider.GetQualifiedName(ctx, service.ServersTransport)
|
||||||
|
}
|
||||||
|
|
||||||
|
roundTripper, err := m.roundTripperManager.Get(service.ServersTransport)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fwd, err := buildProxy(service.PassHostHeader, service.ResponseForwarding, roundTripper, m.bufferPool)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -213,7 +227,7 @@ func (m *Manager) LaunchHealthCheck() {
|
||||||
if hcOpts := buildHealthCheckOptions(ctx, balancers, serviceName, service.HealthCheck); hcOpts != nil {
|
if hcOpts := buildHealthCheckOptions(ctx, balancers, serviceName, service.HealthCheck); hcOpts != nil {
|
||||||
log.FromContext(ctx).Debugf("Setting up healthcheck for service %s with %s", serviceName, *hcOpts)
|
log.FromContext(ctx).Debugf("Setting up healthcheck for service %s with %s", serviceName, *hcOpts)
|
||||||
|
|
||||||
hcOpts.Transport = m.defaultRoundTripper
|
hcOpts.Transport, _ = m.roundTripperManager.Get(service.ServersTransport)
|
||||||
backendHealthCheck = healthcheck.NewBackendConfig(*hcOpts, serviceName)
|
backendHealthCheck = healthcheck.NewBackendConfig(*hcOpts, serviceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,11 @@ func TestGetLoadBalancer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||||
sm := NewManager(nil, http.DefaultTransport, nil, nil)
|
sm := NewManager(nil, nil, nil, &RoundTripperManager{
|
||||||
|
roundTrippers: map[string]http.RoundTripper{
|
||||||
|
"default@internal": http.DefaultTransport,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
server1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("X-From", "first")
|
w.Header().Set("X-From", "first")
|
||||||
|
@ -332,7 +336,11 @@ func TestManager_Build(t *testing.T) {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
manager := NewManager(test.configs, http.DefaultTransport, nil, nil)
|
manager := NewManager(test.configs, nil, nil, &RoundTripperManager{
|
||||||
|
roundTrippers: map[string]http.RoundTripper{
|
||||||
|
"default@internal": http.DefaultTransport,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
if len(test.providerName) > 0 {
|
if len(test.providerName) > 0 {
|
||||||
|
@ -355,7 +363,11 @@ func TestMultipleTypeOnBuildHTTP(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
manager := NewManager(services, http.DefaultTransport, nil, nil)
|
manager := NewManager(services, nil, nil, &RoundTripperManager{
|
||||||
|
roundTrippers: map[string]http.RoundTripper{
|
||||||
|
"default@internal": http.DefaultTransport,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
_, err := manager.BuildHTTP(context.Background(), "test@file")
|
_, err := manager.BuildHTTP(context.Background(), "test@file")
|
||||||
assert.Error(t, err, "cannot create service: multi-types service not supported, consider declaring two different pieces of service instead")
|
assert.Error(t, err, "cannot create service: multi-types service not supported, consider declaring two different pieces of service instead")
|
||||||
|
|
|
@ -7,7 +7,8 @@ import (
|
||||||
// BuildConfiguration is a helper to create a configuration.
|
// BuildConfiguration is a helper to create a configuration.
|
||||||
func BuildConfiguration(dynamicConfigBuilders ...func(*dynamic.HTTPConfiguration)) *dynamic.HTTPConfiguration {
|
func BuildConfiguration(dynamicConfigBuilders ...func(*dynamic.HTTPConfiguration)) *dynamic.HTTPConfiguration {
|
||||||
conf := &dynamic.HTTPConfiguration{
|
conf := &dynamic.HTTPConfiguration{
|
||||||
Models: map[string]*dynamic.Model{},
|
Models: map[string]*dynamic.Model{},
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, build := range dynamicConfigBuilders {
|
for _, build := range dynamicConfigBuilders {
|
||||||
|
|
|
@ -56,6 +56,23 @@ type Certificate struct {
|
||||||
// Certs and Keys could be either a file path, or the file content itself.
|
// Certs and Keys could be either a file path, or the file content itself.
|
||||||
type Certificates []Certificate
|
type Certificates []Certificate
|
||||||
|
|
||||||
|
// GetCertificates retrieves the certificates as slice of tls.Certificate.
|
||||||
|
func (c Certificates) GetCertificates() []tls.Certificate {
|
||||||
|
var certs []tls.Certificate
|
||||||
|
|
||||||
|
for _, certificate := range c {
|
||||||
|
cert, err := certificate.GetCertificate()
|
||||||
|
if err != nil {
|
||||||
|
log.WithoutContext().Debugf("Error while getting certificate: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
certs = append(certs, cert)
|
||||||
|
}
|
||||||
|
|
||||||
|
return certs
|
||||||
|
}
|
||||||
|
|
||||||
// FileOrContent hold a file path or content.
|
// FileOrContent hold a file path or content.
|
||||||
type FileOrContent string
|
type FileOrContent string
|
||||||
|
|
||||||
|
@ -190,6 +207,26 @@ func (c *Certificate) AppendCertificate(certs map[string]map[string]*tls.Certifi
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCertificate retrieves Certificate as tls.Certificate.
|
||||||
|
func (c *Certificate) GetCertificate() (tls.Certificate, error) {
|
||||||
|
certContent, err := c.CertFile.Read()
|
||||||
|
if err != nil {
|
||||||
|
return tls.Certificate{}, fmt.Errorf("unable to read CertFile : %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyContent, err := c.KeyFile.Read()
|
||||||
|
if err != nil {
|
||||||
|
return tls.Certificate{}, fmt.Errorf("unable to read KeyFile : %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cert, err := tls.X509KeyPair(certContent, keyContent)
|
||||||
|
if err != nil {
|
||||||
|
return tls.Certificate{}, fmt.Errorf("unable to generate TLS certificate : %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetTruncatedCertificateName truncates the certificate name.
|
// GetTruncatedCertificateName truncates the certificate name.
|
||||||
func (c *Certificate) GetTruncatedCertificateName() string {
|
func (c *Certificate) GetTruncatedCertificateName() string {
|
||||||
certName := c.CertFile.String()
|
certName := c.CertFile.String()
|
||||||
|
|
Loading…
Reference in a new issue