From d50f3b9d20e200f7289ae38ef13822a8ab2b562f Mon Sep 17 00:00:00 2001 From: mikutas <23391543+mikutas@users.noreply.github.com> Date: Thu, 28 Nov 2024 22:02:46 +0900 Subject: [PATCH 1/2] Add WAFv2ACLArn field to IngressClassParams --- apis/elbv2/v1beta1/ingressclassparams_types.go | 4 ++++ .../crd/bases/elbv2.k8s.aws_ingressclassparams.yaml | 3 +++ config/webhook/manifests.yaml | 1 - docs/guide/ingress/ingress_class.md | 11 +++++++++-- helm/aws-load-balancer-controller/crds/crds.yaml | 3 +++ pkg/ingress/model_build_load_balancer_addons.go | 5 +++++ 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apis/elbv2/v1beta1/ingressclassparams_types.go b/apis/elbv2/v1beta1/ingressclassparams_types.go index 4fc9216946..cb7ab8a046 100644 --- a/apis/elbv2/v1beta1/ingressclassparams_types.go +++ b/apis/elbv2/v1beta1/ingressclassparams_types.go @@ -156,6 +156,10 @@ type IngressClassParamsSpec struct { // MinimumLoadBalancerCapacity define the capacity reservation for LoadBalancers for all Ingress that belong to IngressClass with this IngressClassParams. // +optional MinimumLoadBalancerCapacity *MinimumLoadBalancerCapacity `json:"minimumLoadBalancerCapacity,omitempty"` + + // WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL. + // +optional + WAFv2ACLArn string `json:"wafv2AclArn"` } // +kubebuilder:object:root=true diff --git a/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml b/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml index 7f65f28ad7..4a7148db42 100644 --- a/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml +++ b/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml @@ -246,6 +246,9 @@ spec: - value type: object type: array + wafv2AclArn: + description: WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL. + type: string type: object type: object served: true diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 0b1a24bfed..1493d5386a 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -1,4 +1,3 @@ ---- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: diff --git a/docs/guide/ingress/ingress_class.md b/docs/guide/ingress/ingress_class.md index fd5d6ee954..51f811d9e2 100644 --- a/docs/guide/ingress/ingress_class.md +++ b/docs/guide/ingress/ingress_class.md @@ -187,8 +187,9 @@ Cluster administrators can use the optional `inboundCIDRs` field to specify the If the field is specified, LBC will ignore the `alb.ingress.kubernetes.io/inbound-cidrs` annotation. #### spec.certificateArn + Cluster administrators can use the optional `certificateARN` field to specify the ARN of the certificates for all Ingresses that belong to IngressClass with this IngressClassParams. - + If the field is specified, LBC will ignore the `alb.ingress.kubernetes.io/certificate-arn` annotation. #### spec.sslPolicy @@ -251,4 +252,10 @@ They may specify `capacityUnits`. If the field is specified, LBC will ignore the ##### spec.minimumLoadBalancerCapacity.capacityUnits -If `capacityUnits` is specified, it must be to valid positive value greater than 0. If set to 0, the LBC will reset the capacity reservation for the load balancer. \ No newline at end of file +If `capacityUnits` is specified, it must be to valid positive value greater than 0. If set to 0, the LBC will reset the capacity reservation for the load balancer. + +#### spec.wafv2AclArn + +Cluster administrators can use the optional `wafv2AclArn` field to specify ARN for the Amazon WAFv2 web ACL. +Only Regional WAFv2 is supported. +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'. diff --git a/helm/aws-load-balancer-controller/crds/crds.yaml b/helm/aws-load-balancer-controller/crds/crds.yaml index b72e687892..3b1048c677 100644 --- a/helm/aws-load-balancer-controller/crds/crds.yaml +++ b/helm/aws-load-balancer-controller/crds/crds.yaml @@ -245,6 +245,9 @@ spec: - value type: object type: array + wafv2AclArn: + description: WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL. + type: string type: object type: object served: true diff --git a/pkg/ingress/model_build_load_balancer_addons.go b/pkg/ingress/model_build_load_balancer_addons.go index dde8c7595c..f8bca68c14 100644 --- a/pkg/ingress/model_build_load_balancer_addons.go +++ b/pkg/ingress/model_build_load_balancer_addons.go @@ -2,6 +2,7 @@ package ingress import ( "context" + "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/aws-load-balancer-controller/pkg/annotations" @@ -39,6 +40,10 @@ func (t *defaultModelBuildTask) buildWAFv2WebACLAssociation(_ context.Context, l if rawWebACLARN != "" { explicitWebACLARNs.Insert(rawWebACLARN) } + params := member.IngClassConfig.IngClassParams + if params != nil && params.Spec.WAFv2ACLArn != "" { + explicitWebACLARNs.Insert(params.Spec.WAFv2ACLArn) + } } if len(explicitWebACLARNs) == 0 { return nil, nil From a64780e98dfe8cc9210f294a9100394a12d1683d Mon Sep 17 00:00:00 2001 From: mikutas <23391543+mikutas@users.noreply.github.com> Date: Thu, 28 Nov 2024 22:27:56 +0900 Subject: [PATCH 2/2] Add a test --- pkg/ingress/model_builder_test.go | 108 +++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/pkg/ingress/model_builder_test.go b/pkg/ingress/model_builder_test.go index c9040a4b3e..21a9c3445d 100644 --- a/pkg/ingress/model_builder_test.go +++ b/pkg/ingress/model_builder_test.go @@ -3,11 +3,12 @@ package ingress import ( "context" "encoding/json" - ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" - elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "testing" "time" + ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" + awssdk "github.com/aws/aws-sdk-go-v2/aws" jsonpatch "github.com/evanphx/json-patch" "github.com/go-logr/logr" @@ -2141,6 +2142,109 @@ func Test_defaultModelBuilder_Build(t *testing.T) { "80:3": null } } +}`, + }, + { + name: "Ingress - wafv2AclArn in IngressClassParams", + env: env{ + svcs: []*corev1.Service{ns_1_svc_1, ns_1_svc_2, ns_1_svc_3}, + }, + fields: fields{ + resolveViaDiscoveryCalls: []resolveViaDiscoveryCall{resolveViaDiscoveryCallForInternalLB}, + listLoadBalancersCalls: []listLoadBalancersCall{listLoadBalancerCallForEmptyLB}, + enableBackendSG: true, + }, + args: args{ + ingGroup: Group{ + ID: GroupID{Namespace: "ns-1", Name: "ing-1"}, + Members: []ClassifiedIngress{ + { + IngClassConfig: ClassConfiguration{ + IngClassParams: &v1beta1.IngressClassParams{ + Spec: v1beta1.IngressClassParamsSpec{ + WAFv2ACLArn: "alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:us-west-2:xxxxx:regional/webacl/xxxxxxx/3ab78708-85b0-49d3-b4e1-7a9615a6613b", + }, + }, + }, + Ing: &networking.Ingress{ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-1", + Name: "ing-1", + }, + Spec: networking.IngressSpec{ + Rules: []networking.IngressRule{ + { + Host: "app-1.example.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/svc-1", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_1.Name, + Port: networking.ServiceBackendPort{ + Name: "http", + }, + }, + }, + }, + { + Path: "/svc-2", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_2.Name, + Port: networking.ServiceBackendPort{ + Name: "http", + }, + }, + }, + }, + }, + }, + }, + }, + { + Host: "app-2.example.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/svc-3", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_3.Name, + Port: networking.ServiceBackendPort{ + Name: "https", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + wantStackPatch: ` +{ + "id":"ns-1/ing-1", + "resources":{ + "AWS::WAFv2::WebACLAssociation":{ + "LoadBalancer":{ + "spec":{ + "resourceARN":{ + "$ref":"#/resources/AWS::ElasticLoadBalancingV2::LoadBalancer/LoadBalancer/status/loadBalancerARN" + }, + "webACLARN":"alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:us-west-2:xxxxx:regional/webacl/xxxxxxx/3ab78708-85b0-49d3-b4e1-7a9615a6613b" + } + } + } + } }`, }, {