1
0
Fork 0

Merge current v2.7 into v2.8

This commit is contained in:
romain 2022-06-27 16:12:21 +02:00
commit 41748c3ae4
59 changed files with 5767 additions and 1086 deletions

View file

@ -124,6 +124,7 @@ func (w *WRRService) SetDefaults() {
// Sticky holds the sticky configuration.
type Sticky struct {
// Cookie defines the sticky cookie configuration.
Cookie *Cookie `json:"cookie,omitempty" toml:"cookie,omitempty" yaml:"cookie,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
}
@ -131,9 +132,14 @@ type Sticky struct {
// Cookie holds the sticky configuration based on cookie.
type Cookie struct {
Name string `json:"name,omitempty" toml:"name,omitempty" yaml:"name,omitempty" export:"true"`
Secure bool `json:"secure,omitempty" toml:"secure,omitempty" yaml:"secure,omitempty" export:"true"`
HTTPOnly bool `json:"httpOnly,omitempty" toml:"httpOnly,omitempty" yaml:"httpOnly,omitempty" export:"true"`
// Name defines the Cookie name.
Name string `json:"name,omitempty" toml:"name,omitempty" yaml:"name,omitempty" export:"true"`
// Secure defines whether the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Secure bool `json:"secure,omitempty" toml:"secure,omitempty" yaml:"secure,omitempty" export:"true"`
// HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript.
HTTPOnly bool `json:"httpOnly,omitempty" toml:"httpOnly,omitempty" yaml:"httpOnly,omitempty" export:"true"`
// SameSite defines the same site policy.
// More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
SameSite string `json:"sameSite,omitempty" toml:"sameSite,omitempty" yaml:"sameSite,omitempty" export:"true"`
}
@ -178,8 +184,13 @@ func (l *ServersLoadBalancer) SetDefaults() {
// +k8s:deepcopy-gen=true
// ResponseForwarding holds configuration for the forward of the response.
// ResponseForwarding holds the response forwarding configuration.
type ResponseForwarding struct {
// FlushInterval defines the interval, in milliseconds, in between flushes to the client while copying the response body.
// A negative value means to flush immediately after each write to the client.
// This configuration is ignored when ReverseProxy recognizes a response as a streaming response;
// for such responses, writes are flushed to the client immediately.
// Default: 100ms
FlushInterval string `json:"flushInterval,omitempty" toml:"flushInterval,omitempty" yaml:"flushInterval,omitempty" export:"true"`
}

View file

@ -40,60 +40,93 @@ type Middleware struct {
// +k8s:deepcopy-gen=true
// ContentType middleware - or rather its unique `autoDetect` option -
// specifies whether to let the `Content-Type` header,
// if it has not been set by the backend,
// be automatically set to a value derived from the contents of the response.
// As a proxy, the default behavior should be to leave the header alone,
// regardless of what the backend did with it.
// However, the historic default was to always auto-detect and set the header if it was nil,
// and it is going to be kept that way in order to support users currently relying on it.
// ContentType holds the content-type middleware configuration.
// This middleware exists to enable the correct behavior until at least the default one can be changed in a future version.
type ContentType struct {
// AutoDetect specifies whether to let the `Content-Type` header, if it has not been set by the backend,
// be automatically set to a value derived from the contents of the response.
// As a proxy, the default behavior should be to leave the header alone, regardless of what the backend did with it.
// However, the historic default was to always auto-detect and set the header if it was nil,
// and it is going to be kept that way in order to support users currently relying on it.
AutoDetect bool `json:"autoDetect,omitempty" toml:"autoDetect,omitempty" yaml:"autoDetect,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// AddPrefix holds the AddPrefix configuration.
// AddPrefix holds the add prefix middleware configuration.
// This middleware updates the path of a request before forwarding it.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/addprefix/
type AddPrefix struct {
// Prefix is the string to add before the current path in the requested URL.
// It should include a leading slash (/).
Prefix string `json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// BasicAuth holds the HTTP basic authentication configuration.
// BasicAuth holds the basic auth middleware configuration.
// This middleware restricts access to your services to known users.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/basicauth/
type BasicAuth struct {
Users Users `json:"users,omitempty" toml:"users,omitempty" yaml:"users,omitempty" loggable:"false"`
UsersFile string `json:"usersFile,omitempty" toml:"usersFile,omitempty" yaml:"usersFile,omitempty"`
Realm string `json:"realm,omitempty" toml:"realm,omitempty" yaml:"realm,omitempty"`
RemoveHeader bool `json:"removeHeader,omitempty" toml:"removeHeader,omitempty" yaml:"removeHeader,omitempty" export:"true"`
HeaderField string `json:"headerField,omitempty" toml:"headerField,omitempty" yaml:"headerField,omitempty" export:"true"`
// Users is an array of authorized users.
// Each user must be declared using the name:hashed-password format.
// Tip: Use htpasswd to generate the passwords.
Users Users `json:"users,omitempty" toml:"users,omitempty" yaml:"users,omitempty" loggable:"false"`
// UsersFile is the path to an external file that contains the authorized users.
UsersFile string `json:"usersFile,omitempty" toml:"usersFile,omitempty" yaml:"usersFile,omitempty"`
// Realm allows the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme.
// Default: traefik.
Realm string `json:"realm,omitempty" toml:"realm,omitempty" yaml:"realm,omitempty"`
// RemoveHeader sets the removeHeader option to true to remove the authorization header before forwarding the request to your service.
// Default: false.
RemoveHeader bool `json:"removeHeader,omitempty" toml:"removeHeader,omitempty" yaml:"removeHeader,omitempty" export:"true"`
// HeaderField defines a header field to store the authenticated user.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/basicauth/#headerfield
HeaderField string `json:"headerField,omitempty" toml:"headerField,omitempty" yaml:"headerField,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// Buffering holds the request/response buffering configuration.
// Buffering holds the buffering middleware configuration.
// This middleware retries or limits the size of requests that can be forwarded to backends.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/buffering/#maxrequestbodybytes
type Buffering struct {
MaxRequestBodyBytes int64 `json:"maxRequestBodyBytes,omitempty" toml:"maxRequestBodyBytes,omitempty" yaml:"maxRequestBodyBytes,omitempty" export:"true"`
MemRequestBodyBytes int64 `json:"memRequestBodyBytes,omitempty" toml:"memRequestBodyBytes,omitempty" yaml:"memRequestBodyBytes,omitempty" export:"true"`
MaxResponseBodyBytes int64 `json:"maxResponseBodyBytes,omitempty" toml:"maxResponseBodyBytes,omitempty" yaml:"maxResponseBodyBytes,omitempty" export:"true"`
MemResponseBodyBytes int64 `json:"memResponseBodyBytes,omitempty" toml:"memResponseBodyBytes,omitempty" yaml:"memResponseBodyBytes,omitempty" export:"true"`
RetryExpression string `json:"retryExpression,omitempty" toml:"retryExpression,omitempty" yaml:"retryExpression,omitempty" export:"true"`
// MaxRequestBodyBytes defines the maximum allowed body size for the request (in bytes).
// If the request exceeds the allowed size, it is not forwarded to the service, and the client gets a 413 (Request Entity Too Large) response.
// Default: 0 (no maximum).
MaxRequestBodyBytes int64 `json:"maxRequestBodyBytes,omitempty" toml:"maxRequestBodyBytes,omitempty" yaml:"maxRequestBodyBytes,omitempty" export:"true"`
// MemRequestBodyBytes defines the threshold (in bytes) from which the request will be buffered on disk instead of in memory.
// Default: 1048576 (1Mi).
MemRequestBodyBytes int64 `json:"memRequestBodyBytes,omitempty" toml:"memRequestBodyBytes,omitempty" yaml:"memRequestBodyBytes,omitempty" export:"true"`
// MaxResponseBodyBytes defines the maximum allowed response size from the service (in bytes).
// If the response exceeds the allowed size, it is not forwarded to the client. The client gets a 500 (Internal Server Error) response instead.
// Default: 0 (no maximum).
MaxResponseBodyBytes int64 `json:"maxResponseBodyBytes,omitempty" toml:"maxResponseBodyBytes,omitempty" yaml:"maxResponseBodyBytes,omitempty" export:"true"`
// MemResponseBodyBytes defines the threshold (in bytes) from which the response will be buffered on disk instead of in memory.
// Default: 1048576 (1Mi).
MemResponseBodyBytes int64 `json:"memResponseBodyBytes,omitempty" toml:"memResponseBodyBytes,omitempty" yaml:"memResponseBodyBytes,omitempty" export:"true"`
// RetryExpression defines the retry conditions.
// It is a logical combination of functions with operators AND (&&) and OR (||).
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/buffering/#retryexpression
RetryExpression string `json:"retryExpression,omitempty" toml:"retryExpression,omitempty" yaml:"retryExpression,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// Chain holds a chain of middlewares.
// Chain holds the chain middleware configuration.
// This middleware enables to define reusable combinations of other pieces of middleware.
type Chain struct {
// Middlewares is the list of middleware names which composes the chain.
Middlewares []string `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// CircuitBreaker holds the circuit breaker configuration.
// CircuitBreaker holds the circuit breaker middleware configuration.
// This middleware protects the system from stacking requests to unhealthy services, resulting in cascading failures.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/circuitbreaker/
type CircuitBreaker struct {
// Expression is the condition that triggers the tripped state.
// Expression defines the expression that, once matched, opens the circuit breaker and applies the fallback mechanism instead of calling the services.
Expression string `json:"expression,omitempty" toml:"expression,omitempty" yaml:"expression,omitempty" export:"true"`
// CheckPeriod is the interval between successive checks of the circuit breaker condition (when in standby state).
CheckPeriod ptypes.Duration `json:"checkPeriod,omitempty" toml:"checkPeriod,omitempty" yaml:"checkPeriod,omitempty" export:"true"`
@ -112,95 +145,158 @@ func (c *CircuitBreaker) SetDefaults() {
// +k8s:deepcopy-gen=true
// Compress holds the compress configuration.
// Compress holds the compress middleware configuration.
// This middleware compresses responses before sending them to the client, using gzip compression.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/compress/
type Compress struct {
// ExcludedContentTypes defines the list of content types to compare the Content-Type header of the incoming requests and responses before compressing.
ExcludedContentTypes []string `json:"excludedContentTypes,omitempty" toml:"excludedContentTypes,omitempty" yaml:"excludedContentTypes,omitempty" export:"true"`
MinResponseBodyBytes int `json:"minResponseBodyBytes,omitempty" toml:"minResponseBodyBytes,omitempty" yaml:"minResponseBodyBytes,omitempty" export:"true"`
// MinResponseBodyBytes defines the minimum amount of bytes a response body must have to be compressed.
// Default: 1024.
MinResponseBodyBytes int `json:"minResponseBodyBytes,omitempty" toml:"minResponseBodyBytes,omitempty" yaml:"minResponseBodyBytes,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// DigestAuth holds the Digest HTTP authentication configuration.
// DigestAuth holds the digest auth middleware configuration.
// This middleware restricts access to your services to known users.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/digestauth/
type DigestAuth struct {
Users Users `json:"users,omitempty" toml:"users,omitempty" yaml:"users,omitempty" loggable:"false"`
UsersFile string `json:"usersFile,omitempty" toml:"usersFile,omitempty" yaml:"usersFile,omitempty"`
RemoveHeader bool `json:"removeHeader,omitempty" toml:"removeHeader,omitempty" yaml:"removeHeader,omitempty" export:"true"`
Realm string `json:"realm,omitempty" toml:"realm,omitempty" yaml:"realm,omitempty"`
HeaderField string `json:"headerField,omitempty" toml:"headerField,omitempty" yaml:"headerField,omitempty" export:"true"`
// Users defines the authorized users.
// Each user should be declared using the name:realm:encoded-password format.
Users Users `json:"users,omitempty" toml:"users,omitempty" yaml:"users,omitempty" loggable:"false"`
// UsersFile is the path to an external file that contains the authorized users for the middleware.
UsersFile string `json:"usersFile,omitempty" toml:"usersFile,omitempty" yaml:"usersFile,omitempty"`
// RemoveHeader defines whether to remove the authorization header before forwarding the request to the backend.
RemoveHeader bool `json:"removeHeader,omitempty" toml:"removeHeader,omitempty" yaml:"removeHeader,omitempty" export:"true"`
// Realm allows the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme.
// Default: traefik.
Realm string `json:"realm,omitempty" toml:"realm,omitempty" yaml:"realm,omitempty"`
// HeaderField defines a header field to store the authenticated user.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/basicauth/#headerfield
HeaderField string `json:"headerField,omitempty" toml:"headerField,omitempty" yaml:"headerField,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// ErrorPage holds the custom error page configuration.
// ErrorPage holds the custom error middleware configuration.
// This middleware returns a custom page in lieu of the default, according to configured ranges of HTTP Status codes.
type ErrorPage struct {
Status []string `json:"status,omitempty" toml:"status,omitempty" yaml:"status,omitempty" export:"true"`
Service string `json:"service,omitempty" toml:"service,omitempty" yaml:"service,omitempty" export:"true"`
Query string `json:"query,omitempty" toml:"query,omitempty" yaml:"query,omitempty" export:"true"`
// Status defines which status or range of statuses should result in an error page.
// It can be either a status code as a number (500),
// as multiple comma-separated numbers (500,502),
// as ranges by separating two codes with a dash (500-599),
// or a combination of the two (404,418,500-599).
Status []string `json:"status,omitempty" toml:"status,omitempty" yaml:"status,omitempty" export:"true"`
// Service defines the name of the service that will serve the error page.
Service string `json:"service,omitempty" toml:"service,omitempty" yaml:"service,omitempty" export:"true"`
// Query defines the URL for the error page (hosted by service).
// The {status} variable can be used in order to insert the status code in the URL.
Query string `json:"query,omitempty" toml:"query,omitempty" yaml:"query,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// ForwardAuth holds the http forward authentication configuration.
// ForwardAuth holds the forward auth middleware configuration.
// This middleware delegates the request authentication to a Service.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/forwardauth/
type ForwardAuth struct {
Address string `json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`
TLS *types.ClientTLS `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
TrustForwardHeader bool `json:"trustForwardHeader,omitempty" toml:"trustForwardHeader,omitempty" yaml:"trustForwardHeader,omitempty" export:"true"`
AuthResponseHeaders []string `json:"authResponseHeaders,omitempty" toml:"authResponseHeaders,omitempty" yaml:"authResponseHeaders,omitempty" export:"true"`
AuthResponseHeadersRegex string `json:"authResponseHeadersRegex,omitempty" toml:"authResponseHeadersRegex,omitempty" yaml:"authResponseHeadersRegex,omitempty" export:"true"`
AuthRequestHeaders []string `json:"authRequestHeaders,omitempty" toml:"authRequestHeaders,omitempty" yaml:"authRequestHeaders,omitempty" export:"true"`
// Address defines the authentication server address.
Address string `json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`
// TLS defines the configuration used to secure the connection to the authentication server.
TLS *types.ClientTLS `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
// TrustForwardHeader defines whether to trust (ie: forward) all X-Forwarded-* headers.
TrustForwardHeader bool `json:"trustForwardHeader,omitempty" toml:"trustForwardHeader,omitempty" yaml:"trustForwardHeader,omitempty" export:"true"`
// AuthResponseHeaders defines the list of headers to copy from the authentication server response and set on forwarded request, replacing any existing conflicting headers.
AuthResponseHeaders []string `json:"authResponseHeaders,omitempty" toml:"authResponseHeaders,omitempty" yaml:"authResponseHeaders,omitempty" export:"true"`
// AuthResponseHeadersRegex defines the regex to match headers to copy from the authentication server response and set on forwarded request, after stripping all headers that match the regex.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/forwardauth/#authresponseheadersregex
AuthResponseHeadersRegex string `json:"authResponseHeadersRegex,omitempty" toml:"authResponseHeadersRegex,omitempty" yaml:"authResponseHeadersRegex,omitempty" export:"true"`
// AuthRequestHeaders defines the list of the headers to copy from the request to the authentication server.
// If not set or empty then all request headers are passed.
AuthRequestHeaders []string `json:"authRequestHeaders,omitempty" toml:"authRequestHeaders,omitempty" yaml:"authRequestHeaders,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// Headers holds the custom header configuration.
// Headers holds the headers middleware configuration.
// This middleware manages the requests and responses headers.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/headers/#customrequestheaders
type Headers struct {
CustomRequestHeaders map[string]string `json:"customRequestHeaders,omitempty" toml:"customRequestHeaders,omitempty" yaml:"customRequestHeaders,omitempty" export:"true"`
// CustomRequestHeaders defines the header names and values to apply to the request.
CustomRequestHeaders map[string]string `json:"customRequestHeaders,omitempty" toml:"customRequestHeaders,omitempty" yaml:"customRequestHeaders,omitempty" export:"true"`
// CustomResponseHeaders defines the header names and values to apply to the response.
CustomResponseHeaders map[string]string `json:"customResponseHeaders,omitempty" toml:"customResponseHeaders,omitempty" yaml:"customResponseHeaders,omitempty" export:"true"`
// AccessControlAllowCredentials is only valid if true. false is ignored.
// AccessControlAllowCredentials defines whether the request can include user credentials.
AccessControlAllowCredentials bool `json:"accessControlAllowCredentials,omitempty" toml:"accessControlAllowCredentials,omitempty" yaml:"accessControlAllowCredentials,omitempty" export:"true"`
// AccessControlAllowHeaders must be used in response to a preflight request with Access-Control-Request-Headers set.
// AccessControlAllowHeaders defines the Access-Control-Request-Headers values sent in preflight response.
AccessControlAllowHeaders []string `json:"accessControlAllowHeaders,omitempty" toml:"accessControlAllowHeaders,omitempty" yaml:"accessControlAllowHeaders,omitempty" export:"true"`
// AccessControlAllowMethods must be used in response to a preflight request with Access-Control-Request-Method set.
// AccessControlAllowMethods defines the Access-Control-Request-Method values sent in preflight response.
AccessControlAllowMethods []string `json:"accessControlAllowMethods,omitempty" toml:"accessControlAllowMethods,omitempty" yaml:"accessControlAllowMethods,omitempty" export:"true"`
// AccessControlAllowOriginList is a list of allowable origins. Can also be a wildcard origin "*".
AccessControlAllowOriginList []string `json:"accessControlAllowOriginList,omitempty" toml:"accessControlAllowOriginList,omitempty" yaml:"accessControlAllowOriginList,omitempty"`
// AccessControlAllowOriginListRegex is a list of allowable origins written following the Regular Expression syntax (https://golang.org/pkg/regexp/).
AccessControlAllowOriginListRegex []string `json:"accessControlAllowOriginListRegex,omitempty" toml:"accessControlAllowOriginListRegex,omitempty" yaml:"accessControlAllowOriginListRegex,omitempty"`
// AccessControlExposeHeaders sets valid headers for the response.
// AccessControlExposeHeaders defines the Access-Control-Expose-Headers values sent in preflight response.
AccessControlExposeHeaders []string `json:"accessControlExposeHeaders,omitempty" toml:"accessControlExposeHeaders,omitempty" yaml:"accessControlExposeHeaders,omitempty" export:"true"`
// AccessControlMaxAge sets the time that a preflight request may be cached.
// AccessControlMaxAge defines the time that a preflight request may be cached.
AccessControlMaxAge int64 `json:"accessControlMaxAge,omitempty" toml:"accessControlMaxAge,omitempty" yaml:"accessControlMaxAge,omitempty" export:"true"`
// AddVaryHeader controls if the Vary header is automatically added/updated when the AccessControlAllowOriginList is set.
// AddVaryHeader defines whether the Vary header is automatically added/updated when the AccessControlAllowOriginList is set.
AddVaryHeader bool `json:"addVaryHeader,omitempty" toml:"addVaryHeader,omitempty" yaml:"addVaryHeader,omitempty" export:"true"`
AllowedHosts []string `json:"allowedHosts,omitempty" toml:"allowedHosts,omitempty" yaml:"allowedHosts,omitempty"`
// AllowedHosts defines the fully qualified list of allowed domain names.
AllowedHosts []string `json:"allowedHosts,omitempty" toml:"allowedHosts,omitempty" yaml:"allowedHosts,omitempty"`
// HostsProxyHeaders defines the header keys that may hold a proxied hostname value for the request.
HostsProxyHeaders []string `json:"hostsProxyHeaders,omitempty" toml:"hostsProxyHeaders,omitempty" yaml:"hostsProxyHeaders,omitempty" export:"true"`
// Deprecated: use EntryPoint redirection or RedirectScheme instead.
SSLRedirect bool `json:"sslRedirect,omitempty" toml:"sslRedirect,omitempty" yaml:"sslRedirect,omitempty" export:"true"`
// Deprecated: use EntryPoint redirection or RedirectScheme instead.
SSLTemporaryRedirect bool `json:"sslTemporaryRedirect,omitempty" toml:"sslTemporaryRedirect,omitempty" yaml:"sslTemporaryRedirect,omitempty" export:"true"`
// Deprecated: use RedirectRegex instead.
SSLHost string `json:"sslHost,omitempty" toml:"sslHost,omitempty" yaml:"sslHost,omitempty"`
SSLHost string `json:"sslHost,omitempty" toml:"sslHost,omitempty" yaml:"sslHost,omitempty"`
// SSLProxyHeaders defines the header keys with associated values that would indicate a valid HTTPS request.
// It can be useful when using other proxies (example: "X-Forwarded-Proto": "https").
SSLProxyHeaders map[string]string `json:"sslProxyHeaders,omitempty" toml:"sslProxyHeaders,omitempty" yaml:"sslProxyHeaders,omitempty"`
// Deprecated: use RedirectRegex instead.
SSLForceHost bool `json:"sslForceHost,omitempty" toml:"sslForceHost,omitempty" yaml:"sslForceHost,omitempty" export:"true"`
STSSeconds int64 `json:"stsSeconds,omitempty" toml:"stsSeconds,omitempty" yaml:"stsSeconds,omitempty" export:"true"`
STSIncludeSubdomains bool `json:"stsIncludeSubdomains,omitempty" toml:"stsIncludeSubdomains,omitempty" yaml:"stsIncludeSubdomains,omitempty" export:"true"`
STSPreload bool `json:"stsPreload,omitempty" toml:"stsPreload,omitempty" yaml:"stsPreload,omitempty" export:"true"`
ForceSTSHeader bool `json:"forceSTSHeader,omitempty" toml:"forceSTSHeader,omitempty" yaml:"forceSTSHeader,omitempty" export:"true"`
FrameDeny bool `json:"frameDeny,omitempty" toml:"frameDeny,omitempty" yaml:"frameDeny,omitempty" export:"true"`
SSLForceHost bool `json:"sslForceHost,omitempty" toml:"sslForceHost,omitempty" yaml:"sslForceHost,omitempty" export:"true"`
// STSSeconds defines the max-age of the Strict-Transport-Security header.
// If set to 0, the header is not set.
STSSeconds int64 `json:"stsSeconds,omitempty" toml:"stsSeconds,omitempty" yaml:"stsSeconds,omitempty" export:"true"`
// STSIncludeSubdomains defines whether the includeSubDomains directive is appended to the Strict-Transport-Security header.
STSIncludeSubdomains bool `json:"stsIncludeSubdomains,omitempty" toml:"stsIncludeSubdomains,omitempty" yaml:"stsIncludeSubdomains,omitempty" export:"true"`
// STSPreload defines whether the preload flag is appended to the Strict-Transport-Security header.
STSPreload bool `json:"stsPreload,omitempty" toml:"stsPreload,omitempty" yaml:"stsPreload,omitempty" export:"true"`
// ForceSTSHeader defines whether to add the STS header even when the connection is HTTP.
ForceSTSHeader bool `json:"forceSTSHeader,omitempty" toml:"forceSTSHeader,omitempty" yaml:"forceSTSHeader,omitempty" export:"true"`
// FrameDeny defines whether to add the X-Frame-Options header with the DENY value.
FrameDeny bool `json:"frameDeny,omitempty" toml:"frameDeny,omitempty" yaml:"frameDeny,omitempty" export:"true"`
// CustomFrameOptionsValue defines the X-Frame-Options header value.
// This overrides the FrameDeny option.
CustomFrameOptionsValue string `json:"customFrameOptionsValue,omitempty" toml:"customFrameOptionsValue,omitempty" yaml:"customFrameOptionsValue,omitempty"`
ContentTypeNosniff bool `json:"contentTypeNosniff,omitempty" toml:"contentTypeNosniff,omitempty" yaml:"contentTypeNosniff,omitempty" export:"true"`
BrowserXSSFilter bool `json:"browserXssFilter,omitempty" toml:"browserXssFilter,omitempty" yaml:"browserXssFilter,omitempty" export:"true"`
CustomBrowserXSSValue string `json:"customBrowserXSSValue,omitempty" toml:"customBrowserXSSValue,omitempty" yaml:"customBrowserXSSValue,omitempty"`
ContentSecurityPolicy string `json:"contentSecurityPolicy,omitempty" toml:"contentSecurityPolicy,omitempty" yaml:"contentSecurityPolicy,omitempty"`
PublicKey string `json:"publicKey,omitempty" toml:"publicKey,omitempty" yaml:"publicKey,omitempty"`
ReferrerPolicy string `json:"referrerPolicy,omitempty" toml:"referrerPolicy,omitempty" yaml:"referrerPolicy,omitempty" export:"true"`
// ContentTypeNosniff defines whether to add the X-Content-Type-Options header with the nosniff value.
ContentTypeNosniff bool `json:"contentTypeNosniff,omitempty" toml:"contentTypeNosniff,omitempty" yaml:"contentTypeNosniff,omitempty" export:"true"`
// BrowserXSSFilter defines whether to add the X-XSS-Protection header with the value 1; mode=block.
BrowserXSSFilter bool `json:"browserXssFilter,omitempty" toml:"browserXssFilter,omitempty" yaml:"browserXssFilter,omitempty" export:"true"`
// CustomBrowserXSSValue defines the X-XSS-Protection header value.
// This overrides the BrowserXssFilter option.
CustomBrowserXSSValue string `json:"customBrowserXSSValue,omitempty" toml:"customBrowserXSSValue,omitempty" yaml:"customBrowserXSSValue,omitempty"`
// ContentSecurityPolicy defines the Content-Security-Policy header value.
ContentSecurityPolicy string `json:"contentSecurityPolicy,omitempty" toml:"contentSecurityPolicy,omitempty" yaml:"contentSecurityPolicy,omitempty"`
// PublicKey is the public key that implements HPKP to prevent MITM attacks with forged certificates.
PublicKey string `json:"publicKey,omitempty" toml:"publicKey,omitempty" yaml:"publicKey,omitempty"`
// ReferrerPolicy defines the Referrer-Policy header value.
// This allows sites to control whether browsers forward the Referer header to other sites.
ReferrerPolicy string `json:"referrerPolicy,omitempty" toml:"referrerPolicy,omitempty" yaml:"referrerPolicy,omitempty" export:"true"`
// Deprecated: use PermissionsPolicy instead.
FeaturePolicy string `json:"featurePolicy,omitempty" toml:"featurePolicy,omitempty" yaml:"featurePolicy,omitempty" export:"true"`
FeaturePolicy string `json:"featurePolicy,omitempty" toml:"featurePolicy,omitempty" yaml:"featurePolicy,omitempty" export:"true"`
// PermissionsPolicy defines the Permissions-Policy header value.
// This allows sites to control browser features.
PermissionsPolicy string `json:"permissionsPolicy,omitempty" toml:"permissionsPolicy,omitempty" yaml:"permissionsPolicy,omitempty" export:"true"`
IsDevelopment bool `json:"isDevelopment,omitempty" toml:"isDevelopment,omitempty" yaml:"isDevelopment,omitempty" export:"true"`
// IsDevelopment defines whether to mitigate the unwanted effects of the AllowedHosts, SSL, and STS options when developing.
// Usually testing takes place using HTTP, not HTTPS, and on localhost, not your production domain.
// If you would like your development environment to mimic production with complete Host blocking, SSL redirects,
// and STS headers, leave this as false.
IsDevelopment bool `json:"isDevelopment,omitempty" toml:"isDevelopment,omitempty" yaml:"isDevelopment,omitempty" export:"true"`
}
// HasCustomHeadersDefined checks to see if any of the custom header elements have been set.
@ -249,9 +345,12 @@ func (h *Headers) HasSecureHeadersDefined() bool {
// +k8s:deepcopy-gen=true
// IPStrategy holds the ip strategy configuration.
// IPStrategy holds the IP strategy configuration used by Traefik to determine the client IP.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/ipwhitelist/#ipstrategy
type IPStrategy struct {
Depth int `json:"depth,omitempty" toml:"depth,omitempty" yaml:"depth,omitempty" export:"true"`
// Depth tells Traefik to use the X-Forwarded-For header and take the IP located at the depth position (starting from the right).
Depth int `json:"depth,omitempty" toml:"depth,omitempty" yaml:"depth,omitempty" export:"true"`
// ExcludedIPs configures Traefik to scan the X-Forwarded-For header and select the first IP not in the list.
ExcludedIPs []string `json:"excludedIPs,omitempty" toml:"excludedIPs,omitempty" yaml:"excludedIPs,omitempty"`
// TODO(mpl): I think we should make RemoteAddr an explicit field. For one thing, it would yield better documentation.
}
@ -286,25 +385,40 @@ func (s *IPStrategy) Get() (ip.Strategy, error) {
// +k8s:deepcopy-gen=true
// IPWhiteList holds the ip white list configuration.
// IPWhiteList holds the IP whitelist middleware configuration.
// This middleware accepts / refuses requests based on the client IP.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/ipwhitelist/
type IPWhiteList struct {
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation).
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
}
// +k8s:deepcopy-gen=true
// InFlightReq limits the number of requests being processed and served concurrently.
// InFlightReq holds the in-flight request middleware configuration.
// This middleware limits the number of requests being processed and served concurrently.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/inflightreq/
type InFlightReq struct {
Amount int64 `json:"amount,omitempty" toml:"amount,omitempty" yaml:"amount,omitempty" export:"true"`
// Amount defines the maximum amount of allowed simultaneous in-flight request.
// The middleware responds with HTTP 429 Too Many Requests if there are already amount requests in progress (based on the same sourceCriterion strategy).
Amount int64 `json:"amount,omitempty" toml:"amount,omitempty" yaml:"amount,omitempty" export:"true"`
// SourceCriterion defines what criterion is used to group requests as originating from a common source.
// If several strategies are defined at the same time, an error will be raised.
// If none are set, the default is to use the requestHost.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/inflightreq/#sourcecriterion
SourceCriterion *SourceCriterion `json:"sourceCriterion,omitempty" toml:"sourceCriterion,omitempty" yaml:"sourceCriterion,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// PassTLSClientCert holds the TLS client cert headers configuration.
// PassTLSClientCert holds the pass TLS client cert middleware configuration.
// This middleware adds the selected data from the passed client TLS certificate to a header.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/passtlsclientcert/
type PassTLSClientCert struct {
PEM bool `json:"pem,omitempty" toml:"pem,omitempty" yaml:"pem,omitempty" export:"true"`
// PEM sets the X-Forwarded-Tls-Client-Cert header with the escaped certificate.
PEM bool `json:"pem,omitempty" toml:"pem,omitempty" yaml:"pem,omitempty" export:"true"`
// Info selects the specific client certificate details you want to add to the X-Forwarded-Tls-Client-Cert-Info header.
Info *TLSClientCertificateInfo `json:"info,omitempty" toml:"info,omitempty" yaml:"info,omitempty" export:"true"`
}
@ -314,14 +428,17 @@ type PassTLSClientCert struct {
// If none are set, the default is to use the request's remote address field.
// All fields are mutually exclusive.
type SourceCriterion struct {
IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" export:"true"`
RequestHeaderName string `json:"requestHeaderName,omitempty" toml:"requestHeaderName,omitempty" yaml:"requestHeaderName,omitempty" export:"true"`
RequestHost bool `json:"requestHost,omitempty" toml:"requestHost,omitempty" yaml:"requestHost,omitempty" export:"true"`
IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" export:"true"`
// RequestHeaderName defines the name of the header used to group incoming requests.
RequestHeaderName string `json:"requestHeaderName,omitempty" toml:"requestHeaderName,omitempty" yaml:"requestHeaderName,omitempty" export:"true"`
// RequestHost defines whether to consider the request Host as the source.
RequestHost bool `json:"requestHost,omitempty" toml:"requestHost,omitempty" yaml:"requestHost,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// RateLimit holds the rate limiting configuration for a given router.
// RateLimit holds the rate limit configuration.
// This middleware ensures that services will receive a fair amount of requests, and allows one to define what fair is.
type RateLimit struct {
// Average is the maximum rate, by default in requests/s, allowed for the given source.
// It defaults to 0, which means no rate limiting.
@ -337,6 +454,9 @@ type RateLimit struct {
// It defaults to 1.
Burst int64 `json:"burst,omitempty" toml:"burst,omitempty" yaml:"burst,omitempty" export:"true"`
// SourceCriterion defines what criterion is used to group requests as originating from a common source.
// If several strategies are defined at the same time, an error will be raised.
// If none are set, the default is to use the request's remote address field (as an ipStrategy).
SourceCriterion *SourceCriterion `json:"sourceCriterion,omitempty" toml:"sourceCriterion,omitempty" yaml:"sourceCriterion,omitempty" export:"true"`
}
@ -348,51 +468,82 @@ func (r *RateLimit) SetDefaults() {
// +k8s:deepcopy-gen=true
// RedirectRegex holds the redirection configuration.
// RedirectRegex holds the redirect regex middleware configuration.
// This middleware redirects a request using regex matching and replacement.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/redirectregex/#regex
type RedirectRegex struct {
Regex string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty"`
// Regex defines the regex used to match and capture elements from the request URL.
Regex string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty"`
// Replacement defines how to modify the URL to have the new target URL.
Replacement string `json:"replacement,omitempty" toml:"replacement,omitempty" yaml:"replacement,omitempty"`
Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
// Permanent defines whether the redirection is permanent (301).
Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// RedirectScheme holds the scheme redirection configuration.
// RedirectScheme holds the redirect scheme middleware configuration.
// This middleware redirects requests from a scheme/port to another.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/redirectscheme/
type RedirectScheme struct {
Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"`
Port string `json:"port,omitempty" toml:"port,omitempty" yaml:"port,omitempty" export:"true"`
Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
// Scheme defines the scheme of the new URL.
Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"`
// Port defines the port of the new URL.
Port string `json:"port,omitempty" toml:"port,omitempty" yaml:"port,omitempty" export:"true"`
// Permanent defines whether the redirection is permanent (301).
Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// ReplacePath holds the ReplacePath configuration.
// ReplacePath holds the replace path middleware configuration.
// This middleware replaces the path of the request URL and store the original path in an X-Replaced-Path header.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/replacepath/
type ReplacePath struct {
// Path defines the path to use as replacement in the request URL.
Path string `json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// ReplacePathRegex holds the ReplacePathRegex configuration.
// ReplacePathRegex holds the replace path regex middleware configuration.
// This middleware replaces the path of a URL using regex matching and replacement.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/replacepathregex/
type ReplacePathRegex struct {
Regex string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty" export:"true"`
// Regex defines the regular expression used to match and capture the path from the request URL.
Regex string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty" export:"true"`
// Replacement defines the replacement path format, which can include captured variables.
Replacement string `json:"replacement,omitempty" toml:"replacement,omitempty" yaml:"replacement,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// Retry holds the retry configuration.
// Retry holds the retry middleware configuration.
// This middleware reissues requests a given number of times to a backend server if that server does not reply.
// As soon as the server answers, the middleware stops retrying, regardless of the response status.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/retry/
type Retry struct {
Attempts int `json:"attempts,omitempty" toml:"attempts,omitempty" yaml:"attempts,omitempty" export:"true"`
// Attempts defines how many times the request should be retried.
Attempts int `json:"attempts,omitempty" toml:"attempts,omitempty" yaml:"attempts,omitempty" export:"true"`
// InitialInterval defines the first wait time in the exponential backoff series.
// The maximum interval is calculated as twice the initialInterval.
// If unspecified, requests will be retried immediately.
// The value of initialInterval should be provided in seconds or as a valid duration format,
// see https://pkg.go.dev/time#ParseDuration.
InitialInterval ptypes.Duration `json:"initialInterval,omitempty" toml:"initialInterval,omitempty" yaml:"initialInterval,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// StripPrefix holds the StripPrefix configuration.
// StripPrefix holds the strip prefix middleware configuration.
// This middleware removes the specified prefixes from the URL path.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/stripprefix/
type StripPrefix struct {
Prefixes []string `json:"prefixes,omitempty" toml:"prefixes,omitempty" yaml:"prefixes,omitempty" export:"true"`
ForceSlash bool `json:"forceSlash,omitempty" toml:"forceSlash,omitempty" yaml:"forceSlash,omitempty" export:"true"` // Deprecated
// Prefixes defines the prefixes to strip from the request URL.
Prefixes []string `json:"prefixes,omitempty" toml:"prefixes,omitempty" yaml:"prefixes,omitempty" export:"true"`
// ForceSlash ensures that the resulting stripped path is not the empty string, by replacing it with / when necessary.
// Default: true.
ForceSlash bool `json:"forceSlash,omitempty" toml:"forceSlash,omitempty" yaml:"forceSlash,omitempty" export:"true"` // Deprecated
}
// SetDefaults Default values for a StripPrefix.
@ -402,8 +553,11 @@ func (s *StripPrefix) SetDefaults() {
// +k8s:deepcopy-gen=true
// StripPrefixRegex holds the StripPrefixRegex configuration.
// StripPrefixRegex holds the strip prefix regex middleware configuration.
// This middleware removes the matching prefixes from the URL path.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/stripprefixregex/
type StripPrefixRegex struct {
// Regex defines the regular expression to match the path prefix from the request URL.
Regex []string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty" export:"true"`
}
@ -411,12 +565,18 @@ type StripPrefixRegex struct {
// TLSClientCertificateInfo holds the client TLS certificate info configuration.
type TLSClientCertificateInfo struct {
NotAfter bool `json:"notAfter,omitempty" toml:"notAfter,omitempty" yaml:"notAfter,omitempty" export:"true"`
NotBefore bool `json:"notBefore,omitempty" toml:"notBefore,omitempty" yaml:"notBefore,omitempty" export:"true"`
Sans bool `json:"sans,omitempty" toml:"sans,omitempty" yaml:"sans,omitempty" export:"true"`
Subject *TLSClientCertificateSubjectDNInfo `json:"subject,omitempty" toml:"subject,omitempty" yaml:"subject,omitempty" export:"true"`
Issuer *TLSClientCertificateIssuerDNInfo `json:"issuer,omitempty" toml:"issuer,omitempty" yaml:"issuer,omitempty" export:"true"`
SerialNumber bool `json:"serialNumber,omitempty" toml:"serialNumber,omitempty" yaml:"serialNumber,omitempty" export:"true"`
// NotAfter defines whether to add the Not After information from the Validity part.
NotAfter bool `json:"notAfter,omitempty" toml:"notAfter,omitempty" yaml:"notAfter,omitempty" export:"true"`
// NotBefore defines whether to add the Not Before information from the Validity part.
NotBefore bool `json:"notBefore,omitempty" toml:"notBefore,omitempty" yaml:"notBefore,omitempty" export:"true"`
// Sans defines whether to add the Subject Alternative Name information from the Subject Alternative Name part.
Sans bool `json:"sans,omitempty" toml:"sans,omitempty" yaml:"sans,omitempty" export:"true"`
// SerialNumber defines whether to add the client serialNumber information.
SerialNumber bool `json:"serialNumber,omitempty" toml:"serialNumber,omitempty" yaml:"serialNumber,omitempty" export:"true"`
// Subject defines the client certificate subject details to add to the X-Forwarded-Tls-Client-Cert-Info header.
Subject *TLSClientCertificateSubjectDNInfo `json:"subject,omitempty" toml:"subject,omitempty" yaml:"subject,omitempty" export:"true"`
// Issuer defines the client certificate issuer details to add to the X-Forwarded-Tls-Client-Cert-Info header.
Issuer *TLSClientCertificateIssuerDNInfo `json:"issuer,omitempty" toml:"issuer,omitempty" yaml:"issuer,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
@ -424,12 +584,19 @@ type TLSClientCertificateInfo struct {
// TLSClientCertificateIssuerDNInfo holds the client TLS certificate distinguished name info configuration.
// cf https://tools.ietf.org/html/rfc3739
type TLSClientCertificateIssuerDNInfo struct {
Country bool `json:"country,omitempty" toml:"country,omitempty" yaml:"country,omitempty" export:"true"`
Province bool `json:"province,omitempty" toml:"province,omitempty" yaml:"province,omitempty" export:"true"`
Locality bool `json:"locality,omitempty" toml:"locality,omitempty" yaml:"locality,omitempty" export:"true"`
Organization bool `json:"organization,omitempty" toml:"organization,omitempty" yaml:"organization,omitempty" export:"true"`
CommonName bool `json:"commonName,omitempty" toml:"commonName,omitempty" yaml:"commonName,omitempty" export:"true"`
SerialNumber bool `json:"serialNumber,omitempty" toml:"serialNumber,omitempty" yaml:"serialNumber,omitempty" export:"true"`
// Country defines whether to add the country information into the issuer.
Country bool `json:"country,omitempty" toml:"country,omitempty" yaml:"country,omitempty" export:"true"`
// Province defines whether to add the province information into the issuer.
Province bool `json:"province,omitempty" toml:"province,omitempty" yaml:"province,omitempty" export:"true"`
// Locality defines whether to add the locality information into the issuer.
Locality bool `json:"locality,omitempty" toml:"locality,omitempty" yaml:"locality,omitempty" export:"true"`
// Organization defines whether to add the organization information into the issuer.
Organization bool `json:"organization,omitempty" toml:"organization,omitempty" yaml:"organization,omitempty" export:"true"`
// CommonName defines whether to add the organizationalUnit information into the issuer.
CommonName bool `json:"commonName,omitempty" toml:"commonName,omitempty" yaml:"commonName,omitempty" export:"true"`
// SerialNumber defines whether to add the serialNumber information into the issuer.
SerialNumber bool `json:"serialNumber,omitempty" toml:"serialNumber,omitempty" yaml:"serialNumber,omitempty" export:"true"`
// DomainComponent defines whether to add the domainComponent information into the issuer.
DomainComponent bool `json:"domainComponent,omitempty" toml:"domainComponent,omitempty" yaml:"domainComponent,omitempty" export:"true"`
}
@ -438,14 +605,22 @@ type TLSClientCertificateIssuerDNInfo struct {
// TLSClientCertificateSubjectDNInfo holds the client TLS certificate distinguished name info configuration.
// cf https://tools.ietf.org/html/rfc3739
type TLSClientCertificateSubjectDNInfo struct {
Country bool `json:"country,omitempty" toml:"country,omitempty" yaml:"country,omitempty" export:"true"`
Province bool `json:"province,omitempty" toml:"province,omitempty" yaml:"province,omitempty" export:"true"`
Locality bool `json:"locality,omitempty" toml:"locality,omitempty" yaml:"locality,omitempty" export:"true"`
Organization bool `json:"organization,omitempty" toml:"organization,omitempty" yaml:"organization,omitempty" export:"true"`
// Country defines whether to add the country information into the subject.
Country bool `json:"country,omitempty" toml:"country,omitempty" yaml:"country,omitempty" export:"true"`
// Province defines whether to add the province information into the subject.
Province bool `json:"province,omitempty" toml:"province,omitempty" yaml:"province,omitempty" export:"true"`
// Locality defines whether to add the locality information into the subject.
Locality bool `json:"locality,omitempty" toml:"locality,omitempty" yaml:"locality,omitempty" export:"true"`
// Organization defines whether to add the organization information into the subject.
Organization bool `json:"organization,omitempty" toml:"organization,omitempty" yaml:"organization,omitempty" export:"true"`
// OrganizationalUnit defines whether to add the organizationalUnit information into the subject.
OrganizationalUnit bool `json:"organizationalUnit,omitempty" toml:"organizationalUnit,omitempty" yaml:"organizationalUnit,omitempty" export:"true"`
CommonName bool `json:"commonName,omitempty" toml:"commonName,omitempty" yaml:"commonName,omitempty" export:"true"`
SerialNumber bool `json:"serialNumber,omitempty" toml:"serialNumber,omitempty" yaml:"serialNumber,omitempty" export:"true"`
DomainComponent bool `json:"domainComponent,omitempty" toml:"domainComponent,omitempty" yaml:"domainComponent,omitempty" export:"true"`
// CommonName defines whether to add the organizationalUnit information into the subject.
CommonName bool `json:"commonName,omitempty" toml:"commonName,omitempty" yaml:"commonName,omitempty" export:"true"`
// SerialNumber defines whether to add the serialNumber information into the subject.
SerialNumber bool `json:"serialNumber,omitempty" toml:"serialNumber,omitempty" yaml:"serialNumber,omitempty" export:"true"`
// DomainComponent defines whether to add the domainComponent information into the subject.
DomainComponent bool `json:"domainComponent,omitempty" toml:"domainComponent,omitempty" yaml:"domainComponent,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true

View file

@ -113,8 +113,10 @@ type TCPServer struct {
// +k8s:deepcopy-gen=true
// ProxyProtocol holds the ProxyProtocol configuration.
// ProxyProtocol holds the PROXY Protocol configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/services/#proxy-protocol
type ProxyProtocol struct {
// Version defines the PROXY Protocol version to use.
Version int `json:"version,omitempty" toml:"version,omitempty" yaml:"version,omitempty" export:"true"`
}

View file

@ -10,14 +10,21 @@ type TCPMiddleware struct {
// +k8s:deepcopy-gen=true
// TCPInFlightConn holds the TCP in flight connection configuration.
// TCPInFlightConn holds the TCP InFlightConn middleware configuration.
// This middleware prevents services from being overwhelmed with high load,
// by limiting the number of allowed simultaneous connections for one IP.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/tcp/inflightconn/
type TCPInFlightConn struct {
// Amount defines the maximum amount of allowed simultaneous connections.
// The middleware closes the connection if there are already amount connections opened.
Amount int64 `json:"amount,omitempty" toml:"amount,omitempty" yaml:"amount,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// TCPIPWhiteList holds the TCP ip white list configuration.
// TCPIPWhiteList holds the TCP IPWhiteList middleware configuration.
// This middleware accepts/refuses connections based on the client IP.
type TCPIPWhiteList struct {
// SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation).
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
}

View file

@ -375,17 +375,31 @@ func (lb *LbStatusUpdater) UpsertServer(u *url.URL, options ...roundrobin.Server
// Balancers is a list of Balancers(s) that implements the Balancer interface.
type Balancers []Balancer
// Servers returns the servers url from all the BalancerHandler.
// Servers returns the deduplicated server URLs from all the Balancer.
// Note that the deduplication is only possible because all the underlying
// balancers are of the same kind (the oxy implementation).
// The comparison property is the same as the one found at:
// https://github.com/vulcand/oxy/blob/fb2728c857b7973a27f8de2f2190729c0f22cf49/roundrobin/rr.go#L347.
func (b Balancers) Servers() []*url.URL {
seen := make(map[string]struct{})
var servers []*url.URL
for _, lb := range b {
servers = append(servers, lb.Servers()...)
for _, server := range lb.Servers() {
key := serverKey(server)
if _, ok := seen[key]; ok {
continue
}
servers = append(servers, server)
seen[key] = struct{}{}
}
}
return servers
}
// RemoveServer removes the given server from all the BalancerHandler,
// RemoveServer removes the given server from all the Balancer,
// and updates the status of the server to "DOWN".
func (b Balancers) RemoveServer(u *url.URL) error {
for _, lb := range b {
@ -396,7 +410,7 @@ func (b Balancers) RemoveServer(u *url.URL) error {
return nil
}
// UpsertServer adds the given server to all the BalancerHandler,
// UpsertServer adds the given server to all the Balancer,
// and updates the status of the server to "UP".
func (b Balancers) UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error {
for _, lb := range b {
@ -406,3 +420,7 @@ func (b Balancers) UpsertServer(u *url.URL, options ...roundrobin.ServerOption)
}
return nil
}
func serverKey(u *url.URL) string {
return u.Path + u.Host + u.Scheme
}

View file

@ -362,6 +362,81 @@ func TestAddHeadersAndHost(t *testing.T) {
}
}
func TestBalancers_Servers(t *testing.T) {
server1, err := url.Parse("http://foo.com")
require.NoError(t, err)
balancer1, err := roundrobin.New(nil)
require.NoError(t, err)
err = balancer1.UpsertServer(server1)
require.NoError(t, err)
server2, err := url.Parse("http://foo.com")
require.NoError(t, err)
balancer2, err := roundrobin.New(nil)
require.NoError(t, err)
err = balancer2.UpsertServer(server2)
require.NoError(t, err)
balancers := Balancers([]Balancer{balancer1, balancer2})
want, err := url.Parse("http://foo.com")
require.NoError(t, err)
assert.Equal(t, 1, len(balancers.Servers()))
assert.Equal(t, want, balancers.Servers()[0])
}
func TestBalancers_UpsertServer(t *testing.T) {
balancer1, err := roundrobin.New(nil)
require.NoError(t, err)
balancer2, err := roundrobin.New(nil)
require.NoError(t, err)
want, err := url.Parse("http://foo.com")
require.NoError(t, err)
balancers := Balancers([]Balancer{balancer1, balancer2})
err = balancers.UpsertServer(want)
require.NoError(t, err)
assert.Equal(t, 1, len(balancer1.Servers()))
assert.Equal(t, want, balancer1.Servers()[0])
assert.Equal(t, 1, len(balancer2.Servers()))
assert.Equal(t, want, balancer2.Servers()[0])
}
func TestBalancers_RemoveServer(t *testing.T) {
server, err := url.Parse("http://foo.com")
require.NoError(t, err)
balancer1, err := roundrobin.New(nil)
require.NoError(t, err)
err = balancer1.UpsertServer(server)
require.NoError(t, err)
balancer2, err := roundrobin.New(nil)
require.NoError(t, err)
err = balancer2.UpsertServer(server)
require.NoError(t, err)
balancers := Balancers([]Balancer{balancer1, balancer2})
err = balancers.RemoveServer(server)
require.NoError(t, err)
assert.Equal(t, 0, len(balancer1.Servers()))
assert.Equal(t, 0, len(balancer2.Servers()))
}
type testLoadBalancer struct {
// RWMutex needed due to parallel test execution: Both the system-under-test
// and the test assertions reference the counters.

View file

@ -13,8 +13,9 @@ import (
)
const (
typeSchemeName = "RedirectScheme"
uriPattern = `^(https?:\/\/)?(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$`
typeSchemeName = "RedirectScheme"
uriPattern = `^(https?:\/\/)?(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$`
xForwardedProto = "X-Forwarded-Proto"
)
// NewRedirectScheme creates a new RedirectScheme middleware.
@ -63,7 +64,11 @@ func rawURLScheme(req *http.Request) string {
scheme = schemeHTTPS
}
if scheme == schemeHTTP && port == ":80" || scheme == schemeHTTPS && port == ":443" || port == "" {
if value := req.Header.Get(xForwardedProto); value != "" {
scheme = value
}
if scheme == schemeHTTP && port == ":80" || scheme == schemeHTTPS && port == ":443" {
port = ""
}

View file

@ -47,11 +47,22 @@ func TestRedirectSchemeHandler(t *testing.T) {
},
url: "http://foo",
headers: map[string]string{
"X-Forwarded-Proto": "https",
"X-Forwarded-Proto": "http",
},
expectedURL: "https://foo",
expectedStatus: http.StatusFound,
},
{
desc: "HTTP to HTTPS, with X-Forwarded-Proto to HTTPS",
config: dynamic.RedirectScheme{
Scheme: "https",
},
url: "http://foo",
headers: map[string]string{
"X-Forwarded-Proto": "https",
},
expectedStatus: http.StatusOK,
},
{
desc: "HTTP with port to HTTPS without port",
config: dynamic.RedirectScheme{

View file

@ -1,6 +1,8 @@
package http
import (
"bufio"
"bytes"
"net/http"
"net/http/httptest"
"testing"
@ -956,3 +958,74 @@ func TestParseDomains(t *testing.T) {
})
}
}
func TestAbsoluteFormURL(t *testing.T) {
testCases := []struct {
desc string
request string
rule string
expected int
}{
{
desc: "!HostRegexp with absolute-form URL with empty host with non-matching host header",
request: "GET http://@/ HTTP/1.1\r\nHost: test.localhost\r\n\r\n",
rule: "!HostRegexp(`test.localhost`)",
expected: http.StatusNotFound,
},
{
desc: "!Host with absolute-form URL with empty host with non-matching host header",
request: "GET http://@/ HTTP/1.1\r\nHost: test.localhost\r\n\r\n",
rule: "!Host(`test.localhost`)",
expected: http.StatusNotFound,
},
{
desc: "!HostRegexp with absolute-form URL with matching host header",
request: "GET http://test.localhost/ HTTP/1.1\r\nHost: toto.localhost\r\n\r\n",
rule: "!HostRegexp(`test.localhost`)",
expected: http.StatusNotFound,
},
{
desc: "!Host with absolute-form URL with matching host header",
request: "GET http://test.localhost/ HTTP/1.1\r\nHost: toto.localhost\r\n\r\n",
rule: "!Host(`test.localhost`)",
expected: http.StatusNotFound,
},
{
desc: "!HostRegexp with absolute-form URL with non-matching host header",
request: "GET http://test.localhost/ HTTP/1.1\r\nHost: toto.localhost\r\n\r\n",
rule: "!HostRegexp(`toto.localhost`)",
expected: http.StatusOK,
},
{
desc: "!Host with absolute-form URL with non-matching host header",
request: "GET http://test.localhost/ HTTP/1.1\r\nHost: toto.localhost\r\n\r\n",
rule: "!Host(`toto.localhost`)",
expected: http.StatusOK,
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
muxer, err := NewMuxer()
require.NoError(t, err)
err = muxer.AddRoute(test.rule, 0, handler)
require.NoError(t, err)
// RequestDecorator is necessary for the host rule
reqHost := requestdecorator.New(nil)
w := httptest.NewRecorder()
req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader([]byte(test.request))))
require.NoError(t, err)
reqHost.ServeHTTP(w, req, muxer.ServeHTTP)
assert.Equal(t, test.expected, w.Code)
})
}
}

View file

@ -84,7 +84,7 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli
serviceName := normalized
if len(route.Services) > 1 {
spec := v1alpha1.ServiceSpec{
spec := v1alpha1.TraefikServiceSpec{
Weighted: &v1alpha1.WeightedRoundRobin{
Services: route.Services,
},
@ -217,7 +217,7 @@ func (c configBuilder) buildTraefikService(ctx context.Context, tService *v1alph
// buildServicesLB creates the configuration for the load-balancer of services named id, and defined in tService.
// It adds it to the given conf map.
func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tService v1alpha1.ServiceSpec, id string, conf map[string]*dynamic.Service) error {
func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tService v1alpha1.TraefikServiceSpec, id string, conf map[string]*dynamic.Service) error {
var wrrServices []dynamic.WRRService
for _, service := range tService.Weighted.Services {

View file

@ -7,90 +7,130 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
// IngressRouteSpec is a specification for a IngressRouteSpec resource.
// IngressRouteSpec defines the desired state of IngressRoute.
type IngressRouteSpec struct {
Routes []Route `json:"routes"`
// Routes defines the list of routes.
Routes []Route `json:"routes"`
// EntryPoints defines the list of entry point names to bind to.
// Entry points have to be configured in the static configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/entrypoints/
// Default: all.
EntryPoints []string `json:"entryPoints,omitempty"`
TLS *TLS `json:"tls,omitempty"`
// TLS defines the TLS configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#tls
TLS *TLS `json:"tls,omitempty"`
}
// Route contains the set of routes.
// Route holds the HTTP route configuration.
type Route struct {
// Match defines the router's rule.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#rule
Match string `json:"match"`
// Kind defines the kind of the route.
// Rule is the only supported kind.
// +kubebuilder:validation:Enum=Rule
Kind string `json:"kind"`
Priority int `json:"priority,omitempty"`
Services []Service `json:"services,omitempty"`
Kind string `json:"kind"`
// Priority defines the router's priority.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#priority
Priority int `json:"priority,omitempty"`
// Services defines the list of Service.
// It can contain any combination of TraefikService and/or reference to a Kubernetes Service.
Services []Service `json:"services,omitempty"`
// Middlewares defines the list of references to Middleware resources.
// More info: https://doc.traefik.io/traefik/v2.7/routing/providers/kubernetes-crd/#kind-middleware
Middlewares []MiddlewareRef `json:"middlewares,omitempty"`
}
// TLS contains the TLS certificates configuration of the routes.
// To enable Let's Encrypt, use an empty TLS struct,
// e.g. in YAML:
//
// tls: {} # inline format
//
// tls:
// secretName: # block format
// TLS holds the TLS configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#tls
type TLS struct {
// SecretName is the name of the referenced Kubernetes Secret to specify the
// certificate details.
// SecretName is the name of the referenced Kubernetes Secret to specify the certificate details.
SecretName string `json:"secretName,omitempty"`
// Options is a reference to a TLSOption, that specifies the parameters of the TLS connection.
// Options defines the reference to a TLSOption, that specifies the parameters of the TLS connection.
// If not defined, the `default` TLSOption is used.
// More info: https://doc.traefik.io/traefik/v2.7/https/tls/#tls-options
Options *TLSOptionRef `json:"options,omitempty"`
// Store is a reference to a TLSStore, that specifies the parameters of the TLS store.
Store *TLSStoreRef `json:"store,omitempty"`
CertResolver string `json:"certResolver,omitempty"`
Domains []types.Domain `json:"domains,omitempty"`
// Store defines the reference to the TLSStore, that will be used to store certificates.
// Please note that only `default` TLSStore can be used.
Store *TLSStoreRef `json:"store,omitempty"`
// CertResolver defines the name of the certificate resolver to use.
// Cert resolvers have to be configured in the static configuration.
// More info: https://doc.traefik.io/traefik/v2.7/https/acme/#certificate-resolvers
CertResolver string `json:"certResolver,omitempty"`
// Domains defines the list of domains that will be used to issue certificates.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#domains
Domains []types.Domain `json:"domains,omitempty"`
}
// TLSOptionRef is a ref to the TLSOption resources.
// TLSOptionRef is a reference to a TLSOption resource.
type TLSOptionRef struct {
Name string `json:"name"`
// Name defines the name of the referenced TLSOption.
// More info: https://doc.traefik.io/traefik/v2.7/routing/providers/kubernetes-crd/#kind-tlsoption
Name string `json:"name"`
// Namespace defines the namespace of the referenced TLSOption.
// More info: https://doc.traefik.io/traefik/v2.7/routing/providers/kubernetes-crd/#kind-tlsoption
Namespace string `json:"namespace,omitempty"`
}
// TLSStoreRef is a ref to the TLSStore resource.
// TLSStoreRef is a reference to a TLSStore resource.
type TLSStoreRef struct {
Name string `json:"name"`
// Name defines the name of the referenced TLSStore.
// More info: https://doc.traefik.io/traefik/v2.7/routing/providers/kubernetes-crd/#kind-tlsstore
Name string `json:"name"`
// Namespace defines the namespace of the referenced TLSStore.
// More info: https://doc.traefik.io/traefik/v2.7/routing/providers/kubernetes-crd/#kind-tlsstore
Namespace string `json:"namespace,omitempty"`
}
// LoadBalancerSpec can reference either a Kubernetes Service object (a load-balancer of servers),
// or a TraefikService object (a traefik load-balancer of services).
// LoadBalancerSpec defines the desired state of LoadBalancer.
// It can reference either a Kubernetes Service object (a load-balancer of servers),
// or a TraefikService object (a load-balancer of Traefik services).
type LoadBalancerSpec struct {
// Name is a reference to a Kubernetes Service object (for a load-balancer of servers),
// or to a TraefikService object (service load-balancer, mirroring, etc).
// Name defines the name of the referenced Kubernetes Service or TraefikService.
// The differentiation between the two is specified in the Kind field.
Name string `json:"name"`
// Kind defines the kind of the Service.
// +kubebuilder:validation:Enum=Service;TraefikService
Kind string `json:"kind,omitempty"`
Namespace string `json:"namespace,omitempty"`
Sticky *dynamic.Sticky `json:"sticky,omitempty"`
// Port and all the fields below are related to a servers load-balancer,
// and therefore should only be specified when Name references a Kubernetes Service.
Port intstr.IntOrString `json:"port,omitempty"`
Scheme string `json:"scheme,omitempty"`
Strategy string `json:"strategy,omitempty"`
PassHostHeader *bool `json:"passHostHeader,omitempty"`
Kind string `json:"kind,omitempty"`
// Namespace defines the namespace of the referenced Kubernetes Service or TraefikService.
Namespace string `json:"namespace,omitempty"`
// Sticky defines the sticky sessions configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/services/#sticky-sessions
Sticky *dynamic.Sticky `json:"sticky,omitempty"`
// Port defines the port of a Kubernetes Service.
// This can be a reference to a named port.
Port intstr.IntOrString `json:"port,omitempty"`
// Scheme defines the scheme to use for the request to the upstream Kubernetes Service.
// It defaults to https when Kubernetes Service port is 443, http otherwise.
Scheme string `json:"scheme,omitempty"`
// Strategy defines the load balancing strategy between the servers.
// RoundRobin is the only supported value at the moment.
Strategy string `json:"strategy,omitempty"`
// PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service.
// By default, passHostHeader is true.
PassHostHeader *bool `json:"passHostHeader,omitempty"`
// ResponseForwarding defines how Traefik forwards the response from the upstream Kubernetes Service to the client.
ResponseForwarding *dynamic.ResponseForwarding `json:"responseForwarding,omitempty"`
ServersTransport string `json:"serversTransport,omitempty"`
// ServersTransport defines the name of ServersTransport resource to use.
// It allows to configure the transport between Traefik and your servers.
// Can only be used on a Kubernetes Service.
ServersTransport string `json:"serversTransport,omitempty"`
// Weight should only be specified when Name references a TraefikService object
// Weight defines the weight and should only be specified when Name references a TraefikService object
// (and to be precise, one that embeds a Weighted Round Robin).
Weight *int `json:"weight,omitempty"`
}
// Service defines an upstream to proxy traffic.
// Service defines an upstream HTTP service to proxy traffic to.
type Service struct {
LoadBalancerSpec `json:",inline"`
}
// MiddlewareRef is a ref to the Middleware resources.
// MiddlewareRef is a reference to a Middleware resource.
type MiddlewareRef struct {
Name string `json:"name"`
// Name defines the name of the referenced Middleware resource.
Name string `json:"name"`
// Namespace defines the namespace of the referenced Middleware resource.
Namespace string `json:"namespace,omitempty"`
}
@ -98,9 +138,11 @@ type MiddlewareRef struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// IngressRoute is an Ingress CRD specification.
// IngressRoute is the CRD implementation of a Traefik HTTP Router.
type IngressRoute struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec IngressRouteSpec `json:"spec"`
@ -108,9 +150,13 @@ type IngressRoute struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// IngressRouteList is a list of IngressRoutes.
// IngressRouteList is a collection of IngressRoute.
type IngressRouteList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
Items []IngressRoute `json:"items"`
// Items is the list of IngressRoute.
Items []IngressRoute `json:"items"`
}

View file

@ -7,60 +7,88 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
// IngressRouteTCPSpec is a specification for a IngressRouteTCPSpec resource.
// IngressRouteTCPSpec defines the desired state of IngressRouteTCP.
type IngressRouteTCPSpec struct {
Routes []RouteTCP `json:"routes"`
EntryPoints []string `json:"entryPoints,omitempty"`
TLS *TLSTCP `json:"tls,omitempty"`
// Routes defines the list of routes.
Routes []RouteTCP `json:"routes"`
// EntryPoints defines the list of entry point names to bind to.
// Entry points have to be configured in the static configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/entrypoints/
// Default: all.
EntryPoints []string `json:"entryPoints,omitempty"`
// TLS defines the TLS configuration on a layer 4 / TCP Route.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#tls_1
TLS *TLSTCP `json:"tls,omitempty"`
}
// RouteTCP contains the set of routes.
// RouteTCP holds the TCP route configuration.
type RouteTCP struct {
Match string `json:"match"`
Priority int `json:"priority,omitempty"`
// Match defines the router's rule.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#rule_1
Match string `json:"match"`
// Priority defines the router's priority.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#priority_1
Priority int `json:"priority,omitempty"`
// Services defines the list of TCP services.
Services []ServiceTCP `json:"services,omitempty"`
// Middlewares contains references to MiddlewareTCP resources.
// Middlewares defines the list of references to MiddlewareTCP resources.
Middlewares []ObjectReference `json:"middlewares,omitempty"`
}
// TLSTCP contains the TLS certificates configuration of the routes.
// To enable Let's Encrypt, use an empty TLS struct,
// e.g. in YAML:
//
// tls: {} # inline format
//
// tls:
// secretName: # block format
// TLSTCP holds the TLS configuration for an IngressRouteTCP.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#tls_1
type TLSTCP struct {
// SecretName is the name of the referenced Kubernetes Secret to specify the
// certificate details.
SecretName string `json:"secretName,omitempty"`
Passthrough bool `json:"passthrough,omitempty"`
// Options is a reference to a TLSOption, that specifies the parameters of the TLS connection.
// SecretName is the name of the referenced Kubernetes Secret to specify the certificate details.
SecretName string `json:"secretName,omitempty"`
// Passthrough defines whether a TLS router will terminate the TLS connection.
Passthrough bool `json:"passthrough,omitempty"`
// Options defines the reference to a TLSOption, that specifies the parameters of the TLS connection.
// If not defined, the `default` TLSOption is used.
// More info: https://doc.traefik.io/traefik/v2.7/https/tls/#tls-options
Options *ObjectReference `json:"options,omitempty"`
// Store is a reference to a TLSStore, that specifies the parameters of the TLS store.
Store *ObjectReference `json:"store,omitempty"`
CertResolver string `json:"certResolver,omitempty"`
Domains []types.Domain `json:"domains,omitempty"`
// Store defines the reference to the TLSStore, that will be used to store certificates.
// Please note that only `default` TLSStore can be used.
Store *ObjectReference `json:"store,omitempty"`
// CertResolver defines the name of the certificate resolver to use.
// Cert resolvers have to be configured in the static configuration.
// More info: https://doc.traefik.io/traefik/v2.7/https/acme/#certificate-resolvers
CertResolver string `json:"certResolver,omitempty"`
// Domains defines the list of domains that will be used to issue certificates.
// More info: https://doc.traefik.io/traefik/v2.7/routing/routers/#domains
Domains []types.Domain `json:"domains,omitempty"`
}
// ServiceTCP defines an upstream to proxy traffic.
// ServiceTCP defines an upstream TCP service to proxy traffic to.
type ServiceTCP struct {
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
Port intstr.IntOrString `json:"port"`
Weight *int `json:"weight,omitempty"`
TerminationDelay *int `json:"terminationDelay,omitempty"`
ProxyProtocol *dynamic.ProxyProtocol `json:"proxyProtocol,omitempty"`
// Name defines the name of the referenced Kubernetes Service.
Name string `json:"name"`
// Namespace defines the namespace of the referenced Kubernetes Service.
Namespace string `json:"namespace,omitempty"`
// Port defines the port of a Kubernetes Service.
// This can be a reference to a named port.
Port intstr.IntOrString `json:"port"`
// Weight defines the weight used when balancing requests between multiple Kubernetes Service.
Weight *int `json:"weight,omitempty"`
// TerminationDelay defines the deadline that the proxy sets, after one of its connected peers indicates
// it has closed the writing capability of its connection, to close the reading capability as well,
// hence fully terminating the connection.
// It is a duration in milliseconds, defaulting to 100.
// A negative value means an infinite deadline (i.e. the reading capability is never closed).
TerminationDelay *int `json:"terminationDelay,omitempty"`
// ProxyProtocol defines the PROXY protocol configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/services/#proxy-protocol
ProxyProtocol *dynamic.ProxyProtocol `json:"proxyProtocol,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// IngressRouteTCP is an Ingress CRD specification.
// IngressRouteTCP is the CRD implementation of a Traefik TCP Router.
type IngressRouteTCP struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec IngressRouteTCPSpec `json:"spec"`
@ -68,9 +96,13 @@ type IngressRouteTCP struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// IngressRouteTCPList is a list of IngressRoutes.
// IngressRouteTCPList is a collection of IngressRouteTCP.
type IngressRouteTCPList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
Items []IngressRouteTCP `json:"items"`
// Items is the list of IngressRouteTCP.
Items []IngressRouteTCP `json:"items"`
}

View file

@ -5,38 +5,45 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
// IngressRouteUDPSpec is a specification for a IngressRouteUDPSpec resource.
// IngressRouteUDPSpec defines the desired state of a IngressRouteUDP.
type IngressRouteUDPSpec struct {
Routes []RouteUDP `json:"routes"`
EntryPoints []string `json:"entryPoints,omitempty"`
// Routes defines the list of routes.
Routes []RouteUDP `json:"routes"`
// EntryPoints defines the list of entry point names to bind to.
// Entry points have to be configured in the static configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/entrypoints/
// Default: all.
EntryPoints []string `json:"entryPoints,omitempty"`
}
// RouteUDP contains the set of routes.
// RouteUDP holds the UDP route configuration.
type RouteUDP struct {
// Services defines the list of UDP services.
Services []ServiceUDP `json:"services,omitempty"`
}
// TLSOptionUDPRef is a ref to the TLSOption resources.
type TLSOptionUDPRef struct {
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
}
// ServiceUDP defines an upstream to proxy traffic.
// ServiceUDP defines an upstream UDP service to proxy traffic to.
type ServiceUDP struct {
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
Port intstr.IntOrString `json:"port"`
Weight *int `json:"weight,omitempty"`
// Name defines the name of the referenced Kubernetes Service.
Name string `json:"name"`
// Namespace defines the namespace of the referenced Kubernetes Service.
Namespace string `json:"namespace,omitempty"`
// Port defines the port of a Kubernetes Service.
// This can be a reference to a named port.
Port intstr.IntOrString `json:"port"`
// Weight defines the weight used when balancing requests between multiple Kubernetes Service.
Weight *int `json:"weight,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// IngressRouteUDP is an Ingress CRD specification.
// IngressRouteUDP is a CRD implementation of a Traefik UDP Router.
type IngressRouteUDP struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec IngressRouteUDPSpec `json:"spec"`
@ -44,9 +51,13 @@ type IngressRouteUDP struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// IngressRouteUDPList is a list of IngressRoutes.
// IngressRouteUDPList is a collection of IngressRouteUDP.
type IngressRouteUDPList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
Items []IngressRouteUDP `json:"items"`
// Items is the list of IngressRouteUDP.
Items []IngressRouteUDP `json:"items"`
}

View file

@ -11,9 +11,12 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// Middleware is a specification for a Middleware resource.
// Middleware is the CRD implementation of a Traefik Middleware.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/overview/
type Middleware struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec MiddlewareSpec `json:"spec"`
@ -21,7 +24,7 @@ type Middleware struct {
// +k8s:deepcopy-gen=true
// MiddlewareSpec holds the Middleware configuration.
// MiddlewareSpec defines the desired state of a Middleware.
type MiddlewareSpec struct {
AddPrefix *dynamic.AddPrefix `json:"addPrefix,omitempty"`
StripPrefix *dynamic.StripPrefix `json:"stripPrefix,omitempty"`
@ -50,11 +53,22 @@ type MiddlewareSpec struct {
// +k8s:deepcopy-gen=true
// ErrorPage holds the custom error page configuration.
// ErrorPage holds the custom error middleware configuration.
// This middleware returns a custom page in lieu of the default, according to configured ranges of HTTP Status codes.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/errorpages/
type ErrorPage struct {
Status []string `json:"status,omitempty"`
Service Service `json:"service,omitempty"`
Query string `json:"query,omitempty"`
// Status defines which status or range of statuses should result in an error page.
// It can be either a status code as a number (500),
// as multiple comma-separated numbers (500,502),
// as ranges by separating two codes with a dash (500-599),
// or a combination of the two (404,418,500-599).
Status []string `json:"status,omitempty"`
// Service defines the reference to a Kubernetes Service that will serve the error page.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/errorpages/#service
Service Service `json:"service,omitempty"`
// Query defines the URL for the error page (hosted by service).
// The {status} variable can be used in order to insert the status code in the URL.
Query string `json:"query,omitempty"`
}
// +k8s:deepcopy-gen=true
@ -73,75 +87,135 @@ type CircuitBreaker struct {
// +k8s:deepcopy-gen=true
// Chain holds a chain of middlewares.
// Chain holds the configuration of the chain middleware.
// This middleware enables to define reusable combinations of other pieces of middleware.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/chain/
type Chain struct {
// Middlewares is the list of MiddlewareRef which composes the chain.
Middlewares []MiddlewareRef `json:"middlewares,omitempty"`
}
// +k8s:deepcopy-gen=true
// BasicAuth holds the HTTP basic authentication configuration.
// BasicAuth holds the basic auth middleware configuration.
// This middleware restricts access to your services to known users.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/basicauth/
type BasicAuth struct {
Secret string `json:"secret,omitempty"`
Realm string `json:"realm,omitempty"`
RemoveHeader bool `json:"removeHeader,omitempty"`
HeaderField string `json:"headerField,omitempty"`
// Secret is the name of the referenced Kubernetes Secret containing user credentials.
Secret string `json:"secret,omitempty"`
// Realm allows the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme.
// Default: traefik.
Realm string `json:"realm,omitempty"`
// RemoveHeader sets the removeHeader option to true to remove the authorization header before forwarding the request to your service.
// Default: false.
RemoveHeader bool `json:"removeHeader,omitempty"`
// HeaderField defines a header field to store the authenticated user.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/basicauth/#headerfield
HeaderField string `json:"headerField,omitempty"`
}
// +k8s:deepcopy-gen=true
// DigestAuth holds the Digest HTTP authentication configuration.
// DigestAuth holds the digest auth middleware configuration.
// This middleware restricts access to your services to known users.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/digestauth/
type DigestAuth struct {
Secret string `json:"secret,omitempty"`
RemoveHeader bool `json:"removeHeader,omitempty"`
Realm string `json:"realm,omitempty"`
HeaderField string `json:"headerField,omitempty"`
// Secret is the name of the referenced Kubernetes Secret containing user credentials.
Secret string `json:"secret,omitempty"`
// RemoveHeader defines whether to remove the authorization header before forwarding the request to the backend.
RemoveHeader bool `json:"removeHeader,omitempty"`
// Realm allows the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme.
// Default: traefik.
Realm string `json:"realm,omitempty"`
// HeaderField defines a header field to store the authenticated user.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/basicauth/#headerfield
HeaderField string `json:"headerField,omitempty"`
}
// +k8s:deepcopy-gen=true
// ForwardAuth holds the http forward authentication configuration.
// ForwardAuth holds the forward auth middleware configuration.
// This middleware delegates the request authentication to a Service.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/forwardauth/
type ForwardAuth struct {
Address string `json:"address,omitempty"`
TrustForwardHeader bool `json:"trustForwardHeader,omitempty"`
AuthResponseHeaders []string `json:"authResponseHeaders,omitempty"`
AuthResponseHeadersRegex string `json:"authResponseHeadersRegex,omitempty"`
AuthRequestHeaders []string `json:"authRequestHeaders,omitempty"`
TLS *ClientTLS `json:"tls,omitempty"`
// Address defines the authentication server address.
Address string `json:"address,omitempty"`
// TrustForwardHeader defines whether to trust (ie: forward) all X-Forwarded-* headers.
TrustForwardHeader bool `json:"trustForwardHeader,omitempty"`
// AuthResponseHeaders defines the list of headers to copy from the authentication server response and set on forwarded request, replacing any existing conflicting headers.
AuthResponseHeaders []string `json:"authResponseHeaders,omitempty"`
// AuthResponseHeadersRegex defines the regex to match headers to copy from the authentication server response and set on forwarded request, after stripping all headers that match the regex.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/forwardauth/#authresponseheadersregex
AuthResponseHeadersRegex string `json:"authResponseHeadersRegex,omitempty"`
// AuthRequestHeaders defines the list of the headers to copy from the request to the authentication server.
// If not set or empty then all request headers are passed.
AuthRequestHeaders []string `json:"authRequestHeaders,omitempty"`
// TLS defines the configuration used to secure the connection to the authentication server.
TLS *ClientTLS `json:"tls,omitempty"`
}
// ClientTLS holds TLS specific configurations as client.
// ClientTLS holds the client TLS configuration.
type ClientTLS struct {
CASecret string `json:"caSecret,omitempty"`
CAOptional bool `json:"caOptional,omitempty"`
CertSecret string `json:"certSecret,omitempty"`
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// MiddlewareList is a list of Middleware resources.
type MiddlewareList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []Middleware `json:"items"`
// CASecret is the name of the referenced Kubernetes Secret containing the CA to validate the server certificate.
// The CA certificate is extracted from key `tls.ca` or `ca.crt`.
CASecret string `json:"caSecret,omitempty"`
// CertSecret is the name of the referenced Kubernetes Secret containing the client certificate.
// The client certificate is extracted from the keys `tls.crt` and `tls.key`.
CertSecret string `json:"certSecret,omitempty"`
// InsecureSkipVerify defines whether the server certificates should be validated.
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
CAOptional bool `json:"caOptional,omitempty"`
}
// +k8s:deepcopy-gen=true
// RateLimit holds the rate limiting configuration for a given router.
// RateLimit holds the rate limit configuration.
// This middleware ensures that services will receive a fair amount of requests, and allows one to define what fair is.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/ratelimit/
type RateLimit struct {
Average int64 `json:"average,omitempty"`
Period *intstr.IntOrString `json:"period,omitempty"`
Burst *int64 `json:"burst,omitempty"`
// Average is the maximum rate, by default in requests/s, allowed for the given source.
// It defaults to 0, which means no rate limiting.
// The rate is actually defined by dividing Average by Period. So for a rate below 1req/s,
// one needs to define a Period larger than a second.
Average int64 `json:"average,omitempty"`
// Period, in combination with Average, defines the actual maximum rate, such as:
// r = Average / Period. It defaults to a second.
Period *intstr.IntOrString `json:"period,omitempty"`
// Burst is the maximum number of requests allowed to arrive in the same arbitrarily small period of time.
// It defaults to 1.
Burst *int64 `json:"burst,omitempty"`
// SourceCriterion defines what criterion is used to group requests as originating from a common source.
// If several strategies are defined at the same time, an error will be raised.
// If none are set, the default is to use the request's remote address field (as an ipStrategy).
SourceCriterion *dynamic.SourceCriterion `json:"sourceCriterion,omitempty"`
}
// +k8s:deepcopy-gen=true
// Retry holds the retry configuration.
// Retry holds the retry middleware configuration.
// This middleware reissues requests a given number of times to a backend server if that server does not reply.
// As soon as the server answers, the middleware stops retrying, regardless of the response status.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/http/retry/
type Retry struct {
Attempts int `json:"attempts,omitempty"`
// Attempts defines how many times the request should be retried.
Attempts int `json:"attempts,omitempty"`
// InitialInterval defines the first wait time in the exponential backoff series.
// The maximum interval is calculated as twice the initialInterval.
// If unspecified, requests will be retried immediately.
// The value of initialInterval should be provided in seconds or as a valid duration format,
// see https://pkg.go.dev/time#ParseDuration.
InitialInterval intstr.IntOrString `json:"initialInterval,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// MiddlewareList is a collection of Middleware resources.
type MiddlewareList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
// Items is the list of Middleware.
Items []Middleware `json:"items"`
}

View file

@ -8,9 +8,12 @@ import (
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// MiddlewareTCP is a specification for a MiddlewareTCP resource.
// MiddlewareTCP is the CRD implementation of a Traefik TCP middleware.
// More info: https://doc.traefik.io/traefik/v2.7/middlewares/overview/
type MiddlewareTCP struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec MiddlewareTCPSpec `json:"spec"`
@ -18,18 +21,23 @@ type MiddlewareTCP struct {
// +k8s:deepcopy-gen=true
// MiddlewareTCPSpec holds the MiddlewareTCP configuration.
// MiddlewareTCPSpec defines the desired state of a MiddlewareTCP.
type MiddlewareTCPSpec struct {
// InFlightConn defines the InFlightConn middleware configuration.
InFlightConn *dynamic.TCPInFlightConn `json:"inFlightConn,omitempty"`
IPWhiteList *dynamic.TCPIPWhiteList `json:"ipWhiteList,omitempty"`
// IPWhiteList defines the IPWhiteList middleware configuration.
IPWhiteList *dynamic.TCPIPWhiteList `json:"ipWhiteList,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// MiddlewareTCPList is a list of MiddlewareTCP resources.
// MiddlewareTCPList is a collection of MiddlewareTCP resources.
type MiddlewareTCPList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
// Items is the list of MiddlewareTCP.
Items []MiddlewareTCP `json:"items"`
}

View file

@ -2,6 +2,8 @@ package v1alpha1
// ObjectReference is a generic reference to a Traefik resource.
type ObjectReference struct {
Name string `json:"name"`
// Name defines the name of the referenced Traefik resource.
Name string `json:"name"`
// Namespace defines the namespace of the referenced Traefik resource.
Namespace string `json:"namespace,omitempty"`
}

View file

@ -9,9 +9,14 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// ServersTransport is a specification for a ServersTransport resource.
// ServersTransport is the CRD implementation of a ServersTransport.
// If no serversTransport is specified, the default@internal will be used.
// The default@internal serversTransport is created from the static configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/services/#serverstransport_1
type ServersTransport struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec ServersTransportSpec `json:"spec"`
@ -19,38 +24,37 @@ type ServersTransport struct {
// +k8s:deepcopy-gen=true
// ServersTransportSpec options to configure communication between Traefik and the servers.
// ServersTransportSpec defines the desired state of a ServersTransport.
type ServersTransportSpec struct {
// ServerName used to contact the server.
// ServerName defines the server name used to contact the server.
ServerName string `json:"serverName,omitempty"`
// Disable SSL certificate verification.
// InsecureSkipVerify disables SSL certificate verification.
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
// Add cert file for self-signed certificate.
// RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
RootCAsSecrets []string `json:"rootCAsSecrets,omitempty"`
// Certificates for mTLS.
// CertificatesSecrets defines a list of secret storing client certificates for mTLS.
CertificatesSecrets []string `json:"certificatesSecrets,omitempty"`
// If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
// MaxIdleConnsPerHost controls the maximum idle (keep-alive) to keep per-host.
MaxIdleConnsPerHost int `json:"maxIdleConnsPerHost,omitempty"`
// Timeouts for requests forwarded to the backend servers.
// ForwardingTimeouts defines the timeouts for requests forwarded to the backend servers.
ForwardingTimeouts *ForwardingTimeouts `json:"forwardingTimeouts,omitempty"`
// Disable HTTP/2 for connections with backend servers.
// DisableHTTP2 disables HTTP/2 for connections with backend servers.
DisableHTTP2 bool `json:"disableHTTP2,omitempty"`
// URI used to match against SAN URI during the peer certificate verification.
// PeerCertURI defines the peer cert URI used to match against SAN URI during the peer certificate verification.
PeerCertURI string `json:"peerCertURI,omitempty"`
}
// +k8s:deepcopy-gen=true
// ForwardingTimeouts contains timeout configurations for forwarding requests to the backend servers.
// ForwardingTimeouts holds the timeout configurations for forwarding requests to the backend servers.
type ForwardingTimeouts struct {
// DialTimeout is the amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists.
// DialTimeout is the amount of time to wait until a connection to a backend server can be established.
DialTimeout *intstr.IntOrString `json:"dialTimeout,omitempty"`
// ResponseHeaderTimeout is 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.
ResponseHeaderTimeout *intstr.IntOrString `json:"responseHeaderTimeout,omitempty"`
// IdleConnTimeout is the maximum period for which an idle HTTP keep-alive connection will remain open before closing itself.
IdleConnTimeout *intstr.IntOrString `json:"idleConnTimeout,omitempty"`
// ReadIdleTimeout is the timeout after which a health check using ping frame will be carried out if no frame is received on the HTTP/2 connection. If zero, no health check is performed.
// ReadIdleTimeout is the timeout after which a health check using ping frame will be carried out if no frame is received on the HTTP/2 connection.
ReadIdleTimeout *intstr.IntOrString `json:"readIdleTimeout,omitempty"`
// PingTimeout is the timeout after which the HTTP/2 connection will be closed if a response to ping is not received.
PingTimeout *intstr.IntOrString `json:"pingTimeout,omitempty"`
@ -58,10 +62,13 @@ type ForwardingTimeouts struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ServersTransportList is a list of ServersTransport resources.
// ServersTransportList is a collection of ServersTransport resources.
type ServersTransportList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
// Items is the list of ServersTransport.
Items []ServersTransport `json:"items"`
}

View file

@ -9,60 +9,77 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// TraefikService is the specification for a service (that an IngressRoute refers
// to) that is usually not a terminal service (i.e. not a pod of servers), as
// opposed to a Kubernetes Service. That is to say, it usually refers to other
// (children) services, which themselves can be TraefikServices or Services.
// TraefikService is the CRD implementation of a Traefik Service.
// TraefikService object allows to:
// - Apply weight to Services on load-balancing
// - Mirror traffic on services
// More info: https://doc.traefik.io/traefik/v2.7/routing/providers/kubernetes-crd/#kind-traefikservice
type TraefikService struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec ServiceSpec `json:"spec"`
Spec TraefikServiceSpec `json:"spec"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TraefikServiceList is a list of TraefikService resources.
// TraefikServiceList is a collection of TraefikService resources.
type TraefikServiceList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
// Items is the list of TraefikService.
Items []TraefikService `json:"items"`
}
// +k8s:deepcopy-gen=true
// ServiceSpec defines whether a TraefikService is a load-balancer of services or a
// mirroring service.
type ServiceSpec struct {
Weighted *WeightedRoundRobin `json:"weighted,omitempty"`
Mirroring *Mirroring `json:"mirroring,omitempty"`
// TraefikServiceSpec defines the desired state of a TraefikService.
type TraefikServiceSpec struct {
// Weighted defines the Weighted Round Robin configuration.
Weighted *WeightedRoundRobin `json:"weighted,omitempty"`
// Mirroring defines the Mirroring service configuration.
Mirroring *Mirroring `json:"mirroring,omitempty"`
}
// +k8s:deepcopy-gen=true
// Mirroring defines a mirroring service, which is composed of a main
// load-balancer, and a list of mirrors.
// Mirroring holds the mirroring service configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/services/#mirroring-service
type Mirroring struct {
LoadBalancerSpec `json:",inline"`
MaxBodySize *int64 `json:"maxBodySize,omitempty"`
Mirrors []MirrorService `json:"mirrors,omitempty"`
// MaxBodySize defines the maximum size allowed for the body of the request.
// If the body is larger, the request is not mirrored.
// Default value is -1, which means unlimited size.
MaxBodySize *int64 `json:"maxBodySize,omitempty"`
// Mirrors defines the list of mirrors where Traefik will duplicate the traffic.
Mirrors []MirrorService `json:"mirrors,omitempty"`
}
// +k8s:deepcopy-gen=true
// MirrorService defines one of the mirrors of a Mirroring service.
// MirrorService holds the mirror configuration.
type MirrorService struct {
LoadBalancerSpec `json:",inline"`
// Percent defines the part of the traffic to mirror.
// Supported values: 0 to 100.
Percent int `json:"percent,omitempty"`
}
// +k8s:deepcopy-gen=true
// WeightedRoundRobin defines a load-balancer of services.
// WeightedRoundRobin holds the weighted round-robin configuration.
// More info: https://doc.traefik.io/traefik/v2.7/routing/services/#weighted-round-robin-service
type WeightedRoundRobin struct {
Services []Service `json:"services,omitempty"`
Sticky *dynamic.Sticky `json:"sticky,omitempty"`
// Services defines the list of Kubernetes Service and/or TraefikService to load-balance, with weight.
Services []Service `json:"services,omitempty"`
// Sticky defines whether sticky sessions are enabled.
// More info: https://doc.traefik.io/traefik/v2.7/routing/providers/kubernetes-crd/#stickiness-and-load-balancing
Sticky *dynamic.Sticky `json:"sticky,omitempty"`
}

View file

@ -8,9 +8,12 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// TLSOption is a specification for a TLSOption resource.
// TLSOption is the CRD implementation of a Traefik TLS Option, allowing to configure some parameters of the TLS connection.
// More info: https://doc.traefik.io/traefik/v2.7/https/tls/#tls-options
type TLSOption struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec TLSOptionSpec `json:"spec"`
@ -18,35 +21,54 @@ type TLSOption struct {
// +k8s:deepcopy-gen=true
// TLSOptionSpec configures TLS for an entry point.
// TLSOptionSpec defines the desired state of a TLSOption.
type TLSOptionSpec struct {
MinVersion string `json:"minVersion,omitempty"`
MaxVersion string `json:"maxVersion,omitempty"`
CipherSuites []string `json:"cipherSuites,omitempty"`
CurvePreferences []string `json:"curvePreferences,omitempty"`
ClientAuth ClientAuth `json:"clientAuth,omitempty"`
SniStrict bool `json:"sniStrict,omitempty"`
PreferServerCipherSuites bool `json:"preferServerCipherSuites,omitempty"`
ALPNProtocols []string `json:"alpnProtocols,omitempty"`
// MinVersion defines the minimum TLS version that Traefik will accept.
// Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13.
// Default: VersionTLS10.
MinVersion string `json:"minVersion,omitempty"`
// MaxVersion defines the maximum TLS version that Traefik will accept.
// Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13.
// Default: None.
MaxVersion string `json:"maxVersion,omitempty"`
// CipherSuites defines the list of supported cipher suites for TLS versions up to TLS 1.2.
// More info: https://doc.traefik.io/traefik/v2.7/https/tls/#cipher-suites
CipherSuites []string `json:"cipherSuites,omitempty"`
// CurvePreferences defines the preferred elliptic curves in a specific order.
// More info: https://doc.traefik.io/traefik/v2.7/https/tls/#curve-preferences
CurvePreferences []string `json:"curvePreferences,omitempty"`
// ClientAuth defines the server's policy for TLS Client Authentication.
ClientAuth ClientAuth `json:"clientAuth,omitempty"`
// SniStrict defines whether Traefik allows connections from clients connections that do not specify a server_name extension.
SniStrict bool `json:"sniStrict,omitempty"`
// PreferServerCipherSuites defines whether the server chooses a cipher suite among his own instead of among the client's.
// It is enabled automatically when minVersion or maxVersion are set.
PreferServerCipherSuites bool `json:"preferServerCipherSuites,omitempty"`
// ALPNProtocols defines the list of supported application level protocols for the TLS handshake, in order of preference.
// More info: https://doc.traefik.io/traefik/v2.7/https/tls/#alpn-protocols
ALPNProtocols []string `json:"alpnProtocols,omitempty"`
}
// +k8s:deepcopy-gen=true
// ClientAuth defines the parameters of the client authentication part of the TLS connection, if any.
// ClientAuth holds the TLS client authentication configuration.
type ClientAuth struct {
// SecretName is the name of the referenced Kubernetes Secret to specify the certificate details.
// SecretNames defines the names of the referenced Kubernetes Secret storing certificate details.
SecretNames []string `json:"secretNames,omitempty"`
// +kubebuilder:validation:Enum=NoClientCert;RequestClientCert;RequireAnyClientCert;VerifyClientCertIfGiven;RequireAndVerifyClientCert
// ClientAuthType defines the client authentication type to apply.
// +kubebuilder:validation:Enum=NoClientCert;RequestClientCert;RequireAnyClientCert;VerifyClientCertIfGiven;RequireAndVerifyClientCert
ClientAuthType string `json:"clientAuthType,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TLSOptionList is a list of TLSOption resources.
// TLSOptionList is a collection of TLSOption resources.
type TLSOptionList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
// Items is the list of TLSOption.
Items []TLSOption `json:"items"`
}

View file

@ -8,9 +8,14 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// TLSStore is a specification for a TLSStore resource.
// TLSStore is the CRD implementation of a Traefik TLS Store.
// For the time being, only the TLSStore named default is supported.
// This means that you cannot have two stores that are named default in different Kubernetes namespaces.
// More info: https://doc.traefik.io/traefik/v2.7/https/tls/#certificates-stores
type TLSStore struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata"`
Spec TLSStoreSpec `json:"spec"`
@ -18,9 +23,9 @@ type TLSStore struct {
// +k8s:deepcopy-gen=true
// TLSStoreSpec configures a TLSStore resource.
// TLSStoreSpec defines the desired state of a TLSStore.
type TLSStoreSpec struct {
// DefaultCertificate is the name of the secret holding the default key/certificate pair for the store.
// DefaultCertificate defines the default certificate configuration.
DefaultCertificate *Certificate `json:"defaultCertificate,omitempty"`
// Certificates is a list of secret names, each secret holding a key/certificate pair to add to the store.
Certificates []Certificate `json:"certificates,omitempty"`
@ -36,10 +41,13 @@ type Certificate struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TLSStoreList is a list of TLSStore resources.
// TLSStoreList is a collection of TLSStore resources.
type TLSStoreList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ListMeta `json:"metadata"`
// Items is the list of TLSStore.
Items []TLSStore `json:"items"`
}

View file

@ -1171,32 +1171,6 @@ func (in *Service) DeepCopy() *Service {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) {
*out = *in
if in.Weighted != nil {
in, out := &in.Weighted, &out.Weighted
*out = new(WeightedRoundRobin)
(*in).DeepCopyInto(*out)
}
if in.Mirroring != nil {
in, out := &in.Mirroring, &out.Mirroring
*out = new(Mirroring)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSpec.
func (in *ServiceSpec) DeepCopy() *ServiceSpec {
if in == nil {
return nil
}
out := new(ServiceSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceTCP) DeepCopyInto(out *ServiceTCP) {
*out = *in
@ -1392,22 +1366,6 @@ func (in *TLSOptionSpec) DeepCopy() *TLSOptionSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSOptionUDPRef) DeepCopyInto(out *TLSOptionUDPRef) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSOptionUDPRef.
func (in *TLSOptionUDPRef) DeepCopy() *TLSOptionUDPRef {
if in == nil {
return nil
}
out := new(TLSOptionUDPRef)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSStore) DeepCopyInto(out *TLSStore) {
*out = *in
@ -1603,6 +1561,32 @@ func (in *TraefikServiceList) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TraefikServiceSpec) DeepCopyInto(out *TraefikServiceSpec) {
*out = *in
if in.Weighted != nil {
in, out := &in.Weighted, &out.Weighted
*out = new(WeightedRoundRobin)
(*in).DeepCopyInto(*out)
}
if in.Mirroring != nil {
in, out := &in.Mirroring, &out.Mirroring
*out = new(Mirroring)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TraefikServiceSpec.
func (in *TraefikServiceSpec) DeepCopy() *TraefikServiceSpec {
if in == nil {
return nil
}
out := new(TraefikServiceSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WeightedRoundRobin) DeepCopyInto(out *WeightedRoundRobin) {
*out = *in

View file

@ -21,12 +21,13 @@ spec:
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1alpha2
metadata:
name: my-gateway
name: my-gateway-http
namespace: default
spec:
gatewayClassName: my-gateway-class
listeners: # Use GatewayClass defaults for listener definition.
- name: http1
hostname: foo.bar
protocol: HTTP
port: 9080
allowedRoutes:
@ -37,6 +38,7 @@ spec:
from: Same
- name: http2
hostname: foo.bar
protocol: HTTP
port: 9080
allowedRoutes:
@ -45,7 +47,26 @@ spec:
namespaces:
from: Same
- name: tcp
---
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1alpha2
metadata:
name: my-gateway-tcp
namespace: default
spec:
gatewayClassName: my-gateway-class
listeners: # Use GatewayClass defaults for listener definition.
- name: tcp1
hostname: foo.bar
protocol: TCP
port: 9000
allowedRoutes:
kinds:
- kind: TCPRoute
namespaces:
from: Same
- name: tcp2
hostname: foo.bar
protocol: TCP
port: 9000
allowedRoutes:
@ -54,7 +75,17 @@ spec:
namespaces:
from: Same
- name: tls
---
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1alpha2
metadata:
name: my-gateway-tls
namespace: default
spec:
gatewayClassName: my-gateway-class
listeners: # Use GatewayClass defaults for listener definition.
- name: tls1
hostname: foo.bar
protocol: TLS
port: 9000
tls:
@ -66,6 +97,7 @@ spec:
from: Same
- name: tls2
hostname: foo.bar
protocol: TLS
port: 9000
tls:

View file

@ -317,7 +317,7 @@ func (p *Provider) createGatewayConf(ctx context.Context, client Client, gateway
func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway *v1alpha2.Gateway, conf *dynamic.Configuration, tlsConfigs map[string]*tls.CertAndStores) []v1alpha2.ListenerStatus {
logger := log.FromContext(ctx)
listenerStatuses := make([]v1alpha2.ListenerStatus, len(gateway.Spec.Listeners))
allocatedPort := map[v1alpha2.PortNumber]v1alpha2.ProtocolType{}
allocatedListeners := make(map[string]struct{})
for i, listener := range gateway.Spec.Listeners {
listenerStatuses[i] = v1alpha2.ListenerStatus{
@ -340,19 +340,22 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway *
continue
}
if _, ok := allocatedPort[listener.Port]; ok {
listenerKey := makeListenerKey(listener)
if _, ok := allocatedListeners[listenerKey]; ok {
listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{
Type: string(v1alpha2.ListenerConditionDetached),
Type: string(v1alpha2.ListenerConditionConflicted),
Status: metav1.ConditionTrue,
LastTransitionTime: metav1.Now(),
Reason: string(v1alpha2.ListenerReasonPortUnavailable),
Message: fmt.Sprintf("Port %d unavailable", listener.Port),
Reason: "DuplicateListener",
Message: "A listener with same protocol, port and hostname already exists",
})
continue
}
allocatedPort[listener.Port] = listener.Protocol
allocatedListeners[listenerKey] = struct{}{}
ep, err := p.entryPointName(listener.Port, listener.Protocol)
if err != nil {
// update "Detached" status with "PortUnavailable" reason
@ -1700,3 +1703,13 @@ func isInternalService(ref v1alpha2.BackendRef) bool {
*ref.Group == traefikv1alpha1.GroupName &&
strings.HasSuffix(string(ref.Name), "@internal")
}
// makeListenerKey joins protocol, hostname, and port of a listener into a string key.
func makeListenerKey(l v1alpha2.Listener) string {
var hostname v1alpha2.Hostname
if l.Hostname != nil {
hostname = *l.Hostname
}
return fmt.Sprintf("%s|%s|%d", l.Protocol, hostname, l.Port)
}

View file

@ -3566,8 +3566,8 @@ func TestLoadMixedRoutes(t *testing.T) {
},
},
{
desc: "Empty caused by mixed routes multiple protocol using same port",
paths: []string{"services.yml", "mixed/with_multiple_protocol_using_same_port.yml"},
desc: "Empty caused by mixed routes with multiple listeners using same hostname, port and protocol",
paths: []string{"services.yml", "mixed/with_multiple_listeners_using_same_hostname_port_protocol.yml"},
entryPoints: map[string]Entrypoint{
"web": {Address: ":9080"},
"tcp": {Address: ":9000"},
@ -4989,7 +4989,7 @@ func Test_shouldAttach(t *testing.T) {
}
func Test_matchingHostnames(t *testing.T) {
tests := []struct {
testCases := []struct {
desc string
listener v1alpha2.Listener
hostnames []v1alpha2.Hostname
@ -5081,7 +5081,7 @@ func Test_matchingHostnames(t *testing.T) {
},
}
for _, test := range tests {
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
@ -5093,7 +5093,7 @@ func Test_matchingHostnames(t *testing.T) {
}
func Test_getAllowedRoutes(t *testing.T) {
tests := []struct {
testCases := []struct {
desc string
listener v1alpha2.Listener
supportedRouteKinds []v1alpha2.RouteGroupKind
@ -5193,7 +5193,7 @@ func Test_getAllowedRoutes(t *testing.T) {
},
}
for _, test := range tests {
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
@ -5210,6 +5210,45 @@ func Test_getAllowedRoutes(t *testing.T) {
}
}
func Test_makeListenerKey(t *testing.T) {
testCases := []struct {
desc string
listener v1alpha2.Listener
expectedKey string
}{
{
desc: "empty",
expectedKey: "||0",
},
{
desc: "listener with port, protocol and hostname",
listener: v1alpha2.Listener{
Port: 443,
Protocol: v1alpha2.HTTPSProtocolType,
Hostname: hostnamePtr("www.example.com"),
},
expectedKey: "HTTPS|www.example.com|443",
},
{
desc: "listener with port, protocol and nil hostname",
listener: v1alpha2.Listener{
Port: 443,
Protocol: v1alpha2.HTTPSProtocolType,
},
expectedKey: "HTTPS||443",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
assert.Equal(t, test.expectedKey, makeListenerKey(test.listener))
})
}
}
func hostnamePtr(hostname v1alpha2.Hostname) *v1alpha2.Hostname {
return &hostname
}

View file

@ -283,6 +283,7 @@
"notAfter": true,
"notBefore": true,
"sans": true,
"serialNumber": true,
"subject": {
"country": true,
"province": true,
@ -301,8 +302,7 @@
"commonName": true,
"serialNumber": true,
"domainComponent": true
},
"serialNumber": true
}
}
},
"retry": {

View file

@ -286,6 +286,7 @@
"notAfter": true,
"notBefore": true,
"sans": true,
"serialNumber": true,
"subject": {
"country": true,
"province": true,
@ -304,8 +305,7 @@
"commonName": true,
"serialNumber": true,
"domainComponent": true
},
"serialNumber": true
}
}
},
"retry": {

View file

@ -529,6 +529,8 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati
return nil, err
}
handler = http.AllowQuerySemicolons(handler)
if withH2c {
handler = h2c.NewHandler(handler, &http2.Server{
MaxConcurrentStreams: uint32(configuration.HTTP2.MaxConcurrentStreams),

View file

@ -9,6 +9,7 @@ import (
"net/http"
"net/http/httputil"
"net/url"
"strings"
"time"
ptypes "github.com/traefik/paerser/types"
@ -46,7 +47,7 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar
outReq.URL.Path = u.Path
outReq.URL.RawPath = u.RawPath
outReq.URL.RawQuery = u.RawQuery
outReq.URL.RawQuery = strings.ReplaceAll(u.RawQuery, ";", "&")
outReq.RequestURI = "" // Outgoing request should not have RequestURI
outReq.Proto = "HTTP/1.1"

View file

@ -311,12 +311,17 @@ func (m *Manager) LaunchHealthCheck() {
}
func buildHealthCheckOptions(ctx context.Context, lb healthcheck.Balancer, backend string, hc *dynamic.ServerHealthCheck) *healthcheck.Options {
if hc == nil || hc.Path == "" {
if hc == nil {
return nil
}
logger := log.FromContext(ctx)
if hc.Path == "" {
logger.Errorf("Ignoring heath check configuration for '%s': no path provided", backend)
return nil
}
interval := defaultHealthCheckInterval
if hc.Interval != "" {
intervalOverride, err := time.ParseDuration(hc.Interval)