enforce ^~ location modifier when rewrite-target annotation is set

This commit is contained in:
Zenara Daley 2018-09-13 10:39:52 -04:00
parent aff61dc2dc
commit 0e6f0bb88d
3 changed files with 37 additions and 5 deletions

View file

@ -155,6 +155,7 @@ var (
"buildOpentracing": buildOpentracing, "buildOpentracing": buildOpentracing,
"proxySetHeader": proxySetHeader, "proxySetHeader": proxySetHeader,
"buildInfluxDB": buildInfluxDB, "buildInfluxDB": buildInfluxDB,
"atLeastOneNeedsRewrite": atLeastOneNeedsRewrite,
} }
) )
@ -287,9 +288,32 @@ func buildResolvers(res interface{}, disableIpv6 interface{}) string {
return strings.Join(r, " ") + ";" return strings.Join(r, " ") + ";"
} }
func needsRewrite(location *ingress.Location) bool {
if len(location.Rewrite.Target) > 0 && location.Rewrite.Target != location.Path {
return true
}
return false
}
// atLeastOneNeedsRewrite checks if the nginx.ingress.kubernetes.io/rewrite-target annotation is used on the '/' path
func atLeastOneNeedsRewrite(input interface{}) bool {
locations, ok := input.([]*ingress.Location)
if !ok {
glog.Errorf("expected an '[]*ingress.Location' type but %T was returned", input)
return false
}
for _, location := range locations {
if needsRewrite(location) {
return true
}
}
return false
}
// buildLocation produces the location string, if the ingress has redirects // buildLocation produces the location string, if the ingress has redirects
// (specified through the nginx.ingress.kubernetes.io/rewrite-target annotation) // (specified through the nginx.ingress.kubernetes.io/rewrite-target annotation)
func buildLocation(input interface{}) string { func buildLocation(input interface{}, rewrite bool) string {
location, ok := input.(*ingress.Location) location, ok := input.(*ingress.Location)
if !ok { if !ok {
glog.Errorf("expected an '*ingress.Location' type but %T was returned", input) glog.Errorf("expected an '*ingress.Location' type but %T was returned", input)
@ -297,7 +321,7 @@ func buildLocation(input interface{}) string {
} }
path := location.Path path := location.Path
if len(location.Rewrite.Target) > 0 && location.Rewrite.Target != path { if needsRewrite(location) {
if path == slash { if path == slash {
return fmt.Sprintf("~* %s", path) return fmt.Sprintf("~* %s", path)
} }
@ -310,6 +334,12 @@ func buildLocation(input interface{}) string {
return fmt.Sprintf(`~* ^%s%s`, path, baseuri) return fmt.Sprintf(`~* ^%s%s`, path, baseuri)
} }
if rewrite == true {
if path == slash {
return path
}
return fmt.Sprintf(`^~ %s`, path)
}
return path return path
} }

View file

@ -382,7 +382,7 @@ func TestBuildLocation(t *testing.T) {
Rewrite: rewrite.Config{Target: tc.Target, AddBaseURL: tc.AddBaseURL}, Rewrite: rewrite.Config{Target: tc.Target, AddBaseURL: tc.AddBaseURL},
} }
newLoc := buildLocation(loc) newLoc := buildLocation(loc, tc.Path != tc.Target)
if tc.Location != newLoc { if tc.Location != newLoc {
t.Errorf("%s: expected '%v' but returned %v", k, tc.Location, newLoc) t.Errorf("%s: expected '%v' but returned %v", k, tc.Location, newLoc)
} }

View file

@ -452,8 +452,9 @@ http {
{{/* build the maps that will be use to validate the Whitelist */}} {{/* build the maps that will be use to validate the Whitelist */}}
{{ range $server := $servers }} {{ range $server := $servers }}
{{ $usesRewrite := atLeastOneNeedsRewrite $server.Locations }}
{{ range $location := $server.Locations }} {{ range $location := $server.Locations }}
{{ $path := buildLocation $location }} {{ $path := buildLocation $location $usesRewrite }}
{{ if isLocationAllowed $location }} {{ if isLocationAllowed $location }}
{{ if gt (len $location.Whitelist.CIDR) 0 }} {{ if gt (len $location.Whitelist.CIDR) 0 }}
@ -818,8 +819,9 @@ stream {
{{ $server.ServerSnippet }} {{ $server.ServerSnippet }}
{{ end }} {{ end }}
{{ $usesRewrite := atLeastOneNeedsRewrite $server.Locations }}
{{ range $location := $server.Locations }} {{ range $location := $server.Locations }}
{{ $path := buildLocation $location }} {{ $path := buildLocation $location $usesRewrite }}
{{ $proxySetHeader := proxySetHeader $location }} {{ $proxySetHeader := proxySetHeader $location }}
{{ $authPath := buildAuthLocation $location }} {{ $authPath := buildAuthLocation $location }}