Skip to content

Commit

Permalink
api: host header rewrite
Browse files Browse the repository at this point in the history
Signed-off-by: Guy Daich <guy.daich@sap.com>
  • Loading branch information
guydc committed Oct 8, 2024
1 parent 0f4cb27 commit 1200c13
Show file tree
Hide file tree
Showing 6 changed files with 249 additions and 0 deletions.
35 changes: 35 additions & 0 deletions api/v1alpha1/httproutefilter_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ type HTTPRouteFilterSpec struct {

// HTTPURLRewriteFilter define rewrites of HTTP URL components such as path and host
type HTTPURLRewriteFilter struct {
// Hostname is the value to be used to replace the Host header value during
// forwarding.
//
// Support: Extended
//
// +optional
Hostname *HTTPHostnameModifier `json:"hostname,omitempty"`
// Path defines a path rewrite.
//
// +optional
Expand All @@ -53,6 +60,14 @@ const (
RegexHTTPPathModifier HTTPPathModifierType = "ReplaceRegexMatch"
)

// HTTPPathModifierType defines the type of Hostname rewrite.
type HTTPHostnameModifierType string

const (
HeaderHTTPHostnameModifier HTTPHostnameModifierType = "SetFromHeader"
BackendHTTPHostnameModifier HTTPHostnameModifierType = "SetFromBackend"
)

type ReplaceRegexMatch struct {
// Pattern matches a regular expression against the value of the HTTP Path.The regex string must
// adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax.
Expand Down Expand Up @@ -91,6 +106,26 @@ type HTTPPathModifier struct {
ReplaceRegexMatch *ReplaceRegexMatch `json:"replaceRegexMatch,omitempty"`
}

// +kubebuilder:validation:XValidation:message="setFromHeader must be nil if the type is not SetFromHeader",rule="!(has(self.setFromHeader) && self.type != 'SetFromHeader')"
// +kubebuilder:validation:XValidation:message="setFromHeader must be specified for SetFromHeader type",rule="!(!has(self.setFromHeader) && self.type == 'SetFromHeader')"
// +kubebuilder:validation:XValidation:message="setFromBackend must be nil if the type is not SetFromBackend",rule="!(has(self.setFromBackend) && self.type != 'SetFromBackend')"
// +kubebuilder:validation:XValidation:message="setFromBackend must be specified for SetFromBackend type",rule="!(!has(self.setFromBackend) && self.type == 'SetFromBackend')"
type HTTPHostnameModifier struct {
// +kubebuilder:validation:Enum=SetFromHeader;SetFromBackend
// +kubebuilder:validation:Required
Type HTTPHostnameModifierType `json:"type"`

// SetFromHeader indicates that the Host header value would be replaced with the value of the header specified in setFromHeader.
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header
// +optional
SetFromHeader *string `json:"setFromHeader,omitempty"`

// SetFromBackend indicates that the Host header value would be replaced by the DNS name of the backend if it exists.
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite
// +optional
SetFromBackend *bool `json:"setFromBackend,omitempty"`
}

//+kubebuilder:object:root=true

// HTTPRouteFilterList contains a list of HTTPRouteFilter resources.
Expand Down
30 changes: 30 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,43 @@ spec:
description: HTTPURLRewriteFilter define rewrites of HTTP URL components
such as path and host
properties:
hostname:
description: |-
Hostname is the value to be used to replace the Host header value during
forwarding.
Support: Extended
properties:
setFromBackend:
description: |-
SetFromBackend indicates that the Host header value would be replaced by the DNS name of the backend if it exists.
https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite
type: boolean
setFromHeader:
description: |-
SetFromHeader indicates that the Host header value would be replaced with the value of the header specified in setFromHeader.
https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header
type: string
type:
description: HTTPPathModifierType defines the type of Hostname
rewrite.
enum:
- SetFromHeader
- SetFromBackend
type: string
required:
- type
type: object
x-kubernetes-validations:
- message: setFromHeader must be nil if the type is not SetFromHeader
rule: '!(has(self.setFromHeader) && self.type != ''SetFromHeader'')'
- message: setFromHeader must be specified for SetFromHeader type
rule: '!(!has(self.setFromHeader) && self.type == ''SetFromHeader'')'
- message: setFromBackend must be nil if the type is not SetFromBackend
rule: '!(has(self.setFromBackend) && self.type != ''SetFromBackend'')'
- message: setFromBackend must be specified for SetFromBackend
type
rule: '!(!has(self.setFromBackend) && self.type == ''SetFromBackend'')'
path:
description: Path defines a path rewrite.
properties:
Expand Down
32 changes: 32 additions & 0 deletions site/content/en/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -1938,6 +1938,37 @@ _Appears in:_
| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added<br />to the original client request before sending it to the backend server.<br />Note that coexisting headers will be overridden.<br />If not specified, no authorization response headers will be added to the<br />original client request. |


#### HTTPHostnameModifier





_Appears in:_
- [HTTPURLRewriteFilter](#httpurlrewritefilter)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | _[HTTPHostnameModifierType](#httphostnamemodifiertype)_ | true | |
| `setFromHeader` | _string_ | false | SetFromHeader indicates that the Host header value would be replaced with the value of the header specified in setFromHeader.<br />https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header |
| `setFromBackend` | _boolean_ | false | SetFromBackend indicates that the Host header value would be replaced by the DNS name of the backend if it exists.<br />https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite |


#### HTTPHostnameModifierType

_Underlying type:_ _string_

HTTPPathModifierType defines the type of Hostname rewrite.

_Appears in:_
- [HTTPHostnameModifier](#httphostnamemodifier)

| Value | Description |
| ----- | ----------- |
| `SetFromHeader` | |
| `SetFromBackend` | |


#### HTTPPathModifier


Expand Down Expand Up @@ -2053,6 +2084,7 @@ _Appears in:_

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `hostname` | _[HTTPHostnameModifier](#httphostnamemodifier)_ | false | Hostname is the value to be used to replace the Host header value during<br />forwarding.<br /><br />Support: Extended |
| `path` | _[HTTPPathModifier](#httppathmodifier)_ | false | Path defines a path rewrite. |


Expand Down
32 changes: 32 additions & 0 deletions site/content/zh/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -1938,6 +1938,37 @@ _Appears in:_
| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added<br />to the original client request before sending it to the backend server.<br />Note that coexisting headers will be overridden.<br />If not specified, no authorization response headers will be added to the<br />original client request. |


#### HTTPHostnameModifier





_Appears in:_
- [HTTPURLRewriteFilter](#httpurlrewritefilter)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | _[HTTPHostnameModifierType](#httphostnamemodifiertype)_ | true | |
| `setFromHeader` | _string_ | false | SetFromHeader indicates that the Host header value would be replaced with the value of the header specified in setFromHeader.<br />https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header |
| `setFromBackend` | _boolean_ | false | SetFromBackend indicates that the Host header value would be replaced by the DNS name of the backend if it exists.<br />https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite |


#### HTTPHostnameModifierType

_Underlying type:_ _string_

HTTPPathModifierType defines the type of Hostname rewrite.

_Appears in:_
- [HTTPHostnameModifier](#httphostnamemodifier)

| Value | Description |
| ----- | ----------- |
| `SetFromHeader` | |
| `SetFromBackend` | |


#### HTTPPathModifier


Expand Down Expand Up @@ -2053,6 +2084,7 @@ _Appears in:_

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `hostname` | _[HTTPHostnameModifier](#httphostnamemodifier)_ | false | Hostname is the value to be used to replace the Host header value during<br />forwarding.<br /><br />Support: Extended |
| `path` | _[HTTPPathModifier](#httppathmodifier)_ | false | Path defines a path rewrite. |


Expand Down
83 changes: 83 additions & 0 deletions test/cel-validation/httproutefilter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"

egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)
Expand Down Expand Up @@ -85,6 +86,88 @@ func TestHTTPRouteFilter(t *testing.T) {
"spec.urlRewrite.path.replaceRegexMatch.pattern: Invalid value: \"\": spec.urlRewrite.path.replaceRegexMatch.pattern in body should be at least 1 chars long",
},
},
{
desc: "Valid SetFromHeader",
mutate: func(httproutefilter *egv1a1.HTTPRouteFilter) {
httproutefilter.Spec = egv1a1.HTTPRouteFilterSpec{
URLRewrite: &egv1a1.HTTPURLRewriteFilter{
Hostname: &egv1a1.HTTPHostnameModifier{
Type: egv1a1.HeaderHTTPHostnameModifier,
SetFromHeader: ptr.To("foo"),
},
},
}
},
wantErrors: []string{},
},
{
desc: "Valid SetFromBackend",
mutate: func(httproutefilter *egv1a1.HTTPRouteFilter) {
httproutefilter.Spec = egv1a1.HTTPRouteFilterSpec{
URLRewrite: &egv1a1.HTTPURLRewriteFilter{
Hostname: &egv1a1.HTTPHostnameModifier{
Type: egv1a1.BackendHTTPHostnameModifier,
SetFromBackend: ptr.To(true),
},
},
}
},
wantErrors: []string{},
},
{
desc: "invalid SetFromHeader missing settings",
mutate: func(httproutefilter *egv1a1.HTTPRouteFilter) {
httproutefilter.Spec = egv1a1.HTTPRouteFilterSpec{
URLRewrite: &egv1a1.HTTPURLRewriteFilter{
Hostname: &egv1a1.HTTPHostnameModifier{
Type: egv1a1.HeaderHTTPHostnameModifier,
},
},
}
},
wantErrors: []string{"spec.urlRewrite.hostname: Invalid value: \"object\": setFromHeader must be specified for SetFromHeader type"},
},
{
desc: "invalid SetFromBackend missing settings",
mutate: func(httproutefilter *egv1a1.HTTPRouteFilter) {
httproutefilter.Spec = egv1a1.HTTPRouteFilterSpec{
URLRewrite: &egv1a1.HTTPURLRewriteFilter{
Hostname: &egv1a1.HTTPHostnameModifier{
Type: egv1a1.BackendHTTPHostnameModifier,
},
},
}
},
wantErrors: []string{"spec.urlRewrite.hostname: Invalid value: \"object\": setFromBackend must be specified for SetFromBackend type"},
},
{
desc: "invalid SetFromBackend type",
mutate: func(httproutefilter *egv1a1.HTTPRouteFilter) {
httproutefilter.Spec = egv1a1.HTTPRouteFilterSpec{
URLRewrite: &egv1a1.HTTPURLRewriteFilter{
Hostname: &egv1a1.HTTPHostnameModifier{
Type: egv1a1.BackendHTTPHostnameModifier,
SetFromHeader: ptr.To("foo"),
},
},
}
},
wantErrors: []string{"spec.urlRewrite.hostname: Invalid value: \"object\": setFromHeader must be nil if the type is not SetFromHeader, spec.urlRewrite.hostname: Invalid value: \"object\": setFromBackend must be specified for SetFromBackend type"},
},
{
desc: "invalid SetFromHeader type",
mutate: func(httproutefilter *egv1a1.HTTPRouteFilter) {
httproutefilter.Spec = egv1a1.HTTPRouteFilterSpec{
URLRewrite: &egv1a1.HTTPURLRewriteFilter{
Hostname: &egv1a1.HTTPHostnameModifier{
Type: egv1a1.HeaderHTTPHostnameModifier,
SetFromBackend: ptr.To(true),
},
},
}
},
wantErrors: []string{"spec.urlRewrite.hostname: Invalid value: \"object\": setFromHeader must be specified for SetFromHeader type, spec.urlRewrite.hostname: Invalid value: \"object\": setFromBackend must be nil if the type is not SetFromBackend]"},
},
}

for _, tc := range cases {
Expand Down

0 comments on commit 1200c13

Please sign in to comment.