Skip to content

Commit 52fd8f8

Browse files
committed
implementation
Signed-off-by: Huabing Zhao <zhaohuabing@gmail.com>
1 parent 057f003 commit 52fd8f8

13 files changed

Lines changed: 565 additions & 15 deletions

internal/gatewayapi/filters.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,28 @@ func (t *Translator) processExtensionRefHTTPFilter(extFilter *gwapiv1.LocalObjec
886886
hm = &ir.HTTPHostModifier{
887887
Backend: new(true),
888888
}
889+
case egv1a1.PathRegexHTTPHostnameModifier:
890+
if hrf.Spec.URLRewrite.Hostname.PathRegex == nil ||
891+
hrf.Spec.URLRewrite.Hostname.PathRegex.Pattern == "" ||
892+
hrf.Spec.URLRewrite.Hostname.PathRegex.Substitution == "" {
893+
return status.NewRouteStatusError(
894+
errors.New("PathRegex Pattern and Substitution must be set when rewrite hostname type is \"PathRegex\""),
895+
gwapiv1.RouteReasonUnsupportedValue,
896+
).WithType(gwapiv1.RouteConditionAccepted)
897+
} else if _, err := regexp.Compile(hrf.Spec.URLRewrite.Hostname.PathRegex.Pattern); err != nil {
898+
// Avoid envoy NACKs due to invalid regex.
899+
// Golang's regexp is almost identical to RE2: https://pkg.go.dev/regexp/syntax
900+
return status.NewRouteStatusError(
901+
errors.New("PathRegex must be a valid RE2 regular expression"),
902+
gwapiv1.RouteReasonUnsupportedValue,
903+
).WithType(gwapiv1.RouteConditionAccepted)
904+
}
905+
hm = &ir.HTTPHostModifier{
906+
PathRegex: &ir.RegexMatchReplace{
907+
Pattern: hrf.Spec.URLRewrite.Hostname.PathRegex.Pattern,
908+
Substitution: hrf.Spec.URLRewrite.Hostname.PathRegex.Substitution,
909+
},
910+
}
889911
}
890912

891913
if filterContext.URLRewrite != nil {

internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.in.yaml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,56 @@ httpRoutes:
186186
group: gateway.envoyproxy.io
187187
kind: HTTPRouteFilter
188188
name: valid-header
189+
- apiVersion: gateway.networking.k8s.io/v1
190+
kind: HTTPRoute
191+
metadata:
192+
namespace: default
193+
name: httproute-missing-path-regex
194+
spec:
195+
hostnames:
196+
- gateway.envoyproxy.io
197+
parentRefs:
198+
- namespace: envoy-gateway
199+
name: gateway-1
200+
sectionName: http
201+
rules:
202+
- matches:
203+
- path:
204+
value: "/missing-path-regex"
205+
backendRefs:
206+
- name: service-1
207+
port: 8080
208+
filters:
209+
- type: ExtensionRef
210+
extensionRef:
211+
group: gateway.envoyproxy.io
212+
kind: HTTPRouteFilter
213+
name: missing-path-regex
214+
- apiVersion: gateway.networking.k8s.io/v1
215+
kind: HTTPRoute
216+
metadata:
217+
namespace: default
218+
name: httproute-invalid-path-regex
219+
spec:
220+
hostnames:
221+
- gateway.envoyproxy.io
222+
parentRefs:
223+
- namespace: envoy-gateway
224+
name: gateway-1
225+
sectionName: http
226+
rules:
227+
- matches:
228+
- path:
229+
value: "/invalid-path-regex"
230+
backendRefs:
231+
- name: service-1
232+
port: 8080
233+
filters:
234+
- type: ExtensionRef
235+
extensionRef:
236+
group: gateway.envoyproxy.io
237+
kind: HTTPRouteFilter
238+
name: invalid-path-regex
189239
httpFilters:
190240
- apiVersion: gateway.envoyproxy.io/v1alpha1
191241
kind: HTTPRouteFilter
@@ -196,6 +246,27 @@ httpFilters:
196246
urlRewrite:
197247
hostname:
198248
type: Header
249+
- apiVersion: gateway.envoyproxy.io/v1alpha1
250+
kind: HTTPRouteFilter
251+
metadata:
252+
name: missing-path-regex
253+
namespace: default
254+
spec:
255+
urlRewrite:
256+
hostname:
257+
type: PathRegex
258+
- apiVersion: gateway.envoyproxy.io/v1alpha1
259+
kind: HTTPRouteFilter
260+
metadata:
261+
name: invalid-path-regex
262+
namespace: default
263+
spec:
264+
urlRewrite:
265+
hostname:
266+
type: PathRegex
267+
pathRegex:
268+
pattern: '"([a-z]+)"*+?'
269+
substitution: "backend-\\1.service.namespace.svc.cluster.local"
199270
header: my-host
200271
- apiVersion: gateway.envoyproxy.io/v1alpha1
201272
kind: HTTPRouteFilter

internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.out.yaml

Lines changed: 121 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ gateways:
1616
protocol: HTTP
1717
status:
1818
listeners:
19-
- attachedRoutes: 6
19+
- attachedRoutes: 8
2020
conditions:
2121
- lastTransitionTime: null
2222
message: Sending translated listener configuration to the data plane
@@ -115,7 +115,7 @@ httpRoutes:
115115
parents:
116116
- conditions:
117117
- lastTransitionTime: null
118-
message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule.
118+
message: Header must be set when rewrite path type is "Header".
119119
reason: UnsupportedValue
120120
status: "False"
121121
type: Accepted
@@ -209,7 +209,7 @@ httpRoutes:
209209
parents:
210210
- conditions:
211211
- lastTransitionTime: null
212-
message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule.
212+
message: Header must be set when rewrite path type is "Header".
213213
reason: UnsupportedValue
214214
status: "False"
215215
type: Accepted
@@ -305,7 +305,96 @@ httpRoutes:
305305
parents:
306306
- conditions:
307307
- lastTransitionTime: null
308-
message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule.
308+
message: |-
309+
Header must be set when rewrite path type is "Header".
310+
Header must be set when rewrite path type is "Header".
311+
reason: UnsupportedValue
312+
status: "False"
313+
type: Accepted
314+
- lastTransitionTime: null
315+
message: Resolved all the Object references for the Route
316+
reason: ResolvedRefs
317+
status: "True"
318+
type: ResolvedRefs
319+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
320+
parentRef:
321+
name: gateway-1
322+
namespace: envoy-gateway
323+
sectionName: http
324+
- apiVersion: gateway.networking.k8s.io/v1
325+
kind: HTTPRoute
326+
metadata:
327+
name: httproute-missing-path-regex
328+
namespace: default
329+
spec:
330+
hostnames:
331+
- gateway.envoyproxy.io
332+
parentRefs:
333+
- name: gateway-1
334+
namespace: envoy-gateway
335+
sectionName: http
336+
rules:
337+
- backendRefs:
338+
- name: service-1
339+
port: 8080
340+
filters:
341+
- extensionRef:
342+
group: gateway.envoyproxy.io
343+
kind: HTTPRouteFilter
344+
name: missing-path-regex
345+
type: ExtensionRef
346+
matches:
347+
- path:
348+
value: /missing-path-regex
349+
status:
350+
parents:
351+
- conditions:
352+
- lastTransitionTime: null
353+
message: PathRegex Pattern and Substitution must be set when rewrite hostname
354+
type is "PathRegex".
355+
reason: UnsupportedValue
356+
status: "False"
357+
type: Accepted
358+
- lastTransitionTime: null
359+
message: Resolved all the Object references for the Route
360+
reason: ResolvedRefs
361+
status: "True"
362+
type: ResolvedRefs
363+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
364+
parentRef:
365+
name: gateway-1
366+
namespace: envoy-gateway
367+
sectionName: http
368+
- apiVersion: gateway.networking.k8s.io/v1
369+
kind: HTTPRoute
370+
metadata:
371+
name: httproute-invalid-path-regex
372+
namespace: default
373+
spec:
374+
hostnames:
375+
- gateway.envoyproxy.io
376+
parentRefs:
377+
- name: gateway-1
378+
namespace: envoy-gateway
379+
sectionName: http
380+
rules:
381+
- backendRefs:
382+
- name: service-1
383+
port: 8080
384+
filters:
385+
- extensionRef:
386+
group: gateway.envoyproxy.io
387+
kind: HTTPRouteFilter
388+
name: invalid-path-regex
389+
type: ExtensionRef
390+
matches:
391+
- path:
392+
value: /invalid-path-regex
393+
status:
394+
parents:
395+
- conditions:
396+
- lastTransitionTime: null
397+
message: PathRegex must be a valid RE2 regular expression.
309398
reason: UnsupportedValue
310399
status: "False"
311400
type: Accepted
@@ -393,9 +482,32 @@ xdsIR:
393482
distinct: false
394483
name: ""
395484
prefix: /header-and-backend
396-
urlRewrite:
397-
host:
398-
header: my-host
485+
- directResponse:
486+
statusCode: 500
487+
hostname: gateway.envoyproxy.io
488+
isHTTP2: false
489+
metadata:
490+
kind: HTTPRoute
491+
name: httproute-missing-path-regex
492+
namespace: default
493+
name: httproute/default/httproute-missing-path-regex/rule/0/match/0/gateway_envoyproxy_io
494+
pathMatch:
495+
distinct: false
496+
name: ""
497+
prefix: /missing-path-regex
498+
- directResponse:
499+
statusCode: 500
500+
hostname: gateway.envoyproxy.io
501+
isHTTP2: false
502+
metadata:
503+
kind: HTTPRoute
504+
name: httproute-invalid-path-regex
505+
namespace: default
506+
name: httproute/default/httproute-invalid-path-regex/rule/0/match/0/gateway_envoyproxy_io
507+
pathMatch:
508+
distinct: false
509+
name: ""
510+
prefix: /invalid-path-regex
399511
- directResponse:
400512
statusCode: 500
401513
hostname: gateway.envoyproxy.io
@@ -456,7 +568,7 @@ xdsIR:
456568
prefix: /two-headers
457569
urlRewrite:
458570
host:
459-
header: my-host
571+
header: my-host2
460572
- directResponse:
461573
statusCode: 500
462574
hostname: gateway.envoyproxy.io
@@ -472,7 +584,7 @@ xdsIR:
472584
prefix: /ext-first
473585
urlRewrite:
474586
host:
475-
header: my-host
587+
name: rewrite.com
476588
readyListener:
477589
address: 0.0.0.0
478590
ipFamily: IPv4

internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter.in.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,31 @@ httpRoutes:
161161
group: gateway.envoyproxy.io
162162
kind: HTTPRouteFilter
163163
name: not-found-filter
164+
- apiVersion: gateway.networking.k8s.io/v1
165+
kind: HTTPRoute
166+
metadata:
167+
namespace: default
168+
name: httproute-6
169+
spec:
170+
hostnames:
171+
- gateway.envoyproxy.io
172+
parentRefs:
173+
- namespace: envoy-gateway
174+
name: gateway-1
175+
sectionName: http
176+
rules:
177+
- matches:
178+
- path:
179+
value: "/node"
180+
backendRefs:
181+
- name: service-1
182+
port: 8080
183+
filters:
184+
- type: ExtensionRef
185+
extensionRef:
186+
group: gateway.envoyproxy.io
187+
kind: HTTPRouteFilter
188+
name: valid-path-regex
164189
httpFilters:
165190
- apiVersion: gateway.envoyproxy.io/v1alpha1
166191
kind: HTTPRouteFilter
@@ -181,3 +206,15 @@ httpFilters:
181206
urlRewrite:
182207
hostname:
183208
type: Backend
209+
- apiVersion: gateway.envoyproxy.io/v1alpha1
210+
kind: HTTPRouteFilter
211+
metadata:
212+
name: valid-path-regex
213+
namespace: default
214+
spec:
215+
urlRewrite:
216+
hostname:
217+
type: PathRegex
218+
pathRegex:
219+
pattern: "^/node/([0-9]+)/api.*"
220+
substitution: "backend-\\1.service.namespace.svc.cluster.local"

0 commit comments

Comments
 (0)