Skip to content

Commit

Permalink
keep LB addons' settings unchanged unless explicitly specified
Browse files Browse the repository at this point in the history
  • Loading branch information
M00nF1sh committed Aug 8, 2024
1 parent e5d625f commit e3e44a7
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 84 deletions.
36 changes: 12 additions & 24 deletions pkg/deploy/shield/protection_synthesizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package shield

import (
"context"
"fmt"
"github.com/go-logr/logr"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/aws-load-balancer-controller/pkg/model/core"
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
shieldmodel "sigs.k8s.io/aws-load-balancer-controller/pkg/model/shield"
)

Expand All @@ -32,25 +32,18 @@ type protectionSynthesizer struct {

func (s *protectionSynthesizer) Synthesize(ctx context.Context) error {
var resProtections []*shieldmodel.Protection
s.stack.ListResources(&resProtections)
if err := s.stack.ListResources(&resProtections); err != nil {
return fmt.Errorf("[should never happen] failed to list resources: %w", err)
}
if len(resProtections) == 0 {
return nil
}
resProtectionsByResARN, err := mapResProtectionByResourceARN(resProtections)
if err != nil {
return err
}

var resLBs []*elbv2model.LoadBalancer
s.stack.ListResources(&resLBs)
for _, resLB := range resLBs {
// shield protection can only be associated with ALB for now.
if resLB.Spec.Type != elbv2model.LoadBalancerTypeApplication {
continue
}
lbARN, err := resLB.LoadBalancerARN().Resolve(ctx)
if err != nil {
return err
}
resProtections := resProtectionsByResARN[lbARN]
if err := s.synthesizeProtectionsOnLB(ctx, lbARN, resProtections); err != nil {
for resARN, protections := range resProtectionsByResARN {
if err := s.synthesizeProtectionsOnLB(ctx, resARN, protections); err != nil {
return err
}
}
Expand All @@ -63,15 +56,10 @@ func (s *protectionSynthesizer) PostSynthesize(ctx context.Context) error {
}

func (s *protectionSynthesizer) synthesizeProtectionsOnLB(ctx context.Context, lbARN string, resProtections []*shieldmodel.Protection) error {
if len(resProtections) > 1 {
return errors.Errorf("[should never happen] multiple shield protection desired on LoadBalancer: %v", lbARN)
if len(resProtections) != 1 {
return errors.Errorf("[should never happen] should be exactly one shield protection desired on LoadBalancer: %v", lbARN)
}

enableProtection := false
if len(resProtections) == 1 {
enableProtection = true
}

enableProtection := resProtections[0].Spec.Enabled
protectionInfo, err := s.protectionManager.GetProtection(ctx, lbARN)
if err != nil {
return err
Expand Down
41 changes: 15 additions & 26 deletions pkg/deploy/wafregional/web_acl_association_synthesizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package wafregional

import (
"context"
"fmt"
"github.com/go-logr/logr"
"github.com/pkg/errors"
"sigs.k8s.io/aws-load-balancer-controller/pkg/model/core"
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
wafregionalmodel "sigs.k8s.io/aws-load-balancer-controller/pkg/model/wafregional"
)

Expand All @@ -26,25 +26,18 @@ type webACLAssociationSynthesizer struct {

func (s *webACLAssociationSynthesizer) Synthesize(ctx context.Context) error {
var resAssociations []*wafregionalmodel.WebACLAssociation
s.stack.ListResources(&resAssociations)
if err := s.stack.ListResources(&resAssociations); err != nil {
return fmt.Errorf("[should never happen] failed to list resources: %w", err)
}
if len(resAssociations) == 0 {
return nil
}
resAssociationsByResARN, err := mapResWebACLAssociationByResourceARN(resAssociations)
if err != nil {
return err
}

var resLBs []*elbv2model.LoadBalancer
s.stack.ListResources(&resLBs)
for _, resLB := range resLBs {
// wafRegional WebACL can only be associated with ALB for now.
if resLB.Spec.Type != elbv2model.LoadBalancerTypeApplication {
continue
}
lbARN, err := resLB.LoadBalancerARN().Resolve(ctx)
if err != nil {
return err
}
resAssociations := resAssociationsByResARN[lbARN]
if err := s.synthesizeWebACLAssociationsOnLB(ctx, lbARN, resAssociations); err != nil {
for resARN, webACLAssociations := range resAssociationsByResARN {
if err := s.synthesizeWebACLAssociationsOnLB(ctx, resARN, webACLAssociations); err != nil {
return err
}
}
Expand All @@ -57,30 +50,26 @@ func (s *webACLAssociationSynthesizer) PostSynthesize(ctx context.Context) error
}

func (s *webACLAssociationSynthesizer) synthesizeWebACLAssociationsOnLB(ctx context.Context, lbARN string, resAssociations []*wafregionalmodel.WebACLAssociation) error {
if len(resAssociations) > 1 {
return errors.Errorf("[should never happen] multiple WAFRegional webACL desired on LoadBalancer: %v", lbARN)
}

var desiredWebACLID string
if len(resAssociations) == 1 {
desiredWebACLID = resAssociations[0].Spec.WebACLID
if len(resAssociations) != 1 {
return errors.Errorf("[should never happen] should be exactly one WAFRegional webACL desired on LoadBalancer: %v", lbARN)
}
desiredWebACLID := resAssociations[0].Spec.WebACLID
currentWebACLID, err := s.associationManager.GetAssociatedWebACL(ctx, lbARN)
if err != nil {
return err
}
switch {
case desiredWebACLID == "" && currentWebACLID != "":
if err := s.associationManager.DisassociateWebACL(ctx, lbARN); err != nil {
return errors.Wrap(err, "failed to delete WAFv2 WAFRegional association on LoadBalancer")
return errors.Wrap(err, "failed to delete WAFRegional association on LoadBalancer")
}
case desiredWebACLID != "" && currentWebACLID == "":
if err := s.associationManager.AssociateWebACL(ctx, lbARN, desiredWebACLID); err != nil {
return errors.Wrap(err, "failed to create WAFv2 WAFRegional association on LoadBalancer")
return errors.Wrap(err, "failed to create WAFRegional association on LoadBalancer")
}
case desiredWebACLID != "" && currentWebACLID != "" && desiredWebACLID != currentWebACLID:
if err := s.associationManager.AssociateWebACL(ctx, lbARN, desiredWebACLID); err != nil {
return errors.Wrap(err, "failed to update WAFv2 WAFRegional association on LoadBalancer")
return errors.Wrap(err, "failed to update WAFRegional association on LoadBalancer")
}
}
return nil
Expand Down
35 changes: 12 additions & 23 deletions pkg/deploy/wafv2/web_acl_association_synthesizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package wafv2

import (
"context"
"fmt"
"github.com/go-logr/logr"
"github.com/pkg/errors"
"sigs.k8s.io/aws-load-balancer-controller/pkg/model/core"
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
wafv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/wafv2"
)

Expand All @@ -26,25 +26,18 @@ type webACLAssociationSynthesizer struct {

func (s *webACLAssociationSynthesizer) Synthesize(ctx context.Context) error {
var resAssociations []*wafv2model.WebACLAssociation
s.stack.ListResources(&resAssociations)
if err := s.stack.ListResources(&resAssociations); err != nil {
return fmt.Errorf("[should never happen] failed to list resources: %w", err)
}
if len(resAssociations) == 0 {
return nil
}
resAssociationsByResARN, err := mapResWebACLAssociationByResourceARN(resAssociations)
if err != nil {
return err
}

var resLBs []*elbv2model.LoadBalancer
s.stack.ListResources(&resLBs)
for _, resLB := range resLBs {
// wafv2 WebACL can only be associated with ALB for now.
if resLB.Spec.Type != elbv2model.LoadBalancerTypeApplication {
continue
}
lbARN, err := resLB.LoadBalancerARN().Resolve(ctx)
if err != nil {
return err
}
resAssociations := resAssociationsByResARN[lbARN]
if err := s.synthesizeWebACLAssociationsOnLB(ctx, lbARN, resAssociations); err != nil {
for resARN, webACLAssociations := range resAssociationsByResARN {
if err := s.synthesizeWebACLAssociationsOnLB(ctx, resARN, webACLAssociations); err != nil {
return err
}
}
Expand All @@ -57,14 +50,10 @@ func (s *webACLAssociationSynthesizer) PostSynthesize(ctx context.Context) error
}

func (s *webACLAssociationSynthesizer) synthesizeWebACLAssociationsOnLB(ctx context.Context, lbARN string, resAssociations []*wafv2model.WebACLAssociation) error {
if len(resAssociations) > 1 {
return errors.Errorf("[should never happen] multiple WAFv2 webACL desired on LoadBalancer: %v", lbARN)
}

var desiredWebACLARN string
if len(resAssociations) == 1 {
desiredWebACLARN = resAssociations[0].Spec.WebACLARN
if len(resAssociations) != 1 {
return errors.Errorf("[should never happen] should be exactly one WAFv2 webACL association on LoadBalancer: %v", lbARN)
}
desiredWebACLARN := resAssociations[0].Spec.WebACLARN
currentWebACLARN, err := s.associationManager.GetAssociatedWebACL(ctx, lbARN)
if err != nil {
return err
Expand Down
44 changes: 33 additions & 11 deletions pkg/ingress/model_build_load_balancer_addons.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import (
wafv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/wafv2"
)

const (
// sentinel annotation value to disable wafv2 ACL on resources.
wafv2ACLARNNone = "none"
// sentinel annotation value to disable wafRegional on resources.
webACLIDNone = "none"
)

func (t *defaultModelBuildTask) buildLoadBalancerAddOns(ctx context.Context, lbARN core.StringToken) error {
if _, err := t.buildWAFv2WebACLAssociation(ctx, lbARN); err != nil {
return err
Expand Down Expand Up @@ -39,14 +46,22 @@ func (t *defaultModelBuildTask) buildWAFv2WebACLAssociation(_ context.Context, l
return nil, errors.Errorf("conflicting WAFv2 WebACL ARNs: %v", explicitWebACLARNs.List())
}
webACLARN, _ := explicitWebACLARNs.PopAny()
if webACLARN != "" {
switch webACLARN {
case "":
return nil, nil
case wafv2ACLARNNone:
association := wafv2model.NewWebACLAssociation(t.stack, resourceIDLoadBalancer, wafv2model.WebACLAssociationSpec{
WebACLARN: "",
ResourceARN: lbARN,
})
return association, nil
default:
association := wafv2model.NewWebACLAssociation(t.stack, resourceIDLoadBalancer, wafv2model.WebACLAssociationSpec{
WebACLARN: webACLARN,
ResourceARN: lbARN,
})
return association, nil
}
return nil, nil
}

func (t *defaultModelBuildTask) buildWAFRegionalWebACLAssociation(_ context.Context, lbARN core.StringToken) (*wafregionalmodel.WebACLAssociation, error) {
Expand All @@ -66,14 +81,22 @@ func (t *defaultModelBuildTask) buildWAFRegionalWebACLAssociation(_ context.Cont
return nil, errors.Errorf("conflicting WAFRegional WebACL IDs: %v", explicitWebACLIDs.List())
}
webACLID, _ := explicitWebACLIDs.PopAny()
if webACLID != "" {
switch webACLID {
case "":
return nil, nil
case webACLIDNone:
association := wafregionalmodel.NewWebACLAssociation(t.stack, resourceIDLoadBalancer, wafregionalmodel.WebACLAssociationSpec{
WebACLID: "",
ResourceARN: lbARN,
})
return association, nil
default:
association := wafregionalmodel.NewWebACLAssociation(t.stack, resourceIDLoadBalancer, wafregionalmodel.WebACLAssociationSpec{
WebACLID: webACLID,
ResourceARN: lbARN,
})
return association, nil
}
return nil, nil
}

func (t *defaultModelBuildTask) buildShieldProtection(_ context.Context, lbARN core.StringToken) (*shieldmodel.Protection, error) {
Expand All @@ -94,11 +117,10 @@ func (t *defaultModelBuildTask) buildShieldProtection(_ context.Context, lbARN c
if len(explicitEnableProtections) > 1 {
return nil, errors.New("conflicting enable shield advanced protection")
}
if _, enableProtection := explicitEnableProtections[true]; enableProtection {
protection := shieldmodel.NewProtection(t.stack, resourceIDLoadBalancer, shieldmodel.ProtectionSpec{
ResourceARN: lbARN,
})
return protection, nil
}
return nil, nil
_, enableProtection := explicitEnableProtections[true]
protection := shieldmodel.NewProtection(t.stack, resourceIDLoadBalancer, shieldmodel.ProtectionSpec{
Enabled: enableProtection,
ResourceARN: lbARN,
})
return protection, nil
}
1 change: 1 addition & 0 deletions pkg/model/shield/protection.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ func (p *Protection) registerDependencies(stack core.Stack) {

// ProtectionSpec defines the desired state of Protection.
type ProtectionSpec struct {
Enabled bool `json:"enabled"`
ResourceARN core.StringToken `json:"resourceARN"`
}

0 comments on commit e3e44a7

Please sign in to comment.