package kv import ( "context" "errors" "testing" "time" "github.com/kvtools/valkeyrie/store" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" "github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/tls" "github.com/traefik/traefik/v3/pkg/types" ) func pointer[T any](v T) *T { return &v } func Test_buildConfiguration(t *testing.T) { provider := newProviderMock(mapToPairs(map[string]string{ "traefik/http/routers/Router0/entryPoints/0": "foobar", "traefik/http/routers/Router0/entryPoints/1": "foobar", "traefik/http/routers/Router0/middlewares/0": "foobar", "traefik/http/routers/Router0/middlewares/1": "foobar", "traefik/http/routers/Router0/service": "foobar", "traefik/http/routers/Router0/rule": "foobar", "traefik/http/routers/Router0/priority": "42", "traefik/http/routers/Router0/tls": "", "traefik/http/routers/Router1/rule": "foobar", "traefik/http/routers/Router1/priority": "42", "traefik/http/routers/Router1/tls/domains/0/main": "foobar", "traefik/http/routers/Router1/tls/domains/0/sans/0": "foobar", "traefik/http/routers/Router1/tls/domains/0/sans/1": "foobar", "traefik/http/routers/Router1/tls/domains/1/main": "foobar", "traefik/http/routers/Router1/tls/domains/1/sans/0": "foobar", "traefik/http/routers/Router1/tls/domains/1/sans/1": "foobar", "traefik/http/routers/Router1/tls/options": "foobar", "traefik/http/routers/Router1/tls/certResolver": "foobar", "traefik/http/routers/Router1/entryPoints/0": "foobar", "traefik/http/routers/Router1/entryPoints/1": "foobar", "traefik/http/routers/Router1/middlewares/0": "foobar", "traefik/http/routers/Router1/middlewares/1": "foobar", "traefik/http/routers/Router1/service": "foobar", "traefik/http/services/Service01/loadBalancer/healthCheck/path": "foobar", "traefik/http/services/Service01/loadBalancer/healthCheck/port": "42", "traefik/http/services/Service01/loadBalancer/healthCheck/interval": "1s", "traefik/http/services/Service01/loadBalancer/healthCheck/timeout": "1s", "traefik/http/services/Service01/loadBalancer/healthCheck/hostname": "foobar", "traefik/http/services/Service01/loadBalancer/healthCheck/headers/name0": "foobar", "traefik/http/services/Service01/loadBalancer/healthCheck/headers/name1": "foobar", "traefik/http/services/Service01/loadBalancer/healthCheck/scheme": "foobar", "traefik/http/services/Service01/loadBalancer/healthCheck/mode": "foobar", "traefik/http/services/Service01/loadBalancer/healthCheck/followredirects": "true", "traefik/http/services/Service01/loadBalancer/responseForwarding/flushInterval": "1s", "traefik/http/services/Service01/loadBalancer/passHostHeader": "true", "traefik/http/services/Service01/loadBalancer/sticky/cookie/name": "foobar", "traefik/http/services/Service01/loadBalancer/sticky/cookie/secure": "true", "traefik/http/services/Service01/loadBalancer/sticky/cookie/httpOnly": "true", "traefik/http/services/Service01/loadBalancer/sticky/cookie/path": "foobar", "traefik/http/services/Service01/loadBalancer/servers/0/url": "foobar", "traefik/http/services/Service01/loadBalancer/servers/1/url": "foobar", "traefik/http/services/Service02/mirroring/service": "foobar", "traefik/http/services/Service02/mirroring/mirrorBody": "true", "traefik/http/services/Service02/mirroring/maxBodySize": "42", "traefik/http/services/Service02/mirroring/mirrors/0/name": "foobar", "traefik/http/services/Service02/mirroring/mirrors/0/percent": "42", "traefik/http/services/Service02/mirroring/mirrors/1/name": "foobar", "traefik/http/services/Service02/mirroring/mirrors/1/percent": "42", "traefik/http/services/Service03/weighted/sticky/cookie/name": "foobar", "traefik/http/services/Service03/weighted/sticky/cookie/secure": "true", "traefik/http/services/Service03/weighted/sticky/cookie/httpOnly": "true", "traefik/http/services/Service03/weighted/sticky/cookie/path": "foobar", "traefik/http/services/Service03/weighted/services/0/name": "foobar", "traefik/http/services/Service03/weighted/services/0/weight": "42", "traefik/http/services/Service03/weighted/services/1/name": "foobar", "traefik/http/services/Service03/weighted/services/1/weight": "42", "traefik/http/services/Service04/failover/service": "foobar", "traefik/http/services/Service04/failover/fallback": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/authResponseHeaders/0": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/authResponseHeaders/1": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/authRequestHeaders/0": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/authRequestHeaders/1": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/tls/key": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/tls/insecureSkipVerify": "true", "traefik/http/middlewares/Middleware08/forwardAuth/tls/ca": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/tls/caOptional": "true", "traefik/http/middlewares/Middleware08/forwardAuth/tls/cert": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/address": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/trustForwardHeader": "true", "traefik/http/middlewares/Middleware15/redirectScheme/scheme": "foobar", "traefik/http/middlewares/Middleware15/redirectScheme/port": "foobar", "traefik/http/middlewares/Middleware15/redirectScheme/permanent": "true", "traefik/http/middlewares/Middleware17/replacePathRegex/regex": "foobar", "traefik/http/middlewares/Middleware17/replacePathRegex/replacement": "foobar", "traefik/http/middlewares/Middleware14/redirectRegex/regex": "foobar", "traefik/http/middlewares/Middleware14/redirectRegex/replacement": "foobar", "traefik/http/middlewares/Middleware14/redirectRegex/permanent": "true", "traefik/http/middlewares/Middleware16/replacePath/path": "foobar", "traefik/http/middlewares/Middleware06/digestAuth/removeHeader": "true", "traefik/http/middlewares/Middleware06/digestAuth/realm": "foobar", "traefik/http/middlewares/Middleware06/digestAuth/headerField": "foobar", "traefik/http/middlewares/Middleware06/digestAuth/users/0": "foobar", "traefik/http/middlewares/Middleware06/digestAuth/users/1": "foobar", "traefik/http/middlewares/Middleware06/digestAuth/usersFile": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlAllowHeaders/0": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlAllowHeaders/1": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlAllowOriginList/0": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlAllowOriginList/1": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlAllowOriginListRegex/0": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlAllowOriginListRegex/1": "foobar", "traefik/http/middlewares/Middleware09/headers/contentTypeNosniff": "true", "traefik/http/middlewares/Middleware09/headers/accessControlAllowCredentials": "true", "traefik/http/middlewares/Middleware09/headers/featurePolicy": "foobar", "traefik/http/middlewares/Middleware09/headers/permissionsPolicy": "foobar", "traefik/http/middlewares/Middleware09/headers/forceSTSHeader": "true", "traefik/http/middlewares/Middleware09/headers/sslRedirect": "true", "traefik/http/middlewares/Middleware09/headers/sslHost": "foobar", "traefik/http/middlewares/Middleware09/headers/sslForceHost": "true", "traefik/http/middlewares/Middleware09/headers/sslProxyHeaders/name1": "foobar", "traefik/http/middlewares/Middleware09/headers/sslProxyHeaders/name0": "foobar", "traefik/http/middlewares/Middleware09/headers/allowedHosts/0": "foobar", "traefik/http/middlewares/Middleware09/headers/allowedHosts/1": "foobar", "traefik/http/middlewares/Middleware09/headers/stsPreload": "true", "traefik/http/middlewares/Middleware09/headers/frameDeny": "true", "traefik/http/middlewares/Middleware09/headers/isDevelopment": "true", "traefik/http/middlewares/Middleware09/headers/customResponseHeaders/name1": "foobar", "traefik/http/middlewares/Middleware09/headers/customResponseHeaders/name0": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlAllowMethods/0": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlAllowMethods/1": "foobar", "traefik/http/middlewares/Middleware09/headers/stsSeconds": "42", "traefik/http/middlewares/Middleware09/headers/stsIncludeSubdomains": "true", "traefik/http/middlewares/Middleware09/headers/customFrameOptionsValue": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlMaxAge": "42", "traefik/http/middlewares/Middleware09/headers/addVaryHeader": "true", "traefik/http/middlewares/Middleware09/headers/hostsProxyHeaders/0": "foobar", "traefik/http/middlewares/Middleware09/headers/hostsProxyHeaders/1": "foobar", "traefik/http/middlewares/Middleware09/headers/sslTemporaryRedirect": "true", "traefik/http/middlewares/Middleware09/headers/customBrowserXSSValue": "foobar", "traefik/http/middlewares/Middleware09/headers/referrerPolicy": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlExposeHeaders/0": "foobar", "traefik/http/middlewares/Middleware09/headers/accessControlExposeHeaders/1": "foobar", "traefik/http/middlewares/Middleware09/headers/contentSecurityPolicy": "foobar", "traefik/http/middlewares/Middleware09/headers/contentSecurityPolicyReportOnly": "foobar", "traefik/http/middlewares/Middleware09/headers/publicKey": "foobar", "traefik/http/middlewares/Middleware09/headers/customRequestHeaders/name0": "foobar", "traefik/http/middlewares/Middleware09/headers/customRequestHeaders/name1": "foobar", "traefik/http/middlewares/Middleware09/headers/browserXssFilter": "true", "traefik/http/middlewares/Middleware10/ipAllowList/sourceRange/0": "foobar", "traefik/http/middlewares/Middleware10/ipAllowList/sourceRange/1": "foobar", "traefik/http/middlewares/Middleware10/ipAllowList/ipStrategy/excludedIPs/0": "foobar", "traefik/http/middlewares/Middleware10/ipAllowList/ipStrategy/excludedIPs/1": "foobar", "traefik/http/middlewares/Middleware10/ipAllowList/ipStrategy/depth": "42", "traefik/http/middlewares/Middleware11/inFlightReq/amount": "42", "traefik/http/middlewares/Middleware11/inFlightReq/sourceCriterion/requestHost": "true", "traefik/http/middlewares/Middleware11/inFlightReq/sourceCriterion/ipStrategy/depth": "42", "traefik/http/middlewares/Middleware11/inFlightReq/sourceCriterion/ipStrategy/excludedIPs/0": "foobar", "traefik/http/middlewares/Middleware11/inFlightReq/sourceCriterion/ipStrategy/excludedIPs/1": "foobar", "traefik/http/middlewares/Middleware11/inFlightReq/sourceCriterion/requestHeaderName": "foobar", "traefik/http/middlewares/Middleware12/passTLSClientCert/pem": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/notAfter": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/notBefore": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/sans": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/subject/country": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/subject/province": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/subject/locality": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/subject/organization": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/subject/organizationalunit": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/subject/commonName": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/subject/serialNumber": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/subject/domainComponent": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/issuer/country": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/issuer/province": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/issuer/locality": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/issuer/organization": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/issuer/commonName": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/issuer/serialNumber": "true", "traefik/http/middlewares/Middleware12/passTLSClientCert/info/issuer/domainComponent": "true", "traefik/http/middlewares/Middleware00/addPrefix/prefix": "foobar", "traefik/http/middlewares/Middleware03/chain/middlewares/0": "foobar", "traefik/http/middlewares/Middleware03/chain/middlewares/1": "foobar", "traefik/http/middlewares/Middleware04/circuitBreaker/expression": "foobar", "traefik/http/middlewares/Middleware04/circuitBreaker/checkPeriod": "1s", "traefik/http/middlewares/Middleware04/circuitBreaker/fallbackDuration": "1s", "traefik/http/middlewares/Middleware04/circuitBreaker/recoveryDuration": "1s", "traefik/http/middlewares/Middleware04/circuitBreaker/responseCode": "404", "traefik/http/middlewares/Middleware07/errors/status/0": "foobar", "traefik/http/middlewares/Middleware07/errors/status/1": "foobar", "traefik/http/middlewares/Middleware07/errors/service": "foobar", "traefik/http/middlewares/Middleware07/errors/query": "foobar", "traefik/http/middlewares/Middleware13/rateLimit/average": "42", "traefik/http/middlewares/Middleware13/rateLimit/period": "1s", "traefik/http/middlewares/Middleware13/rateLimit/burst": "42", "traefik/http/middlewares/Middleware13/rateLimit/sourceCriterion/requestHeaderName": "foobar", "traefik/http/middlewares/Middleware13/rateLimit/sourceCriterion/requestHost": "true", "traefik/http/middlewares/Middleware13/rateLimit/sourceCriterion/ipStrategy/depth": "42", "traefik/http/middlewares/Middleware13/rateLimit/sourceCriterion/ipStrategy/excludedIPs/0": "foobar", "traefik/http/middlewares/Middleware13/rateLimit/sourceCriterion/ipStrategy/excludedIPs/1": "foobar", "traefik/http/middlewares/Middleware20/stripPrefixRegex/regex/0": "foobar", "traefik/http/middlewares/Middleware20/stripPrefixRegex/regex/1": "foobar", "traefik/http/middlewares/Middleware01/basicAuth/users/0": "foobar", "traefik/http/middlewares/Middleware01/basicAuth/users/1": "foobar", "traefik/http/middlewares/Middleware01/basicAuth/usersFile": "foobar", "traefik/http/middlewares/Middleware01/basicAuth/realm": "foobar", "traefik/http/middlewares/Middleware01/basicAuth/removeHeader": "true", "traefik/http/middlewares/Middleware01/basicAuth/headerField": "foobar", "traefik/http/middlewares/Middleware02/buffering/maxResponseBodyBytes": "42", "traefik/http/middlewares/Middleware02/buffering/memResponseBodyBytes": "42", "traefik/http/middlewares/Middleware02/buffering/retryExpression": "foobar", "traefik/http/middlewares/Middleware02/buffering/maxRequestBodyBytes": "42", "traefik/http/middlewares/Middleware02/buffering/memRequestBodyBytes": "42", "traefik/http/middlewares/Middleware05/compress/encodings": "foobar, foobar", "traefik/http/middlewares/Middleware05/compress/minResponseBodyBytes": "42", "traefik/http/middlewares/Middleware18/retry/attempts": "42", "traefik/http/middlewares/Middleware19/stripPrefix/prefixes/0": "foobar", "traefik/http/middlewares/Middleware19/stripPrefix/prefixes/1": "foobar", "traefik/http/middlewares/Middleware19/stripPrefix/forceSlash": "true", "traefik/tcp/routers/TCPRouter0/entryPoints/0": "foobar", "traefik/tcp/routers/TCPRouter0/entryPoints/1": "foobar", "traefik/tcp/routers/TCPRouter0/service": "foobar", "traefik/tcp/routers/TCPRouter0/rule": "foobar", "traefik/tcp/routers/TCPRouter0/tls/options": "foobar", "traefik/tcp/routers/TCPRouter0/tls/certResolver": "foobar", "traefik/tcp/routers/TCPRouter0/tls/domains/0/main": "foobar", "traefik/tcp/routers/TCPRouter0/tls/domains/0/sans/0": "foobar", "traefik/tcp/routers/TCPRouter0/tls/domains/0/sans/1": "foobar", "traefik/tcp/routers/TCPRouter0/tls/domains/1/main": "foobar", "traefik/tcp/routers/TCPRouter0/tls/domains/1/sans/0": "foobar", "traefik/tcp/routers/TCPRouter0/tls/domains/1/sans/1": "foobar", "traefik/tcp/routers/TCPRouter0/tls/passthrough": "true", "traefik/tcp/routers/TCPRouter1/entryPoints/0": "foobar", "traefik/tcp/routers/TCPRouter1/entryPoints/1": "foobar", "traefik/tcp/routers/TCPRouter1/service": "foobar", "traefik/tcp/routers/TCPRouter1/rule": "foobar", "traefik/tcp/routers/TCPRouter1/tls/domains/0/main": "foobar", "traefik/tcp/routers/TCPRouter1/tls/domains/0/sans/0": "foobar", "traefik/tcp/routers/TCPRouter1/tls/domains/0/sans/1": "foobar", "traefik/tcp/routers/TCPRouter1/tls/domains/1/main": "foobar", "traefik/tcp/routers/TCPRouter1/tls/domains/1/sans/0": "foobar", "traefik/tcp/routers/TCPRouter1/tls/domains/1/sans/1": "foobar", "traefik/tcp/routers/TCPRouter1/tls/passthrough": "true", "traefik/tcp/routers/TCPRouter1/tls/options": "foobar", "traefik/tcp/routers/TCPRouter1/tls/certResolver": "foobar", "traefik/tcp/services/TCPService01/loadBalancer/terminationDelay": "42", "traefik/tcp/services/TCPService01/loadBalancer/servers/0/address": "foobar", "traefik/tcp/services/TCPService01/loadBalancer/servers/1/address": "foobar", "traefik/tcp/services/TCPService02/weighted/services/0/name": "foobar", "traefik/tcp/services/TCPService02/weighted/services/0/weight": "42", "traefik/tcp/services/TCPService02/weighted/services/1/name": "foobar", "traefik/tcp/services/TCPService02/weighted/services/1/weight": "43", "traefik/udp/routers/UDPRouter0/entrypoints/0": "foobar", "traefik/udp/routers/UDPRouter0/entrypoints/1": "foobar", "traefik/udp/routers/UDPRouter0/service": "foobar", "traefik/udp/routers/UDPRouter1/entrypoints/0": "foobar", "traefik/udp/routers/UDPRouter1/entrypoints/1": "foobar", "traefik/udp/routers/UDPRouter1/service": "foobar", "traefik/udp/services/UDPService01/loadBalancer/servers/0/address": "foobar", "traefik/udp/services/UDPService01/loadBalancer/servers/1/address": "foobar", "traefik/udp/services/UDPService02/loadBalancer/servers/0/address": "foobar", "traefik/udp/services/UDPService02/loadBalancer/servers/1/address": "foobar", "traefik/tls/options/Options0/minVersion": "foobar", "traefik/tls/options/Options0/maxVersion": "foobar", "traefik/tls/options/Options0/cipherSuites/0": "foobar", "traefik/tls/options/Options0/cipherSuites/1": "foobar", "traefik/tls/options/Options0/sniStrict": "true", "traefik/tls/options/Options0/curvePreferences/0": "foobar", "traefik/tls/options/Options0/curvePreferences/1": "foobar", "traefik/tls/options/Options0/clientAuth/caFiles/0": "foobar", "traefik/tls/options/Options0/clientAuth/caFiles/1": "foobar", "traefik/tls/options/Options0/clientAuth/clientAuthType": "foobar", "traefik/tls/options/Options1/sniStrict": "true", "traefik/tls/options/Options1/curvePreferences/0": "foobar", "traefik/tls/options/Options1/curvePreferences/1": "foobar", "traefik/tls/options/Options1/clientAuth/caFiles/0": "foobar", "traefik/tls/options/Options1/clientAuth/caFiles/1": "foobar", "traefik/tls/options/Options1/clientAuth/clientAuthType": "foobar", "traefik/tls/options/Options1/minVersion": "foobar", "traefik/tls/options/Options1/maxVersion": "foobar", "traefik/tls/options/Options1/cipherSuites/0": "foobar", "traefik/tls/options/Options1/cipherSuites/1": "foobar", "traefik/tls/stores/Store0/defaultCertificate/certFile": "foobar", "traefik/tls/stores/Store0/defaultCertificate/keyFile": "foobar", "traefik/tls/stores/Store1/defaultCertificate/certFile": "foobar", "traefik/tls/stores/Store1/defaultCertificate/keyFile": "foobar", "traefik/tls/certificates/0/certFile": "foobar", "traefik/tls/certificates/0/keyFile": "foobar", "traefik/tls/certificates/0/stores/0": "foobar", "traefik/tls/certificates/0/stores/1": "foobar", "traefik/tls/certificates/1/certFile": "foobar", "traefik/tls/certificates/1/keyFile": "foobar", "traefik/tls/certificates/1/stores/0": "foobar", "traefik/tls/certificates/1/stores/1": "foobar", })) cfg, err := provider.buildConfiguration(context.Background()) require.NoError(t, err) expected := &dynamic.Configuration{ HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "Router1": { EntryPoints: []string{ "foobar", "foobar", }, Middlewares: []string{ "foobar", "foobar", }, Service: "foobar", Rule: "foobar", Priority: 42, TLS: &dynamic.RouterTLSConfig{ Options: "foobar", CertResolver: "foobar", Domains: []types.Domain{ { Main: "foobar", SANs: []string{ "foobar", "foobar", }, }, { Main: "foobar", SANs: []string{ "foobar", "foobar", }, }, }, }, }, "Router0": { EntryPoints: []string{ "foobar", "foobar", }, Middlewares: []string{ "foobar", "foobar", }, Service: "foobar", Rule: "foobar", Priority: 42, TLS: &dynamic.RouterTLSConfig{}, }, }, Middlewares: map[string]*dynamic.Middleware{ "Middleware10": { IPAllowList: &dynamic.IPAllowList{ SourceRange: []string{ "foobar", "foobar", }, IPStrategy: &dynamic.IPStrategy{ Depth: 42, ExcludedIPs: []string{ "foobar", "foobar", }, }, }, }, "Middleware13": { RateLimit: &dynamic.RateLimit{ Average: 42, Burst: 42, Period: ptypes.Duration(time.Second), SourceCriterion: &dynamic.SourceCriterion{ IPStrategy: &dynamic.IPStrategy{ Depth: 42, ExcludedIPs: []string{ "foobar", "foobar", }, }, RequestHeaderName: "foobar", RequestHost: true, }, }, }, "Middleware19": { StripPrefix: &dynamic.StripPrefix{ Prefixes: []string{ "foobar", "foobar", }, ForceSlash: pointer(true), }, }, "Middleware00": { AddPrefix: &dynamic.AddPrefix{ Prefix: "foobar", }, }, "Middleware02": { Buffering: &dynamic.Buffering{ MaxRequestBodyBytes: 42, MemRequestBodyBytes: 42, MaxResponseBodyBytes: 42, MemResponseBodyBytes: 42, RetryExpression: "foobar", }, }, "Middleware04": { CircuitBreaker: &dynamic.CircuitBreaker{ Expression: "foobar", CheckPeriod: ptypes.Duration(time.Second), FallbackDuration: ptypes.Duration(time.Second), RecoveryDuration: ptypes.Duration(time.Second), ResponseCode: 404, }, }, "Middleware05": { Compress: &dynamic.Compress{ MinResponseBodyBytes: 42, Encodings: []string{ "foobar", "foobar", }, }, }, "Middleware08": { ForwardAuth: &dynamic.ForwardAuth{ Address: "foobar", TLS: &dynamic.ClientTLS{ CA: "foobar", Cert: "foobar", Key: "foobar", InsecureSkipVerify: true, CAOptional: pointer(true), }, TrustForwardHeader: true, AuthResponseHeaders: []string{ "foobar", "foobar", }, AuthRequestHeaders: []string{ "foobar", "foobar", }, }, }, "Middleware06": { DigestAuth: &dynamic.DigestAuth{ Users: dynamic.Users{ "foobar", "foobar", }, UsersFile: "foobar", RemoveHeader: true, Realm: "foobar", HeaderField: "foobar", }, }, "Middleware18": { Retry: &dynamic.Retry{ Attempts: 42, }, }, "Middleware16": { ReplacePath: &dynamic.ReplacePath{ Path: "foobar", }, }, "Middleware20": { StripPrefixRegex: &dynamic.StripPrefixRegex{ Regex: []string{ "foobar", "foobar", }, }, }, "Middleware03": { Chain: &dynamic.Chain{ Middlewares: []string{ "foobar", "foobar", }, }, }, "Middleware11": { InFlightReq: &dynamic.InFlightReq{ Amount: 42, SourceCriterion: &dynamic.SourceCriterion{ IPStrategy: &dynamic.IPStrategy{ Depth: 42, ExcludedIPs: []string{ "foobar", "foobar", }, }, RequestHeaderName: "foobar", RequestHost: true, }, }, }, "Middleware12": { PassTLSClientCert: &dynamic.PassTLSClientCert{ PEM: true, Info: &dynamic.TLSClientCertificateInfo{ NotAfter: true, NotBefore: true, Sans: true, Subject: &dynamic.TLSClientCertificateSubjectDNInfo{ Country: true, Province: true, Locality: true, Organization: true, OrganizationalUnit: true, CommonName: true, SerialNumber: true, DomainComponent: true, }, Issuer: &dynamic.TLSClientCertificateIssuerDNInfo{ Country: true, Province: true, Locality: true, Organization: true, CommonName: true, SerialNumber: true, DomainComponent: true, }, }, }, }, "Middleware14": { RedirectRegex: &dynamic.RedirectRegex{ Regex: "foobar", Replacement: "foobar", Permanent: true, }, }, "Middleware15": { RedirectScheme: &dynamic.RedirectScheme{ Scheme: "foobar", Port: "foobar", Permanent: true, }, }, "Middleware01": { BasicAuth: &dynamic.BasicAuth{ Users: dynamic.Users{ "foobar", "foobar", }, UsersFile: "foobar", Realm: "foobar", RemoveHeader: true, HeaderField: "foobar", }, }, "Middleware07": { Errors: &dynamic.ErrorPage{ Status: []string{ "foobar", "foobar", }, Service: "foobar", Query: "foobar", }, }, "Middleware09": { Headers: &dynamic.Headers{ CustomRequestHeaders: map[string]string{ "name0": "foobar", "name1": "foobar", }, CustomResponseHeaders: map[string]string{ "name0": "foobar", "name1": "foobar", }, AccessControlAllowCredentials: true, AccessControlAllowHeaders: []string{ "foobar", "foobar", }, AccessControlAllowMethods: []string{ "foobar", "foobar", }, AccessControlAllowOriginList: []string{ "foobar", "foobar", }, AccessControlAllowOriginListRegex: []string{ "foobar", "foobar", }, AccessControlExposeHeaders: []string{ "foobar", "foobar", }, AccessControlMaxAge: 42, AddVaryHeader: true, AllowedHosts: []string{ "foobar", "foobar", }, HostsProxyHeaders: []string{ "foobar", "foobar", }, SSLRedirect: pointer(true), SSLTemporaryRedirect: pointer(true), SSLHost: pointer("foobar"), SSLProxyHeaders: map[string]string{ "name1": "foobar", "name0": "foobar", }, SSLForceHost: pointer(true), STSSeconds: 42, STSIncludeSubdomains: true, STSPreload: true, ForceSTSHeader: true, FrameDeny: true, CustomFrameOptionsValue: "foobar", ContentTypeNosniff: true, BrowserXSSFilter: true, CustomBrowserXSSValue: "foobar", ContentSecurityPolicy: "foobar", ContentSecurityPolicyReportOnly: "foobar", PublicKey: "foobar", ReferrerPolicy: "foobar", FeaturePolicy: pointer("foobar"), PermissionsPolicy: "foobar", IsDevelopment: true, }, }, "Middleware17": { ReplacePathRegex: &dynamic.ReplacePathRegex{ Regex: "foobar", Replacement: "foobar", }, }, }, Services: map[string]*dynamic.Service{ "Service01": { LoadBalancer: &dynamic.ServersLoadBalancer{ Sticky: &dynamic.Sticky{ Cookie: &dynamic.Cookie{ Name: "foobar", Secure: true, HTTPOnly: true, Path: func(v string) *string { return &v }("foobar"), }, }, Servers: []dynamic.Server{ { URL: "foobar", Scheme: "http", }, { URL: "foobar", Scheme: "http", }, }, HealthCheck: &dynamic.ServerHealthCheck{ Scheme: "foobar", Mode: "foobar", Path: "foobar", Port: 42, Interval: ptypes.Duration(time.Second), Timeout: ptypes.Duration(time.Second), Hostname: "foobar", FollowRedirects: pointer(true), Headers: map[string]string{ "name0": "foobar", "name1": "foobar", }, }, PassHostHeader: pointer(true), ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: ptypes.Duration(time.Second), }, }, }, "Service02": { Mirroring: &dynamic.Mirroring{ Service: "foobar", MirrorBody: pointer(true), MaxBodySize: pointer[int64](42), Mirrors: []dynamic.MirrorService{ { Name: "foobar", Percent: 42, }, { Name: "foobar", Percent: 42, }, }, }, }, "Service03": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { Name: "foobar", Weight: pointer(42), }, { Name: "foobar", Weight: pointer(42), }, }, Sticky: &dynamic.Sticky{ Cookie: &dynamic.Cookie{ Name: "foobar", Secure: true, HTTPOnly: true, Path: func(v string) *string { return &v }("foobar"), }, }, }, }, "Service04": { Failover: &dynamic.Failover{ Service: "foobar", Fallback: "foobar", }, }, }, }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ "TCPRouter0": { EntryPoints: []string{ "foobar", "foobar", }, Service: "foobar", Rule: "foobar", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, Options: "foobar", CertResolver: "foobar", Domains: []types.Domain{ { Main: "foobar", SANs: []string{ "foobar", "foobar", }, }, { Main: "foobar", SANs: []string{ "foobar", "foobar", }, }, }, }, }, "TCPRouter1": { EntryPoints: []string{ "foobar", "foobar", }, Service: "foobar", Rule: "foobar", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, Options: "foobar", CertResolver: "foobar", Domains: []types.Domain{ { Main: "foobar", SANs: []string{ "foobar", "foobar", }, }, { Main: "foobar", SANs: []string{ "foobar", "foobar", }, }, }, }, }, }, Services: map[string]*dynamic.TCPService{ "TCPService01": { LoadBalancer: &dynamic.TCPServersLoadBalancer{ TerminationDelay: pointer(42), Servers: []dynamic.TCPServer{ {Address: "foobar"}, {Address: "foobar"}, }, }, }, "TCPService02": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { Name: "foobar", Weight: pointer(42), }, { Name: "foobar", Weight: pointer(43), }, }, }, }, }, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{ "UDPRouter0": { EntryPoints: []string{"foobar", "foobar"}, Service: "foobar", }, "UDPRouter1": { EntryPoints: []string{"foobar", "foobar"}, Service: "foobar", }, }, Services: map[string]*dynamic.UDPService{ "UDPService01": { LoadBalancer: &dynamic.UDPServersLoadBalancer{ Servers: []dynamic.UDPServer{ {Address: "foobar"}, {Address: "foobar"}, }, }, }, "UDPService02": { LoadBalancer: &dynamic.UDPServersLoadBalancer{ Servers: []dynamic.UDPServer{ {Address: "foobar"}, {Address: "foobar"}, }, }, }, }, }, TLS: &dynamic.TLSConfiguration{ Certificates: []*tls.CertAndStores{ { Certificate: tls.Certificate{ CertFile: types.FileOrContent("foobar"), KeyFile: types.FileOrContent("foobar"), }, Stores: []string{ "foobar", "foobar", }, }, { Certificate: tls.Certificate{ CertFile: types.FileOrContent("foobar"), KeyFile: types.FileOrContent("foobar"), }, Stores: []string{ "foobar", "foobar", }, }, }, Options: map[string]tls.Options{ "Options0": { MinVersion: "foobar", MaxVersion: "foobar", CipherSuites: []string{ "foobar", "foobar", }, CurvePreferences: []string{ "foobar", "foobar", }, ClientAuth: tls.ClientAuth{ CAFiles: []types.FileOrContent{ types.FileOrContent("foobar"), types.FileOrContent("foobar"), }, ClientAuthType: "foobar", }, SniStrict: true, ALPNProtocols: []string{ "h2", "http/1.1", "acme-tls/1", }, }, "Options1": { MinVersion: "foobar", MaxVersion: "foobar", CipherSuites: []string{ "foobar", "foobar", }, CurvePreferences: []string{ "foobar", "foobar", }, ClientAuth: tls.ClientAuth{ CAFiles: []types.FileOrContent{ types.FileOrContent("foobar"), types.FileOrContent("foobar"), }, ClientAuthType: "foobar", }, SniStrict: true, ALPNProtocols: []string{ "h2", "http/1.1", "acme-tls/1", }, }, }, Stores: map[string]tls.Store{ "Store0": { DefaultCertificate: &tls.Certificate{ CertFile: types.FileOrContent("foobar"), KeyFile: types.FileOrContent("foobar"), }, }, "Store1": { DefaultCertificate: &tls.Certificate{ CertFile: types.FileOrContent("foobar"), KeyFile: types.FileOrContent("foobar"), }, }, }, }, } assert.Equal(t, expected, cfg) } func Test_buildConfiguration_KV_error(t *testing.T) { provider := &Provider{ RootKey: "traefik", kvClient: &Mock{ Error: KvError{ List: errors.New("OOPS"), }, KVPairs: mapToPairs(map[string]string{ "traefik/foo": "bar", }), }, } cfg, err := provider.buildConfiguration(context.Background()) require.Error(t, err) assert.Nil(t, cfg) } func TestKvWatchTree(t *testing.T) { returnedChans := make(chan chan []*store.KVPair) provider := Provider{ kvClient: &Mock{ WatchTreeMethod: func() <-chan []*store.KVPair { c := make(chan []*store.KVPair, 10) returnedChans <- c return c }, }, } configChan := make(chan dynamic.Message) go func() { err := provider.watchKv(context.Background(), configChan) require.NoError(t, err) }() select { case c1 := <-returnedChans: c1 <- []*store.KVPair{} <-configChan close(c1) // WatchTree chans can close due to error case <-time.After(1 * time.Second): t.Fatalf("Failed to create a new WatchTree chan") } select { case c2 := <-returnedChans: c2 <- []*store.KVPair{} <-configChan case <-time.After(1 * time.Second): t.Fatalf("Failed to create a new WatchTree chan") } select { case <-configChan: t.Fatalf("configChan should be empty") default: } } func mapToPairs(in map[string]string) []*store.KVPair { var out []*store.KVPair for k, v := range in { out = append(out, &store.KVPair{Key: k, Value: []byte(v)}) } return out }