Merge branch 'v1.5' into master
This commit is contained in:
commit
c84fb9895e
35 changed files with 462 additions and 124 deletions
|
@ -21,9 +21,9 @@ func (p *CatalogProvider) buildConfiguration(catalog []catalogUpdate) *types.Con
|
|||
"getBackendName": getBackendName,
|
||||
"getBackendAddress": getBackendAddress,
|
||||
"getBasicAuth": p.getBasicAuth,
|
||||
"getSticky": getSticky,
|
||||
"hasStickinessLabel": hasStickinessLabel,
|
||||
"getStickinessCookieName": getStickinessCookieName,
|
||||
"getSticky": p.getSticky,
|
||||
"hasStickinessLabel": p.hasStickinessLabel,
|
||||
"getStickinessCookieName": p.getStickinessCookieName,
|
||||
"getAttribute": p.getAttribute,
|
||||
"getTag": getTag,
|
||||
"hasTag": hasTag,
|
||||
|
@ -147,8 +147,8 @@ func getBackendName(node *api.ServiceEntry, index int) string {
|
|||
|
||||
// TODO: Deprecated
|
||||
// Deprecated replaced by Stickiness
|
||||
func getSticky(tags []string) string {
|
||||
stickyTag := getTag(label.TraefikBackendLoadBalancerSticky, tags, "")
|
||||
func (p *CatalogProvider) getSticky(tags []string) string {
|
||||
stickyTag := p.getAttribute(label.SuffixBackendLoadBalancerSticky, tags, "")
|
||||
if len(stickyTag) > 0 {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, label.TraefikBackendLoadBalancerStickiness)
|
||||
} else {
|
||||
|
@ -157,11 +157,11 @@ func getSticky(tags []string) string {
|
|||
return stickyTag
|
||||
}
|
||||
|
||||
func hasStickinessLabel(tags []string) bool {
|
||||
stickinessTag := getTag(label.TraefikBackendLoadBalancerStickiness, tags, "")
|
||||
func (p *CatalogProvider) hasStickinessLabel(tags []string) bool {
|
||||
stickinessTag := p.getAttribute(label.SuffixBackendLoadBalancerStickiness, tags, "")
|
||||
return len(stickinessTag) > 0 && strings.EqualFold(strings.TrimSpace(stickinessTag), "true")
|
||||
}
|
||||
|
||||
func getStickinessCookieName(tags []string) string {
|
||||
return getTag(label.TraefikBackendLoadBalancerStickinessCookieName, tags, "")
|
||||
func (p *CatalogProvider) getStickinessCookieName(tags []string) string {
|
||||
return p.getAttribute(label.SuffixBackendLoadBalancerStickinessCookieName, tags, "")
|
||||
}
|
||||
|
|
|
@ -1006,6 +1006,10 @@ func TestGetBasicAuth(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestHasStickinessLabel(t *testing.T) {
|
||||
p := &CatalogProvider{
|
||||
Prefix: "traefik",
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
tags []string
|
||||
|
@ -1037,7 +1041,7 @@ func TestHasStickinessLabel(t *testing.T) {
|
|||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := hasStickinessLabel(test.tags)
|
||||
actual := p.hasStickinessLabel(test.tags)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ func (p *Provider) buildConfiguration(containersInspected []dockerData) *types.C
|
|||
"getRateLimitsExtractorFunc": getFuncStringLabel(label.TraefikFrontendRateLimitExtractorFunc, ""),
|
||||
"getRateLimits": getRateLimits,
|
||||
// Headers
|
||||
"hasHeaders": hasHeaders,
|
||||
"hasRequestHeaders": hasFunc(label.TraefikFrontendRequestHeaders),
|
||||
"getRequestHeaders": getFuncMapLabel(label.TraefikFrontendRequestHeaders),
|
||||
"hasResponseHeaders": hasFunc(label.TraefikFrontendResponseHeaders),
|
||||
|
|
|
@ -187,6 +187,15 @@ func getRateLimits(container dockerData) map[string]*types.Rate {
|
|||
return label.ParseRateSets(container.Labels, prefix, label.RegexpFrontendRateLimit)
|
||||
}
|
||||
|
||||
func hasHeaders(container dockerData) bool {
|
||||
for key := range container.Labels {
|
||||
if strings.HasPrefix(key, label.TraefikFrontendHeaders) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Label functions
|
||||
|
||||
func getFuncInt64Label(labelName string, defaultValue int64) func(container dockerData) int64 {
|
||||
|
|
|
@ -75,9 +75,9 @@ func checkServiceLabelPort(container dockerData) error {
|
|||
// Extract backend from labels for a given service and a given docker container
|
||||
func getServiceBackend(container dockerData, serviceName string) string {
|
||||
if value, ok := getServiceLabels(container, serviceName)[label.SuffixFrontendBackend]; ok {
|
||||
return container.ServiceName + "-" + value
|
||||
return provider.Normalize(container.ServiceName + "-" + value)
|
||||
}
|
||||
return strings.TrimPrefix(container.ServiceName, "/") + "-" + getBackend(container) + "-" + provider.Normalize(serviceName)
|
||||
return provider.Normalize(container.ServiceName + "-" + getBackend(container) + "-" + serviceName)
|
||||
}
|
||||
|
||||
// Extract port from labels for a given service and a given docker container
|
||||
|
|
|
@ -402,12 +402,22 @@ func TestDockerGetServiceBackend(t *testing.T) {
|
|||
})),
|
||||
expected: "fake-another-backend-myservice",
|
||||
},
|
||||
{
|
||||
container: containerJSON(name("foo.bar")),
|
||||
expected: "foo-bar-foo-bar-myservice",
|
||||
},
|
||||
{
|
||||
container: containerJSON(labels(map[string]string{
|
||||
"traefik.myservice.frontend.backend": "custom-backend",
|
||||
})),
|
||||
expected: "fake-custom-backend",
|
||||
},
|
||||
{
|
||||
container: containerJSON(labels(map[string]string{
|
||||
label.TraefikBackend: "another.backend",
|
||||
})),
|
||||
expected: "fake-another-backend-myservice",
|
||||
},
|
||||
}
|
||||
|
||||
for containerID, test := range testCases {
|
||||
|
|
|
@ -126,7 +126,10 @@ func sendConfigToChannel(configurationChan chan<- types.ConfigMessage, configura
|
|||
}
|
||||
|
||||
func loadFileConfig(filename string) (*types.Configuration, error) {
|
||||
configuration := new(types.Configuration)
|
||||
configuration := &types.Configuration{
|
||||
Frontends: make(map[string]*types.Frontend),
|
||||
Backends: make(map[string]*types.Backend),
|
||||
}
|
||||
if _, err := toml.DecodeFile(filename, configuration); err != nil {
|
||||
return nil, fmt.Errorf("error reading configuration file: %s", err)
|
||||
}
|
||||
|
@ -142,9 +145,8 @@ func loadFileConfigFromDirectory(directory string, configuration *types.Configur
|
|||
|
||||
if configuration == nil {
|
||||
configuration = &types.Configuration{
|
||||
Frontends: make(map[string]*types.Frontend),
|
||||
Backends: make(map[string]*types.Backend),
|
||||
TLSConfiguration: make([]*tls.Configuration, 0),
|
||||
Frontends: make(map[string]*types.Frontend),
|
||||
Backends: make(map[string]*types.Backend),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,6 +152,12 @@ func priority(value int) func(*types.Frontend) {
|
|||
}
|
||||
}
|
||||
|
||||
func headers() func(*types.Frontend) {
|
||||
return func(f *types.Frontend) {
|
||||
f.Headers = &types.Headers{}
|
||||
}
|
||||
}
|
||||
|
||||
func redirectEntryPoint(name string) func(*types.Frontend) {
|
||||
return func(f *types.Frontend) {
|
||||
if f.Redirect == nil {
|
||||
|
|
|
@ -212,7 +212,7 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
|||
|
||||
priority := label.GetIntValue(i.Annotations, label.TraefikFrontendPriority, 0)
|
||||
|
||||
headers := types.Headers{
|
||||
headers := &types.Headers{
|
||||
CustomRequestHeaders: label.GetMapValue(i.Annotations, annotationKubernetesCustomRequestHeaders),
|
||||
CustomResponseHeaders: label.GetMapValue(i.Annotations, annotationKubernetesCustomResponseHeaders),
|
||||
AllowedHosts: label.GetSliceStringValue(i.Annotations, annotationKubernetesAllowedHosts),
|
||||
|
|
|
@ -137,18 +137,21 @@ func TestLoadIngresses(t *testing.T) {
|
|||
),
|
||||
frontends(
|
||||
frontend("foo/bar",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("/bar", "PathPrefix:/bar"),
|
||||
route("foo", "Host:foo")),
|
||||
),
|
||||
frontend("foo/namedthing",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("/namedthing", "PathPrefix:/namedthing"),
|
||||
route("foo", "Host:foo")),
|
||||
),
|
||||
frontend("bar",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(route("bar", "Host:bar")),
|
||||
),
|
||||
|
@ -222,6 +225,7 @@ func TestRuleType(t *testing.T) {
|
|||
require.NoError(t, err, "error loading ingresses")
|
||||
|
||||
expected := buildFrontends(frontend("host/path",
|
||||
headers(),
|
||||
routes(
|
||||
route("/path", fmt.Sprintf("%s:/path", test.frontendRuleType)),
|
||||
route("host", "Host:host")),
|
||||
|
@ -267,6 +271,7 @@ func TestGetPassHostHeader(t *testing.T) {
|
|||
backends(backend("foo/bar", lbMethod("wrr"), servers())),
|
||||
frontends(
|
||||
frontend("foo/bar",
|
||||
headers(),
|
||||
routes(
|
||||
route("/bar", "PathPrefix:/bar"),
|
||||
route("foo", "Host:foo")),
|
||||
|
@ -310,6 +315,7 @@ func TestGetPassTLSCert(t *testing.T) {
|
|||
expected := buildConfiguration(
|
||||
backends(backend("foo/bar", lbMethod("wrr"), servers())),
|
||||
frontends(frontend("foo/bar",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
passTLSCert(),
|
||||
routes(
|
||||
|
@ -364,6 +370,7 @@ func TestOnlyReferencesServicesFromOwnNamespace(t *testing.T) {
|
|||
expected := buildConfiguration(
|
||||
backends(backend("foo", lbMethod("wrr"), servers())),
|
||||
frontends(frontend("foo",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(route("foo", "Host:foo")),
|
||||
)),
|
||||
|
@ -405,7 +412,9 @@ func TestHostlessIngress(t *testing.T) {
|
|||
|
||||
expected := buildConfiguration(
|
||||
backends(backend("/bar", lbMethod("wrr"), servers())),
|
||||
frontends(frontend("/bar", routes(route("/bar", "PathPrefix:/bar")))),
|
||||
frontends(frontend("/bar",
|
||||
headers(),
|
||||
routes(route("/bar", "PathPrefix:/bar")))),
|
||||
)
|
||||
|
||||
assert.Equal(t, expected, actual)
|
||||
|
@ -503,12 +512,14 @@ func TestServiceAnnotations(t *testing.T) {
|
|||
),
|
||||
frontends(
|
||||
frontend("foo/bar",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("/bar", "PathPrefix:/bar"),
|
||||
route("foo", "Host:foo")),
|
||||
),
|
||||
frontend("bar",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(route("bar", "Host:bar"))),
|
||||
),
|
||||
|
@ -712,17 +723,20 @@ func TestIngressAnnotations(t *testing.T) {
|
|||
),
|
||||
frontends(
|
||||
frontend("foo/bar",
|
||||
headers(),
|
||||
routes(
|
||||
route("/bar", "PathPrefix:/bar"),
|
||||
route("foo", "Host:foo")),
|
||||
),
|
||||
frontend("other/stuff",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("/stuff", "PathPrefix:/stuff"),
|
||||
route("other", "Host:other")),
|
||||
),
|
||||
frontend("other/",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
entryPoints("http", "https"),
|
||||
routes(
|
||||
|
@ -730,6 +744,7 @@ func TestIngressAnnotations(t *testing.T) {
|
|||
route("other", "Host:other")),
|
||||
),
|
||||
frontend("other/sslstuff",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
passTLSCert(),
|
||||
routes(
|
||||
|
@ -737,6 +752,7 @@ func TestIngressAnnotations(t *testing.T) {
|
|||
route("other", "Host:other")),
|
||||
),
|
||||
frontend("other/sslstuff",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
passTLSCert(),
|
||||
routes(
|
||||
|
@ -744,6 +760,7 @@ func TestIngressAnnotations(t *testing.T) {
|
|||
route("other", "Host:other")),
|
||||
),
|
||||
frontend("basic/auth",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
basicAuth("myUser:myEncodedPW"),
|
||||
routes(
|
||||
|
@ -751,6 +768,7 @@ func TestIngressAnnotations(t *testing.T) {
|
|||
route("basic", "Host:basic")),
|
||||
),
|
||||
frontend("redirect/https",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
redirectEntryPoint("https"),
|
||||
routes(
|
||||
|
@ -758,6 +776,7 @@ func TestIngressAnnotations(t *testing.T) {
|
|||
route("redirect", "Host:redirect")),
|
||||
),
|
||||
frontend("test/whitelist-source-range",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
whitelistSourceRange("1.1.1.1/24", "1234:abcd::42/32"),
|
||||
routes(
|
||||
|
@ -765,6 +784,7 @@ func TestIngressAnnotations(t *testing.T) {
|
|||
route("test", "Host:test")),
|
||||
),
|
||||
frontend("rewrite/api",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("/api", "PathPrefix:/api;ReplacePath:/"),
|
||||
|
@ -824,6 +844,7 @@ func TestPriorityHeaderValue(t *testing.T) {
|
|||
),
|
||||
frontends(
|
||||
frontend("foo/bar",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
priority(1337),
|
||||
routes(
|
||||
|
@ -882,6 +903,7 @@ func TestInvalidPassTLSCertValue(t *testing.T) {
|
|||
),
|
||||
frontends(
|
||||
frontend("foo/bar",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("/bar", "PathPrefix:/bar"),
|
||||
|
@ -939,6 +961,7 @@ func TestInvalidPassHostHeaderValue(t *testing.T) {
|
|||
),
|
||||
frontends(
|
||||
frontend("foo/bar",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("/bar", "PathPrefix:/bar"),
|
||||
|
@ -1112,14 +1135,17 @@ func TestMissingResources(t *testing.T) {
|
|||
),
|
||||
frontends(
|
||||
frontend("fully_working",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(route("fully_working", "Host:fully_working")),
|
||||
),
|
||||
frontend("missing_endpoints",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(route("missing_endpoints", "Host:missing_endpoints")),
|
||||
),
|
||||
frontend("missing_endpoint_subsets",
|
||||
headers(),
|
||||
passHostHeader(),
|
||||
routes(route("missing_endpoint_subsets", "Host:missing_endpoint_subsets")),
|
||||
),
|
||||
|
|
|
@ -27,26 +27,27 @@ const (
|
|||
SuffixFrontendAuthBasic = "frontend.auth.basic"
|
||||
SuffixFrontendBackend = "frontend.backend"
|
||||
SuffixFrontendEntryPoints = "frontend.entryPoints"
|
||||
SuffixFrontendRequestHeaders = "frontend.headers.customRequestHeaders"
|
||||
SuffixFrontendResponseHeaders = "frontend.headers.customResponseHeaders"
|
||||
SuffixFrontendHeadersAllowedHosts = "frontend.headers.allowedHosts"
|
||||
SuffixFrontendHeadersHostsProxyHeaders = "frontend.headers.hostsProxyHeaders"
|
||||
SuffixFrontendHeadersSSLRedirect = "frontend.headers.SSLRedirect"
|
||||
SuffixFrontendHeadersSSLTemporaryRedirect = "frontend.headers.SSLTemporaryRedirect"
|
||||
SuffixFrontendHeadersSSLHost = "frontend.headers.SSLHost"
|
||||
SuffixFrontendHeadersSSLProxyHeaders = "frontend.headers.SSLProxyHeaders"
|
||||
SuffixFrontendHeadersSTSSeconds = "frontend.headers.STSSeconds"
|
||||
SuffixFrontendHeadersSTSIncludeSubdomains = "frontend.headers.STSIncludeSubdomains"
|
||||
SuffixFrontendHeadersSTSPreload = "frontend.headers.STSPreload"
|
||||
SuffixFrontendHeadersForceSTSHeader = "frontend.headers.forceSTSHeader"
|
||||
SuffixFrontendHeadersFrameDeny = "frontend.headers.frameDeny"
|
||||
SuffixFrontendHeadersCustomFrameOptionsValue = "frontend.headers.customFrameOptionsValue"
|
||||
SuffixFrontendHeadersContentTypeNosniff = "frontend.headers.contentTypeNosniff"
|
||||
SuffixFrontendHeadersBrowserXSSFilter = "frontend.headers.browserXSSFilter"
|
||||
SuffixFrontendHeadersContentSecurityPolicy = "frontend.headers.contentSecurityPolicy"
|
||||
SuffixFrontendHeadersPublicKey = "frontend.headers.publicKey"
|
||||
SuffixFrontendHeadersReferrerPolicy = "frontend.headers.referrerPolicy"
|
||||
SuffixFrontendHeadersIsDevelopment = "frontend.headers.isDevelopment"
|
||||
SuffixFrontendHeaders = "frontend.headers."
|
||||
SuffixFrontendRequestHeaders = SuffixFrontendHeaders + "customRequestHeaders"
|
||||
SuffixFrontendResponseHeaders = SuffixFrontendHeaders + "customResponseHeaders"
|
||||
SuffixFrontendHeadersAllowedHosts = SuffixFrontendHeaders + "allowedHosts"
|
||||
SuffixFrontendHeadersHostsProxyHeaders = SuffixFrontendHeaders + "hostsProxyHeaders"
|
||||
SuffixFrontendHeadersSSLRedirect = SuffixFrontendHeaders + "SSLRedirect"
|
||||
SuffixFrontendHeadersSSLTemporaryRedirect = SuffixFrontendHeaders + "SSLTemporaryRedirect"
|
||||
SuffixFrontendHeadersSSLHost = SuffixFrontendHeaders + "SSLHost"
|
||||
SuffixFrontendHeadersSSLProxyHeaders = SuffixFrontendHeaders + "SSLProxyHeaders"
|
||||
SuffixFrontendHeadersSTSSeconds = SuffixFrontendHeaders + "STSSeconds"
|
||||
SuffixFrontendHeadersSTSIncludeSubdomains = SuffixFrontendHeaders + "STSIncludeSubdomains"
|
||||
SuffixFrontendHeadersSTSPreload = SuffixFrontendHeaders + "STSPreload"
|
||||
SuffixFrontendHeadersForceSTSHeader = SuffixFrontendHeaders + "forceSTSHeader"
|
||||
SuffixFrontendHeadersFrameDeny = SuffixFrontendHeaders + "frameDeny"
|
||||
SuffixFrontendHeadersCustomFrameOptionsValue = SuffixFrontendHeaders + "customFrameOptionsValue"
|
||||
SuffixFrontendHeadersContentTypeNosniff = SuffixFrontendHeaders + "contentTypeNosniff"
|
||||
SuffixFrontendHeadersBrowserXSSFilter = SuffixFrontendHeaders + "browserXSSFilter"
|
||||
SuffixFrontendHeadersContentSecurityPolicy = SuffixFrontendHeaders + "contentSecurityPolicy"
|
||||
SuffixFrontendHeadersPublicKey = SuffixFrontendHeaders + "publicKey"
|
||||
SuffixFrontendHeadersReferrerPolicy = SuffixFrontendHeaders + "referrerPolicy"
|
||||
SuffixFrontendHeadersIsDevelopment = SuffixFrontendHeaders + "isDevelopment"
|
||||
SuffixFrontendPassHostHeader = "frontend.passHostHeader"
|
||||
SuffixFrontendPassTLSCert = "frontend.passTLSCert"
|
||||
SuffixFrontendPriority = "frontend.priority"
|
||||
|
@ -92,6 +93,7 @@ const (
|
|||
TraefikFrontendRuleType = Prefix + SuffixFrontendRuleType
|
||||
TraefikFrontendValue = Prefix + SuffixFrontendValue
|
||||
TraefikFrontendWhitelistSourceRange = Prefix + SuffixFrontendWhitelistSourceRange
|
||||
TraefikFrontendHeaders = Prefix + SuffixFrontendHeaders
|
||||
TraefikFrontendRequestHeaders = Prefix + SuffixFrontendRequestHeaders
|
||||
TraefikFrontendResponseHeaders = Prefix + SuffixFrontendResponseHeaders
|
||||
TraefikFrontendAllowedHosts = Prefix + SuffixFrontendHeadersAllowedHosts
|
||||
|
|
|
@ -64,6 +64,7 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
"getRateLimitsExtractorFunc": getFuncStringService(label.SuffixFrontendRateLimitExtractorFunc, ""),
|
||||
"getRateLimits": getRateLimits,
|
||||
// Headers
|
||||
"hasHeaders": hasPrefixFuncService(label.TraefikFrontendHeaders),
|
||||
"hasRequestHeaders": hasFuncService(label.SuffixFrontendRequestHeaders),
|
||||
"getRequestHeaders": getFuncMapService(label.SuffixFrontendRequestHeaders),
|
||||
"hasResponseHeaders": hasFuncService(label.SuffixFrontendResponseHeaders),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue