Skip to content

Commit

Permalink
Simplify code
Browse files Browse the repository at this point in the history
  • Loading branch information
sjberman committed Jul 11, 2023
1 parent e9f9058 commit e7a3213
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 134 deletions.
49 changes: 24 additions & 25 deletions internal/mode/static/nginx/config/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ func createLocations(pathRules []dataplane.PathRule, listenerPort int32) []http.
m := r.GetMatch()

buildLocations := extLocations
intLocation, match, intLocationExists := initializeInternalLocation(rule, matchRuleIdx, m)
if intLocationExists {
if len(rule.MatchRules) != 1 || !isPathOnlyMatch(m) {
intLocation, match := initializeInternalLocation(rule, matchRuleIdx, m)
buildLocations = []http.Location{intLocation}
matches = append(matches, match)
}
Expand Down Expand Up @@ -138,17 +138,9 @@ func createLocations(pathRules []dataplane.PathRule, listenerPort int32) []http.
}

if len(matches) > 0 {
// FIXME(sberman): De-dupe matches and associated locations
// so we don't need nginx/njs to perform unnecessary matching.
// https://github.com/nginxinc/nginx-kubernetes-gateway/issues/662
b, err := json.Marshal(matches)
if err != nil {
// panic is safe here because we should never fail to marshal the match unless we constructed it incorrectly.
panic(fmt.Errorf("could not marshal http match: %w", err))
}

matchesStr := convertMatchesToString(matches)
for i := range extLocations {
extLocations[i].HTTPMatchVar = string(b)
extLocations[i].HTTPMatchVar = matchesStr
}
locs = append(locs, extLocations...)
}
Expand Down Expand Up @@ -198,7 +190,9 @@ func initializeExternalLocations(
// that handles the Exact prefix case (if it doesn't already exist), and the first location is updated
// to handle the trailing slash prefix case (if it doesn't already exist)
if isNonSlashedPrefixPath(rule.PathType, externalLocPath) {
// if Exact path and trailing slash Prefix path already exist, then we don't need to build anything
// if Exact path and/or trailing slash Prefix path already exists, this means some routing rule
// configures it. The routing rule location has priority over this location, so we don't try to
// overwrite it and we don't add a duplicate location to NGINX because that will cause an NGINX config error.
_, exactPathExists := pathsAndTypes[rule.Path][dataplane.PathTypeExact]
var trailingSlashPrefixPathExists bool
if pathTypes, exists := pathsAndTypes[rule.Path+"/"]; exists {
Expand Down Expand Up @@ -235,17 +229,9 @@ func initializeInternalLocation(
rule dataplane.PathRule,
matchRuleIdx int,
match v1beta1.HTTPRouteMatch,
) (http.Location, httpMatch, bool) {
var intLocation http.Location
var hm httpMatch
intLocationNeeded := len(rule.MatchRules) != 1 || !isPathOnlyMatch(match)
if intLocationNeeded {
path := createPathForMatch(rule.Path, rule.PathType, matchRuleIdx)
hm = createHTTPMatch(match, path)
intLocation = createMatchLocation(path)
}

return intLocation, hm, intLocationNeeded
) (http.Location, httpMatch) {
path := createPathForMatch(rule.Path, rule.PathType, matchRuleIdx)
return createMatchLocation(path), createHTTPMatch(match, path)
}

func createReturnValForRedirectFilter(filter *v1beta1.HTTPRequestRedirectFilter, listenerPort int32) *http.Return {
Expand Down Expand Up @@ -438,6 +424,19 @@ func convertSetHeaders(headers []dataplane.HTTPHeader) []http.Header {
return locHeaders
}

func convertMatchesToString(matches []httpMatch) string {
// FIXME(sberman): De-dupe matches and associated locations
// so we don't need nginx/njs to perform unnecessary matching.
// https://github.com/nginxinc/nginx-kubernetes-gateway/issues/662
b, err := json.Marshal(matches)
if err != nil {
// panic is safe here because we should never fail to marshal the match unless we constructed it incorrectly.
panic(fmt.Errorf("could not marshal http match: %w", err))
}

return string(b)
}

func exactPath(path string) string {
return fmt.Sprintf("= %s", path)
}
Expand All @@ -463,7 +462,7 @@ func createDefaultRootLocation() http.Location {
}
}

// returns whether or not a path is of type Prefix and does not contain a trailing slash
// isNonSlashedPrefixPath returns whether or not a path is of type Prefix and does not contain a trailing slash
func isNonSlashedPrefixPath(pathType dataplane.PathType, path string) bool {
return pathType == dataplane.PathTypePrefix && !strings.HasSuffix(path, "/")
}
197 changes: 88 additions & 109 deletions internal/mode/static/nginx/config/servers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,41 @@ func TestCreateServersConflicts(t *testing.T) {
return hr
}

hr1 := createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee",
pathType: v1beta1.PathMatchExact,
},
})
hr2 := createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee/",
pathType: v1beta1.PathMatchPathPrefix,
},
})
hr3 := createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee/",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee",
pathType: v1beta1.PathMatchExact,
},
})

fooGroup := dataplane.BackendGroup{
Source: types.NamespacedName{Namespace: "test", Name: "route"},
RuleIdx: 0,
Expand Down Expand Up @@ -939,18 +974,9 @@ func TestCreateServersConflicts(t *testing.T) {
PathType: dataplane.PathTypePrefix,
MatchRules: []dataplane.MatchRule{
{
MatchIdx: 0,
RuleIdx: 0,
Source: createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee",
pathType: v1beta1.PathMatchExact,
},
}),
MatchIdx: 0,
RuleIdx: 0,
Source: hr1,
BackendGroup: fooGroup,
},
},
Expand All @@ -960,18 +986,9 @@ func TestCreateServersConflicts(t *testing.T) {
PathType: dataplane.PathTypeExact,
MatchRules: []dataplane.MatchRule{
{
MatchIdx: 0,
RuleIdx: 0,
Source: createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee",
pathType: v1beta1.PathMatchExact,
},
}),
MatchIdx: 0,
RuleIdx: 0,
Source: hr1,
BackendGroup: barGroup,
},
},
Expand All @@ -997,18 +1014,9 @@ func TestCreateServersConflicts(t *testing.T) {
PathType: dataplane.PathTypePrefix,
MatchRules: []dataplane.MatchRule{
{
MatchIdx: 0,
RuleIdx: 0,
Source: createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee/",
pathType: v1beta1.PathMatchPathPrefix,
},
}),
MatchIdx: 0,
RuleIdx: 0,
Source: hr2,
BackendGroup: fooGroup,
},
},
Expand All @@ -1018,18 +1026,9 @@ func TestCreateServersConflicts(t *testing.T) {
PathType: dataplane.PathTypePrefix,
MatchRules: []dataplane.MatchRule{
{
MatchIdx: 0,
RuleIdx: 1,
Source: createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee/",
pathType: v1beta1.PathMatchPathPrefix,
},
}),
MatchIdx: 0,
RuleIdx: 1,
Source: hr2,
BackendGroup: barGroup,
},
},
Expand All @@ -1055,22 +1054,9 @@ func TestCreateServersConflicts(t *testing.T) {
PathType: dataplane.PathTypePrefix,
MatchRules: []dataplane.MatchRule{
{
MatchIdx: 0,
RuleIdx: 0,
Source: createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee/",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee",
pathType: v1beta1.PathMatchExact,
},
}),
MatchIdx: 0,
RuleIdx: 0,
Source: hr3,
BackendGroup: fooGroup,
},
},
Expand All @@ -1080,22 +1066,9 @@ func TestCreateServersConflicts(t *testing.T) {
PathType: dataplane.PathTypePrefix,
MatchRules: []dataplane.MatchRule{
{
MatchIdx: 0,
RuleIdx: 1,
Source: createHR([]pathAndType{
{
path: "/coffee",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee/",
pathType: v1beta1.PathMatchPathPrefix,
},
{
path: "/coffee",
pathType: v1beta1.PathMatchExact,
},
}),
MatchIdx: 0,
RuleIdx: 1,
Source: hr3,
BackendGroup: barGroup,
},
},
Expand Down Expand Up @@ -1762,40 +1735,46 @@ func TestIsPathOnlyMatch(t *testing.T) {
func TestCreateProxyPass(t *testing.T) {
g := NewGomegaWithT(t)

expected := "http://10.0.0.1:80"

grp := dataplane.BackendGroup{
Backends: []dataplane.Backend{
{
UpstreamName: "10.0.0.1:80",
Valid: true,
Weight: 1,
tests := []struct {
expected string
grp dataplane.BackendGroup
}{
{
expected: "http://10.0.0.1:80",
grp: dataplane.BackendGroup{
Backends: []dataplane.Backend{
{
UpstreamName: "10.0.0.1:80",
Valid: true,
Weight: 1,
},
},
},
},
}

result := createProxyPass(grp)
g.Expect(result).To(Equal(expected))

expected = "http://$ns1__bg_rule0"

grp = dataplane.BackendGroup{
Source: types.NamespacedName{Namespace: "ns1", Name: "bg"},
Backends: []dataplane.Backend{
{
UpstreamName: "my-variable",
Valid: true,
Weight: 1,
},
{
UpstreamName: "my-variable2",
Valid: true,
Weight: 1,
{
expected: "http://$ns1__bg_rule0",
grp: dataplane.BackendGroup{
Source: types.NamespacedName{Namespace: "ns1", Name: "bg"},
Backends: []dataplane.Backend{
{
UpstreamName: "my-variable",
Valid: true,
Weight: 1,
},
{
UpstreamName: "my-variable2",
Valid: true,
Weight: 1,
},
},
},
},
}
result = createProxyPass(grp)
g.Expect(result).To(Equal(expected))

for _, tc := range tests {
result := createProxyPass(tc.grp)
g.Expect(result).To(Equal(tc.expected))
}
}

func TestCreateMatchLocation(t *testing.T) {
Expand Down

0 comments on commit e7a3213

Please sign in to comment.