Skip to content

Commit 79261fb

Browse files
authored
Merge pull request #421 from kubernetes-sigs/annotation-cleanup
Normalized load balancer attributes annotation
2 parents a2cdf03 + 9af6f7b commit 79261fb

File tree

5 files changed

+107
-27
lines changed

5 files changed

+107
-27
lines changed

docs/ingress-resources.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Required annotations are:
5151
### Optional Annotations
5252
5353
```
54-
alb.ingress.kubernetes.io/attributes
54+
alb.ingress.kubernetes.io/load-balancer-attributes
5555
alb.ingress.kubernetes.io/backend-protocol
5656
alb.ingress.kubernetes.io/certificate-arn
5757
alb.ingress.kubernetes.io/connection-idle-timeout
@@ -75,7 +75,7 @@ alb.ingress.kubernetes.io/ssl-policy
7575
7676
Optional annotations are:
7777
78-
- **attributes**: Defines [Load Balancer Attributes](http://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_LoadBalancerAttribute.html) that should be applied to the ALB. This can be used to enable the S3 access logs feature of the ALB. Example: `alb.ingress.kubernetes.io/attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=my-access-log-bucket`
78+
- **load-balancer-attributes**: Defines [Load Balancer Attributes](http://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_LoadBalancerAttribute.html) that should be applied to the ALB. This can be used to enable the S3 access logs feature of the ALB. Example: `alb.ingress.kubernetes.io/attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=my-access-log-bucket`
7979
8080
- **backend-protocol**: Enables selection of protocol for ALB to use to connect to backend service. When omitted, `HTTP` is used.
8181

pkg/alb/lb/loadbalancer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func NewDesiredLoadBalancer(o *NewDesiredLoadBalancerOptions) (newLoadBalancer *
4646

4747
newLoadBalancer = &LoadBalancer{
4848
id: name,
49-
attributes: attributes{desired: o.Annotations.Attributes},
49+
attributes: attributes{desired: o.Annotations.LoadBalancerAttributes},
5050
tags: tags{desired: o.Tags},
5151
options: options{
5252
desired: opts{

pkg/alb/lb/loadbalancer_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package lb
22

33
import (
4-
"fmt"
54
"testing"
65

76
"github.com/aws/aws-sdk-go/aws"
@@ -96,8 +95,7 @@ func TestNewDesiredLoadBalancer(t *testing.T) {
9695
}
9796

9897
expectedID := createLBName(namespace, ingressName, clusterName)
99-
l, err := NewDesiredLoadBalancer(lbOpts)
100-
fmt.Println(err)
98+
l, _ := NewDesiredLoadBalancer(lbOpts)
10199

102100
key1, _ := l.tags.desired.Get(tag1Key)
103101
switch {

pkg/annotations/annotations.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const (
3838
healthyThresholdCountKey = "alb.ingress.kubernetes.io/healthy-threshold-count"
3939
unhealthyThresholdCountKey = "alb.ingress.kubernetes.io/unhealthy-threshold-count"
4040
inboundCidrsKey = "alb.ingress.kubernetes.io/security-group-inbound-cidrs"
41+
loadbalancerAttributesKey = "alb.ingress.kubernetes.io/load-balancer-attributes"
42+
loadbalancerAttributesAltKey = "alb.ingress.kubernetes.io/attributes"
4143
portKey = "alb.ingress.kubernetes.io/listen-ports"
4244
schemeKey = "alb.ingress.kubernetes.io/scheme"
4345
sslPolicyKey = "alb.ingress.kubernetes.io/ssl-policy"
@@ -53,7 +55,6 @@ const (
5355
clusterTagValue = "shared"
5456
albRoleTagKey = "tag:kubernetes.io/role/alb-ingress"
5557
albManagedSubnetsCacheKey = "alb-managed-subnets"
56-
attributesKey = "alb.ingress.kubernetes.io/attributes"
5758
)
5859

5960
// Annotations contains all of the annotation configuration for an ingress
@@ -81,7 +82,7 @@ type Annotations struct {
8182
TargetGroupAttributes albelbv2.TargetGroupAttributes
8283
SslPolicy *string
8384
VPCID *string
84-
Attributes []*elbv2.LoadBalancerAttribute
85+
LoadBalancerAttributes []*elbv2.LoadBalancerAttribute
8586
}
8687

8788
type PortData struct {
@@ -147,7 +148,7 @@ func (vf ValidatingAnnotationFactory) ParseAnnotations(ingress *extensions.Ingre
147148
a.setTags(annotations),
148149
a.setIgnoreHostHeader(annotations),
149150
a.setWafACLID(annotations, vf.validator),
150-
a.setAttributes(annotations),
151+
a.setLoadBalancerAttributes(annotations),
151152
a.setTargetGroupAttributes(annotations),
152153
a.setSslPolicy(annotations, vf.validator),
153154
} {
@@ -159,10 +160,15 @@ func (vf ValidatingAnnotationFactory) ParseAnnotations(ingress *extensions.Ingre
159160
return a, nil
160161
}
161162

162-
func (a *Annotations) setAttributes(annotations map[string]string) error {
163+
func (a *Annotations) setLoadBalancerAttributes(annotations map[string]string) error {
163164
var attrs []*elbv2.LoadBalancerAttribute
164165
var badAttrs []string
165-
rawAttrs := util.NewAWSStringSlice(annotations[attributesKey])
166+
v, ok := annotations[loadbalancerAttributesKey]
167+
if !ok {
168+
v = annotations[loadbalancerAttributesAltKey]
169+
}
170+
171+
rawAttrs := util.NewAWSStringSlice(v)
166172

167173
for _, rawAttr := range rawAttrs {
168174
parts := strings.Split(*rawAttr, "=")
@@ -178,7 +184,7 @@ func (a *Annotations) setAttributes(annotations map[string]string) error {
178184
Value: aws.String(parts[1]),
179185
})
180186
}
181-
a.Attributes = attrs
187+
a.LoadBalancerAttributes = attrs
182188

183189
if len(badAttrs) > 0 {
184190
return fmt.Errorf("Unable to parse `%s` into Key=Value pair(s)", strings.Join(badAttrs, ", "))

pkg/annotations/annotations_test.go

Lines changed: 91 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -198,23 +198,99 @@ func TestConnectionIdleTimeoutValidation(t *testing.T) {
198198
}
199199
}
200200

201-
func TestSetAttributesAsList(t *testing.T) {
202-
annotations := &Annotations{}
203-
expected := elbv2.LoadBalancerAttribute{}
204-
expected.SetKey("access_logs.s3.enabled")
205-
expected.SetValue("true")
206-
207-
attributes := map[string]string{attributesKey: "access_logs.s3.enabled=true"}
208-
err := annotations.setAttributes(attributes)
209-
210-
if err != nil || len(annotations.Attributes) != 1 {
211-
t.Errorf("setAttributes - number of attributes incorrect")
201+
func TestSetLoadBalancerAttributes(t *testing.T) {
202+
var tests = []struct {
203+
annotations map[string]string
204+
expected []elbv2.LoadBalancerAttribute
205+
length int
206+
pass bool
207+
}{
208+
{
209+
map[string]string{loadbalancerAttributesKey: "access_logs.s3.enabled=true"},
210+
func() []elbv2.LoadBalancerAttribute {
211+
e := elbv2.LoadBalancerAttribute{}
212+
e.SetKey("access_logs.s3.enabled")
213+
e.SetValue("true")
214+
return []elbv2.LoadBalancerAttribute{e}
215+
}(),
216+
1,
217+
true,
218+
},
219+
{
220+
map[string]string{loadbalancerAttributesAltKey: "access_logs.s3.enabled=true"},
221+
func() []elbv2.LoadBalancerAttribute {
222+
e := elbv2.LoadBalancerAttribute{}
223+
e.SetKey("access_logs.s3.enabled")
224+
e.SetValue("true")
225+
return []elbv2.LoadBalancerAttribute{e}
226+
}(),
227+
1,
228+
true,
229+
},
230+
{
231+
map[string]string{
232+
loadbalancerAttributesKey: "access_logs.s3.enabled=true",
233+
loadbalancerAttributesAltKey: "deletion_protection.enabled=true",
234+
},
235+
func() []elbv2.LoadBalancerAttribute {
236+
e := elbv2.LoadBalancerAttribute{}
237+
e.SetKey("access_logs.s3.enabled")
238+
e.SetValue("true")
239+
return []elbv2.LoadBalancerAttribute{e}
240+
}(),
241+
1,
242+
true,
243+
},
244+
{
245+
map[string]string{loadbalancerAttributesKey: "access_logs.s3.enabled=true,deletion_protection.enabled=true"},
246+
func() (v []elbv2.LoadBalancerAttribute) {
247+
e := elbv2.LoadBalancerAttribute{}
248+
e.SetKey("access_logs.s3.enabled")
249+
e.SetValue("true")
250+
v = append(v, e)
251+
e = elbv2.LoadBalancerAttribute{}
252+
e.SetKey("deletion_protection.enabled")
253+
e.SetValue("true")
254+
v = append(v, e)
255+
return v
256+
}(),
257+
2,
258+
true,
259+
},
260+
{
261+
map[string]string{loadbalancerAttributesKey: "access_logs.s3.enabled=false"},
262+
func() []elbv2.LoadBalancerAttribute {
263+
e := elbv2.LoadBalancerAttribute{}
264+
e.SetKey("access_logs.s3.enabled")
265+
e.SetValue("true")
266+
return []elbv2.LoadBalancerAttribute{e}
267+
}(),
268+
1,
269+
false,
270+
},
212271
}
272+
for v, tt := range tests {
273+
a := &Annotations{}
213274

214-
actual := annotations.Attributes[0]
215-
216-
if err == nil && *actual.Key != *expected.Key || *actual.Value != *expected.Value {
217-
t.Errorf("setAttributes - values did not match")
275+
err := a.setLoadBalancerAttributes(tt.annotations)
276+
if err != nil && tt.pass {
277+
t.Errorf("setLoadBalancerAttributes(%v): expected %v, errored: %v", tt.annotations, tt.expected, err)
278+
}
279+
if err != nil && !tt.pass {
280+
t.Errorf("setLoadBalancerAttributes(%v): should have errored", tt.annotations)
281+
}
282+
if err == nil && len(a.LoadBalancerAttributes) != tt.length {
283+
t.Errorf("setLoadBalancerAttributes(%v): expected %v attributes, actual %v", tt.annotations, tt.length, len(a.LoadBalancerAttributes))
284+
continue
285+
}
286+
for i := range a.LoadBalancerAttributes {
287+
if tt.pass && (*a.LoadBalancerAttributes[i].Key != *tt.expected[i].Key ||
288+
*a.LoadBalancerAttributes[i].Value != *tt.expected[i].Value) {
289+
t.Errorf("setLoadBalancerAttributes(%v): [test %v, attribute %v] passed but did not match (%v != %v) or (%v != %v)",
290+
tt.annotations, v, i, *a.LoadBalancerAttributes[i].Key, *tt.expected[i].Key,
291+
*a.LoadBalancerAttributes[i].Value, *tt.expected[i].Value)
292+
}
293+
}
218294
}
219295
}
220296

0 commit comments

Comments
 (0)