Skip to content

Commit 5426ba0

Browse files
committed
Update rule management to avoid sporadic 503 errors
1 parent 57472c4 commit 5426ba0

File tree

11 files changed

+175
-71
lines changed

11 files changed

+175
-71
lines changed

.go-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.22.8
1+
1.23.0

docs/install/iam_policy.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"elasticloadbalancing:DescribeTags",
4343
"elasticloadbalancing:DescribeTrustStores",
4444
"elasticloadbalancing:DescribeListenerAttributes",
45-
"elasticloadbalancing:DescribeCapacityReservation"
45+
"elasticloadbalancing:DescribeCapacityReservation",
46+
"elasticloadbalancing:SetRulePriorities"
4647
],
4748
"Resource": "*"
4849
},

docs/install/iam_policy_cn.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"elasticloadbalancing:DescribeTags",
4343
"elasticloadbalancing:DescribeTrustStores",
4444
"elasticloadbalancing:DescribeListenerAttributes",
45-
"elasticloadbalancing:DescribeCapacityReservation"
45+
"elasticloadbalancing:DescribeCapacityReservation",
46+
"elasticloadbalancing:SetRulePriorities"
4647
],
4748
"Resource": "*"
4849
},

docs/install/iam_policy_iso.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"elasticloadbalancing:DescribeTargetGroups",
4040
"elasticloadbalancing:DescribeTargetGroupAttributes",
4141
"elasticloadbalancing:DescribeTargetHealth",
42-
"elasticloadbalancing:DescribeTags"
42+
"elasticloadbalancing:DescribeTags",
43+
"elasticloadbalancing:SetRulePriorities"
4344
],
4445
"Resource": "*"
4546
},

docs/install/iam_policy_isob.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"elasticloadbalancing:DescribeTargetGroups",
4040
"elasticloadbalancing:DescribeTargetGroupAttributes",
4141
"elasticloadbalancing:DescribeTargetHealth",
42-
"elasticloadbalancing:DescribeTags"
42+
"elasticloadbalancing:DescribeTags",
43+
"elasticloadbalancing:SetRulePriorities"
4344
],
4445
"Resource": "*"
4546
},

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module sigs.k8s.io/aws-load-balancer-controller
22

3-
go 1.22.8
3+
go 1.23.0
44

55
require (
66
github.com/aws/aws-sdk-go v1.55.5

pkg/aws/services/elbv2.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ type ELBV2 interface {
5050
DescribeRulesWithContext(ctx context.Context, input *elasticloadbalancingv2.DescribeRulesInput) (*elasticloadbalancingv2.DescribeRulesOutput, error)
5151
CreateRuleWithContext(ctx context.Context, input *elasticloadbalancingv2.CreateRuleInput) (*elasticloadbalancingv2.CreateRuleOutput, error)
5252
DeleteRuleWithContext(ctx context.Context, input *elasticloadbalancingv2.DeleteRuleInput) (*elasticloadbalancingv2.DeleteRuleOutput, error)
53-
ModifyRuleWithContext(ctx context.Context, inout *elasticloadbalancingv2.ModifyRuleInput) (*elasticloadbalancingv2.ModifyRuleOutput, error)
53+
ModifyRuleWithContext(ctx context.Context, input *elasticloadbalancingv2.ModifyRuleInput) (*elasticloadbalancingv2.ModifyRuleOutput, error)
54+
SetRulePrioritiesWithContext(ctx context.Context, input *elasticloadbalancingv2.SetRulePrioritiesInput) (*elasticloadbalancingv2.SetRulePrioritiesOutput, error)
5455
RegisterTargetsWithContext(ctx context.Context, input *elasticloadbalancingv2.RegisterTargetsInput) (*elasticloadbalancingv2.RegisterTargetsOutput, error)
5556
DeregisterTargetsWithContext(ctx context.Context, input *elasticloadbalancingv2.DeregisterTargetsInput) (*elasticloadbalancingv2.DeregisterTargetsOutput, error)
5657
DescribeTrustStoresWithContext(ctx context.Context, input *elasticloadbalancingv2.DescribeTrustStoresInput) (*elasticloadbalancingv2.DescribeTrustStoresOutput, error)
@@ -163,6 +164,14 @@ func (c *elbv2Client) DeleteRuleWithContext(ctx context.Context, input *elasticl
163164
return client.DeleteRule(ctx, input)
164165
}
165166

167+
func (c *elbv2Client) SetRulePrioritiesWithContext(ctx context.Context, input *elasticloadbalancingv2.SetRulePrioritiesInput) (*elasticloadbalancingv2.SetRulePrioritiesOutput, error) {
168+
client, err := c.awsClientsProvider.GetELBv2Client(ctx, "SetRulePriorities")
169+
if err != nil {
170+
return nil, err
171+
}
172+
return client.SetRulePriorities(ctx, input)
173+
}
174+
166175
func (c *elbv2Client) CreateRuleWithContext(ctx context.Context, input *elasticloadbalancingv2.CreateRuleInput) (*elasticloadbalancingv2.CreateRuleOutput, error) {
167176
client, err := c.getClient(ctx, "CreateRule")
168177
if err != nil {

pkg/aws/services/elbv2_mocks.go

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

pkg/deploy/elbv2/listener_rule_manager.go

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,26 @@ import (
66
elbv2sdk "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
77
elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
88
"github.com/go-logr/logr"
9-
"github.com/google/go-cmp/cmp"
109
"github.com/pkg/errors"
1110
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
1211
"sigs.k8s.io/aws-load-balancer-controller/pkg/config"
1312
"sigs.k8s.io/aws-load-balancer-controller/pkg/deploy/tracking"
14-
elbv2equality "sigs.k8s.io/aws-load-balancer-controller/pkg/equality/elbv2"
1513
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
1614
"sigs.k8s.io/aws-load-balancer-controller/pkg/runtime"
15+
"slices"
16+
"strconv"
1717
"time"
1818
)
1919

2020
// ListenerRuleManager is responsible for create/update/delete ListenerRule resources.
2121
type ListenerRuleManager interface {
22-
Create(ctx context.Context, resLR *elbv2model.ListenerRule) (elbv2model.ListenerRuleStatus, error)
22+
Create(ctx context.Context, resLR *elbv2model.ListenerRule, desiredActionsAndConditions *resLRDesiredActionsAndConditionsPair) (elbv2model.ListenerRuleStatus, error)
2323

2424
Update(ctx context.Context, resLR *elbv2model.ListenerRule, sdkLR ListenerRuleWithTags) (elbv2model.ListenerRuleStatus, error)
2525

2626
Delete(ctx context.Context, sdkLR ListenerRuleWithTags) error
27+
28+
SetRulePriorities(ctx context.Context, sdkLR []ListenerRuleWithTags, lastAvailablePriority int32) (int32, error)
2729
}
2830

2931
// NewDefaultListenerRuleManager constructs new defaultListenerRuleManager.
@@ -54,8 +56,8 @@ type defaultListenerRuleManager struct {
5456
waitLSExistenceTimeout time.Duration
5557
}
5658

57-
func (m *defaultListenerRuleManager) Create(ctx context.Context, resLR *elbv2model.ListenerRule) (elbv2model.ListenerRuleStatus, error) {
58-
req, err := buildSDKCreateListenerRuleInput(resLR.Spec, m.featureGates)
59+
func (m *defaultListenerRuleManager) Create(ctx context.Context, resLR *elbv2model.ListenerRule, desiredActionsAndConditions *resLRDesiredActionsAndConditionsPair) (elbv2model.ListenerRuleStatus, error) {
60+
req, err := buildSDKCreateListenerRuleInput(resLR.Spec, desiredActionsAndConditions, m.featureGates)
5961
if err != nil {
6062
return elbv2model.ListenerRuleStatus{}, err
6163
}
@@ -96,9 +98,6 @@ func (m *defaultListenerRuleManager) Update(ctx context.Context, resLR *elbv2mod
9698
return elbv2model.ListenerRuleStatus{}, err
9799
}
98100
}
99-
if err := m.updateSDKListenerRuleWithSettings(ctx, resLR, sdkLR); err != nil {
100-
return elbv2model.ListenerRuleStatus{}, err
101-
}
102101
return buildResListenerRuleStatus(sdkLR), nil
103102
}
104103

@@ -116,30 +115,21 @@ func (m *defaultListenerRuleManager) Delete(ctx context.Context, sdkLR ListenerR
116115
return nil
117116
}
118117

119-
func (m *defaultListenerRuleManager) updateSDKListenerRuleWithSettings(ctx context.Context, resLR *elbv2model.ListenerRule, sdkLR ListenerRuleWithTags) error {
120-
desiredActions, err := buildSDKActions(resLR.Spec.Actions, m.featureGates)
121-
if err != nil {
122-
return err
123-
}
124-
desiredConditions := buildSDKRuleConditions(resLR.Spec.Conditions)
125-
if !isSDKListenerRuleSettingsDrifted(resLR.Spec, sdkLR, desiredActions, desiredConditions) {
126-
return nil
127-
}
128-
129-
req := buildSDKModifyListenerRuleInput(resLR.Spec, desiredActions, desiredConditions)
130-
req.RuleArn = sdkLR.ListenerRule.RuleArn
131-
m.logger.Info("modifying listener rule",
132-
"stackID", resLR.Stack().StackID(),
133-
"resourceID", resLR.ID(),
134-
"arn", awssdk.ToString(sdkLR.ListenerRule.RuleArn))
135-
if _, err := m.elbv2Client.ModifyRuleWithContext(ctx, req); err != nil {
136-
return err
137-
}
138-
m.logger.Info("modified listener rule",
139-
"stackID", resLR.Stack().StackID(),
140-
"resourceID", resLR.ID(),
141-
"arn", awssdk.ToString(sdkLR.ListenerRule.RuleArn))
142-
return nil
118+
func (m *defaultListenerRuleManager) SetRulePriorities(ctx context.Context, unmatchedSDKLRs []ListenerRuleWithTags, lastAvailablePriority int32) (int32, error) {
119+
for _, sdkLR := range slices.Backward(unmatchedSDKLRs) {
120+
//Update rule priorities
121+
sdkLR.ListenerRule.Priority = awssdk.String(strconv.Itoa(int(lastAvailablePriority)))
122+
lastAvailablePriority--
123+
}
124+
req := buildSDKSetRulePrioritiesInput(unmatchedSDKLRs)
125+
m.logger.Info("setting listener rule priorities",
126+
"rule priority pairs", req.RulePriorities)
127+
if _, err := m.elbv2Client.SetRulePrioritiesWithContext(ctx, req); err != nil {
128+
return lastAvailablePriority, err
129+
}
130+
m.logger.Info("setting listener rule priorities complete",
131+
"rule priority pairs", req.RulePriorities)
132+
return lastAvailablePriority, nil
143133
}
144134

145135
func (m *defaultListenerRuleManager) updateSDKListenerRuleWithTags(ctx context.Context, resLR *elbv2model.ListenerRule, sdkLR ListenerRuleWithTags) error {
@@ -149,20 +139,7 @@ func (m *defaultListenerRuleManager) updateSDKListenerRuleWithTags(ctx context.C
149139
WithIgnoredTagKeys(m.externalManagedTags))
150140
}
151141

152-
func isSDKListenerRuleSettingsDrifted(lrSpec elbv2model.ListenerRuleSpec, sdkLR ListenerRuleWithTags,
153-
desiredActions []elbv2types.Action, desiredConditions []elbv2types.RuleCondition) bool {
154-
155-
if !cmp.Equal(desiredActions, sdkLR.ListenerRule.Actions, elbv2equality.CompareOptionForActions()) {
156-
return true
157-
}
158-
if !cmp.Equal(desiredConditions, sdkLR.ListenerRule.Conditions, elbv2equality.CompareOptionForRuleConditions()) {
159-
return true
160-
}
161-
162-
return false
163-
}
164-
165-
func buildSDKCreateListenerRuleInput(lrSpec elbv2model.ListenerRuleSpec, featureGates config.FeatureGates) (*elbv2sdk.CreateRuleInput, error) {
142+
func buildSDKCreateListenerRuleInput(lrSpec elbv2model.ListenerRuleSpec, desiredActionsAndConditions *resLRDesiredActionsAndConditionsPair, featureGates config.FeatureGates) (*elbv2sdk.CreateRuleInput, error) {
166143
ctx := context.Background()
167144
lsARN, err := lrSpec.ListenerARN.Resolve(ctx)
168145
if err != nil {
@@ -171,22 +148,38 @@ func buildSDKCreateListenerRuleInput(lrSpec elbv2model.ListenerRuleSpec, feature
171148
sdkObj := &elbv2sdk.CreateRuleInput{}
172149
sdkObj.ListenerArn = awssdk.String(lsARN)
173150
sdkObj.Priority = awssdk.Int32(lrSpec.Priority)
174-
actions, err := buildSDKActions(lrSpec.Actions, featureGates)
175-
if err != nil {
176-
return nil, err
151+
if desiredActionsAndConditions != nil && desiredActionsAndConditions.desiredActions != nil {
152+
sdkObj.Actions = desiredActionsAndConditions.desiredActions
153+
} else {
154+
actions, err := buildSDKActions(lrSpec.Actions, featureGates)
155+
if err != nil {
156+
return nil, err
157+
}
158+
sdkObj.Actions = actions
159+
}
160+
if desiredActionsAndConditions != nil && desiredActionsAndConditions.desiredConditions != nil {
161+
sdkObj.Conditions = desiredActionsAndConditions.desiredConditions
162+
} else {
163+
sdkObj.Conditions = buildSDKRuleConditions(lrSpec.Conditions)
177164
}
178-
sdkObj.Actions = actions
179-
sdkObj.Conditions = buildSDKRuleConditions(lrSpec.Conditions)
180165
return sdkObj, nil
181166
}
182167

183-
func buildSDKModifyListenerRuleInput(_ elbv2model.ListenerRuleSpec, desiredActions []elbv2types.Action, desiredConditions []elbv2types.RuleCondition) *elbv2sdk.ModifyRuleInput {
184-
sdkObj := &elbv2sdk.ModifyRuleInput{}
185-
sdkObj.Actions = desiredActions
186-
sdkObj.Conditions = desiredConditions
168+
func buildSDKSetRulePrioritiesInput(sdkLRs []ListenerRuleWithTags) *elbv2sdk.SetRulePrioritiesInput {
169+
var rulePriorities []elbv2types.RulePriorityPair
170+
for _, sdkLR := range sdkLRs {
171+
p, _ := strconv.ParseInt(awssdk.ToString(sdkLR.ListenerRule.Priority), 10, 32)
172+
rulePriorityPair := elbv2types.RulePriorityPair{
173+
RuleArn: sdkLR.ListenerRule.RuleArn,
174+
Priority: awssdk.Int32(int32(p)),
175+
}
176+
rulePriorities = append(rulePriorities, rulePriorityPair)
177+
}
178+
sdkObj := &elbv2sdk.SetRulePrioritiesInput{
179+
RulePriorities: rulePriorities,
180+
}
187181
return sdkObj
188182
}
189-
190183
func buildResListenerRuleStatus(sdkLR ListenerRuleWithTags) elbv2model.ListenerRuleStatus {
191184
return elbv2model.ListenerRuleStatus{
192185
RuleARN: awssdk.ToString(sdkLR.ListenerRule.RuleArn),

0 commit comments

Comments
 (0)