Ability to use "X-Forwarded-For" as a source of IP for white list.
This commit is contained in:
parent
4802484729
commit
d2766b1b4f
50 changed files with 1496 additions and 599 deletions
|
@ -43,20 +43,20 @@ func (p *Provider) buildConfiguration(catalog []catalogUpdate) *types.Configurat
|
|||
"getBuffering": p.getBuffering,
|
||||
|
||||
// Frontend functions
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getBasicAuth": p.getFuncSliceAttribute(label.SuffixFrontendAuthBasic),
|
||||
"getEntryPoints": getEntryPoints, // TODO Deprecated [breaking]
|
||||
"getFrontEndEntryPoints": p.getFuncSliceAttribute(label.SuffixFrontendEntryPoints), // TODO [breaking] rename to getEntryPoints when getEntryPoints will be removed
|
||||
"getPriority": p.getFuncIntAttribute(label.SuffixFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getPassHostHeader": p.getFuncBoolAttribute(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": p.getFuncBoolAttribute(label.SuffixFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getWhitelistSourceRange": p.getFuncSliceAttribute(label.SuffixFrontendWhitelistSourceRange),
|
||||
"getRedirect": p.getRedirect,
|
||||
"hasErrorPages": p.getFuncHasAttributePrefix(label.BaseFrontendErrorPage),
|
||||
"getErrorPages": p.getErrorPages,
|
||||
"hasRateLimit": p.getFuncHasAttributePrefix(label.BaseFrontendRateLimit),
|
||||
"getRateLimit": p.getRateLimit,
|
||||
"getHeaders": p.getHeaders,
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getBasicAuth": p.getFuncSliceAttribute(label.SuffixFrontendAuthBasic),
|
||||
"getEntryPoints": getEntryPoints, // TODO Deprecated [breaking]
|
||||
"getFrontEndEntryPoints": p.getFuncSliceAttribute(label.SuffixFrontendEntryPoints), // TODO [breaking] rename to getEntryPoints when getEntryPoints will be removed
|
||||
"getPriority": p.getFuncIntAttribute(label.SuffixFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getPassHostHeader": p.getFuncBoolAttribute(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": p.getFuncBoolAttribute(label.SuffixFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getWhiteList": p.getWhiteList,
|
||||
"getRedirect": p.getRedirect,
|
||||
"hasErrorPages": p.getFuncHasAttributePrefix(label.BaseFrontendErrorPage),
|
||||
"getErrorPages": p.getErrorPages,
|
||||
"hasRateLimit": p.getFuncHasAttributePrefix(label.BaseFrontendRateLimit),
|
||||
"getRateLimit": p.getRateLimit,
|
||||
"getHeaders": p.getHeaders,
|
||||
}
|
||||
|
||||
var allNodes []*api.ServiceEntry
|
||||
|
@ -311,6 +311,19 @@ func (p *Provider) getBuffering(tags []string) *types.Buffering {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Provider) getWhiteList(tags []string) *types.WhiteList {
|
||||
ranges := p.getSliceAttribute(label.SuffixFrontendWhiteListSourceRange, tags)
|
||||
|
||||
if len(ranges) > 0 {
|
||||
return &types.WhiteList{
|
||||
SourceRange: ranges,
|
||||
UseXForwardedFor: p.getBoolAttribute(label.SuffixFrontendWhiteListUseXForwardedFor, tags, false),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) getRedirect(tags []string) *types.Redirect {
|
||||
permanent := p.getBoolAttribute(label.SuffixFrontendRedirectPermanent, tags, false)
|
||||
|
||||
|
|
|
@ -1048,6 +1048,65 @@ func TestProviderGetBuffering(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestProviderWhiteList(t *testing.T) {
|
||||
p := &Provider{
|
||||
Prefix: "traefik",
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
tags []string
|
||||
expected *types.WhiteList
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no white list labels",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when only range",
|
||||
tags: []string{
|
||||
label.TraefikFrontendWhiteListSourceRange + "=10.10.10.10",
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when range and UseXForwardedFor",
|
||||
tags: []string{
|
||||
label.TraefikFrontendWhiteListSourceRange + "=10.10.10.10",
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor + "=true",
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only UseXForwardedFor",
|
||||
tags: []string{
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor + "=true",
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := p.getWhiteList(test.tags)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetRedirect(t *testing.T) {
|
||||
p := &Provider{
|
||||
Prefix: "traefik",
|
||||
|
|
|
@ -40,18 +40,18 @@ func (p *Provider) buildConfigurationV2(containersInspected []dockerData) *types
|
|||
"getLoadBalancer": getLoadBalancer,
|
||||
|
||||
// Frontend functions
|
||||
"getBackendName": getBackendName,
|
||||
"getPriority": getFuncIntLabel(label.TraefikFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getPassHostHeader": getFuncBoolLabel(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBoolLabel(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": getFuncSliceStringLabel(label.TraefikFrontendEntryPoints),
|
||||
"getBasicAuth": getFuncSliceStringLabel(label.TraefikFrontendAuthBasic),
|
||||
"getWhitelistSourceRange": getFuncSliceStringLabel(label.TraefikFrontendWhitelistSourceRange),
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getHeaders": getHeaders,
|
||||
"getBackendName": getBackendName,
|
||||
"getPriority": getFuncIntLabel(label.TraefikFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getPassHostHeader": getFuncBoolLabel(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBoolLabel(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": getFuncSliceStringLabel(label.TraefikFrontendEntryPoints),
|
||||
"getBasicAuth": getFuncSliceStringLabel(label.TraefikFrontendAuthBasic),
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getHeaders": getHeaders,
|
||||
"getWhiteList": getWhiteList,
|
||||
}
|
||||
|
||||
// filter containers
|
||||
|
@ -276,6 +276,31 @@ func getBackendName(container dockerData) string {
|
|||
return getDefaultBackendName(container)
|
||||
}
|
||||
|
||||
func getWhiteList(labels map[string]string) *types.WhiteList {
|
||||
if label.Has(labels, label.TraefikFrontendWhitelistSourceRange) {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikFrontendWhitelistSourceRange, label.TraefikFrontendWhiteListSourceRange)
|
||||
}
|
||||
|
||||
ranges := label.GetSliceStringValue(labels, label.TraefikFrontendWhiteListSourceRange)
|
||||
if len(ranges) > 0 {
|
||||
return &types.WhiteList{
|
||||
SourceRange: ranges,
|
||||
UseXForwardedFor: label.GetBoolValue(labels, label.TraefikFrontendWhiteListUseXForwardedFor, false),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Deprecated
|
||||
values := label.GetSliceStringValue(labels, label.TraefikFrontendWhitelistSourceRange)
|
||||
if len(values) > 0 {
|
||||
return &types.WhiteList{
|
||||
SourceRange: values,
|
||||
UseXForwardedFor: false,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRedirect(labels map[string]string) *types.Redirect {
|
||||
permanent := label.GetBoolValue(labels, label.TraefikFrontendRedirectPermanent, false)
|
||||
|
||||
|
|
|
@ -113,17 +113,18 @@ func TestDockerBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendBufferingMemRequestBodyBytes: "2097152",
|
||||
label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2",
|
||||
|
||||
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
label.TraefikFrontendEntryPoints: "http,https",
|
||||
label.TraefikFrontendPassHostHeader: "true",
|
||||
label.TraefikFrontendPassTLSCert: "true",
|
||||
label.TraefikFrontendPriority: "666",
|
||||
label.TraefikFrontendRedirectEntryPoint: "https",
|
||||
label.TraefikFrontendRedirectRegex: "nope",
|
||||
label.TraefikFrontendRedirectReplacement: "nope",
|
||||
label.TraefikFrontendRedirectPermanent: "true",
|
||||
label.TraefikFrontendRule: "Host:traefik.io",
|
||||
label.TraefikFrontendWhitelistSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
label.TraefikFrontendEntryPoints: "http,https",
|
||||
label.TraefikFrontendPassHostHeader: "true",
|
||||
label.TraefikFrontendPassTLSCert: "true",
|
||||
label.TraefikFrontendPriority: "666",
|
||||
label.TraefikFrontendRedirectEntryPoint: "https",
|
||||
label.TraefikFrontendRedirectRegex: "nope",
|
||||
label.TraefikFrontendRedirectReplacement: "nope",
|
||||
label.TraefikFrontendRedirectPermanent: "true",
|
||||
label.TraefikFrontendRule: "Host:traefik.io",
|
||||
label.TraefikFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: "true",
|
||||
|
||||
label.TraefikFrontendRequestHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
label.TraefikFrontendResponseHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
|
@ -187,8 +188,9 @@ func TestDockerBuildConfiguration(t *testing.T) {
|
|||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.10.10.10",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{"10.10.10.10"},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
Headers: &types.Headers{
|
||||
CustomRequestHeaders: map[string]string{
|
||||
|
@ -692,17 +694,17 @@ func TestDockerGetSliceStringLabel(t *testing.T) {
|
|||
{
|
||||
desc: "whitelist-label with empty string",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhitelistSourceRange: "",
|
||||
label.TraefikFrontendWhiteListSourceRange: "",
|
||||
},
|
||||
labelName: label.TraefikFrontendWhitelistSourceRange,
|
||||
labelName: label.TraefikFrontendWhiteListSourceRange,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "whitelist-label with IPv4 mask",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhitelistSourceRange: "1.2.3.4/16",
|
||||
label.TraefikFrontendWhiteListSourceRange: "1.2.3.4/16",
|
||||
},
|
||||
labelName: label.TraefikFrontendWhitelistSourceRange,
|
||||
labelName: label.TraefikFrontendWhiteListSourceRange,
|
||||
expected: []string{
|
||||
"1.2.3.4/16",
|
||||
},
|
||||
|
@ -710,9 +712,9 @@ func TestDockerGetSliceStringLabel(t *testing.T) {
|
|||
{
|
||||
desc: "whitelist-label with IPv6 mask",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhitelistSourceRange: "fe80::/16",
|
||||
label.TraefikFrontendWhiteListSourceRange: "fe80::/16",
|
||||
},
|
||||
labelName: label.TraefikFrontendWhitelistSourceRange,
|
||||
labelName: label.TraefikFrontendWhiteListSourceRange,
|
||||
expected: []string{
|
||||
"fe80::/16",
|
||||
},
|
||||
|
@ -720,9 +722,9 @@ func TestDockerGetSliceStringLabel(t *testing.T) {
|
|||
{
|
||||
desc: "whitelist-label with multiple masks",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhitelistSourceRange: "1.1.1.1/24, 1234:abcd::42/32",
|
||||
label.TraefikFrontendWhiteListSourceRange: "1.1.1.1/24, 1234:abcd::42/32",
|
||||
},
|
||||
labelName: label.TraefikFrontendWhitelistSourceRange,
|
||||
labelName: label.TraefikFrontendWhiteListSourceRange,
|
||||
expected: []string{
|
||||
"1.1.1.1/24",
|
||||
"1234:abcd::42/32",
|
||||
|
@ -1025,3 +1027,85 @@ func TestDockerGetPort(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWhiteList(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
expected *types.WhiteList
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no white list labels",
|
||||
labels: map[string]string{},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when deprecated label",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhitelistSourceRange: "10.10.10.10",
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when only range",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when range and UseXForwardedFor",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: "true",
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when mix deprecated label and new labels",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhitelistSourceRange: "20.20.20.20",
|
||||
label.TraefikFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: "true",
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only UseXForwardedFor",
|
||||
labels: map[string]string{
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: "true",
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := getWhiteList(test.labels)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,16 +122,17 @@ func TestSwarmBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendBufferingMemRequestBodyBytes: "2097152",
|
||||
label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2",
|
||||
|
||||
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
label.TraefikFrontendEntryPoints: "http,https",
|
||||
label.TraefikFrontendPassHostHeader: "true",
|
||||
label.TraefikFrontendPassTLSCert: "true",
|
||||
label.TraefikFrontendPriority: "666",
|
||||
label.TraefikFrontendRedirectEntryPoint: "https",
|
||||
label.TraefikFrontendRedirectRegex: "nope",
|
||||
label.TraefikFrontendRedirectReplacement: "nope",
|
||||
label.TraefikFrontendRule: "Host:traefik.io",
|
||||
label.TraefikFrontendWhitelistSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
label.TraefikFrontendEntryPoints: "http,https",
|
||||
label.TraefikFrontendPassHostHeader: "true",
|
||||
label.TraefikFrontendPassTLSCert: "true",
|
||||
label.TraefikFrontendPriority: "666",
|
||||
label.TraefikFrontendRedirectEntryPoint: "https",
|
||||
label.TraefikFrontendRedirectRegex: "nope",
|
||||
label.TraefikFrontendRedirectReplacement: "nope",
|
||||
label.TraefikFrontendRule: "Host:traefik.io",
|
||||
label.TraefikFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: "true",
|
||||
|
||||
label.TraefikFrontendRequestHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
label.TraefikFrontendResponseHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
|
@ -193,8 +194,9 @@ func TestSwarmBuildConfiguration(t *testing.T) {
|
|||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.10.10.10",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{"10.10.10.10"},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
Headers: &types.Headers{
|
||||
CustomRequestHeaders: map[string]string{
|
||||
|
|
|
@ -76,16 +76,17 @@ func TestSegmentBuildConfiguration(t *testing.T) {
|
|||
label.Prefix + "sauternes." + label.SuffixProtocol: "https",
|
||||
label.Prefix + "sauternes." + label.SuffixWeight: "12",
|
||||
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendEntryPoints: "http,https",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendPassHostHeader: "true",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendPassTLSCert: "true",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendPriority: "666",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRedirectEntryPoint: "https",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRedirectRegex: "nope",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRedirectReplacement: "nope",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRedirectPermanent: "true",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendWhitelistSourceRange: "10.10.10.10",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendEntryPoints: "http,https",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendPassHostHeader: "true",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendPassTLSCert: "true",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendPriority: "666",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRedirectEntryPoint: "https",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRedirectRegex: "nope",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRedirectReplacement: "nope",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRedirectPermanent: "true",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendWhiteListUseXForwardedFor: "true",
|
||||
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendRequestHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
label.Prefix + "sauternes." + label.SuffixFrontendResponseHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
|
@ -144,8 +145,9 @@ func TestSegmentBuildConfiguration(t *testing.T) {
|
|||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.10.10.10",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{"10.10.10.10"},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
Headers: &types.Headers{
|
||||
CustomRequestHeaders: map[string]string{
|
||||
|
|
|
@ -103,7 +103,7 @@ func (p *Provider) buildConfigurationV1(containersInspected []dockerData) *types
|
|||
"getServiceWeight": getFuncServiceStringLabelV1(label.SuffixWeight, label.DefaultWeight),
|
||||
// Services - Frontend functions
|
||||
"getServiceEntryPoints": getFuncServiceSliceStringLabelV1(label.SuffixFrontendEntryPoints),
|
||||
"getServiceWhitelistSourceRange": getFuncServiceSliceStringLabelV1(label.SuffixFrontendWhitelistSourceRange),
|
||||
"getServiceWhitelistSourceRange": getFuncServiceSliceStringLabelV1(label.SuffixFrontendWhiteListSourceRange),
|
||||
"getServiceBasicAuth": getFuncServiceSliceStringLabelV1(label.SuffixFrontendAuthBasic),
|
||||
"getServiceFrontendRule": p.getServiceFrontendRuleV1,
|
||||
"getServicePassHostHeader": getFuncServiceBoolLabelV1(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
|
|
|
@ -48,18 +48,18 @@ func (p *Provider) buildConfiguration(services map[string][]ecsInstance) (*types
|
|||
"getHealthCheckInterval": getFuncFirstStringValue(label.TraefikBackendHealthCheckInterval, ""),
|
||||
|
||||
// Frontend functions
|
||||
"filterFrontends": filterFrontends,
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getPassHostHeader": getFuncBoolValue(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBoolValue(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getPriority": getFuncIntValue(label.TraefikFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getBasicAuth": getFuncSliceString(label.TraefikFrontendAuthBasic),
|
||||
"getEntryPoints": getFuncSliceString(label.TraefikFrontendEntryPoints),
|
||||
"getWhitelistSourceRange": getFuncSliceString(label.TraefikFrontendWhitelistSourceRange),
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getHeaders": getHeaders,
|
||||
"filterFrontends": filterFrontends,
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getPassHostHeader": getFuncBoolValue(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBoolValue(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getPriority": getFuncIntValue(label.TraefikFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getBasicAuth": getFuncSliceString(label.TraefikFrontendAuthBasic),
|
||||
"getEntryPoints": getFuncSliceString(label.TraefikFrontendEntryPoints),
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getHeaders": getHeaders,
|
||||
"getWhiteList": getWhiteList,
|
||||
}
|
||||
return p.GetConfiguration("templates/ecs.tmpl", ecsFuncMap, struct {
|
||||
Services map[string][]ecsInstance
|
||||
|
@ -211,6 +211,18 @@ func getServers(instances []ecsInstance) map[string]types.Server {
|
|||
return servers
|
||||
}
|
||||
|
||||
func getWhiteList(instance ecsInstance) *types.WhiteList {
|
||||
ranges := getSliceString(instance, label.TraefikFrontendWhiteListSourceRange)
|
||||
if len(ranges) > 0 {
|
||||
return &types.WhiteList{
|
||||
SourceRange: ranges,
|
||||
UseXForwardedFor: getBoolValue(instance, label.TraefikFrontendWhiteListUseXForwardedFor, false),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRedirect(instance ecsInstance) *types.Redirect {
|
||||
permanent := getBoolValue(instance, label.TraefikFrontendRedirectPermanent, false)
|
||||
|
||||
|
|
|
@ -142,17 +142,18 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendBufferingMemRequestBodyBytes: aws.String("2097152"),
|
||||
label.TraefikBackendBufferingRetryExpression: aws.String("IsNetworkError() && Attempts() <= 2"),
|
||||
|
||||
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||
label.TraefikFrontendEntryPoints: aws.String("http,https"),
|
||||
label.TraefikFrontendPassHostHeader: aws.String("true"),
|
||||
label.TraefikFrontendPassTLSCert: aws.String("true"),
|
||||
label.TraefikFrontendPriority: aws.String("666"),
|
||||
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
|
||||
label.TraefikFrontendRedirectRegex: aws.String("nope"),
|
||||
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
|
||||
label.TraefikFrontendRedirectPermanent: aws.String("true"),
|
||||
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
|
||||
label.TraefikFrontendWhitelistSourceRange: aws.String("10.10.10.10"),
|
||||
label.TraefikFrontendAuthBasic: aws.String("test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||
label.TraefikFrontendEntryPoints: aws.String("http,https"),
|
||||
label.TraefikFrontendPassHostHeader: aws.String("true"),
|
||||
label.TraefikFrontendPassTLSCert: aws.String("true"),
|
||||
label.TraefikFrontendPriority: aws.String("666"),
|
||||
label.TraefikFrontendRedirectEntryPoint: aws.String("https"),
|
||||
label.TraefikFrontendRedirectRegex: aws.String("nope"),
|
||||
label.TraefikFrontendRedirectReplacement: aws.String("nope"),
|
||||
label.TraefikFrontendRedirectPermanent: aws.String("true"),
|
||||
label.TraefikFrontendRule: aws.String("Host:traefik.io"),
|
||||
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
||||
|
||||
label.TraefikFrontendRequestHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
|
||||
label.TraefikFrontendResponseHeaders: aws.String("Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
|
||||
|
@ -257,8 +258,9 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.10.10.10",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{"10.10.10.10"},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
Headers: &types.Headers{
|
||||
CustomRequestHeaders: map[string]string{
|
||||
|
@ -1115,6 +1117,74 @@ func TestGetServers(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWhiteList(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
instance ecsInstance
|
||||
expected *types.WhiteList
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no white list labels",
|
||||
instance: ecsInstance{
|
||||
containerDefinition: &ecs.ContainerDefinition{
|
||||
DockerLabels: map[string]*string{},
|
||||
},
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when only range",
|
||||
instance: ecsInstance{
|
||||
containerDefinition: &ecs.ContainerDefinition{
|
||||
DockerLabels: map[string]*string{
|
||||
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
||||
}},
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when range and UseXForwardedFor",
|
||||
instance: ecsInstance{
|
||||
containerDefinition: &ecs.ContainerDefinition{
|
||||
DockerLabels: map[string]*string{
|
||||
label.TraefikFrontendWhiteListSourceRange: aws.String("10.10.10.10"),
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
||||
}},
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only UseXForwardedFor",
|
||||
instance: ecsInstance{
|
||||
containerDefinition: &ecs.ContainerDefinition{
|
||||
DockerLabels: map[string]*string{
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: aws.String("true"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := getWhiteList(test.instance)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRedirect(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
|
@ -5,31 +5,32 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
annotationKubernetesIngressClass = "kubernetes.io/ingress.class"
|
||||
annotationKubernetesAuthRealm = "ingress.kubernetes.io/auth-realm"
|
||||
annotationKubernetesAuthType = "ingress.kubernetes.io/auth-type"
|
||||
annotationKubernetesAuthSecret = "ingress.kubernetes.io/auth-secret"
|
||||
annotationKubernetesRewriteTarget = "ingress.kubernetes.io/rewrite-target"
|
||||
annotationKubernetesWhitelistSourceRange = "ingress.kubernetes.io/whitelist-source-range"
|
||||
annotationKubernetesPreserveHost = "ingress.kubernetes.io/preserve-host"
|
||||
annotationKubernetesPassTLSCert = "ingress.kubernetes.io/pass-tls-cert"
|
||||
annotationKubernetesFrontendEntryPoints = "ingress.kubernetes.io/frontend-entry-points"
|
||||
annotationKubernetesPriority = "ingress.kubernetes.io/priority"
|
||||
annotationKubernetesCircuitBreakerExpression = "ingress.kubernetes.io/circuit-breaker-expression"
|
||||
annotationKubernetesLoadBalancerMethod = "ingress.kubernetes.io/load-balancer-method"
|
||||
annotationKubernetesAffinity = "ingress.kubernetes.io/affinity"
|
||||
annotationKubernetesSessionCookieName = "ingress.kubernetes.io/session-cookie-name"
|
||||
annotationKubernetesRuleType = "ingress.kubernetes.io/rule-type"
|
||||
annotationKubernetesRedirectEntryPoint = "ingress.kubernetes.io/redirect-entry-point"
|
||||
annotationKubernetesRedirectPermanent = "ingress.kubernetes.io/redirect-permanent"
|
||||
annotationKubernetesRedirectRegex = "ingress.kubernetes.io/redirect-regex"
|
||||
annotationKubernetesRedirectReplacement = "ingress.kubernetes.io/redirect-replacement"
|
||||
annotationKubernetesMaxConnAmount = "ingress.kubernetes.io/max-conn-amount"
|
||||
annotationKubernetesMaxConnExtractorFunc = "ingress.kubernetes.io/max-conn-extractor-func"
|
||||
annotationKubernetesRateLimit = "ingress.kubernetes.io/rate-limit"
|
||||
annotationKubernetesErrorPages = "ingress.kubernetes.io/error-pages"
|
||||
annotationKubernetesBuffering = "ingress.kubernetes.io/buffering"
|
||||
annotationKubernetesAppRoot = "ingress.kubernetes.io/app-root"
|
||||
annotationKubernetesIngressClass = "kubernetes.io/ingress.class"
|
||||
annotationKubernetesAuthRealm = "ingress.kubernetes.io/auth-realm"
|
||||
annotationKubernetesAuthType = "ingress.kubernetes.io/auth-type"
|
||||
annotationKubernetesAuthSecret = "ingress.kubernetes.io/auth-secret"
|
||||
annotationKubernetesRewriteTarget = "ingress.kubernetes.io/rewrite-target"
|
||||
annotationKubernetesWhiteListSourceRange = "ingress.kubernetes.io/whitelist-source-range"
|
||||
annotationKubernetesWhiteListUseXForwardedFor = "ingress.kubernetes.io/whitelist-x-forwarded-for"
|
||||
annotationKubernetesPreserveHost = "ingress.kubernetes.io/preserve-host"
|
||||
annotationKubernetesPassTLSCert = "ingress.kubernetes.io/pass-tls-cert"
|
||||
annotationKubernetesFrontendEntryPoints = "ingress.kubernetes.io/frontend-entry-points"
|
||||
annotationKubernetesPriority = "ingress.kubernetes.io/priority"
|
||||
annotationKubernetesCircuitBreakerExpression = "ingress.kubernetes.io/circuit-breaker-expression"
|
||||
annotationKubernetesLoadBalancerMethod = "ingress.kubernetes.io/load-balancer-method"
|
||||
annotationKubernetesAffinity = "ingress.kubernetes.io/affinity"
|
||||
annotationKubernetesSessionCookieName = "ingress.kubernetes.io/session-cookie-name"
|
||||
annotationKubernetesRuleType = "ingress.kubernetes.io/rule-type"
|
||||
annotationKubernetesRedirectEntryPoint = "ingress.kubernetes.io/redirect-entry-point"
|
||||
annotationKubernetesRedirectPermanent = "ingress.kubernetes.io/redirect-permanent"
|
||||
annotationKubernetesRedirectRegex = "ingress.kubernetes.io/redirect-regex"
|
||||
annotationKubernetesRedirectReplacement = "ingress.kubernetes.io/redirect-replacement"
|
||||
annotationKubernetesMaxConnAmount = "ingress.kubernetes.io/max-conn-amount"
|
||||
annotationKubernetesMaxConnExtractorFunc = "ingress.kubernetes.io/max-conn-extractor-func"
|
||||
annotationKubernetesRateLimit = "ingress.kubernetes.io/rate-limit"
|
||||
annotationKubernetesErrorPages = "ingress.kubernetes.io/error-pages"
|
||||
annotationKubernetesBuffering = "ingress.kubernetes.io/buffering"
|
||||
annotationKubernetesAppRoot = "ingress.kubernetes.io/app-root"
|
||||
|
||||
annotationKubernetesSSLRedirect = "ingress.kubernetes.io/ssl-redirect"
|
||||
annotationKubernetesHSTSMaxAge = "ingress.kubernetes.io/hsts-max-age"
|
||||
|
|
|
@ -202,9 +202,13 @@ func basicAuth(auth ...string) func(*types.Frontend) {
|
|||
}
|
||||
}
|
||||
|
||||
func whitelistSourceRange(ranges ...string) func(*types.Frontend) {
|
||||
func whiteList(useXFF bool, ranges ...string) func(*types.Frontend) {
|
||||
return func(f *types.Frontend) {
|
||||
f.WhitelistSourceRange = ranges
|
||||
if f.WhiteList == nil {
|
||||
f.WhiteList = &types.WhiteList{}
|
||||
}
|
||||
f.WhiteList.UseXForwardedFor = useXFF
|
||||
f.WhiteList.SourceRange = ranges
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -200,21 +200,20 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
|||
passTLSCert := getBoolValue(i.Annotations, annotationKubernetesPassTLSCert, p.EnablePassTLSCert)
|
||||
priority := getIntValue(i.Annotations, annotationKubernetesPriority, 0)
|
||||
entryPoints := getSliceStringValue(i.Annotations, annotationKubernetesFrontendEntryPoints)
|
||||
whitelistSourceRange := getSliceStringValue(i.Annotations, annotationKubernetesWhitelistSourceRange)
|
||||
|
||||
templateObjects.Frontends[baseName] = &types.Frontend{
|
||||
Backend: baseName,
|
||||
PassHostHeader: passHostHeader,
|
||||
PassTLSCert: passTLSCert,
|
||||
Routes: make(map[string]types.Route),
|
||||
Priority: priority,
|
||||
BasicAuth: basicAuthCreds,
|
||||
WhitelistSourceRange: whitelistSourceRange,
|
||||
Redirect: getFrontendRedirect(i),
|
||||
EntryPoints: entryPoints,
|
||||
Headers: getHeader(i),
|
||||
Errors: getErrorPages(i),
|
||||
RateLimit: getRateLimit(i),
|
||||
Backend: baseName,
|
||||
PassHostHeader: passHostHeader,
|
||||
PassTLSCert: passTLSCert,
|
||||
Routes: make(map[string]types.Route),
|
||||
Priority: priority,
|
||||
BasicAuth: basicAuthCreds,
|
||||
WhiteList: getWhiteList(i),
|
||||
Redirect: getFrontendRedirect(i),
|
||||
EntryPoints: entryPoints,
|
||||
Headers: getHeader(i),
|
||||
Errors: getErrorPages(i),
|
||||
RateLimit: getRateLimit(i),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,7 +456,7 @@ func getTLS(ingress *extensionsv1beta1.Ingress, k8sClient Client) ([]*tls.Config
|
|||
|
||||
func endpointPortNumber(servicePort corev1.ServicePort, endpointPorts []corev1.EndpointPort) int {
|
||||
if len(endpointPorts) > 0 {
|
||||
//name is optional if there is only one port
|
||||
// name is optional if there is only one port
|
||||
port := endpointPorts[0]
|
||||
for _, endpointPort := range endpointPorts {
|
||||
if servicePort.Name == endpointPort.Name {
|
||||
|
@ -510,6 +509,18 @@ func getFrontendRedirect(i *extensionsv1beta1.Ingress) *types.Redirect {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getWhiteList(i *extensionsv1beta1.Ingress) *types.WhiteList {
|
||||
ranges := getSliceStringValue(i.Annotations, annotationKubernetesWhiteListSourceRange)
|
||||
if len(ranges) <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &types.WhiteList{
|
||||
SourceRange: ranges,
|
||||
UseXForwardedFor: getBoolValue(i.Annotations, annotationKubernetesWhiteListUseXForwardedFor, false),
|
||||
}
|
||||
}
|
||||
|
||||
func getBuffering(service *corev1.Service) *types.Buffering {
|
||||
var buffering *types.Buffering
|
||||
|
||||
|
|
|
@ -665,7 +665,8 @@ func TestIngressAnnotations(t *testing.T) {
|
|||
),
|
||||
buildIngress(
|
||||
iNamespace("testing"),
|
||||
iAnnotation(annotationKubernetesWhitelistSourceRange, "1.1.1.1/24, 1234:abcd::42/32"),
|
||||
iAnnotation(annotationKubernetesWhiteListSourceRange, "1.1.1.1/24, 1234:abcd::42/32"),
|
||||
iAnnotation(annotationKubernetesWhiteListUseXForwardedFor, "true"),
|
||||
iRules(
|
||||
iRule(
|
||||
iHost("test"),
|
||||
|
@ -984,7 +985,7 @@ rateset:
|
|||
),
|
||||
frontend("test/whitelist-source-range",
|
||||
passHostHeader(),
|
||||
whitelistSourceRange("1.1.1.1/24", "1234:abcd::42/32"),
|
||||
whiteList(true, "1.1.1.1/24", "1234:abcd::42/32"),
|
||||
routes(
|
||||
route("/whitelist-source-range", "PathPrefix:/whitelist-source-range"),
|
||||
route("test", "Host:test")),
|
||||
|
|
|
@ -22,29 +22,30 @@ const (
|
|||
pathBackendBufferingMemRequestBodyBytes = pathBackendBuffering + "memrequestbodybytes"
|
||||
pathBackendBufferingRetryExpression = pathBackendBuffering + "retryexpression"
|
||||
|
||||
pathFrontends = "/frontends/"
|
||||
pathFrontendBackend = "/backend"
|
||||
pathFrontendPriority = "/priority"
|
||||
pathFrontendPassHostHeaderDeprecated = "/passHostHeader" // Deprecated
|
||||
pathFrontendPassHostHeader = "/passhostheader"
|
||||
pathFrontendPassTLSCert = "/passtlscert"
|
||||
pathFrontendWhiteListSourceRange = "/whitelistsourcerange"
|
||||
pathFrontendBasicAuth = "/basicauth"
|
||||
pathFrontendEntryPoints = "/entrypoints"
|
||||
pathFrontendRedirectEntryPoint = "/redirect/entrypoint"
|
||||
pathFrontendRedirectRegex = "/redirect/regex"
|
||||
pathFrontendRedirectReplacement = "/redirect/replacement"
|
||||
pathFrontendRedirectPermanent = "/redirect/permanent"
|
||||
pathFrontendErrorPages = "/errors/"
|
||||
pathFrontendErrorPagesBackend = "/backend"
|
||||
pathFrontendErrorPagesQuery = "/query"
|
||||
pathFrontendErrorPagesStatus = "/status"
|
||||
pathFrontendRateLimit = "/ratelimit/"
|
||||
pathFrontendRateLimitRateSet = pathFrontendRateLimit + "rateset/"
|
||||
pathFrontendRateLimitExtractorFunc = pathFrontendRateLimit + "extractorfunc"
|
||||
pathFrontendRateLimitPeriod = "/period"
|
||||
pathFrontendRateLimitAverage = "/average"
|
||||
pathFrontendRateLimitBurst = "/burst"
|
||||
pathFrontends = "/frontends/"
|
||||
pathFrontendBackend = "/backend"
|
||||
pathFrontendPriority = "/priority"
|
||||
pathFrontendPassHostHeaderDeprecated = "/passHostHeader" // Deprecated
|
||||
pathFrontendPassHostHeader = "/passhostheader"
|
||||
pathFrontendPassTLSCert = "/passtlscert"
|
||||
pathFrontendWhiteListSourceRange = "/whitelist/sourcerange"
|
||||
pathFrontendWhiteListUseXForwardedFor = "/whitelist/usexforwardedfor"
|
||||
pathFrontendBasicAuth = "/basicauth"
|
||||
pathFrontendEntryPoints = "/entrypoints"
|
||||
pathFrontendRedirectEntryPoint = "/redirect/entrypoint"
|
||||
pathFrontendRedirectRegex = "/redirect/regex"
|
||||
pathFrontendRedirectReplacement = "/redirect/replacement"
|
||||
pathFrontendRedirectPermanent = "/redirect/permanent"
|
||||
pathFrontendErrorPages = "/errors/"
|
||||
pathFrontendErrorPagesBackend = "/backend"
|
||||
pathFrontendErrorPagesQuery = "/query"
|
||||
pathFrontendErrorPagesStatus = "/status"
|
||||
pathFrontendRateLimit = "/ratelimit/"
|
||||
pathFrontendRateLimitRateSet = pathFrontendRateLimit + "rateset/"
|
||||
pathFrontendRateLimitExtractorFunc = pathFrontendRateLimit + "extractorfunc"
|
||||
pathFrontendRateLimitPeriod = "/period"
|
||||
pathFrontendRateLimitAverage = "/average"
|
||||
pathFrontendRateLimitBurst = "/burst"
|
||||
|
||||
pathFrontendCustomRequestHeaders = "/headers/customrequestheaders/"
|
||||
pathFrontendCustomResponseHeaders = "/headers/customresponseheaders/"
|
||||
|
|
|
@ -41,18 +41,18 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
"getTLSSection": p.getTLSSection,
|
||||
|
||||
// Frontend functions
|
||||
"getBackendName": p.getFuncString(pathFrontendBackend, ""),
|
||||
"getPriority": p.getFuncInt(pathFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getPassHostHeader": p.getPassHostHeader(),
|
||||
"getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": p.getFuncList(pathFrontendEntryPoints),
|
||||
"getWhitelistSourceRange": p.getFuncList(pathFrontendWhiteListSourceRange),
|
||||
"getBasicAuth": p.getFuncList(pathFrontendBasicAuth),
|
||||
"getRoutes": p.getRoutes,
|
||||
"getRedirect": p.getRedirect,
|
||||
"getErrorPages": p.getErrorPages,
|
||||
"getRateLimit": p.getRateLimit,
|
||||
"getHeaders": p.getHeaders,
|
||||
"getBackendName": p.getFuncString(pathFrontendBackend, ""),
|
||||
"getPriority": p.getFuncInt(pathFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getPassHostHeader": p.getPassHostHeader(),
|
||||
"getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": p.getFuncList(pathFrontendEntryPoints),
|
||||
"getBasicAuth": p.getFuncList(pathFrontendBasicAuth),
|
||||
"getRoutes": p.getRoutes,
|
||||
"getRedirect": p.getRedirect,
|
||||
"getErrorPages": p.getErrorPages,
|
||||
"getRateLimit": p.getRateLimit,
|
||||
"getHeaders": p.getHeaders,
|
||||
"getWhiteList": p.getWhiteList,
|
||||
|
||||
// Backend functions
|
||||
"getServers": p.getServers,
|
||||
|
@ -125,6 +125,19 @@ func (p *Provider) getStickinessCookieName(rootPath string) string {
|
|||
return p.get("", rootPath, pathBackendLoadBalancerStickinessCookieName)
|
||||
}
|
||||
|
||||
func (p *Provider) getWhiteList(rootPath string) *types.WhiteList {
|
||||
ranges := p.getList(rootPath, pathFrontendWhiteListSourceRange)
|
||||
|
||||
if len(ranges) > 0 {
|
||||
return &types.WhiteList{
|
||||
SourceRange: ranges,
|
||||
UseXForwardedFor: p.getBool(false, rootPath, pathFrontendWhiteListUseXForwardedFor),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) getRedirect(rootPath string) *types.Redirect {
|
||||
permanent := p.getBool(false, rootPath, pathFrontendRedirectPermanent)
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
withPair(pathFrontendPassTLSCert, "true"),
|
||||
withPair(pathFrontendEntryPoints, "http,https"),
|
||||
withPair(pathFrontendWhiteListSourceRange, "1.1.1.1/24, 1234:abcd::42/32"),
|
||||
withPair(pathFrontendWhiteListUseXForwardedFor, "true"),
|
||||
withPair(pathFrontendBasicAuth, "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/, test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
|
||||
withPair(pathFrontendRedirectEntryPoint, "https"),
|
||||
withPair(pathFrontendRedirectRegex, "nope"),
|
||||
|
@ -180,12 +181,15 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
Frontends: map[string]*types.Frontend{
|
||||
"frontend1": {
|
||||
Priority: 6,
|
||||
EntryPoints: []string{"http", "https"},
|
||||
Backend: "backend1",
|
||||
PassTLSCert: true,
|
||||
WhitelistSourceRange: []string{"1.1.1.1/24", "1234:abcd::42/32"},
|
||||
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
|
||||
Priority: 6,
|
||||
EntryPoints: []string{"http", "https"},
|
||||
Backend: "backend1",
|
||||
PassTLSCert: true,
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{"1.1.1.1/24", "1234:abcd::42/32"},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
BasicAuth: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"},
|
||||
Redirect: &types.Redirect{
|
||||
EntryPoint: "https",
|
||||
Permanent: true,
|
||||
|
@ -1031,6 +1035,68 @@ func TestProviderHasStickinessLabel(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWhiteList(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
rootPath string
|
||||
kvPairs []*store.KVPair
|
||||
expected *types.WhiteList
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no white list labels",
|
||||
rootPath: "traefik/frontends/foo",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when only range",
|
||||
rootPath: "traefik/frontends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair(pathFrontendWhiteListSourceRange, "10.10.10.10"))),
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when range and UseXForwardedFor",
|
||||
rootPath: "traefik/frontends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair(pathFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
withPair(pathFrontendWhiteListUseXForwardedFor, "true"))),
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only UseXForwardedFor",
|
||||
rootPath: "traefik/frontends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair(pathFrontendWhiteListUseXForwardedFor, "true"))),
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := newProviderMock(test.kvPairs)
|
||||
|
||||
actual := p.getWhiteList(test.rootPath)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetRedirect(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
|
@ -65,7 +65,10 @@ const (
|
|||
SuffixFrontendRedirectReplacement = "frontend.redirect.replacement"
|
||||
SuffixFrontendRedirectPermanent = "frontend.redirect.permanent"
|
||||
SuffixFrontendRule = "frontend.rule"
|
||||
SuffixFrontendWhitelistSourceRange = "frontend.whitelistSourceRange"
|
||||
SuffixFrontendWhitelistSourceRange = "frontend.whitelistSourceRange" // Deprecated
|
||||
SuffixFrontendWhiteList = "frontend.whiteList."
|
||||
SuffixFrontendWhiteListSourceRange = SuffixFrontendWhiteList + "sourceRange"
|
||||
SuffixFrontendWhiteListUseXForwardedFor = SuffixFrontendWhiteList + "useXForwardedFor"
|
||||
TraefikDomain = Prefix + SuffixDomain
|
||||
TraefikEnable = Prefix + SuffixEnable
|
||||
TraefikPort = Prefix + SuffixPort
|
||||
|
@ -106,7 +109,9 @@ const (
|
|||
TraefikFrontendRedirectReplacement = Prefix + SuffixFrontendRedirectReplacement
|
||||
TraefikFrontendRedirectPermanent = Prefix + SuffixFrontendRedirectPermanent
|
||||
TraefikFrontendRule = Prefix + SuffixFrontendRule
|
||||
TraefikFrontendWhitelistSourceRange = Prefix + SuffixFrontendWhitelistSourceRange
|
||||
TraefikFrontendWhitelistSourceRange = Prefix + SuffixFrontendWhitelistSourceRange // Deprecated
|
||||
TraefikFrontendWhiteListSourceRange = Prefix + SuffixFrontendWhiteListSourceRange
|
||||
TraefikFrontendWhiteListUseXForwardedFor = Prefix + SuffixFrontendWhiteListUseXForwardedFor
|
||||
TraefikFrontendRequestHeaders = Prefix + SuffixFrontendRequestHeaders
|
||||
TraefikFrontendResponseHeaders = Prefix + SuffixFrontendResponseHeaders
|
||||
TraefikFrontendAllowedHosts = Prefix + SuffixFrontendHeadersAllowedHosts
|
||||
|
|
|
@ -67,20 +67,23 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
"getHealthCheckInterval": getFuncString(label.TraefikBackendHealthCheckInterval, ""),
|
||||
|
||||
// Frontend functions
|
||||
"getServiceNames": getServiceNames,
|
||||
"getServiceNameSuffix": getServiceNameSuffix,
|
||||
"getPassHostHeader": getFuncBoolService(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBoolService(label.SuffixFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getPriority": getFuncIntService(label.SuffixFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getEntryPoints": getFuncSliceStringService(label.SuffixFrontendEntryPoints),
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getFrontendName": p.getFrontendName,
|
||||
"getBasicAuth": getFuncSliceStringService(label.SuffixFrontendAuthBasic),
|
||||
"getServiceNames": getServiceNames,
|
||||
"getServiceNameSuffix": getServiceNameSuffix,
|
||||
"getPassHostHeader": getFuncBoolService(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBoolService(label.SuffixFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getPriority": getFuncIntService(label.SuffixFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getEntryPoints": getFuncSliceStringService(label.SuffixFrontendEntryPoints),
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getFrontendName": p.getFrontendName,
|
||||
"getBasicAuth": getFuncSliceStringService(label.SuffixFrontendAuthBasic),
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getHeaders": getHeaders,
|
||||
"getWhiteList": getWhiteList,
|
||||
|
||||
// TODO Deprecated [breaking]
|
||||
"getWhitelistSourceRange": getFuncSliceStringService(label.SuffixFrontendWhitelistSourceRange),
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getHeaders": getHeaders,
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
|
@ -486,6 +489,20 @@ func (p *Provider) getServers(application marathon.Application, serviceName stri
|
|||
return servers
|
||||
}
|
||||
|
||||
func getWhiteList(application marathon.Application, serviceName string) *types.WhiteList {
|
||||
labels := getLabels(application, serviceName)
|
||||
|
||||
ranges := label.GetSliceStringValue(labels, getLabelName(serviceName, label.SuffixFrontendWhiteListSourceRange))
|
||||
if len(ranges) > 0 {
|
||||
return &types.WhiteList{
|
||||
SourceRange: ranges,
|
||||
UseXForwardedFor: label.GetBoolValue(labels, getLabelName(serviceName, label.SuffixFrontendWhiteListUseXForwardedFor), false),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRedirect(application marathon.Application, serviceName string) *types.Redirect {
|
||||
labels := getLabels(application, serviceName)
|
||||
|
||||
|
|
|
@ -206,7 +206,8 @@ func TestBuildConfigurationNonAPIErrors(t *testing.T) {
|
|||
withLabel(label.TraefikFrontendRedirectReplacement, "nope"),
|
||||
withLabel(label.TraefikFrontendRedirectPermanent, "true"),
|
||||
withLabel(label.TraefikFrontendRule, "Host:traefik.io"),
|
||||
withLabel(label.TraefikFrontendWhitelistSourceRange, "10.10.10.10"),
|
||||
withLabel(label.TraefikFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
withLabel(label.TraefikFrontendWhiteListUseXForwardedFor, "true"),
|
||||
|
||||
withLabel(label.TraefikFrontendRequestHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
|
||||
withLabel(label.TraefikFrontendResponseHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8"),
|
||||
|
@ -268,8 +269,9 @@ func TestBuildConfigurationNonAPIErrors(t *testing.T) {
|
|||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.10.10.10",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{"10.10.10.10"},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
Headers: &types.Headers{
|
||||
CustomRequestHeaders: map[string]string{
|
||||
|
@ -498,7 +500,7 @@ func TestBuildConfigurationServicesNonAPIErrors(t *testing.T) {
|
|||
application: application(
|
||||
appPorts(80, 81),
|
||||
|
||||
//withLabel(label.TraefikBackend, "foobar"),
|
||||
// withLabel(label.TraefikBackend, "foobar"),
|
||||
|
||||
withLabel(label.TraefikBackendCircuitBreakerExpression, "NetworkErrorRatio() > 0.5"),
|
||||
withLabel(label.TraefikBackendHealthCheckPath, "/health"),
|
||||
|
@ -530,7 +532,8 @@ func TestBuildConfigurationServicesNonAPIErrors(t *testing.T) {
|
|||
withServiceLabel(label.TraefikFrontendRedirectReplacement, "nope", "containous"),
|
||||
withServiceLabel(label.TraefikFrontendRedirectPermanent, "true", "containous"),
|
||||
withServiceLabel(label.TraefikFrontendRule, "Host:traefik.io", "containous"),
|
||||
withServiceLabel(label.TraefikFrontendWhitelistSourceRange, "10.10.10.10", "containous"),
|
||||
withServiceLabel(label.TraefikFrontendWhiteListSourceRange, "10.10.10.10", "containous"),
|
||||
withServiceLabel(label.TraefikFrontendWhiteListUseXForwardedFor, "true", "containous"),
|
||||
|
||||
withServiceLabel(label.TraefikFrontendRequestHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", "containous"),
|
||||
withServiceLabel(label.TraefikFrontendResponseHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8", "containous"),
|
||||
|
@ -591,8 +594,9 @@ func TestBuildConfigurationServicesNonAPIErrors(t *testing.T) {
|
|||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.10.10.10",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{"10.10.10.10"},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
Headers: &types.Headers{
|
||||
CustomRequestHeaders: map[string]string{
|
||||
|
@ -1627,6 +1631,107 @@ func TestGetServers(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWhiteList(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
application marathon.Application
|
||||
serviceName string
|
||||
expected *types.WhiteList
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no white list labels",
|
||||
application: application(
|
||||
appPorts(80),
|
||||
),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when only range",
|
||||
application: application(
|
||||
appPorts(80),
|
||||
withLabel(label.TraefikFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
),
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when range and UseXForwardedFor",
|
||||
application: application(
|
||||
appPorts(80),
|
||||
withLabel(label.TraefikFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
withLabel(label.TraefikFrontendWhiteListUseXForwardedFor, "true"),
|
||||
),
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only UseXForwardedFor",
|
||||
application: application(
|
||||
appPorts(80),
|
||||
withLabel(label.TraefikFrontendWhiteListUseXForwardedFor, "true"),
|
||||
),
|
||||
expected: nil,
|
||||
},
|
||||
// Service
|
||||
{
|
||||
desc: "should return a struct when only range on service",
|
||||
application: application(
|
||||
appPorts(80),
|
||||
withLabel(label.Prefix+"containous."+label.SuffixFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
),
|
||||
serviceName: "containous",
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when range and UseXForwardedFor on service",
|
||||
application: application(
|
||||
appPorts(80),
|
||||
withLabel(label.Prefix+"containous."+label.SuffixFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
withLabel(label.Prefix+"containous."+label.SuffixFrontendWhiteListUseXForwardedFor, "true"),
|
||||
),
|
||||
serviceName: "containous",
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only UseXForwardedFor on service",
|
||||
application: application(
|
||||
appPorts(80),
|
||||
withLabel(label.Prefix+"containous."+label.SuffixFrontendWhiteListUseXForwardedFor, "true"),
|
||||
),
|
||||
serviceName: "containous",
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := getWhiteList(test.application, test.serviceName)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRedirect(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
|
@ -41,18 +41,18 @@ func (p *Provider) buildConfiguration(tasks []state.Task) *types.Configuration {
|
|||
"getPort": p.getPort,
|
||||
|
||||
// Frontend functions
|
||||
"getFrontEndName": getFrontendName,
|
||||
"getEntryPoints": getFuncSliceStringValue(label.TraefikFrontendEntryPoints),
|
||||
"getBasicAuth": getFuncSliceStringValue(label.TraefikFrontendAuthBasic),
|
||||
"getWhitelistSourceRange": getFuncSliceStringValue(label.TraefikFrontendWhitelistSourceRange),
|
||||
"getPriority": getFuncStringValue(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
|
||||
"getPassHostHeader": getFuncBoolValue(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBoolValue(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getHeaders": getHeaders,
|
||||
"getFrontEndName": getFrontendName,
|
||||
"getEntryPoints": getFuncSliceStringValue(label.TraefikFrontendEntryPoints),
|
||||
"getBasicAuth": getFuncSliceStringValue(label.TraefikFrontendAuthBasic),
|
||||
"getPriority": getFuncStringValue(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
|
||||
"getPassHostHeader": getFuncBoolValue(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBoolValue(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getHeaders": getHeaders,
|
||||
"getWhiteList": getWhiteList,
|
||||
|
||||
// TODO Deprecated [breaking]
|
||||
"getFrontendBackend": getBackendName,
|
||||
|
@ -337,6 +337,18 @@ func (p *Provider) getServers(tasks []state.Task) map[string]types.Server {
|
|||
return servers
|
||||
}
|
||||
|
||||
func getWhiteList(task state.Task) *types.WhiteList {
|
||||
ranges := getSliceStringValue(task, label.TraefikFrontendWhiteListSourceRange)
|
||||
if len(ranges) > 0 {
|
||||
return &types.WhiteList{
|
||||
SourceRange: ranges,
|
||||
UseXForwardedFor: getBoolValue(task, label.TraefikFrontendWhiteListUseXForwardedFor, false),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRedirect(task state.Task) *types.Redirect {
|
||||
permanent := getBoolValue(task, label.TraefikFrontendRedirectPermanent, false)
|
||||
|
||||
|
|
|
@ -148,7 +148,8 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
withLabel(label.TraefikFrontendRedirectReplacement, "nope"),
|
||||
withLabel(label.TraefikFrontendRedirectPermanent, "true"),
|
||||
withLabel(label.TraefikFrontendRule, "Host:traefik.io"),
|
||||
withLabel(label.TraefikFrontendWhitelistSourceRange, "10.10.10.10"),
|
||||
withLabel(label.TraefikFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
withLabel(label.TraefikFrontendWhiteListUseXForwardedFor, "true"),
|
||||
|
||||
withLabel(label.TraefikFrontendRequestHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type:application/json; charset=utf-8"),
|
||||
withLabel(label.TraefikFrontendResponseHeaders, "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type:application/json; charset=utf-8"),
|
||||
|
@ -212,8 +213,9 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.10.10.10",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{"10.10.10.10"},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
Headers: &types.Headers{
|
||||
CustomRequestHeaders: map[string]string{
|
||||
|
@ -953,6 +955,75 @@ func TestGetServers(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWhiteList(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
task state.Task
|
||||
expected *types.WhiteList
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no white list labels",
|
||||
task: aTask("ID1",
|
||||
withIP("10.10.10.10"),
|
||||
withInfo("name1", withPorts(withPort("TCP", 80, "WEB"))),
|
||||
withDefaultStatus(),
|
||||
),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when only range",
|
||||
task: aTask("ID1",
|
||||
withLabel(label.TraefikFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
withIP("10.10.10.10"),
|
||||
withInfo("name1", withPorts(withPort("TCP", 80, "WEB"))),
|
||||
withDefaultStatus(),
|
||||
),
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when range and UseXForwardedFor",
|
||||
task: aTask("ID1",
|
||||
withLabel(label.TraefikFrontendWhiteListSourceRange, "10.10.10.10"),
|
||||
withLabel(label.TraefikFrontendWhiteListUseXForwardedFor, "true"),
|
||||
withIP("10.10.10.10"),
|
||||
withInfo("name1", withPorts(withPort("TCP", 80, "WEB"))),
|
||||
withDefaultStatus(),
|
||||
),
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only UseXForwardedFor",
|
||||
task: aTask("ID1",
|
||||
withLabel(label.TraefikFrontendWhiteListUseXForwardedFor, "true"),
|
||||
withIP("10.10.10.10"),
|
||||
withInfo("name1", withPorts(withPort("TCP", 80, "WEB"))),
|
||||
withDefaultStatus(),
|
||||
),
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := getWhiteList(test.task)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRedirect(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
|
@ -55,20 +55,22 @@ func (p *Provider) buildConfiguration(services []rancherData) *types.Configurati
|
|||
"getStickinessCookieName": getFuncString(label.TraefikBackendLoadBalancerStickinessCookieName, label.DefaultBackendLoadbalancerStickinessCookieName),
|
||||
|
||||
// Frontend functions
|
||||
"getBackend": getBackendName, // TODO Deprecated [breaking] replaced by getBackendName
|
||||
"getBackendName": getBackendName,
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getPriority": getFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getPassHostHeader": getFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": getFuncSliceString(label.TraefikFrontendEntryPoints),
|
||||
"getBasicAuth": getFuncSliceString(label.TraefikFrontendAuthBasic),
|
||||
"getWhitelistSourceRange": getFuncSliceString(label.TraefikFrontendWhitelistSourceRange),
|
||||
"getBackend": getBackendName, // TODO Deprecated [breaking] replaced by getBackendName
|
||||
"getBackendName": getBackendName,
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getPriority": getFuncInt(label.TraefikFrontendPriority, label.DefaultFrontendPriorityInt),
|
||||
"getPassHostHeader": getFuncBool(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeaderBool),
|
||||
"getPassTLSCert": getFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": getFuncSliceString(label.TraefikFrontendEntryPoints),
|
||||
"getBasicAuth": getFuncSliceString(label.TraefikFrontendAuthBasic),
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getRedirect": getRedirect,
|
||||
"getHeaders": getHeaders,
|
||||
"getWhiteList": getWhiteList,
|
||||
|
||||
"getErrorPages": getErrorPages,
|
||||
"getRateLimit": getRateLimit,
|
||||
"getRedirect": getRedirect,
|
||||
"getHeaders": getHeaders,
|
||||
// TODO Deprecated [breaking]
|
||||
"getWhitelistSourceRange": getFuncSliceString(label.TraefikFrontendWhitelistSourceRange),
|
||||
}
|
||||
|
||||
// filter services
|
||||
|
@ -271,6 +273,19 @@ func getServers(service rancherData) map[string]types.Server {
|
|||
return servers
|
||||
}
|
||||
|
||||
func getWhiteList(service rancherData) *types.WhiteList {
|
||||
ranges := label.GetSliceStringValue(service.Labels, label.TraefikFrontendWhiteListSourceRange)
|
||||
|
||||
if len(ranges) > 0 {
|
||||
return &types.WhiteList{
|
||||
SourceRange: ranges,
|
||||
UseXForwardedFor: label.GetBoolValue(service.Labels, label.TraefikFrontendWhiteListUseXForwardedFor, false),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRedirect(service rancherData) *types.Redirect {
|
||||
permanent := label.GetBoolValue(service.Labels, label.TraefikFrontendRedirectPermanent, false)
|
||||
|
||||
|
|
|
@ -56,17 +56,18 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendBufferingMemRequestBodyBytes: "2097152",
|
||||
label.TraefikBackendBufferingRetryExpression: "IsNetworkError() && Attempts() <= 2",
|
||||
|
||||
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
label.TraefikFrontendEntryPoints: "http,https",
|
||||
label.TraefikFrontendPassHostHeader: "true",
|
||||
label.TraefikFrontendPassTLSCert: "true",
|
||||
label.TraefikFrontendPriority: "666",
|
||||
label.TraefikFrontendRedirectEntryPoint: "https",
|
||||
label.TraefikFrontendRedirectRegex: "nope",
|
||||
label.TraefikFrontendRedirectReplacement: "nope",
|
||||
label.TraefikFrontendRedirectPermanent: "true",
|
||||
label.TraefikFrontendRule: "Host:traefik.io",
|
||||
label.TraefikFrontendWhitelistSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendAuthBasic: "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
label.TraefikFrontendEntryPoints: "http,https",
|
||||
label.TraefikFrontendPassHostHeader: "true",
|
||||
label.TraefikFrontendPassTLSCert: "true",
|
||||
label.TraefikFrontendPriority: "666",
|
||||
label.TraefikFrontendRedirectEntryPoint: "https",
|
||||
label.TraefikFrontendRedirectRegex: "nope",
|
||||
label.TraefikFrontendRedirectReplacement: "nope",
|
||||
label.TraefikFrontendRedirectPermanent: "true",
|
||||
label.TraefikFrontendRule: "Host:traefik.io",
|
||||
label.TraefikFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: "true",
|
||||
|
||||
label.TraefikFrontendRequestHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
label.TraefikFrontendResponseHeaders: "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
|
@ -128,8 +129,11 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.10.10.10",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
Headers: &types.Headers{
|
||||
CustomRequestHeaders: map[string]string{
|
||||
|
@ -1001,6 +1005,78 @@ func TestGetServers(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWhiteList(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
service rancherData
|
||||
expected *types.WhiteList
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no white list labels",
|
||||
service: rancherData{
|
||||
Labels: map[string]string{},
|
||||
Health: "healthy",
|
||||
State: "active",
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when only range",
|
||||
service: rancherData{
|
||||
Labels: map[string]string{
|
||||
label.TraefikFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
},
|
||||
Health: "healthy",
|
||||
State: "active",
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a struct when range and UseXForwardedFor",
|
||||
service: rancherData{
|
||||
Labels: map[string]string{
|
||||
label.TraefikFrontendWhiteListSourceRange: "10.10.10.10",
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: "true",
|
||||
},
|
||||
Health: "healthy",
|
||||
State: "active",
|
||||
},
|
||||
expected: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.10.10.10",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only UseXForwardedFor",
|
||||
service: rancherData{
|
||||
Labels: map[string]string{
|
||||
label.TraefikFrontendWhiteListUseXForwardedFor: "true",
|
||||
},
|
||||
Health: "healthy",
|
||||
State: "active",
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := getWhiteList(test.service)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRedirect(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue