Skip to content

Commit

Permalink
Fix for leaking target groups on service delete (#525)
Browse files Browse the repository at this point in the history
* Fix for leaking target groups on service delete due to listener delete race condition
  • Loading branch information
erikfuller authored Nov 18, 2023
1 parent af28cb1 commit f69e34c
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docs/contributing/developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ make e2e-clean

## Local Development

A minimal sanity check on changes can be done with make presubmit. This command will also run on PR.
A minimal test of changes can be done with ```make presubmit```. This command will also run on PR.

```
make presubmit
Expand Down
18 changes: 18 additions & 0 deletions pkg/aws/services/vpclattice.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func IsInvalidError(err error) bool {

type Lattice interface {
vpclatticeiface.VPCLatticeAPI
ListListenersAsList(ctx context.Context, input *vpclattice.ListListenersInput) ([]*vpclattice.ListenerSummary, error)
GetRulesAsList(ctx context.Context, input *vpclattice.ListRulesInput) ([]*vpclattice.GetRuleOutput, error)
ListRulesAsList(ctx context.Context, input *vpclattice.ListRulesInput) ([]*vpclattice.RuleSummary, error)
ListServiceNetworksAsList(ctx context.Context, input *vpclattice.ListServiceNetworksInput) ([]*vpclattice.ServiceNetworkSummary, error)
Expand Down Expand Up @@ -128,6 +129,23 @@ func NewDefaultLattice(sess *session.Session, region string) *defaultLattice {
return &defaultLattice{VPCLatticeAPI: latticeSess, cache: cache}
}

func (d *defaultLattice) ListListenersAsList(ctx context.Context, input *vpclattice.ListListenersInput) ([]*vpclattice.ListenerSummary, error) {
var result []*vpclattice.ListenerSummary

err := d.ListListenersPagesWithContext(ctx, input, func(page *vpclattice.ListListenersOutput, lastPage bool) bool {
for _, l := range page.Items {
result = append(result, l)
}
return true
})

if err != nil {
return nil, err
}

return result, nil
}

func (d *defaultLattice) GetRulesAsList(ctx context.Context, input *vpclattice.ListRulesInput) ([]*vpclattice.GetRuleOutput, error) {
var result []*vpclattice.GetRuleOutput

Expand Down
15 changes: 15 additions & 0 deletions pkg/aws/services/vpclattice_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions pkg/deploy/lattice/service_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,25 @@ func (m *defaultServiceManager) deleteAllAssociations(ctx context.Context, svc *
return nil
}

func (m *defaultServiceManager) deleteAllListeners(ctx context.Context, svc *SvcSummary) error {
listeners, err := m.cloud.Lattice().ListListenersAsList(ctx, &vpclattice.ListListenersInput{
ServiceIdentifier: svc.Id,
})
if err != nil {
return err
}
for _, listener := range listeners {
_, err = m.cloud.Lattice().DeleteListenerWithContext(ctx, &vpclattice.DeleteListenerInput{
ServiceIdentifier: svc.Id,
ListenerIdentifier: listener.Id,
})
if err != nil {
return err
}
}
return nil
}

func (m *defaultServiceManager) deleteAssociation(ctx context.Context, assocArn *string) error {
delReq := &DelSnSvcAssocReq{ServiceNetworkServiceAssociationIdentifier: assocArn}
_, err := m.cloud.Lattice().DeleteServiceNetworkServiceAssociationWithContext(ctx, delReq)
Expand Down Expand Up @@ -371,6 +390,12 @@ func (m *defaultServiceManager) Delete(ctx context.Context, svc *Service) error
return err
}

// deleting listeners explicitly helps ensure target groups are free to delete
err = m.deleteAllListeners(ctx, svcSum)
if err != nil {
return err
}

err = m.deleteService(ctx, svcSum)
if err != nil {
return err
Expand Down
17 changes: 17 additions & 0 deletions pkg/deploy/lattice/service_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,23 @@ func TestServiceManagerInteg(t *testing.T) {
DeleteServiceWithContext(gomock.Any(), gomock.Any()).Return(nil, nil).
Times(1)

// assert we delete listeners
mockLattice.EXPECT().
ListListenersAsList(gomock.Any(), gomock.Any()).
Return([]*vpclattice.ListenerSummary{
{
Id: aws.String("L1"),
},
{
Id: aws.String("L2"),
},
}, nil)

mockLattice.EXPECT().
DeleteListenerWithContext(gomock.Any(), gomock.Any()).
Return(nil, nil).
Times(2)

err := m.Delete(ctx, svc)
assert.Nil(t, err)
})
Expand Down

0 comments on commit f69e34c

Please sign in to comment.