in pkg/awsutils/awsutils.go [1124:1176]
func (cache *EC2InstanceMetadataCache) freeENI(eniName string, sleepDelayAfterDetach time.Duration, maxBackoffDelay time.Duration) error {
log.Infof("Trying to free ENI: %s", eniName)
// Find out attachment
attachID, err := cache.getENIAttachmentID(eniName)
if err != nil {
if err == ErrENINotFound {
log.Infof("ENI %s not found. It seems to be already freed", eniName)
return nil
}
awsUtilsErrInc("getENIAttachmentIDFailed", err)
log.Errorf("Failed to retrieve ENI %s attachment id: %v", eniName, err)
return errors.Wrap(err, "FreeENI: failed to retrieve ENI's attachment id")
}
log.Debugf("Found ENI %s attachment id: %s ", eniName, aws.ToString(attachID))
detachInput := &ec2.DetachNetworkInterfaceInput{
AttachmentId: attachID,
}
// Retry detaching the ENI from the instance
err = retry.NWithBackoff(retry.NewSimpleBackoff(time.Millisecond*200, maxBackoffDelay, 0.15, 2.0), maxENIEC2APIRetries, func() error {
start := time.Now()
_, ec2Err := cache.ec2SVC.DetachNetworkInterface(context.Background(), detachInput)
prometheusmetrics.Ec2ApiReq.WithLabelValues("DetachNetworkInterface").Inc()
prometheusmetrics.AwsAPILatency.WithLabelValues("DetachNetworkInterface", fmt.Sprint(ec2Err != nil), awsReqStatus(ec2Err)).Observe(msSince(start))
if ec2Err != nil {
checkAPIErrorAndBroadcastEvent(err, "ec2:DetachNetworkInterface")
awsAPIErrInc("DetachNetworkInterface", ec2Err)
prometheusmetrics.Ec2ApiErr.WithLabelValues("DetachNetworkInterface").Inc()
log.Errorf("Failed to detach ENI %s %v", eniName, ec2Err)
return errors.New("unable to detach ENI from EC2 instance, giving up")
}
log.Infof("Successfully detached ENI: %s", eniName)
return nil
})
if err != nil {
log.Errorf("Failed to detach ENI %s %v", eniName, err)
return err
}
// It does take awhile for EC2 to detach ENI from instance, so we wait 2s before trying the delete.
time.Sleep(sleepDelayAfterDetach)
err = cache.deleteENI(eniName, maxBackoffDelay)
if err != nil {
awsUtilsErrInc("FreeENIDeleteErr", err)
return errors.Wrapf(err, "FreeENI: failed to free ENI: %s", eniName)
}
log.Infof("Successfully freed ENI: %s", eniName)
return nil
}