1
0
Fork 0

Reintroduce dropped v2 dynamic config

Co-authored-by: Baptiste Mayelle <baptiste.mayelle@traefik.io>
This commit is contained in:
Romain 2024-01-29 17:32:05 +01:00 committed by GitHub
parent 18203f57d2
commit 40de310927
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
53 changed files with 880 additions and 392 deletions

View file

@ -6,7 +6,6 @@ import (
ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v3/pkg/ip"
"github.com/traefik/traefik/v3/pkg/types"
)
// +k8s:deepcopy-gen=true
@ -55,9 +54,13 @@ type GrpcWeb struct {
// +k8s:deepcopy-gen=true
// ContentType holds the content-type middleware configuration.
// This middleware sets the `Content-Type` header value to the media type detected from the response content,
// when it is not set by the backend.
type ContentType struct{}
// 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.
// Deprecated: AutoDetect option is deprecated, Content-Type middleware is only meant to be used to enable the content-type detection, please remove any usage of this option.
AutoDetect *bool `json:"autoDetect,omitempty" toml:"autoDetect,omitempty" yaml:"autoDetect,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
@ -218,7 +221,7 @@ type ForwardAuth struct {
// 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"`
TLS *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.
@ -235,6 +238,20 @@ type ForwardAuth struct {
// +k8s:deepcopy-gen=true
// ClientTLS holds TLS specific configurations as client
// CA, Cert and Key can be either path or file contents.
// TODO: remove this struct when CAOptional option will be removed.
type ClientTLS struct {
CA string `description:"TLS CA" json:"ca,omitempty" toml:"ca,omitempty" yaml:"ca,omitempty"`
Cert string `description:"TLS cert" json:"cert,omitempty" toml:"cert,omitempty" yaml:"cert,omitempty"`
Key string `description:"TLS key" json:"key,omitempty" toml:"key,omitempty" yaml:"key,omitempty" loggable:"false"`
InsecureSkipVerify bool `description:"TLS insecure skip verify" json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"`
// Deprecated: TLS client authentication is a server side option (see https://github.com/golang/go/blob/740a490f71d026bb7d2d13cb8fa2d6d6e0572b70/src/crypto/tls/common.go#L634).
CAOptional *bool `description:"TLS CA.Optional" json:"caOptional,omitempty" toml:"caOptional,omitempty" yaml:"caOptional,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
// Headers holds the headers middleware configuration.
// This middleware manages the requests and responses headers.
// More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/headers/#customrequestheaders
@ -303,6 +320,17 @@ type Headers struct {
// 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"`
// Deprecated: FeaturePolicy option is deprecated, please use PermissionsPolicy instead.
FeaturePolicy *string `json:"featurePolicy,omitempty" toml:"featurePolicy,omitempty" yaml:"featurePolicy,omitempty" export:"true"`
// Deprecated: SSLRedirect option is deprecated, please use EntryPoint redirection or RedirectScheme instead.
SSLRedirect *bool `json:"sslRedirect,omitempty" toml:"sslRedirect,omitempty" yaml:"sslRedirect,omitempty" export:"true"`
// Deprecated: SSLTemporaryRedirect option is deprecated, please use EntryPoint redirection or RedirectScheme instead.
SSLTemporaryRedirect *bool `json:"sslTemporaryRedirect,omitempty" toml:"sslTemporaryRedirect,omitempty" yaml:"sslTemporaryRedirect,omitempty" export:"true"`
// Deprecated: SSLHost option is deprecated, please use RedirectRegex instead.
SSLHost *string `json:"sslHost,omitempty" toml:"sslHost,omitempty" yaml:"sslHost,omitempty"`
// Deprecated: SSLForceHost option is deprecated, please use RedirectRegex instead.
SSLForceHost *bool `json:"sslForceHost,omitempty" toml:"sslForceHost,omitempty" yaml:"sslForceHost,omitempty" export:"true"`
}
// HasCustomHeadersDefined checks to see if any of the custom header elements have been set.
@ -327,6 +355,10 @@ func (h *Headers) HasCorsHeadersDefined() bool {
func (h *Headers) HasSecureHeadersDefined() bool {
return h != nil && (len(h.AllowedHosts) != 0 ||
len(h.HostsProxyHeaders) != 0 ||
(h.SSLRedirect != nil && *h.SSLRedirect) ||
(h.SSLTemporaryRedirect != nil && *h.SSLTemporaryRedirect) ||
(h.SSLForceHost != nil && *h.SSLForceHost) ||
(h.SSLHost != nil && *h.SSLHost != "") ||
len(h.SSLProxyHeaders) != 0 ||
h.STSSeconds != 0 ||
h.STSIncludeSubdomains ||
@ -340,6 +372,7 @@ func (h *Headers) HasSecureHeadersDefined() bool {
h.ContentSecurityPolicy != "" ||
h.PublicKey != "" ||
h.ReferrerPolicy != "" ||
(h.FeaturePolicy != nil && *h.FeaturePolicy != "") ||
h.PermissionsPolicy != "" ||
h.IsDevelopment)
}
@ -557,6 +590,11 @@ type Retry struct {
type StripPrefix struct {
// Prefixes defines the prefixes to strip from the request URL.
Prefixes []string `json:"prefixes,omitempty" toml:"prefixes,omitempty" yaml:"prefixes,omitempty" export:"true"`
// Deprecated: ForceSlash option is deprecated, please remove any usage of this option.
// 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"`
}
// +k8s:deepcopy-gen=true

View file

@ -86,6 +86,14 @@ type TCPServersLoadBalancer struct {
ProxyProtocol *ProxyProtocol `json:"proxyProtocol,omitempty" toml:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
Servers []TCPServer `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server" export:"true"`
ServersTransport string `json:"serversTransport,omitempty" toml:"serversTransport,omitempty" yaml:"serversTransport,omitempty" export:"true"`
// TerminationDelay, corresponds to 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).
// Deprecated: use ServersTransport to configure the TerminationDelay instead.
TerminationDelay *int `json:"terminationDelay,omitempty" toml:"terminationDelay,omitempty" yaml:"terminationDelay,omitempty" export:"true"`
}
// Mergeable tells if the given service is mergeable.

View file

@ -124,6 +124,27 @@ func (in *CircuitBreaker) DeepCopy() *CircuitBreaker {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClientTLS) DeepCopyInto(out *ClientTLS) {
*out = *in
if in.CAOptional != nil {
in, out := &in.CAOptional, &out.CAOptional
*out = new(bool)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientTLS.
func (in *ClientTLS) DeepCopy() *ClientTLS {
if in == nil {
return nil
}
out := new(ClientTLS)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Compress) DeepCopyInto(out *Compress) {
*out = *in
@ -219,6 +240,11 @@ func (in Configurations) DeepCopy() Configurations {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContentType) DeepCopyInto(out *ContentType) {
*out = *in
if in.AutoDetect != nil {
in, out := &in.AutoDetect, &out.AutoDetect
*out = new(bool)
**out = **in
}
return
}
@ -316,8 +342,8 @@ func (in *ForwardAuth) DeepCopyInto(out *ForwardAuth) {
*out = *in
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
*out = new(types.ClientTLS)
**out = **in
*out = new(ClientTLS)
(*in).DeepCopyInto(*out)
}
if in.AuthResponseHeaders != nil {
in, out := &in.AuthResponseHeaders, &out.AuthResponseHeaders
@ -534,6 +560,31 @@ func (in *Headers) DeepCopyInto(out *Headers) {
(*out)[key] = val
}
}
if in.FeaturePolicy != nil {
in, out := &in.FeaturePolicy, &out.FeaturePolicy
*out = new(string)
**out = **in
}
if in.SSLRedirect != nil {
in, out := &in.SSLRedirect, &out.SSLRedirect
*out = new(bool)
**out = **in
}
if in.SSLTemporaryRedirect != nil {
in, out := &in.SSLTemporaryRedirect, &out.SSLTemporaryRedirect
*out = new(bool)
**out = **in
}
if in.SSLHost != nil {
in, out := &in.SSLHost, &out.SSLHost
*out = new(string)
**out = **in
}
if in.SSLForceHost != nil {
in, out := &in.SSLForceHost, &out.SSLForceHost
*out = new(bool)
**out = **in
}
return
}
@ -794,7 +845,7 @@ func (in *Middleware) DeepCopyInto(out *Middleware) {
if in.ContentType != nil {
in, out := &in.ContentType, &out.ContentType
*out = new(ContentType)
**out = **in
(*in).DeepCopyInto(*out)
}
if in.GrpcWeb != nil {
in, out := &in.GrpcWeb, &out.GrpcWeb
@ -1360,6 +1411,11 @@ func (in *StripPrefix) DeepCopyInto(out *StripPrefix) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ForceSlash != nil {
in, out := &in.ForceSlash, &out.ForceSlash
*out = new(bool)
**out = **in
}
return
}
@ -1650,6 +1706,11 @@ func (in *TCPServersLoadBalancer) DeepCopyInto(out *TCPServersLoadBalancer) {
*out = make([]TCPServer, len(*in))
copy(*out, *in)
}
if in.TerminationDelay != nil {
in, out := &in.TerminationDelay, &out.TerminationDelay
*out = new(int)
**out = **in
}
return
}

View file

@ -9,9 +9,11 @@ import (
"github.com/stretchr/testify/require"
ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/types"
)
func Bool(v bool) *bool { return &v }
func String(v string) *string { return &v }
func TestDecodeConfiguration(t *testing.T) {
labels := map[string]string{
"traefik.http.middlewares.Middleware0.addprefix.prefix": "foobar",
@ -43,6 +45,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware7.forwardauth.authresponseheaders": "foobar, fiibar",
"traefik.http.middlewares.Middleware7.forwardauth.authrequestheaders": "foobar, fiibar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.ca": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.caoptional": "true",
"traefik.http.middlewares.Middleware7.forwardauth.tls.cert": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.insecureskipverify": "true",
"traefik.http.middlewares.Middleware7.forwardauth.tls.key": "foobar",
@ -71,9 +74,14 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware8.headers.isdevelopment": "true",
"traefik.http.middlewares.Middleware8.headers.publickey": "foobar",
"traefik.http.middlewares.Middleware8.headers.referrerpolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.featurepolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.permissionspolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslforcehost": "true",
"traefik.http.middlewares.Middleware8.headers.sslhost": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslproxyheaders.name0": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslproxyheaders.name1": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslredirect": "true",
"traefik.http.middlewares.Middleware8.headers.ssltemporaryredirect": "true",
"traefik.http.middlewares.Middleware8.headers.stsincludesubdomains": "true",
"traefik.http.middlewares.Middleware8.headers.stspreload": "true",
"traefik.http.middlewares.Middleware8.headers.stsseconds": "42",
@ -124,6 +132,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware16.retry.attempts": "42",
"traefik.http.middlewares.Middleware16.retry.initialinterval": "1s",
"traefik.http.middlewares.Middleware17.stripprefix.prefixes": "foobar, fiibar",
"traefik.http.middlewares.Middleware17.stripprefix.forceslash": "true",
"traefik.http.middlewares.Middleware18.stripprefixregex.regex": "foobar, fiibar",
"traefik.http.middlewares.Middleware19.compress.minresponsebodybytes": "42",
"traefik.http.middlewares.Middleware20.plugin.tomato.aaa": "foo1",
@ -194,9 +203,11 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.tcp.routers.Router1.tls.options": "foo",
"traefik.tcp.routers.Router1.tls.passthrough": "false",
"traefik.tcp.services.Service0.loadbalancer.server.Port": "42",
"traefik.tcp.services.Service0.loadbalancer.TerminationDelay": "42",
"traefik.tcp.services.Service0.loadbalancer.proxyProtocol.version": "42",
"traefik.tcp.services.Service0.loadbalancer.serversTransport": "foo",
"traefik.tcp.services.Service1.loadbalancer.server.Port": "42",
"traefik.tcp.services.Service1.loadbalancer.TerminationDelay": "42",
"traefik.tcp.services.Service1.loadbalancer.proxyProtocol": "true",
"traefik.tcp.services.Service1.loadbalancer.serversTransport": "foo",
@ -261,6 +272,7 @@ func TestDecodeConfiguration(t *testing.T) {
Port: "42",
},
},
TerminationDelay: func(i int) *int { return &i }(42),
ProxyProtocol: &dynamic.ProxyProtocol{Version: 42},
ServersTransport: "foo",
},
@ -272,6 +284,7 @@ func TestDecodeConfiguration(t *testing.T) {
Port: "42",
},
},
TerminationDelay: func(i int) *int { return &i }(42),
ProxyProtocol: &dynamic.ProxyProtocol{Version: 2},
ServersTransport: "foo",
},
@ -459,6 +472,7 @@ func TestDecodeConfiguration(t *testing.T) {
"foobar",
"fiibar",
},
ForceSlash: Bool(true),
},
},
"Middleware18": {
@ -525,11 +539,12 @@ func TestDecodeConfiguration(t *testing.T) {
"Middleware7": {
ForwardAuth: &dynamic.ForwardAuth{
Address: "foobar",
TLS: &types.ClientTLS{
TLS: &dynamic.ClientTLS{
CA: "foobar",
Cert: "foobar",
Key: "foobar",
InsecureSkipVerify: true,
CAOptional: Bool(true),
},
TrustForwardHeader: true,
AuthResponseHeaders: []string{
@ -583,10 +598,14 @@ func TestDecodeConfiguration(t *testing.T) {
"foobar",
"fiibar",
},
SSLRedirect: Bool(true),
SSLTemporaryRedirect: Bool(true),
SSLHost: String("foobar"),
SSLProxyHeaders: map[string]string{
"name0": "foobar",
"name1": "foobar",
},
SSLForceHost: Bool(true),
STSSeconds: 42,
STSIncludeSubdomains: true,
STSPreload: true,
@ -599,6 +618,7 @@ func TestDecodeConfiguration(t *testing.T) {
ContentSecurityPolicy: "foobar",
PublicKey: "foobar",
ReferrerPolicy: "foobar",
FeaturePolicy: String("foobar"),
PermissionsPolicy: "foobar",
IsDevelopment: true,
},
@ -758,6 +778,7 @@ func TestEncodeConfiguration(t *testing.T) {
},
},
ServersTransport: "foo",
TerminationDelay: func(i int) *int { return &i }(42),
},
},
"Service1": {
@ -768,6 +789,7 @@ func TestEncodeConfiguration(t *testing.T) {
},
},
ServersTransport: "foo",
TerminationDelay: func(i int) *int { return &i }(42),
},
},
},
@ -952,6 +974,7 @@ func TestEncodeConfiguration(t *testing.T) {
"foobar",
"fiibar",
},
ForceSlash: Bool(true),
},
},
"Middleware18": {
@ -1026,11 +1049,12 @@ func TestEncodeConfiguration(t *testing.T) {
"Middleware7": {
ForwardAuth: &dynamic.ForwardAuth{
Address: "foobar",
TLS: &types.ClientTLS{
TLS: &dynamic.ClientTLS{
CA: "foobar",
Cert: "foobar",
Key: "foobar",
InsecureSkipVerify: true,
CAOptional: Bool(true),
},
TrustForwardHeader: true,
AuthResponseHeaders: []string{
@ -1084,10 +1108,14 @@ func TestEncodeConfiguration(t *testing.T) {
"foobar",
"fiibar",
},
SSLRedirect: Bool(true),
SSLTemporaryRedirect: Bool(true),
SSLHost: String("foobar"),
SSLProxyHeaders: map[string]string{
"name0": "foobar",
"name1": "foobar",
},
SSLForceHost: Bool(true),
STSSeconds: 42,
STSIncludeSubdomains: true,
STSPreload: true,
@ -1100,6 +1128,7 @@ func TestEncodeConfiguration(t *testing.T) {
ContentSecurityPolicy: "foobar",
PublicKey: "foobar",
ReferrerPolicy: "foobar",
FeaturePolicy: String("foobar"),
PermissionsPolicy: "foobar",
IsDevelopment: true,
},
@ -1222,6 +1251,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.AuthResponseHeaders": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.AuthRequestHeaders": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.CA": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.CAOptional": "true",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Cert": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.InsecureSkipVerify": "true",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Key": "foobar",
@ -1250,9 +1280,14 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Middlewares.Middleware8.Headers.IsDevelopment": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.PublicKey": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.ReferrerPolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.FeaturePolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.PermissionsPolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLForceHost": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLHost": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders.name0": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders.name1": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLRedirect": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLTemporaryRedirect": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSIncludeSubdomains": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSPreload": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSSeconds": "42",
@ -1304,6 +1339,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Middlewares.Middleware16.Retry.Attempts": "42",
"traefik.HTTP.Middlewares.Middleware16.Retry.InitialInterval": "1000000000",
"traefik.HTTP.Middlewares.Middleware17.StripPrefix.Prefixes": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware17.StripPrefix.ForceSlash": "true",
"traefik.HTTP.Middlewares.Middleware18.StripPrefixRegex.Regex": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware19.Compress.MinResponseBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware20.Plugin.tomato.aaa": "foo1",
@ -1373,9 +1409,11 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.TCP.Services.Service0.LoadBalancer.server.Port": "42",
"traefik.TCP.Services.Service0.LoadBalancer.server.TLS": "false",
"traefik.TCP.Services.Service0.LoadBalancer.ServersTransport": "foo",
"traefik.TCP.Services.Service0.LoadBalancer.TerminationDelay": "42",
"traefik.TCP.Services.Service1.LoadBalancer.server.Port": "42",
"traefik.TCP.Services.Service1.LoadBalancer.server.TLS": "false",
"traefik.TCP.Services.Service1.LoadBalancer.ServersTransport": "foo",
"traefik.TCP.Services.Service1.LoadBalancer.TerminationDelay": "42",
"traefik.UDP.Routers.Router0.EntryPoints": "foobar, fiibar",
"traefik.UDP.Routers.Router0.Service": "foobar",