Skip to content

Commit 875b213

Browse files
committed
Make filters part of MatchRule
1 parent a30aa71 commit 875b213

File tree

4 files changed

+174
-203
lines changed

4 files changed

+174
-203
lines changed

internal/nginx/config/generator.go

+4-28
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,10 @@ func generate(virtualServer state.VirtualServer, serviceStore state.ServiceStore
126126
// If it doesn't work as expected, such situation is silently handled below in findFirstFilters.
127127
// Consider reporting an error. But that should be done in a separate validation layer.
128128

129-
firstFilters := findFirstFilters(r.GetFilters(), supportedFilters)
130-
131-
loc.Return = generateReturnValForRedirectFilter(
132-
firstFilters[v1beta1.HTTPRouteFilterRequestRedirect].RequestRedirect,
133-
listenerPort,
134-
)
135-
136-
// ProxyPass is mutually exclusive with Return
137-
if loc.Return == nil {
129+
// RequestRedirect and proxying are mutually exclusive.
130+
if r.Filters.RequestRedirect != nil {
131+
loc.Return = generateReturnValForRedirectFilter(r.Filters.RequestRedirect, listenerPort)
132+
} else {
138133
address, err := getBackendAddress(r.Source.Spec.Rules[r.RuleIdx].BackendRefs, r.Source.Namespace, serviceStore)
139134
if err != nil {
140135
warnings.AddWarning(r.Source, err.Error())
@@ -174,25 +169,6 @@ func generateProxyPass(address string) string {
174169
return "http://" + address
175170
}
176171

177-
var supportedFilters = map[v1beta1.HTTPRouteFilterType]struct{}{
178-
v1beta1.HTTPRouteFilterRequestRedirect: {},
179-
}
180-
181-
func findFirstFilters(
182-
filters []v1beta1.HTTPRouteFilter,
183-
filterTypes map[v1beta1.HTTPRouteFilterType]struct{},
184-
) map[v1beta1.HTTPRouteFilterType]v1beta1.HTTPRouteFilter {
185-
186-
result := make(map[v1beta1.HTTPRouteFilterType]v1beta1.HTTPRouteFilter)
187-
for i := len(filters) - 1; i >= 0; i-- {
188-
if _, exist := filterTypes[filters[i].Type]; exist {
189-
result[filters[i].Type] = filters[i]
190-
}
191-
}
192-
193-
return result
194-
}
195-
196172
func generateReturnValForRedirectFilter(filter *v1beta1.HTTPRequestRedirectFilter, listenerPort int) *returnVal {
197173
if filter == nil {
198174
return nil

internal/nginx/config/generator_test.go

+13-106
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,7 @@ func TestGenerate(t *testing.T) {
221221
},
222222
},
223223
},
224-
Filters: []v1beta1.HTTPRouteFilter{
225-
{
226-
Type: v1beta1.HTTPRouteFilterRequestRedirect,
227-
RequestRedirect: &v1beta1.HTTPRequestRedirectFilter{
228-
Hostname: (*v1beta1.PreciseHostname)(helpers.GetStringPointer("foo.example.com")),
229-
},
230-
},
231-
},
224+
// redirect is set in the corresponding state.MatchRule
232225
},
233226
{
234227
// A match with a redirect with explicit port
@@ -239,15 +232,7 @@ func TestGenerate(t *testing.T) {
239232
},
240233
},
241234
},
242-
Filters: []v1beta1.HTTPRouteFilter{
243-
{
244-
Type: v1beta1.HTTPRouteFilterRequestRedirect,
245-
RequestRedirect: &v1beta1.HTTPRequestRedirectFilter{
246-
Hostname: (*v1beta1.PreciseHostname)(helpers.GetStringPointer("bar.example.com")),
247-
Port: (*v1beta1.PortNumber)(helpers.GetInt32Pointer(8080)),
248-
},
249-
},
250-
},
235+
// redirect is set in the corresponding state.MatchRule
251236
},
252237
},
253238
},
@@ -342,6 +327,11 @@ func TestGenerate(t *testing.T) {
342327
MatchIdx: 0,
343328
RuleIdx: 3,
344329
Source: hr,
330+
Filters: state.Filters{
331+
RequestRedirect: &v1beta1.HTTPRequestRedirectFilter{
332+
Hostname: (*v1beta1.PreciseHostname)(helpers.GetStringPointer("foo.example.com")),
333+
},
334+
},
345335
},
346336
},
347337
},
@@ -352,6 +342,12 @@ func TestGenerate(t *testing.T) {
352342
MatchIdx: 0,
353343
RuleIdx: 4,
354344
Source: hr,
345+
Filters: state.Filters{
346+
RequestRedirect: &v1beta1.HTTPRequestRedirectFilter{
347+
Hostname: (*v1beta1.PreciseHostname)(helpers.GetStringPointer("bar.example.com")),
348+
Port: (*v1beta1.PortNumber)(helpers.GetInt32Pointer(8080)),
349+
},
350+
},
355351
},
356352
},
357353
},
@@ -476,95 +472,6 @@ func TestGenerateProxyPass(t *testing.T) {
476472
}
477473
}
478474

479-
func TestFindFirstFilters(t *testing.T) {
480-
oneType := map[v1beta1.HTTPRouteFilterType]struct{}{
481-
v1beta1.HTTPRouteFilterRequestRedirect: {},
482-
}
483-
484-
twoTypes := map[v1beta1.HTTPRouteFilterType]struct{}{
485-
v1beta1.HTTPRouteFilterRequestRedirect: {},
486-
v1beta1.HTTPRouteFilterURLRewrite: {},
487-
}
488-
489-
redirect1 := v1beta1.HTTPRouteFilter{
490-
Type: v1beta1.HTTPRouteFilterRequestRedirect,
491-
RequestRedirect: &v1beta1.HTTPRequestRedirectFilter{
492-
Hostname: (*v1beta1.PreciseHostname)(helpers.GetStringPointer("foo.example.com")),
493-
},
494-
}
495-
redirect2 := v1beta1.HTTPRouteFilter{
496-
Type: v1beta1.HTTPRouteFilterRequestRedirect,
497-
RequestRedirect: &v1beta1.HTTPRequestRedirectFilter{
498-
Hostname: (*v1beta1.PreciseHostname)(helpers.GetStringPointer("bar.example.com")),
499-
},
500-
}
501-
rewrite1 := v1beta1.HTTPRouteFilter{
502-
Type: v1beta1.HTTPRouteFilterURLRewrite,
503-
URLRewrite: &v1beta1.HTTPURLRewriteFilter{
504-
Hostname: (*v1beta1.PreciseHostname)(helpers.GetStringPointer("foo.example.com")),
505-
},
506-
}
507-
rewrite2 := v1beta1.HTTPRouteFilter{
508-
Type: v1beta1.HTTPRouteFilterURLRewrite,
509-
URLRewrite: &v1beta1.HTTPURLRewriteFilter{
510-
Hostname: (*v1beta1.PreciseHostname)(helpers.GetStringPointer("bar.example.com")),
511-
},
512-
}
513-
514-
oneTypeFilters := []v1beta1.HTTPRouteFilter{redirect1, redirect2}
515-
516-
twoTypesFilters := []v1beta1.HTTPRouteFilter{
517-
redirect1,
518-
rewrite1,
519-
rewrite2,
520-
redirect2,
521-
}
522-
523-
tests := []struct {
524-
filters []v1beta1.HTTPRouteFilter
525-
filterTypes map[v1beta1.HTTPRouteFilterType]struct{}
526-
expected map[v1beta1.HTTPRouteFilterType]v1beta1.HTTPRouteFilter
527-
msg string
528-
}{
529-
{
530-
filters: []v1beta1.HTTPRouteFilter{},
531-
filterTypes: twoTypes,
532-
expected: map[v1beta1.HTTPRouteFilterType]v1beta1.HTTPRouteFilter{},
533-
msg: "no filters",
534-
},
535-
{
536-
filters: oneTypeFilters,
537-
filterTypes: oneType,
538-
expected: map[v1beta1.HTTPRouteFilterType]v1beta1.HTTPRouteFilter{
539-
v1beta1.HTTPRouteFilterRequestRedirect: redirect1,
540-
},
541-
msg: "only one type",
542-
},
543-
{
544-
filters: twoTypesFilters,
545-
filterTypes: map[v1beta1.HTTPRouteFilterType]struct{}{},
546-
expected: map[v1beta1.HTTPRouteFilterType]v1beta1.HTTPRouteFilter{},
547-
msg: "no supported type",
548-
},
549-
{
550-
filters: twoTypesFilters,
551-
filterTypes: twoTypes,
552-
expected: map[v1beta1.HTTPRouteFilterType]v1beta1.HTTPRouteFilter{
553-
v1beta1.HTTPRouteFilterRequestRedirect: redirect1,
554-
v1beta1.HTTPRouteFilterURLRewrite: rewrite1,
555-
},
556-
msg: "two types two filters",
557-
},
558-
}
559-
560-
for _, test := range tests {
561-
result := findFirstFilters(test.filters, test.filterTypes)
562-
if diff := cmp.Diff(test.expected, result); diff != "" {
563-
t.Errorf("findFirstFilters() mismatch '%s' (-want +got):\n%s", test.msg, diff)
564-
}
565-
}
566-
}
567-
568475
func TestGenerateReturnValForRedirectFilter(t *testing.T) {
569476
const listenerPort = 123
570477

internal/state/configuration.go

+27-5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ type PathRule struct {
4444
MatchRules []MatchRule
4545
}
4646

47+
// Filters hold the filters for a MatchRule.
48+
type Filters struct {
49+
RequestRedirect *v1beta1.HTTPRequestRedirectFilter
50+
}
51+
4752
// MatchRule represents a routing rule. It corresponds directly to a Match in the HTTPRoute resource.
4853
// An HTTPRoute is guaranteed to have at least one rule with one match.
4954
// If no rule or match is specified by the user, the default rule {{path:{ type: "PathPrefix", value: "/"}}} is set by the schema.
@@ -53,19 +58,18 @@ type MatchRule struct {
5358
// RuleIdx is the index of the corresponding rule in the HTTPRoute.
5459
RuleIdx int
5560
// Source is the corresponding HTTPRoute resource.
61+
// FIXME(pleshakov): Consider referencing only the parts neeeded for the config generation rather than
62+
// the entire resource.
5663
Source *v1beta1.HTTPRoute
64+
// Filters holds the filters for the MatchRule.
65+
Filters Filters
5766
}
5867

5968
// GetMatch returns the HTTPRouteMatch of the Route .
6069
func (r *MatchRule) GetMatch() v1beta1.HTTPRouteMatch {
6170
return r.Source.Spec.Rules[r.RuleIdx].Matches[r.MatchIdx]
6271
}
6372

64-
// GetFilters returns the filters for the MatchRule.
65-
func (r *MatchRule) GetFilters() []v1beta1.HTTPRouteFilter {
66-
return r.Source.Spec.Rules[r.RuleIdx].Filters
67-
}
68-
6973
// buildConfiguration builds the Configuration from the graph.
7074
// FIXME(pleshakov) For now we only handle paths with prefix matches. Handle exact and regex matches
7175
func buildConfiguration(graph *graph) Configuration {
@@ -158,6 +162,8 @@ func (b *virtualServerBuilder) upsertListener(l *listener) {
158162
}
159163

160164
for i, rule := range r.Source.Spec.Rules {
165+
filters := createFilters(rule.Filters)
166+
161167
for _, h := range hostnames {
162168
for j, m := range rule.Matches {
163169
path := getPath(m.Path)
@@ -171,6 +177,7 @@ func (b *virtualServerBuilder) upsertListener(l *listener) {
171177
MatchIdx: j,
172178
RuleIdx: i,
173179
Source: r.Source,
180+
Filters: filters,
174181
})
175182

176183
b.rulesPerHost[h][path] = rule
@@ -246,3 +253,18 @@ func getPath(path *v1beta1.HTTPPathMatch) string {
246253
}
247254
return *path.Value
248255
}
256+
257+
func createFilters(filters []v1beta1.HTTPRouteFilter) Filters {
258+
var result Filters
259+
260+
for _, f := range filters {
261+
switch f.Type {
262+
case v1beta1.HTTPRouteFilterRequestRedirect:
263+
result.RequestRedirect = f.RequestRedirect
264+
// using the first filter
265+
return result
266+
}
267+
}
268+
269+
return result
270+
}

0 commit comments

Comments
 (0)