Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove DisassociateAllBranchENIs as it is not useful #400

Merged
merged 3 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

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

14 changes: 9 additions & 5 deletions pkg/aws/ec2/api/cleanup/eni_cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ package cleanup
import (
"context"
"fmt"
"strings"
"time"

"github.com/aws/amazon-vpc-resource-controller-k8s/pkg/aws/ec2/api"
"github.com/aws/amazon-vpc-resource-controller-k8s/pkg/config"
rcHealthz "github.com/aws/amazon-vpc-resource-controller-k8s/pkg/healthz"
"github.com/aws/amazon-vpc-resource-controller-k8s/pkg/utils"

ec2Errors "github.com/aws/amazon-vpc-resource-controller-k8s/pkg/aws/errors"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/go-logr/logr"
Expand Down Expand Up @@ -150,11 +152,13 @@ func (e *ENICleaner) DeleteLeakedResources() error {
NetworkInterfaceId: nwInterface.NetworkInterfaceId,
})
if err != nil {
// append err and continue, we will retry deletion in the next period/reconcile
leakedENICount += 1
errors = append(errors, fmt.Errorf("failed to delete leaked network interface %v:%v", *nwInterface.NetworkInterfaceId, err))
e.Log.Error(err, "failed to delete the leaked network interface",
"id", *nwInterface.NetworkInterfaceId)
if !strings.Contains(err.Error(), ec2Errors.NotFoundInterfaceID) { // ignore InvalidNetworkInterfaceID.NotFound error
// append err and continue, we will retry deletion in the next period/reconcile
leakedENICount += 1
errors = append(errors, fmt.Errorf("failed to delete leaked network interface %v:%v", *nwInterface.NetworkInterfaceId, err))
e.Log.Error(err, "failed to delete the leaked network interface",
"id", *nwInterface.NetworkInterfaceId)
}
continue
}
e.Log.Info("deleted leaked ENI successfully", "eni id", nwInterface.NetworkInterfaceId)
Expand Down
2 changes: 1 addition & 1 deletion pkg/node/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ func (m *manager) performAsyncOperation(job interface{}) (ctrl.Result, error) {
log.V(1).Info("successfully performed node operation")
return ctrl.Result{}, nil
}
log.Error(err, "failed to performed node operation")
log.Error(err, "failed to perform node operation")

return ctrl.Result{}, nil
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/provider/branch/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,14 @@ func (b *branchENIProvider) ProcessAsyncJob(job interface{}) (ctrl.Result, error

// DeleteNode deletes all the cached branch ENIs associated with the trunk and removes the trunk from the cache.
func (b *branchENIProvider) DeleteNode(nodeName string) (ctrl.Result, error) {
trunkENI, isPresent := b.getTrunkFromCache(nodeName)
_, isPresent := b.getTrunkFromCache(nodeName)
if !isPresent {
return ctrl.Result{}, fmt.Errorf("failed to find node %s", nodeName)
}

trunkENI.DisassociateAllBranchENIs()
// At this point, the finalizer routine should have deleted all available branch ENIs
// Any leaked ENIs will be deleted by the periodic cleanup routine if cluster is active
// remove trunk from cache and de-initializer the resource provider
b.removeTrunkFromCache(nodeName)

b.log.Info("de-initialized resource provider successfully", "node name", nodeName)
Expand Down
39 changes: 1 addition & 38 deletions pkg/provider/branch/trunk/trunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ import (
"github.com/go-logr/logr"
"github.com/prometheus/client_golang/prometheus"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/metrics"
)

Expand Down Expand Up @@ -95,8 +93,6 @@ type TrunkENI interface {
Reconcile(pods []v1.Pod) bool
// PushENIsToFrontOfDeleteQueue pushes the eni network interfaces to the front of the delete queue
PushENIsToFrontOfDeleteQueue(*v1.Pod, []*ENIDetails)
// DisassociateAllBranchENIs removes association of all the branch ENI with the trunk
DisassociateAllBranchENIs()
// Introspect returns the state of the Trunk ENI
Introspect() IntrospectResponse
}
Expand Down Expand Up @@ -437,39 +433,6 @@ func (t *trunkENI) CreateAndAssociateBranchENIs(pod *v1.Pod, securityGroups []st
return newENIs, nil
}

// DisassociateAllBranchENIs removes association between all the branch ENIs with the trunk. The branch ENIs will be deleted by the node termination finalizer
// This is the last API call to the the Trunk ENI before it is removed from cache
func (t *trunkENI) DisassociateAllBranchENIs() {
// Disassociate all the branch used by the pod on this trunk ENI, it will be cleaned up by the finalizer routine
// Since after this call, the trunk will be removed from cache. No need to clean up its branch map
for _, podENIs := range t.uidToBranchENIMap {
for _, eni := range podENIs {
err := retry.OnError(
wait.Backoff{
Duration: time.Millisecond * 100,
Factor: 3.0,
Jitter: 0.1,
Steps: 7,
Cap: time.Second * 10,
},
func(err error) bool {
if strings.Contains(err.Error(), ec2Errors.NotFoundAssociationID) {
// association is already deleted, do not retry
return false
}
return true
}, func() error {
return t.ec2ApiHelper.DisassociateTrunkInterface(&eni.AssociationID)
},
)
if err != nil && !strings.Contains(err.Error(), ec2Errors.NotFoundAssociationID) {
// Just log, if the ENI disassociation fails, it will be force deleted
t.log.Error(err, "failed to disassociate eni", "eni id", eni.ID)
}
}
}
}

// DeleteBranchNetworkInterface deletes the branch network interface and returns an error in case of failure to delete
func (t *trunkENI) PushBranchENIsToCoolDownQueue(UID string) {
// Lock is required as Reconciler is also performing operation concurrently
Expand Down Expand Up @@ -529,7 +492,7 @@ func (t *trunkENI) deleteENI(eniDetail *ENIDetails) (err error) {
if err != nil {
trunkENIOperationsErrCount.WithLabelValues("disassociate_trunk_error").Inc()
if !strings.Contains(err.Error(), ec2Errors.NotFoundAssociationID) {
t.log.Error(err, "failed to disassciate branch ENI from trunk, will try to delete the branch ENI")
t.log.Error(err, "failed to disassociate branch ENI from trunk, will try to delete the branch ENI")
// Not returning error here, fallback to force branch ENI deletion
} else {
t.log.Info("AssociationID not found when disassociating branch from trunk ENI, it is already disassociated so delete the branch ENI")
Expand Down
37 changes: 1 addition & 36 deletions pkg/provider/branch/trunk/trunk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/aws/amazon-vpc-resource-controller-k8s/pkg/provider/branch/cooldown"

"github.com/aws/aws-sdk-go/aws"
awsEC2 "github.com/aws/aws-sdk-go/service/ec2"
awsEc2 "github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -148,8 +147,6 @@ var (
Ipv6Address: &BranchV6Ip2,
}

branchENIs2 = []*ENIDetails{EniDetails2}

// Trunk Interface
trunkId = "eni-00000000000000002"
trunkInterface = &awsEc2.NetworkInterface{
Expand All @@ -159,12 +156,6 @@ var (
Status: aws.String(awsEc2.AttachmentStatusAttached),
},
}
nodeNametag = []*awsEC2.Tag{
{
Key: aws.String(config.NetworkInterfaceNodenameKey),
Value: aws.String(FakeInstance.Name()),
},
}

trunkIDTag = &awsEc2.Tag{
Key: aws.String(config.TrunkENIIDTag),
Expand Down Expand Up @@ -201,17 +192,6 @@ var (
},
}

trunkAssociationsBranch1And2 = []*awsEc2.TrunkInterfaceAssociation{
{
BranchInterfaceId: &EniDetails1.ID,
VlanId: aws.Int64(int64(EniDetails1.VlanID)),
},
{
BranchInterfaceId: &EniDetails2.ID,
VlanId: aws.Int64(int64(EniDetails2.VlanID)),
},
}

mockAssociationOutput1 = &awsEc2.AssociateTrunkInterfaceOutput{
InterfaceAssociation: &awsEc2.TrunkInterfaceAssociation{
AssociationId: &MockAssociationID1,
Expand Down Expand Up @@ -262,7 +242,7 @@ func getMockTrunk() trunkENI {
log: log,
usedVlanIds: make([]bool, MaxAllocatableVlanIds),
uidToBranchENIMap: map[string][]*ENIDetails{},
nodeNameTag: []*awsEC2.Tag{
nodeNameTag: []*awsEc2.Tag{
{
Key: aws.String(config.NetworkInterfaceNodenameKey),
Value: aws.String(FakeInstance.Name()),
Expand Down Expand Up @@ -844,21 +824,6 @@ func TestTrunkENI_InitTrunk(t *testing.T) {
}
}

// TestTrunkENI_DisassociateAllBranchENIs tests all branch ENI are disassociated with the trunk
func TestTrunkENI_DisassociateAllBranchENIs(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

trunkENI, mockEC2APIHelper, _ := getMockHelperInstanceAndTrunkObject(ctrl)
trunkENI.uidToBranchENIMap[PodUID] = branchENIs1
trunkENI.uidToBranchENIMap[PodUID2] = branchENIs2

mockEC2APIHelper.EXPECT().DisassociateTrunkInterface(&MockAssociationID1).Return(nil)
mockEC2APIHelper.EXPECT().DisassociateTrunkInterface(&MockAssociationID2).Return(nil)

trunkENI.DisassociateAllBranchENIs()
}

// TestTrunkENI_CreateAndAssociateBranchENIs test branch is created and associated with the trunk and valid eni details
// are returned
func TestTrunkENI_CreateAndAssociateBranchENIs(t *testing.T) {
Expand Down
Loading