Skip to content

Commit 8d7b991

Browse files
authored
Resource tagging for Listener and Rules (#1887)
* resource tagging for Listener and Rules * update iam policies for resource tagging * e2e for listener and rules tagging * iam rules for gov-cloud, specific tags for listener and rules * wrap errors * fix ut failures after merge
1 parent f6bbfca commit 8d7b991

21 files changed

+629
-158
lines changed

docs/install/iam_policy.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@
152152
}
153153
}
154154
},
155+
{
156+
"Effect": "Allow",
157+
"Action": [
158+
"elasticloadbalancing:AddTags",
159+
"elasticloadbalancing:RemoveTags"
160+
],
161+
"Resource": [
162+
"arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
163+
"arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
164+
"arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
165+
"arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
166+
]
167+
},
155168
{
156169
"Effect": "Allow",
157170
"Action": [
@@ -191,4 +204,4 @@
191204
"Resource": "*"
192205
}
193206
]
194-
}
207+
}

docs/install/iam_policy_cn.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@
152152
}
153153
}
154154
},
155+
{
156+
"Effect": "Allow",
157+
"Action": [
158+
"elasticloadbalancing:AddTags",
159+
"elasticloadbalancing:RemoveTags"
160+
],
161+
"Resource": [
162+
"arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
163+
"arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
164+
"arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
165+
"arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
166+
]
167+
},
155168
{
156169
"Effect": "Allow",
157170
"Action": [
@@ -191,4 +204,4 @@
191204
"Resource": "*"
192205
}
193206
]
194-
}
207+
}

docs/install/iam_policy_us-gov.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@
152152
}
153153
}
154154
},
155+
{
156+
"Effect": "Allow",
157+
"Action": [
158+
"elasticloadbalancing:AddTags",
159+
"elasticloadbalancing:RemoveTags"
160+
],
161+
"Resource": [
162+
"arn:aws-us-gov:elasticloadbalancing:*:*:listener/net/*/*/*",
163+
"arn:aws-us-gov:elasticloadbalancing:*:*:listener/app/*/*/*",
164+
"arn:aws-us-gov:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
165+
"arn:aws-us-gov:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
166+
]
167+
},
155168
{
156169
"Effect": "Allow",
157170
"Action": [

pkg/deploy/elbv2/listener_manager.go

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/pkg/errors"
1111
"k8s.io/apimachinery/pkg/util/sets"
1212
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
13+
"sigs.k8s.io/aws-load-balancer-controller/pkg/deploy/tracking"
1314
elbv2equality "sigs.k8s.io/aws-load-balancer-controller/pkg/equality/elbv2"
1415
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
1516
"sigs.k8s.io/aws-load-balancer-controller/pkg/runtime"
@@ -20,14 +21,17 @@ import (
2021
type ListenerManager interface {
2122
Create(ctx context.Context, resLS *elbv2model.Listener) (elbv2model.ListenerStatus, error)
2223

23-
Update(ctx context.Context, resLS *elbv2model.Listener, sdkLS *elbv2sdk.Listener) (elbv2model.ListenerStatus, error)
24+
Update(ctx context.Context, resLS *elbv2model.Listener, sdkLS ListenerWithTags) (elbv2model.ListenerStatus, error)
2425

25-
Delete(ctx context.Context, sdkLS *elbv2sdk.Listener) error
26+
Delete(ctx context.Context, sdkLS ListenerWithTags) error
2627
}
2728

28-
func NewDefaultListenerManager(elbv2Client services.ELBV2, logger logr.Logger) *defaultListenerManager {
29+
func NewDefaultListenerManager(elbv2Client services.ELBV2, trackingProvider tracking.Provider,
30+
taggingManager TaggingManager, logger logr.Logger) *defaultListenerManager {
2931
return &defaultListenerManager{
3032
elbv2Client: elbv2Client,
33+
trackingProvider: trackingProvider,
34+
taggingManager: taggingManager,
3135
logger: logger,
3236
waitLSExistencePollInterval: defaultWaitLSExistencePollInterval,
3337
waitLSExistenceTimeout: defaultWaitLSExistenceTimeout,
@@ -38,8 +42,10 @@ var _ ListenerManager = &defaultListenerManager{}
3842

3943
// default implementation for ListenerManager
4044
type defaultListenerManager struct {
41-
elbv2Client services.ELBV2
42-
logger logr.Logger
45+
elbv2Client services.ELBV2
46+
trackingProvider tracking.Provider
47+
taggingManager TaggingManager
48+
logger logr.Logger
4349

4450
waitLSExistencePollInterval time.Duration
4551
waitLSExistenceTimeout time.Duration
@@ -50,6 +56,8 @@ func (m *defaultListenerManager) Create(ctx context.Context, resLS *elbv2model.L
5056
if err != nil {
5157
return elbv2model.ListenerStatus{}, err
5258
}
59+
lsTags := m.trackingProvider.ResourceTags(resLS.Stack(), resLS, resLS.Spec.Tags)
60+
req.Tags = convertTagsToSDKTags(lsTags)
5361

5462
m.logger.Info("creating listener",
5563
"stackID", resLS.Stack().StackID(),
@@ -58,11 +66,14 @@ func (m *defaultListenerManager) Create(ctx context.Context, resLS *elbv2model.L
5866
if err != nil {
5967
return elbv2model.ListenerStatus{}, err
6068
}
61-
sdkLS := resp.Listeners[0]
69+
sdkLS := ListenerWithTags{
70+
Listener: resp.Listeners[0],
71+
Tags: lsTags,
72+
}
6273
m.logger.Info("created listener",
6374
"stackID", resLS.Stack().StackID(),
6475
"resourceID", resLS.ID(),
65-
"arn", awssdk.StringValue(sdkLS.ListenerArn))
76+
"arn", awssdk.StringValue(sdkLS.Listener.ListenerArn))
6677

6778
if err := runtime.RetryImmediateOnError(m.waitLSExistencePollInterval, m.waitLSExistenceTimeout, isListenerNotFoundError, func() error {
6879
return m.updateSDKListenerWithExtraCertificates(ctx, resLS, sdkLS, true)
@@ -72,7 +83,10 @@ func (m *defaultListenerManager) Create(ctx context.Context, resLS *elbv2model.L
7283
return buildResListenerStatus(sdkLS), nil
7384
}
7485

75-
func (m *defaultListenerManager) Update(ctx context.Context, resLS *elbv2model.Listener, sdkLS *elbv2sdk.Listener) (elbv2model.ListenerStatus, error) {
86+
func (m *defaultListenerManager) Update(ctx context.Context, resLS *elbv2model.Listener, sdkLS ListenerWithTags) (elbv2model.ListenerStatus, error) {
87+
if err := m.updateSDKListenerWithTags(ctx, resLS, sdkLS); err != nil {
88+
return elbv2model.ListenerStatus{}, err
89+
}
7690
if err := m.updateSDKListenerWithSettings(ctx, resLS, sdkLS); err != nil {
7791
return elbv2model.ListenerStatus{}, err
7892
}
@@ -82,9 +96,9 @@ func (m *defaultListenerManager) Update(ctx context.Context, resLS *elbv2model.L
8296
return buildResListenerStatus(sdkLS), nil
8397
}
8498

85-
func (m *defaultListenerManager) Delete(ctx context.Context, sdkLS *elbv2sdk.Listener) error {
99+
func (m *defaultListenerManager) Delete(ctx context.Context, sdkLS ListenerWithTags) error {
86100
req := &elbv2sdk.DeleteListenerInput{
87-
ListenerArn: sdkLS.ListenerArn,
101+
ListenerArn: sdkLS.Listener.ListenerArn,
88102
}
89103
m.logger.Info("deleting listener",
90104
"arn", awssdk.StringValue(req.ListenerArn))
@@ -96,7 +110,13 @@ func (m *defaultListenerManager) Delete(ctx context.Context, sdkLS *elbv2sdk.Lis
96110
return nil
97111
}
98112

99-
func (m *defaultListenerManager) updateSDKListenerWithSettings(ctx context.Context, resLS *elbv2model.Listener, sdkLS *elbv2sdk.Listener) error {
113+
func (m *defaultListenerManager) updateSDKListenerWithTags(ctx context.Context, resLS *elbv2model.Listener, sdkLS ListenerWithTags) error {
114+
desiredLSTags := m.trackingProvider.ResourceTags(resLS.Stack(), resLS, resLS.Spec.Tags)
115+
return m.taggingManager.ReconcileTags(ctx, awssdk.StringValue(sdkLS.Listener.ListenerArn), desiredLSTags,
116+
WithCurrentTags(sdkLS.Tags))
117+
}
118+
119+
func (m *defaultListenerManager) updateSDKListenerWithSettings(ctx context.Context, resLS *elbv2model.Listener, sdkLS ListenerWithTags) error {
100120
desiredDefaultActions, err := buildSDKActions(resLS.Spec.DefaultActions)
101121
if err != nil {
102122
return err
@@ -106,25 +126,25 @@ func (m *defaultListenerManager) updateSDKListenerWithSettings(ctx context.Conte
106126
return nil
107127
}
108128
req := buildSDKModifyListenerInput(resLS.Spec, desiredDefaultActions, desiredDefaultCerts)
109-
req.ListenerArn = sdkLS.ListenerArn
129+
req.ListenerArn = sdkLS.Listener.ListenerArn
110130
m.logger.Info("modifying listener",
111131
"stackID", resLS.Stack().StackID(),
112132
"resourceID", resLS.ID(),
113-
"arn", awssdk.StringValue(sdkLS.ListenerArn))
133+
"arn", awssdk.StringValue(sdkLS.Listener.ListenerArn))
114134
if _, err := m.elbv2Client.ModifyListenerWithContext(ctx, req); err != nil {
115135
return err
116136
}
117137
m.logger.Info("modified listener",
118138
"stackID", resLS.Stack().StackID(),
119139
"resourceID", resLS.ID(),
120-
"arn", awssdk.StringValue(sdkLS.ListenerArn))
140+
"arn", awssdk.StringValue(sdkLS.Listener.ListenerArn))
121141
return nil
122142
}
123143

124144
// updateSDKListenerWithExtraCertificates will update the extra certificates on listener.
125145
// currentExtraCertificates is the current extra certificates, if it's nil, the current extra certificates will be fetched from AWS.
126146
func (m *defaultListenerManager) updateSDKListenerWithExtraCertificates(ctx context.Context, resLS *elbv2model.Listener,
127-
sdkLS *elbv2sdk.Listener, isNewSDKListener bool) error {
147+
sdkLS ListenerWithTags, isNewSDKListener bool) error {
128148
desiredExtraCertARNs := sets.NewString()
129149
_, desiredExtraCerts := buildSDKCertificates(resLS.Spec.Certificates)
130150
for _, cert := range desiredExtraCerts {
@@ -141,7 +161,7 @@ func (m *defaultListenerManager) updateSDKListenerWithExtraCertificates(ctx cont
141161

142162
for _, certARN := range desiredExtraCertARNs.Difference(currentExtraCertARNs).List() {
143163
req := &elbv2sdk.AddListenerCertificatesInput{
144-
ListenerArn: sdkLS.ListenerArn,
164+
ListenerArn: sdkLS.Listener.ListenerArn,
145165
Certificates: []*elbv2sdk.Certificate{
146166
{
147167
CertificateArn: awssdk.String(certARN),
@@ -151,21 +171,21 @@ func (m *defaultListenerManager) updateSDKListenerWithExtraCertificates(ctx cont
151171
m.logger.Info("adding certificate to listener",
152172
"stackID", resLS.Stack().StackID(),
153173
"resourceID", resLS.ID(),
154-
"arn", awssdk.StringValue(sdkLS.ListenerArn),
174+
"arn", awssdk.StringValue(sdkLS.Listener.ListenerArn),
155175
"certificateARN", certARN)
156176
if _, err := m.elbv2Client.AddListenerCertificatesWithContext(ctx, req); err != nil {
157177
return err
158178
}
159179
m.logger.Info("added certificate to listener",
160180
"stackID", resLS.Stack().StackID(),
161181
"resourceID", resLS.ID(),
162-
"arn", awssdk.StringValue(sdkLS.ListenerArn),
182+
"arn", awssdk.StringValue(sdkLS.Listener.ListenerArn),
163183
"certificateARN", certARN)
164184
}
165185

166186
for _, certARN := range currentExtraCertARNs.Difference(desiredExtraCertARNs).List() {
167187
req := &elbv2sdk.RemoveListenerCertificatesInput{
168-
ListenerArn: sdkLS.ListenerArn,
188+
ListenerArn: sdkLS.Listener.ListenerArn,
169189
Certificates: []*elbv2sdk.Certificate{
170190
{
171191
CertificateArn: awssdk.String(certARN),
@@ -175,24 +195,24 @@ func (m *defaultListenerManager) updateSDKListenerWithExtraCertificates(ctx cont
175195
m.logger.Info("removing certificate from listener",
176196
"stackID", resLS.Stack().StackID(),
177197
"resourceID", resLS.ID(),
178-
"arn", awssdk.StringValue(sdkLS.ListenerArn),
198+
"arn", awssdk.StringValue(sdkLS.Listener.ListenerArn),
179199
"certificateARN", certARN)
180200
if _, err := m.elbv2Client.RemoveListenerCertificatesWithContext(ctx, req); err != nil {
181201
return err
182202
}
183203
m.logger.Info("removed certificate from listener",
184204
"stackID", resLS.Stack().StackID(),
185205
"resourceID", resLS.ID(),
186-
"arn", awssdk.StringValue(sdkLS.ListenerArn),
206+
"arn", awssdk.StringValue(sdkLS.Listener.ListenerArn),
187207
"certificateARN", certARN)
188208
}
189209

190210
return nil
191211
}
192212

193-
func (m *defaultListenerManager) fetchSDKListenerExtraCertificateARNs(ctx context.Context, sdkLS *elbv2sdk.Listener) ([]string, error) {
213+
func (m *defaultListenerManager) fetchSDKListenerExtraCertificateARNs(ctx context.Context, sdkLS ListenerWithTags) ([]string, error) {
194214
req := &elbv2sdk.DescribeListenerCertificatesInput{
195-
ListenerArn: sdkLS.ListenerArn,
215+
ListenerArn: sdkLS.Listener.ListenerArn,
196216
}
197217
sdkCerts, err := m.elbv2Client.DescribeListenerCertificatesAsList(ctx, req)
198218
if err != nil {
@@ -207,24 +227,24 @@ func (m *defaultListenerManager) fetchSDKListenerExtraCertificateARNs(ctx contex
207227
return extraCertARNs, nil
208228
}
209229

210-
func isSDKListenerSettingsDrifted(lsSpec elbv2model.ListenerSpec, sdkLS *elbv2sdk.Listener,
230+
func isSDKListenerSettingsDrifted(lsSpec elbv2model.ListenerSpec, sdkLS ListenerWithTags,
211231
desiredDefaultActions []*elbv2sdk.Action, desiredDefaultCerts []*elbv2sdk.Certificate) bool {
212-
if lsSpec.Port != awssdk.Int64Value(sdkLS.Port) {
232+
if lsSpec.Port != awssdk.Int64Value(sdkLS.Listener.Port) {
213233
return true
214234
}
215-
if string(lsSpec.Protocol) != awssdk.StringValue(sdkLS.Protocol) {
235+
if string(lsSpec.Protocol) != awssdk.StringValue(sdkLS.Listener.Protocol) {
216236
return true
217237
}
218-
if !cmp.Equal(desiredDefaultActions, sdkLS.DefaultActions, elbv2equality.CompareOptionForActions()) {
238+
if !cmp.Equal(desiredDefaultActions, sdkLS.Listener.DefaultActions, elbv2equality.CompareOptionForActions()) {
219239
return true
220240
}
221-
if !cmp.Equal(desiredDefaultCerts, sdkLS.Certificates, elbv2equality.CompareOptionForCertificates()) {
241+
if !cmp.Equal(desiredDefaultCerts, sdkLS.Listener.Certificates, elbv2equality.CompareOptionForCertificates()) {
222242
return true
223243
}
224-
if lsSpec.SSLPolicy != nil && awssdk.StringValue(lsSpec.SSLPolicy) != awssdk.StringValue(sdkLS.SslPolicy) {
244+
if lsSpec.SSLPolicy != nil && awssdk.StringValue(lsSpec.SSLPolicy) != awssdk.StringValue(sdkLS.Listener.SslPolicy) {
225245
return true
226246
}
227-
if len(lsSpec.ALPNPolicy) != 0 && !cmp.Equal(lsSpec.ALPNPolicy, awssdk.StringValueSlice(sdkLS.AlpnPolicy), cmpopts.EquateEmpty()) {
247+
if len(lsSpec.ALPNPolicy) != 0 && !cmp.Equal(lsSpec.ALPNPolicy, awssdk.StringValueSlice(sdkLS.Listener.AlpnPolicy), cmpopts.EquateEmpty()) {
228248
return true
229249
}
230250

@@ -289,8 +309,8 @@ func buildSDKCertificate(modelCert elbv2model.Certificate) *elbv2sdk.Certificate
289309
}
290310
}
291311

292-
func buildResListenerStatus(sdkLS *elbv2sdk.Listener) elbv2model.ListenerStatus {
312+
func buildResListenerStatus(sdkLS ListenerWithTags) elbv2model.ListenerStatus {
293313
return elbv2model.ListenerStatus{
294-
ListenerARN: awssdk.StringValue(sdkLS.ListenerArn),
314+
ListenerARN: awssdk.StringValue(sdkLS.Listener.ListenerArn),
295315
}
296316
}

0 commit comments

Comments
 (0)