Skip to content

Commit 04e8e9b

Browse files
authored
[feat gw-api]support source ip and handle grpc filter (#4335)
[feat gw-api]update how source ip is suppported [feat gw-api]add e2e test for source ip handle rebase conflicts
1 parent 03e754b commit 04e8e9b

File tree

13 files changed

+761
-15
lines changed

13 files changed

+761
-15
lines changed

apis/gateway/v1beta1/listenerruleconfig_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ type ListenerRuleCondition struct {
5050
// Information for a source IP condition
5151
// +optional
5252
SourceIPConfig *SourceIPConditionConfig `json:"sourceIPConfig,omitempty"`
53+
54+
// Indexes of Match in a rule to apply source ip to
55+
// If MatchIndexes is not provided, SourceIpConfig will be applied to all conditions where ListenerRuleConfiguration is used
56+
// +optional
57+
MatchIndexes *[]int `json:"matchIndexes,omitempty"`
5358
}
5459

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

apis/gateway/v1beta1/zz_generated.deepcopy.go

Lines changed: 9 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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,13 @@ spec:
324324
enum:
325325
- source-ip
326326
type: string
327+
matchIndexes:
328+
description: |-
329+
Indexes of Match in a rule to apply source ip to
330+
If MatchIndexes is not provided, SourceIpConfig will be applied to all conditions where ListenerRuleConfiguration is used
331+
items:
332+
type: integer
333+
type: array
327334
sourceIPConfig:
328335
description: Information for a source IP condition
329336
properties:

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,13 @@ spec:
325325
enum:
326326
- source-ip
327327
type: string
328+
matchIndexes:
329+
description: |-
330+
Indexes of Match in a rule to apply source ip to
331+
If MatchIndexes is not provided, SourceIpConfig will be applied to all conditions where ListenerRuleConfiguration is used
332+
items:
333+
type: integer
334+
type: array
328335
sourceIPConfig:
329336
description: Information for a source IP condition
330337
properties:

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,13 @@ spec:
324324
enum:
325325
- source-ip
326326
type: string
327+
matchIndexes:
328+
description: |-
329+
Indexes of Match in a rule to apply source ip to
330+
If MatchIndexes is not provided, SourceIpConfig will be applied to all conditions where ListenerRuleConfiguration is used
331+
items:
332+
type: integer
333+
type: array
327334
sourceIPConfig:
328335
description: Information for a source IP condition
329336
properties:

pkg/gateway/model/model_build_listener.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package model
33
import (
44
"context"
55
"fmt"
6+
"strconv"
7+
"strings"
8+
69
"k8s.io/apimachinery/pkg/types"
710
"sigs.k8s.io/aws-load-balancer-controller/pkg/networking"
811
"sigs.k8s.io/aws-load-balancer-controller/pkg/shared_utils"
912
"sigs.k8s.io/controller-runtime/pkg/client"
10-
"strconv"
11-
"strings"
1213

1314
awssdk "github.com/aws/aws-sdk-go-v2/aws"
1415
"github.com/go-logr/logr"
@@ -197,7 +198,7 @@ func (l listenerBuilderImpl) buildListenerRules(ctx context.Context, stack core.
197198
route := ruleWithPrecedence.CommonRulePrecedence.RouteDescriptor
198199
rule := ruleWithPrecedence.CommonRulePrecedence.Rule
199200

200-
// Build Rule Conditions
201+
// Build Rule Conditions based on GRPCRouteMatch and HTTPRouteMatch
201202
var conditionsList []elbv2model.RuleCondition
202203
var err error
203204
switch route.GetRouteKind() {
@@ -210,6 +211,9 @@ func (l listenerBuilderImpl) buildListenerRules(ctx context.Context, stack core.
210211
return nil, err
211212
}
212213

214+
// Add Rule Source-IP Conditions based on ListenerRuleConfiguration CRD
215+
conditionsList = routeutils.BuildSourceIpInCondition(ruleWithPrecedence, conditionsList)
216+
213217
// set up for building routing actions
214218
var actions []elbv2model.Action
215219
var preRoutingAction *elbv2gw.Action

pkg/gateway/routeutils/route_rule_action.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ package routeutils
33
import (
44
"context"
55
"fmt"
6+
"strconv"
7+
"strings"
8+
"unicode"
9+
610
awssdk "github.com/aws/aws-sdk-go-v2/aws"
711
"github.com/pkg/errors"
812
"k8s.io/apimachinery/pkg/types"
@@ -12,12 +16,9 @@ import (
1216
"sigs.k8s.io/aws-load-balancer-controller/pkg/shared_constants"
1317
"sigs.k8s.io/controller-runtime/pkg/client"
1418
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
15-
"strconv"
16-
"strings"
17-
"unicode"
1819
)
1920

20-
// BuildRulePreRoutingActions returns pre-routing action for rule
21+
// BuildRulePreRoutingAction returns pre-routing action for rule
2122
// The assumption is that the ListenerRuleConfiguration CRD makes sure we only have one of the actions (authenticate-cognito, authenticate-oidc) defined
2223
func BuildRulePreRoutingAction(ctx context.Context, route RouteDescriptor, crdPreRoutingAction *elbv2gw.Action, k8sClient client.Client, secretsManager k8s.SecretsManager) (*elbv2model.Action, *types.NamespacedName, error) {
2324
switch crdPreRoutingAction.Type {
@@ -148,6 +149,9 @@ func buildForwardRoutingAction(routingAction *elbv2gw.Action, targetGroupTuples
148149
return nil, nil
149150
}
150151

152+
// buildRedirectRoutingAction
153+
// For HTTPRoute: handle RequestRedirect from HTTPRouteFilterType
154+
// For GRPCRoute: do not support any filter type other than ExtensionRef, which can be used to refer a listener rule configuration CRD
151155
func buildRedirectRoutingAction(rule RouteRule, route RouteDescriptor, routingAction *elbv2gw.Action) (*elbv2model.Action, error) {
152156
switch route.GetRouteKind() {
153157
case HTTPRouteKind:
@@ -163,7 +167,16 @@ func buildRedirectRoutingAction(rule RouteRule, route RouteDescriptor, routingAc
163167
}
164168
return redirectActions, nil
165169
}
166-
// TODO: add case for GRPC
170+
case GRPCRouteKind:
171+
grpcRule := rule.GetRawRouteRule().(*gwv1.GRPCRouteRule)
172+
for _, filter := range grpcRule.Filters {
173+
switch filter.Type {
174+
case gwv1.GRPCRouteFilterExtensionRef:
175+
continue
176+
default:
177+
return nil, errors.Errorf("Unsupported filter type: %v. To specify header modification, please configure it through LoadBalancerConfiguration.", filter.Type)
178+
}
179+
}
167180
}
168181
return nil, nil
169182
}

pkg/gateway/routeutils/route_rule_condition.go

Lines changed: 37 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,42 @@ 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+
// BuildSourceIpInCondition : takes source ip configuration from listener rule configuration CRD, then AND it to condition list
250+
func BuildSourceIpInCondition(ruleWithPrecedence RulePrecedence, conditionsList []elbv2model.RuleCondition) []elbv2model.RuleCondition {
251+
rule := ruleWithPrecedence.CommonRulePrecedence.Rule
252+
matchIndex := ruleWithPrecedence.CommonRulePrecedence.MatchIndexInRule
253+
if rule.GetListenerRuleConfig() != nil {
254+
conditionsFromRuleConfig := rule.GetListenerRuleConfig().Spec.Conditions
255+
for _, condition := range conditionsFromRuleConfig {
256+
switch condition.Field {
257+
case elbv2gw.ListenerRuleConditionFieldSourceIP:
258+
sourceIpCondition := buildSourceIpCondition(condition)
259+
if condition.MatchIndexes == nil {
260+
conditionsList = append(conditionsList, sourceIpCondition...)
261+
} else {
262+
for _, index := range *condition.MatchIndexes {
263+
if index == matchIndex {
264+
conditionsList = append(conditionsList, sourceIpCondition...)
265+
}
266+
}
267+
}
268+
}
269+
}
270+
}
271+
return conditionsList
272+
}
273+
237274
// generateValuesFromMatchHeaderValue takes in header value from route match
238275
// returns list of values
239276
// 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)