Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kuma-cp) add GatewayRoute route generation #2782

Merged
merged 1 commit into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 40 additions & 36 deletions api/mesh/v1alpha1/gateway_route.pb.go

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

10 changes: 7 additions & 3 deletions api/mesh/v1alpha1/gateway_route.proto
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,16 @@ message GatewayRoute {

// Filters are request processing steps that are applied to
// matched requests.
//
// If the redirect filter is specified, it must be the only
// filter given.
repeated Filter filters = 2;

// Backends is the set of services to which the gateway will
// forward requests.
repeated Backend backends = 3
[ (doc.required) = true, (validate.rules).repeated .min_items = 1 ];
// forward requests. If a redirect filter is specified, no
// backends are allowed. Otherwise, at least one backend
// must be given.
repeated Backend backends = 3 [ (doc.required) = false ];
};

// Hostnames lists the server names for which this route is valid. The
Expand Down
30 changes: 26 additions & 4 deletions pkg/core/resources/apis/mesh/gateway_route_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,46 @@ func validateGatewayRouteHTTPRule(
path validators.PathBuilder,
conf *mesh_proto.GatewayRoute_HttpRoute_Rule,
) validators.ValidationError {
var hasRedirect bool

if len(conf.GetMatches()) < 1 {
return validators.MakeRequiredFieldErr(path.Field("matches"))
}

if len(conf.GetBackends()) < 1 {
return validators.MakeRequiredFieldErr(path.Field("backends"))
}

var err validators.ValidationError

for i, m := range conf.GetMatches() {
err.Add(validateGatewayRouteHTTPMatch(path.Field("matches").Index(i), m))
}

for i, f := range conf.GetFilters() {
if f.GetRedirect() != nil {
hasRedirect = true
}

err.Add(validateGatewayRouteHTTPFilter(path.Field("filters").Index(i), f))
}

// It doesn't make sense to redirect and also mirror or rewrite request headers.
if hasRedirect && len(conf.GetFilters()) != 1 {
err.AddViolationAt(path.Field("filters"), "redirects cannot be used with other filters")

// Return since the redirect filter error makes the backend length check ambiguous.
return err
}

switch len(conf.GetBackends()) {
case 0:
// Redirection doesn't forward, so there must not be any backend.
if !hasRedirect {
err.AddViolationAt(path.Field("backends"), "cannot be empty")
}
default:
if hasRedirect {
err.AddViolationAt(path.Field("backends"), "must be empty when using redirect filters")
}
}

for i, b := range conf.GetBackends() {
err.Add(validateGatewayRouteBackend(path.Field("backends").Index(i), b))
}
Expand Down
122 changes: 97 additions & 25 deletions pkg/core/resources/apis/mesh/gateway_route_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func (g GatewayRouteGenerator) New() model.Resource {

var _ = Describe("GatewayRoute", func() {
DescribeValidCases(GatewayRouteGenerator(NewGatewayRouteResource),

Entry("HTTP route", `
type: GatewayRoute
name: route
Expand Down Expand Up @@ -53,19 +54,18 @@ conf:
value: kong
filters:
- request_header:
set:
- name: x-foo
value: foo
add:
- name: x-added
value: added
remove:
- x-deleted
- redirect:
scheme: http
hostname: foo.example.com
port: 80
status_code: 307
set:
- name: x-foo
value: foo
- name: x-foo
value: foo
add:
- name: x-added
value: added
- name: x-added
value: added
remove:
- x-deleted
- mirror:
percentage: 1.12
backend:
Expand All @@ -78,6 +78,41 @@ conf:
- weight: 5
destination:
kuma.io/service: target-2
`),
Entry("HTTP redirect", `
type: GatewayRoute
name: route
mesh: default
selectors:
- match:
kuma.io/service: gateway
conf:
http:
hostnames:
- foo.example.com
rules:
- matches:
- method: GET
path:
match: EXACT
value: /
headers:
- match: EXACT
name: x-foo
value: "my great foo"
- match: REGEX
name: x-count
value: "[0-9]+"
query_parameters:
- match: EXACT
name: customer
value: kong
filters:
- redirect:
scheme: http
hostname: foo.example.com
port: 80
status_code: 307
`),
)

Expand Down Expand Up @@ -496,10 +531,6 @@ conf:
- redirect:
hostname: example.com
status_code: 301
backends:
- weight: 5
destination:
kuma.io/service: target-2
`),
ErrorCase("redirect filter with empty hostname", validators.Violation{
Field: "conf.http.rules[0].filters[0].redirect.hostname",
Expand All @@ -521,10 +552,6 @@ conf:
- redirect:
scheme: https
status_code: 301
backends:
- weight: 5
destination:
kuma.io/service: target-2
`),
ErrorCase("redirect filter with invalid port", validators.Violation{
Field: "conf.http.rules[0].filters[0].redirect.port",
Expand All @@ -548,10 +575,6 @@ conf:
hostname: example.com
port: 128555
status_code: 301
backends:
- weight: 5
destination:
kuma.io/service: target-2
`),
ErrorCase("redirect filter with invalid status", validators.Violation{
Field: "conf.http.rules[0].filters[0].redirect.status_code",
Expand All @@ -574,10 +597,59 @@ conf:
scheme: https
hostname: example.com
status_code: 500
`),
ErrorCase("redirect filter with backend routes", validators.Violation{
Field: "conf.http.rules[0].backends",
Message: "must be empty when using redirect filters",
}, `
type: GatewayRoute
name: route
mesh: default
selectors:
- match:
kuma.io/service: gateway
conf:
http:
rules:
- matches:
- path:
value: /
filters:
- redirect:
scheme: https
hostname: example.com
status_code: 300
backends:
- weight: 5
destination:
kuma.io/service: target-2
`),
ErrorCase("redirect prevents other filters", validators.Violation{
Field: "conf.http.rules[0].filters",
Message: "redirects cannot be used with other filters",
}, `
type: GatewayRoute
name: route
mesh: default
selectors:
- match:
kuma.io/service: gateway
conf:
http:
rules:
- matches:
- path:
value: /
filters:
- redirect:
scheme: https
hostname: example.com
status_code: 300
- mirror:
backends:
- weight: 5
destination:
kuma.io/service: target-2
`),
)
})
Loading