Skip to content

Commit b5986dc

Browse files
authored
feature: get waf arn from name (#4312)
* feature: get waf arn from name * feature: get waf arn from name * feature: add docs and additional tests * feature: add docs and additional tests * feature: fix docs and webaclarn retrieval
1 parent 1655f71 commit b5986dc

File tree

12 files changed

+591
-17
lines changed

12 files changed

+591
-17
lines changed

apis/elbv2/v1beta1/ingressclassparams_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ type IngressClassParamsSpec struct {
189189
// WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL.
190190
// +optional
191191
WAFv2ACLArn string `json:"wafv2AclArn"`
192+
193+
// WAFv2ACLName specifies name of the Amazon WAFv2 web ACL.
194+
// +optional
195+
WAFv2ACLName string `json:"wafv2AclName"`
192196
}
193197

194198
// +kubebuilder:object:root=true

config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,9 @@ spec:
282282
wafv2AclArn:
283283
description: WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL.
284284
type: string
285+
wafv2AclName:
286+
description: WAFv2ACLName specifies name of the Amazon WAFv2 web ACL.
287+
type: string
285288
type: object
286289
x-kubernetes-validations:
287290
- message: cannot specify both 'prefixListsIDs' and 'PrefixListsIDs' fields

controllers/ingress/group_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func NewGroupReconciler(cloud services.Cloud, k8sClient client.Client, eventReco
6262
referenceIndexer := ingress.NewDefaultReferenceIndexer(enhancedBackendBuilder, authConfigBuilder, logger)
6363
trackingProvider := tracking.NewDefaultProvider(ingressTagPrefix, controllerConfig.ClusterName)
6464
modelBuilder := ingress.NewDefaultModelBuilder(k8sClient, eventRecorder,
65-
cloud.EC2(), cloud.ELBV2(), cloud.ACM(),
65+
cloud.EC2(), cloud.ELBV2(), cloud.WAFv2(), cloud.ACM(),
6666
annotationParser, subnetsResolver,
6767
authConfigBuilder, enhancedBackendBuilder, trackingProvider, elbv2TaggingManager, controllerConfig.FeatureGates,
6868
cloud.VpcID(), controllerConfig.ClusterName, controllerConfig.DefaultTags, controllerConfig.ExternalManagedTags,

docs/guide/ingress/annotations.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,24 @@ Load balancer capacity unit reservation can be configured via following annotati
10411041
- disable WAFV2
10421042
```alb.ingress.kubernetes.io/wafv2-acl-arn: none
10431043
```
1044-
1044+
1045+
- <a name="wafv2-acl-name">`alb.ingress.kubernetes.io/wafv2-acl-name`</a> specifies Name of the Amazon WAFv2 web ACL.
1046+
1047+
!!!warning ""
1048+
Only Regional WAFv2 is supported.
1049+
1050+
!!!note ""
1051+
When this annotation is absent or empty, the controller will keep LoadBalancer WAFv2 settings unchanged.
1052+
To disable WAFv2, explicitly set the annotation value to 'none'.
1053+
1054+
!!!example
1055+
- enable WAFv2
1056+
```alb.ingress.kubernetes.io/wafv2-acl-name: web-acl-name-1
1057+
```
1058+
- disable WAFV2
1059+
```alb.ingress.kubernetes.io/wafv2-acl-name: none
1060+
```
1061+
10451062
- <a name="shield-advanced-protection">`alb.ingress.kubernetes.io/shield-advanced-protection`</a> turns on / off the AWS Shield Advanced protection for the load balancer.
10461063
10471064
!!!note ""

docs/guide/ingress/ingress_class.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,15 @@ You can use IngressClassParams to enforce settings for a set of Ingresses.
220220
- key: routing.http.response.server.enabled
221221
value: "false"
222222
```
223+
- with wafv2AclName
224+
```
225+
apiVersion: elbv2.k8s.aws/v1beta1
226+
kind: IngressClassParams
227+
metadata:
228+
name: class2048-config
229+
spec:
230+
wafv2AclName: "web-acl-name-1"
231+
```
223232

224233
### IngressClassParams specification
225234

@@ -384,4 +393,11 @@ Cluster administrators can use `Listeners` field to specify the [Listener Attrib
384393

385394
Cluster administrators can use the optional `wafv2AclArn` field to specify ARN for the Amazon WAFv2 web ACL.
386395
Only Regional WAFv2 is supported.
387-
When this annotation is absent or empty, the controller will keep LoadBalancer WAFv2 settings unchanged. To disable WAFv2, explicitly set the annotation value to 'none'.
396+
When this param is absent or empty, the controller will keep LoadBalancer WAFv2 settings unchanged. To disable WAFv2, explicitly set the annotation value to 'none'.
397+
398+
#### spec.wafv2AclName
399+
400+
Cluster administrators can use the optional `wafv2AclName` field to specify name of the Amazon WAFv2 web ACL.
401+
Only Regional WAFv2 is supported.
402+
When this param is absent or empty, the controller will keep LoadBalancer WAFv2 settings unchanged. To disable WAFv2, explicitly set the param value to 'none'.
403+
If the field is specified, LBC will ignore the 'alb.ingress.kubernetes.io/wafv2-acl-name' annotation.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ spec:
281281
wafv2AclArn:
282282
description: WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL.
283283
type: string
284+
wafv2AclName:
285+
description: WAFv2ACLName specifies name of the Amazon WAFv2 web ACL.
286+
type: string
284287
type: object
285288
x-kubernetes-validations:
286289
- message: cannot specify both 'prefixListsIDs' and 'PrefixListsIDs' fields

pkg/annotations/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const (
2323
IngressSuffixCustomerOwnedIPv4Pool = "customer-owned-ipv4-pool"
2424
IngressSuffixLoadBalancerAttributes = "load-balancer-attributes"
2525
IngressSuffixWAFv2ACLARN = "wafv2-acl-arn"
26+
IngressSuffixWAFv2ACLName = "wafv2-acl-name"
2627
IngressSuffixWAFACLID = "waf-acl-id"
2728
IngressSuffixWebACLID = "web-acl-id" // deprecated, use "waf-acl-id" instead.
2829
IngressSuffixShieldAdvancedProtection = "shield-advanced-protection"

pkg/aws/services/wafv2.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type WAFv2 interface {
1010
AssociateWebACLWithContext(context.Context, *wafv2.AssociateWebACLInput) (*wafv2.AssociateWebACLOutput, error)
1111
DisassociateWebACLWithContext(ctx context.Context, req *wafv2.DisassociateWebACLInput) (*wafv2.DisassociateWebACLOutput, error)
1212
GetWebACLForResourceWithContext(ctx context.Context, req *wafv2.GetWebACLForResourceInput) (*wafv2.GetWebACLForResourceOutput, error)
13+
GetWebACLWithContext(ctx context.Context, req *wafv2.GetWebACLInput) (*wafv2.GetWebACLOutput, error)
1314
}
1415

1516
// NewWAFv2 constructs new WAFv2 implementation.
@@ -46,3 +47,11 @@ func (c *wafv2Client) GetWebACLForResourceWithContext(ctx context.Context, req *
4647
}
4748
return client.GetWebACLForResource(ctx, req)
4849
}
50+
51+
func (c *wafv2Client) GetWebACLWithContext(ctx context.Context, req *wafv2.GetWebACLInput) (*wafv2.GetWebACLOutput, error) {
52+
client, err := c.awsClientsProvider.GetWAFv2Client(ctx, "GetWebACL")
53+
if err != nil {
54+
return nil, err
55+
}
56+
return client.GetWebACL(ctx, req)
57+
}

pkg/aws/services/wafv2_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/ingress/model_build_load_balancer_addons.go

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,63 @@ func (t *defaultModelBuildTask) buildLoadBalancerAddOns(ctx context.Context, lbA
3232
return nil
3333
}
3434

35-
func (t *defaultModelBuildTask) buildWAFv2WebACLAssociation(_ context.Context, lbARN core.StringToken) (*wafv2model.WebACLAssociation, error) {
35+
func (t *defaultModelBuildTask) buildWAFv2WebACLAssociation(ctx context.Context, lbARN core.StringToken) (*wafv2model.WebACLAssociation, error) {
3636
explicitWebACLARNs := sets.NewString()
37+
explicitWebACLNames := sets.NewString()
38+
3739
for _, member := range t.ingGroup.Members {
38-
rawWebACLARN := ""
39-
_ = t.annotationParser.ParseStringAnnotation(annotations.IngressSuffixWAFv2ACLARN, &rawWebACLARN, member.Ing.Annotations)
40-
if rawWebACLARN != "" {
40+
if member.IngClassConfig.IngClassParams != nil && member.IngClassConfig.IngClassParams.Spec.WAFv2ACLName != "" {
41+
rawWebACLName := member.IngClassConfig.IngClassParams.Spec.WAFv2ACLName
42+
explicitWebACLNames.Insert(rawWebACLName)
43+
continue
44+
}
45+
rawWebACLName := ""
46+
_ = t.annotationParser.ParseStringAnnotation(annotations.IngressSuffixWAFv2ACLName, &rawWebACLName, member.Ing.Annotations)
47+
if rawWebACLName != "" {
48+
explicitWebACLNames.Insert(rawWebACLName)
49+
}
50+
}
51+
52+
webACLARN := ""
53+
54+
if len(explicitWebACLNames) == 0 {
55+
for _, member := range t.ingGroup.Members {
56+
if member.IngClassConfig.IngClassParams != nil && member.IngClassConfig.IngClassParams.Spec.WAFv2ACLArn != "" {
57+
webACLARN = member.IngClassConfig.IngClassParams.Spec.WAFv2ACLArn
58+
explicitWebACLARNs.Insert(webACLARN)
59+
continue
60+
}
61+
62+
rawWebACLARN := ""
63+
if exists := t.annotationParser.ParseStringAnnotation(annotations.IngressSuffixWAFv2ACLARN, &rawWebACLARN, member.Ing.Annotations); !exists {
64+
continue
65+
}
4166
explicitWebACLARNs.Insert(rawWebACLARN)
4267
}
43-
params := member.IngClassConfig.IngClassParams
44-
if params != nil && params.Spec.WAFv2ACLArn != "" {
45-
explicitWebACLARNs.Insert(params.Spec.WAFv2ACLArn)
68+
if len(explicitWebACLARNs) == 0 {
69+
return nil, nil
4670
}
71+
if len(explicitWebACLARNs) > 1 {
72+
return nil, errors.Errorf("conflicting WAFv2 WebACL ARNs: %v", explicitWebACLARNs.List())
73+
}
74+
webACLARN, _ = explicitWebACLARNs.PopAny()
4775
}
48-
if len(explicitWebACLARNs) == 0 {
49-
return nil, nil
76+
77+
if len(explicitWebACLNames) > 1 {
78+
return nil, errors.Errorf("conflicting WAFv2 WebACL names: %v", explicitWebACLNames.List())
5079
}
51-
if len(explicitWebACLARNs) > 1 {
52-
return nil, errors.Errorf("conflicting WAFv2 WebACL ARNs: %v", explicitWebACLARNs.List())
80+
81+
if len(explicitWebACLNames) == 1 {
82+
rawWebACLName, _ := explicitWebACLNames.PopAny()
83+
if rawWebACLName != "none" {
84+
var err error
85+
webACLARN, err = t.webACLNameToArnMapper.getArnByName(ctx, rawWebACLName)
86+
if err != nil {
87+
return nil, errors.Errorf("couldn't find WAFv2 WebACL with name: %v", rawWebACLName)
88+
}
89+
}
5390
}
54-
webACLARN, _ := explicitWebACLARNs.PopAny()
91+
5592
switch webACLARN {
5693
case wafv2ACLARNNone:
5794
association := wafv2model.NewWebACLAssociation(t.stack, resourceIDLoadBalancer, wafv2model.WebACLAssociationSpec{

0 commit comments

Comments
 (0)