Skip to content

Commit 82921cb

Browse files
committed
[feat gw-api]support source ip and handle grpc filter
1 parent 9ff2282 commit 82921cb

File tree

10 files changed

+478
-9
lines changed

10 files changed

+478
-9
lines changed

apis/gateway/v1beta1/listenerruleconfig_types.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ type ListenerRuleCondition struct {
5050
// Information for a source IP condition
5151
// +optional
5252
SourceIPConfig *SourceIPConditionConfig `json:"sourceIPConfig,omitempty"`
53+
54+
// Indexes of rule to apply source ip to, identified by ruleIndex and MatchIndex
55+
// If Indexes is not provided, SourceIpConfig will be applied to all conditions under the same HttpRouteRule or GrpcRouteRule where ListenerRuleConfiguration is used
56+
// +optional
57+
Indexes *[]IndexesList `json:"indexes,omitempty"`
58+
}
59+
60+
type IndexesList struct {
61+
// Rule index in a rule array to apply source ip to
62+
// +kubebuilder:default=0
63+
RuleIndex int `json:"ruleIndex,omitempty"`
64+
65+
// Match index in a matches array to apply source ip to
66+
// +kubebuilder:default=0
67+
MatchIndex int `json:"matchIndex,omitempty"`
5368
}
5469

5570
// ActionType defines the type of action for the rule

apis/gateway/v1beta1/zz_generated.deepcopy.go

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/gateway/gateway-crds.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,24 @@ spec:
329329
enum:
330330
- source-ip
331331
type: string
332+
indexes:
333+
description: |-
334+
Indexes of rule to apply source ip to, identified by ruleIndex and MatchIndex
335+
If Indexes is not provided, SourceIpConfig will be applied to all conditions under the same HttpRouteRule or GrpcRouteRule where ListenerRuleConfiguration is used
336+
items:
337+
properties:
338+
matchIndex:
339+
default: 0
340+
description: Match index in a matches array to apply source
341+
ip to
342+
type: integer
343+
ruleIndex:
344+
default: 0
345+
description: Rule index in a rule array to apply source
346+
ip to
347+
type: integer
348+
type: object
349+
type: array
332350
sourceIPConfig:
333351
description: Information for a source IP condition
334352
properties:

config/crd/gateway/gateway.k8s.aws_listenerruleconfigurations.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,24 @@ spec:
330330
enum:
331331
- source-ip
332332
type: string
333+
indexes:
334+
description: |-
335+
Indexes of rule to apply source ip to, identified by ruleIndex and MatchIndex
336+
If Indexes is not provided, SourceIpConfig will be applied to all conditions under the same HttpRouteRule or GrpcRouteRule where ListenerRuleConfiguration is used
337+
items:
338+
properties:
339+
matchIndex:
340+
default: 0
341+
description: Match index in a matches array to apply source
342+
ip to
343+
type: integer
344+
ruleIndex:
345+
default: 0
346+
description: Rule index in a rule array to apply source
347+
ip to
348+
type: integer
349+
type: object
350+
type: array
333351
sourceIPConfig:
334352
description: Information for a source IP condition
335353
properties:

helm/aws-load-balancer-controller/crds/gateway-crds.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,24 @@ spec:
329329
enum:
330330
- source-ip
331331
type: string
332+
indexes:
333+
description: |-
334+
Indexes of rule to apply source ip to, identified by ruleIndex and MatchIndex
335+
If Indexes is not provided, SourceIpConfig will be applied to all conditions under the same HttpRouteRule or GrpcRouteRule where ListenerRuleConfiguration is used
336+
items:
337+
properties:
338+
matchIndex:
339+
default: 0
340+
description: Match index in a matches array to apply source
341+
ip to
342+
type: integer
343+
ruleIndex:
344+
default: 0
345+
description: Rule index in a rule array to apply source
346+
ip to
347+
type: integer
348+
type: object
349+
type: array
332350
sourceIPConfig:
333351
description: Information for a source IP condition
334352
properties:

pkg/gateway/model/model_build_listener.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ package model
33
import (
44
"context"
55
"fmt"
6-
"sigs.k8s.io/aws-load-balancer-controller/pkg/networking"
7-
"sigs.k8s.io/aws-load-balancer-controller/pkg/shared_utils"
86
"strconv"
97
"strings"
108

9+
"sigs.k8s.io/aws-load-balancer-controller/pkg/networking"
10+
"sigs.k8s.io/aws-load-balancer-controller/pkg/shared_utils"
11+
1112
awssdk "github.com/aws/aws-sdk-go-v2/aws"
1213
"github.com/go-logr/logr"
1314
"github.com/pkg/errors"
@@ -190,7 +191,7 @@ func (l listenerBuilderImpl) buildListenerRules(stack core.Stack, ls *elbv2model
190191
route := ruleWithPrecedence.CommonRulePrecedence.RouteDescriptor
191192
rule := ruleWithPrecedence.CommonRulePrecedence.Rule
192193

193-
// Build Rule Conditions
194+
// Build Rule Conditions based on GRPCRouteMatch and HTTPRouteMatch
194195
var conditionsList []elbv2model.RuleCondition
195196
var err error
196197
switch route.GetRouteKind() {
@@ -203,6 +204,9 @@ func (l listenerBuilderImpl) buildListenerRules(stack core.Stack, ls *elbv2model
203204
return err
204205
}
205206

207+
// Add Rule Source-IP Conditions based on ListenerRuleConfiguration CRD
208+
conditionsList = routeutils.BuildSourceIpInCondition(ruleWithPrecedence, conditionsList)
209+
206210
// set up for building routing actions
207211
var actions []elbv2model.Action
208212
var preRoutingAction *elbv2gw.Action

pkg/gateway/routeutils/route_rule_action.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ package routeutils
22

33
import (
44
"fmt"
5+
"strconv"
6+
"strings"
7+
58
awssdk "github.com/aws/aws-sdk-go-v2/aws"
69
"github.com/pkg/errors"
710
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
811
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
912
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
10-
"strconv"
11-
"strings"
1213
)
1314

1415
// BuildRulePreRoutingActions returns pre-routing action for rule
@@ -103,6 +104,9 @@ func buildForwardRoutingAction(routingAction *elbv2gw.Action, targetGroupTuples
103104
return nil, nil
104105
}
105106

107+
// buildRedirectRoutingAction
108+
// For HTTPRoute: handle RequestRedirect from HTTPRouteFilterType
109+
// For GRPCRoute: do not support any filter type other than ExtensionRef, which can be used to refer a listener rule configuration CRD
106110
func buildRedirectRoutingAction(rule RouteRule, route RouteDescriptor, routingAction *elbv2gw.Action) (*elbv2model.Action, error) {
107111
switch route.GetRouteKind() {
108112
case HTTPRouteKind:
@@ -118,7 +122,16 @@ func buildRedirectRoutingAction(rule RouteRule, route RouteDescriptor, routingAc
118122
}
119123
return redirectActions, nil
120124
}
121-
// TODO: add case for GRPC
125+
case GRPCRouteKind:
126+
grpcRule := rule.GetRawRouteRule().(*gwv1.GRPCRouteRule)
127+
for _, filter := range grpcRule.Filters {
128+
switch filter.Type {
129+
case gwv1.GRPCRouteFilterExtensionRef:
130+
continue
131+
default:
132+
return nil, errors.Errorf("Unsupported filter type: %v. To specify header modification, please configure it through LoadBalancerConfiguration.", filter.Type)
133+
}
134+
}
122135
}
123136
return nil, nil
124137
}

pkg/gateway/routeutils/route_rule_condition.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"strings"
66

77
"github.com/pkg/errors"
8+
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
89
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
910
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
1011
)
@@ -234,6 +235,55 @@ func buildGrpcMethodCondition(method *gwv1.GRPCMethodMatch) ([]elbv2model.RuleCo
234235
}, nil
235236
}
236237

238+
func buildSourceIpCondition(condition elbv2gw.ListenerRuleCondition) []elbv2model.RuleCondition {
239+
return []elbv2model.RuleCondition{
240+
{
241+
Field: elbv2model.RuleConditionField(condition.Field),
242+
SourceIPConfig: &elbv2model.SourceIPConditionConfig{
243+
Values: condition.SourceIPConfig.Values,
244+
},
245+
},
246+
}
247+
}
248+
249+
// getRoutingConditions: returns routing conditions from listener rule configuration
250+
func getRoutingConditions(config *elbv2gw.ListenerRuleConfiguration) []elbv2gw.ListenerRuleCondition {
251+
conditions := make([]elbv2gw.ListenerRuleCondition, 0)
252+
if config != nil && config.Spec.Conditions != nil {
253+
for _, condition := range config.Spec.Conditions {
254+
conditions = append(conditions, condition)
255+
}
256+
return conditions
257+
}
258+
return nil
259+
}
260+
261+
// BuildSourceIpInCondition : takes source ip configuration from listener rule configuration CRD, then AND it to condition list
262+
func BuildSourceIpInCondition(ruleWithPrecedence RulePrecedence, conditionsList []elbv2model.RuleCondition) []elbv2model.RuleCondition {
263+
rule := ruleWithPrecedence.CommonRulePrecedence.Rule
264+
ruleIndex := ruleWithPrecedence.CommonRulePrecedence.RuleIndexInRoute
265+
matchIndex := ruleWithPrecedence.CommonRulePrecedence.MatchIndexInRule
266+
if rule.GetListenerRuleConfig() != nil {
267+
conditionsFromRuleConfig := getRoutingConditions(rule.GetListenerRuleConfig())
268+
for _, condition := range conditionsFromRuleConfig {
269+
switch condition.Field {
270+
case elbv2gw.ListenerRuleConditionFieldSourceIP:
271+
sourceIpCondition := buildSourceIpCondition(condition)
272+
if condition.Indexes == nil {
273+
conditionsList = append(conditionsList, sourceIpCondition...)
274+
} else {
275+
for _, index := range *condition.Indexes {
276+
if index.RuleIndex == ruleIndex && index.MatchIndex == matchIndex {
277+
conditionsList = append(conditionsList, sourceIpCondition...)
278+
}
279+
}
280+
}
281+
}
282+
}
283+
}
284+
return conditionsList
285+
}
286+
237287
// generateValuesFromMatchHeaderValue takes in header value from route match
238288
// returns list of values
239289
// for a given HTTPHeaderName/GRPCHeaderName, ALB rule can accept a list of values. However, gateway route headers only accept one value per name, and name cannot duplicate.

0 commit comments

Comments
 (0)