From 1342a6f926e45d4026afeee0fa69d95d857cbfa2 Mon Sep 17 00:00:00 2001 From: James Kwon <96548424+hongil0316@users.noreply.github.com> Date: Sun, 15 Dec 2024 22:25:55 -0500 Subject: [PATCH] Add additional checks and debug message for nil exception checks --- aws/resources/ec2_network_acl.go | 40 +++++---- aws/resources/ec2_network_interface.go | 91 +++++++++++++------- aws/resources/security_group.go | 112 +++++++++++++------------ 3 files changed, 144 insertions(+), 99 deletions(-) diff --git a/aws/resources/ec2_network_acl.go b/aws/resources/ec2_network_acl.go index efd2fd40..97408e33 100644 --- a/aws/resources/ec2_network_acl.go +++ b/aws/resources/ec2_network_acl.go @@ -97,16 +97,18 @@ func (nacl *NetworkACL) nuke(id *string) error { // Thus, to remove the association, it requires another network ACL ID. Here, we check the default network ACL of the VPC to which the current network ACL is attached, // and then associate that network ACL with the association. func (nacl *NetworkACL) nukeAssociatedSubnets(id string) error { + logging.Debugf("[nukeAssociatedSubnets] Start describing network ACL: %s", id) + resp, err := nacl.Client.DescribeNetworkAcls(nacl.Context, &ec2.DescribeNetworkAclsInput{ NetworkAclIds: []string{id}, }) if err != nil { - logging.Debugf("[Network ACL] Failed to describe network ACL: %s", err) + logging.Debugf("[nukeAssociatedSubnets] Failed to describe network ACL: %s", err) return err } if len(resp.NetworkAcls) == 0 { - logging.Debugf("[Network ACL] Nothing found: %s", id) + logging.Debugf("[nukeAssociatedSubnets] No network ACL found for ID: %s", id) return nil } @@ -115,7 +117,8 @@ func (nacl *NetworkACL) nukeAssociatedSubnets(id string) error { vpcID = networkAcl.VpcId ) - // Get the default nacl association id + // Get the default network ACL association ID + logging.Debugf("[nukeAssociatedSubnets] Describing default network ACL for VPC: %s", *vpcID) networkACLs, err := nacl.Client.DescribeNetworkAcls( nacl.Context, &ec2.DescribeNetworkAclsInput{ @@ -123,7 +126,8 @@ func (nacl *NetworkACL) nukeAssociatedSubnets(id string) error { { Name: awsgo.String("vpc-id"), Values: []string{*vpcID}, - }, { + }, + { Name: awsgo.String("default"), Values: []string{"true"}, }, @@ -131,27 +135,32 @@ func (nacl *NetworkACL) nukeAssociatedSubnets(id string) error { }, ) if err != nil { - logging.Debugf("[Network ACL] Failed to describe network ACL: %s", err) + logging.Debugf("[nukeAssociatedSubnets] Failed to describe default network ACL: %s", err) return err } if len(networkACLs.NetworkAcls) == 0 { - logging.Debugf("[Network ACL] Nothing found to check the default association: %s", id) + logging.Debugf("[nukeAssociatedSubnets] No default network ACL found for VPC: %s", *vpcID) return nil } defaultNetworkAclID := networkACLs.NetworkAcls[0].NetworkAclId + logging.Debugf("[nukeAssociatedSubnets] Default network ACL ID: %s", *defaultNetworkAclID) var associations []*types.NetworkAclAssociation for i := range networkAcl.Associations { associations = append(associations, &networkAcl.Associations[i]) } + // Replacing network ACL associations + logging.Debugf("[nukeAssociatedSubnets] Replacing network ACL associations for ID: %s", *defaultNetworkAclID) err = replaceNetworkAclAssociation(nacl.Client, defaultNetworkAclID, associations) if err != nil { - logging.Debugf("Failed to replace network ACL associations: %s", *defaultNetworkAclID) + logging.Debugf("[nukeAssociatedSubnets] Failed to replace network ACL associations: %s", *defaultNetworkAclID) return errors.WithStackTrace(err) } + + logging.Debugf("[nukeAssociatedSubnets] Successfully replaced network ACL associations for ID: %s", *defaultNetworkAclID) return nil } @@ -191,36 +200,35 @@ func (nacl *NetworkACL) nukeAll(identifiers []*string) error { } func replaceNetworkAclAssociation(client NetworkACLAPI, networkAclId *string, associations []*types.NetworkAclAssociation) error { - logging.Debugf("Start replacing network ACL associations: %s", *networkAclId) + logging.Debugf("[replaceNetworkAclAssociation] Start replacing network ACL associations: %s", *networkAclId) for _, association := range associations { - logging.Debugf("Found %d network ACL associations to replace", len(associations)) + logging.Debugf("[replaceNetworkAclAssociation] Found %d network ACL associations to replace", len(associations)) _, err := client.ReplaceNetworkAclAssociation(context.TODO(), &ec2.ReplaceNetworkAclAssociationInput{ AssociationId: association.NetworkAclAssociationId, NetworkAclId: networkAclId, }) if err != nil { - logging.Debugf("Failed to replace network ACL association: %s to default", *association.NetworkAclAssociationId) + logging.Debugf("[replaceNetworkAclAssociation] Failed to replace network ACL association: %s", *association.NetworkAclAssociationId) return errors.WithStackTrace(err) } - logging.Debugf("Successfully replaced network ACL association: %s to default", - *association.NetworkAclAssociationId) + logging.Debugf("[replaceNetworkAclAssociation] Successfully replaced network ACL association: %s", *association.NetworkAclAssociationId) } - logging.Debugf("Successfully replaced network ACL associations: %s", *networkAclId) + logging.Debugf("[replaceNetworkAclAssociation] Successfully replaced network ACL associations: %s", *networkAclId) return nil } func nukeNetworkAcl(client NetworkACLAPI, id *string) error { - logging.Debugf("Deleting network Acl %s", *id) + logging.Debugf("[nukeNetworkAcl] Deleting network ACL %s", *id) if _, err := client.DeleteNetworkAcl(context.TODO(), &ec2.DeleteNetworkAclInput{ NetworkAclId: id, }); err != nil { - logging.Debugf("An error happened while nuking NACL %s, error %v", *id, err) + logging.Debugf("[nukeNetworkAcl] An error occurred while deleting network ACL %s: %v", *id, err) return err } - logging.Debugf("[Ok] network acl deleted successfully %s", *id) + logging.Debugf("[nukeNetworkAcl] Successfully deleted network ACL %s", *id) return nil } diff --git a/aws/resources/ec2_network_interface.go b/aws/resources/ec2_network_interface.go index a763e7b4..6d0ffec4 100644 --- a/aws/resources/ec2_network_interface.go +++ b/aws/resources/ec2_network_interface.go @@ -89,98 +89,131 @@ func (ni *NetworkInterface) nuke(id *string) error { } func (ni *NetworkInterface) detachNetworkInterface(id *string) error { - logging.Debugf("Detaching network interface %s from instances ", awsgo.ToString(id)) + if id == nil || awsgo.ToString(id) == "" { + logging.Debugf("[detachNetworkInterface] Network interface ID is nil or empty, skipping detachment process") + return nil + } + + logging.Debugf("[detachNetworkInterface] Detaching network interface %s from instances", awsgo.ToString(id)) + // Describe the network interface to get details output, err := ni.Client.DescribeNetworkInterfaces(ni.Context, &ec2.DescribeNetworkInterfacesInput{ - NetworkInterfaceIds: []string{*id}, + NetworkInterfaceIds: []string{awsgo.ToString(id)}, }) if err != nil { - logging.Debugf("[Failed] Error describing network interface %s: %s", awsgo.ToString(id), err) + logging.Debugf("[detachNetworkInterface] Failed to describe network interface %s: %v", awsgo.ToString(id), err) return errors.WithStackTrace(err) } for _, networkInterface := range output.NetworkInterfaces { - - // check there has some attachments - if networkInterface.Attachment == nil { + // Check if the network interface has an attachment + if networkInterface.Attachment == nil || networkInterface.Attachment.InstanceId == nil { + logging.Debugf("[detachNetworkInterface] No attachment found for network interface %s, skipping", awsgo.ToString(id)) continue } - // nuking the attached instance - // this will also remove the network interface - if err := ni.nukeInstance(networkInterface.Attachment.InstanceId); err != nil { - logging.Debugf("[Failed] Error nuking the attached instance %s on network interface %s %s", awsgo.ToString(networkInterface.Attachment.InstanceId), awsgo.ToString(id), err) + instanceID := awsgo.ToString(networkInterface.Attachment.InstanceId) + logging.Debugf("[detachNetworkInterface] Found attached instance %s for network interface %s", instanceID, awsgo.ToString(id)) + + // Nuke the attached instance + err := ni.nukeInstance(networkInterface.Attachment.InstanceId) + if err != nil { + logging.Debugf("[detachNetworkInterface] Failed to nuke instance %s attached to network interface %s: %v", instanceID, awsgo.ToString(id), err) return errors.WithStackTrace(err) } - } - logging.Debugf("[OK] successfully detached network interface associated on instances") + logging.Debugf("[detachNetworkInterface] Successfully nuked instance %s and detached network interface %s", instanceID, awsgo.ToString(id)) + } + logging.Debugf("[detachNetworkInterface] Successfully detached network interface %s from instances", awsgo.ToString(id)) return nil } func (ni *NetworkInterface) releaseEIPs(instance *string) error { - logging.Debugf("Releasing Elastic IP address(s) associated on instance %s", awsgo.ToString(instance)) - // get the elastic ip's associated with the EC2's + if instance == nil || awsgo.ToString(instance) == "" { + logging.Debugf("[releaseEIPs] Instance ID is nil or empty, skipping Elastic IP release process") + return nil + } + + logging.Debugf("[releaseEIPs] Releasing Elastic IP address(es) associated with instance %s", awsgo.ToString(instance)) + + // Fetch the Elastic IPs associated with the instance output, err := ni.Client.DescribeAddresses(ni.Context, &ec2.DescribeAddressesInput{ Filters: []types.Filter{ { Name: awsgo.String("instance-id"), Values: []string{ - *instance, + awsgo.ToString(instance), }, }, }, }) if err != nil { + logging.Debugf("[releaseEIPs] Failed to describe addresses for instance %s: %v", awsgo.ToString(instance), err) return err } + // Release each Elastic IP for _, address := range output.Addresses { - if _, err := ni.Client.ReleaseAddress(ni.Context, &ec2.ReleaseAddressInput{ + if address.AllocationId == nil { + logging.Debugf("[releaseEIPs] Skipping address with nil Allocation ID for instance %s", awsgo.ToString(instance)) + continue + } + + _, err := ni.Client.ReleaseAddress(ni.Context, &ec2.ReleaseAddressInput{ AllocationId: address.AllocationId, - }); err != nil { - logging.Debugf("An error happened while releasing the elastic ip address %s, error %v", awsgo.ToString(address.AllocationId), err) + }) + if err != nil { + logging.Debugf("[releaseEIPs] Failed to release Elastic IP address %s for instance %s: %v", + awsgo.ToString(address.AllocationId), awsgo.ToString(instance), err) continue } - logging.Debugf("Released Elastic IP address %s from instance %s", awsgo.ToString(address.AllocationId), awsgo.ToString(instance)) + logging.Debugf("[releaseEIPs] Successfully released Elastic IP address %s from instance %s", + awsgo.ToString(address.AllocationId), awsgo.ToString(instance)) } - logging.Debugf("[OK] successfully released Elastic IP address(s) associated on instances") - + logging.Debugf("[releaseEIPs] Successfully completed Elastic IP release process for instance %s", awsgo.ToString(instance)) return nil } func (ni *NetworkInterface) nukeInstance(id *string) error { + if id == nil || awsgo.ToString(id) == "" { + logging.Debugf("[nukeInstance] Instance ID is nil or empty, skipping termination process") + return nil + } + + instanceID := awsgo.ToString(id) + logging.Debugf("[nukeInstance] Starting to nuke instance %s", instanceID) + // Release the elastic IPs attached to the instance before nuking if err := ni.releaseEIPs(id); err != nil { - logging.Debugf("[Failed EIP release] %s", err) + logging.Debugf("[nukeInstance] Failed to release Elastic IPs for instance %s: %v", instanceID, err) return errors.WithStackTrace(err) } // Terminate the instance _, err := ni.Client.TerminateInstances(ni.Context, &ec2.TerminateInstancesInput{ - InstanceIds: []string{*id}, + InstanceIds: []string{instanceID}, }) if err != nil { - logging.Debugf("[Failed] EC2 termination %s", err) + logging.Debugf("[nukeInstance] Failed to terminate instance %s: %v", instanceID, err) return errors.WithStackTrace(err) } - logging.Debugf("[Instance Termination] waiting to terminate instance %s", awsgo.ToString(id)) + logging.Debugf("[nukeInstance] Waiting for instance %s to terminate", instanceID) - // Use the NewInstanceTerminatedWaiter + // Use the NewInstanceTerminatedWaiter to wait until the instance is terminated waiter := ec2.NewInstanceTerminatedWaiter(ni.Client) err = waiter.Wait(ni.Context, &ec2.DescribeInstancesInput{ - InstanceIds: []string{*id}, + InstanceIds: []string{instanceID}, }, 5*time.Minute) if err != nil { - logging.Debugf("[Instance Termination Waiting] Failed to terminate instance %s : %s", *id, err) + logging.Debugf("[nukeInstance] Instance termination waiting failed for instance %s: %v", instanceID, err) return errors.WithStackTrace(err) } - logging.Debugf("[OK] successfully nuked instance %v", awsgo.ToString(id)) + logging.Debugf("[nukeInstance] Successfully nuked instance %s", instanceID) return nil } diff --git a/aws/resources/security_group.go b/aws/resources/security_group.go index 291f54cd..a049589d 100644 --- a/aws/resources/security_group.go +++ b/aws/resources/security_group.go @@ -2,7 +2,7 @@ package resources import ( "context" - "fmt" + "errors" "time" awsgo "github.com/aws/aws-sdk-go-v2/aws" @@ -13,7 +13,7 @@ import ( "github.com/gruntwork-io/cloud-nuke/logging" r "github.com/gruntwork-io/cloud-nuke/report" // Alias the package as 'r' "github.com/gruntwork-io/cloud-nuke/util" - "github.com/gruntwork-io/go-commons/errors" + cerrors "github.com/gruntwork-io/go-commons/errors" ) // shouldIncludeSecurityGroup determines whether a security group should be included for deletion based on the provided configuration. @@ -58,14 +58,14 @@ func (sg *SecurityGroup) getAll(c context.Context, configObj config.Config) ([]* }) if err != nil { logging.Debugf("[Security Group] Failed to list security groups: %s", err) - return nil, errors.WithStackTrace(err) + return nil, cerrors.WithStackTrace(err) } for _, group := range resp.SecurityGroups { firstSeenTime, err = util.GetOrCreateFirstSeen(c, sg.Client, group.GroupId, util.ConvertTypesTagsToMap(group.Tags)) if err != nil { logging.Error("unable to retrieve first seen tag") - return nil, errors.WithStackTrace(err) + return nil, cerrors.WithStackTrace(err) } if shouldIncludeSecurityGroup(group, firstSeenTime, configObj) { @@ -86,12 +86,12 @@ func (sg *SecurityGroup) getAll(c context.Context, configObj config.Config) ([]* } func (sg *SecurityGroup) detachAssociatedSecurityGroups(id *string) error { - logging.Debugf("[Security Group detach from dependancy] detaching the security group %s from dependant", awsgo.ToString(id)) + logging.Debugf("[detachAssociatedSecurityGroups] detaching the security group %s from dependant", awsgo.ToString(id)) resp, err := sg.Client.DescribeSecurityGroups(sg.Context, &ec2.DescribeSecurityGroupsInput{}) if err != nil { - logging.Debugf("[Security Group] Failed to list security groups: %s", err) - return errors.WithStackTrace(err) + logging.Debugf("[detachAssociatedSecurityGroups] Failed to list security groups: %s", err) + return cerrors.WithStackTrace(err) } for _, securityGroup := range resp.SecurityGroups { @@ -102,29 +102,29 @@ func (sg *SecurityGroup) detachAssociatedSecurityGroups(id *string) error { hasMatching, revokeIpPermissions := hasMatchingGroupIdRule(id, securityGroup.IpPermissions) if hasMatching && len(revokeIpPermissions) > 0 { - logging.Debugf("[Security Group revoke ingress] revoking the ingress rules of %s", awsgo.ToString(securityGroup.GroupId)) + logging.Debugf("[detachAssociatedSecurityGroups] revoking the ingress rules of %s", awsgo.ToString(securityGroup.GroupId)) _, err := sg.Client.RevokeSecurityGroupIngress(sg.Context, &ec2.RevokeSecurityGroupIngressInput{ GroupId: securityGroup.GroupId, IpPermissions: revokeIpPermissions, }) if err != nil { - logging.Debugf("[Security Group] Failed to revoke ingress rules: %s", err) - return errors.WithStackTrace(err) + logging.Debugf("[detachAssociatedSecurityGroups] Failed to revoke ingress rules: %s", err) + return cerrors.WithStackTrace(err) } } // check egress rule hasMatchingEgress, revokeIpPermissions := hasMatchingGroupIdRule(id, securityGroup.IpPermissionsEgress) if hasMatchingEgress && len(revokeIpPermissions) > 0 { - logging.Debugf("[Security Group revoke ingress] revoking the egress rules of %s", awsgo.ToString(securityGroup.GroupId)) + logging.Debugf("[detachAssociatedSecurityGroups] revoking the egress rules of %s", awsgo.ToString(securityGroup.GroupId)) _, err := sg.Client.RevokeSecurityGroupEgress(sg.Context, &ec2.RevokeSecurityGroupEgressInput{ GroupId: securityGroup.GroupId, IpPermissions: revokeIpPermissions, }) if err != nil { - logging.Debugf("[Security Group] Failed to revoke egress rules: %s", err) - return errors.WithStackTrace(err) + logging.Debugf("[detachAssociatedSecurityGroups] Failed to revoke egress rules: %s", err) + return cerrors.WithStackTrace(err) } } @@ -159,28 +159,28 @@ func hasMatchingGroupIdRule(checkingGroup *string, IpPermission []types.IpPermis func (sg *SecurityGroup) nuke(id *string) error { if err := sg.terminateInstancesAssociatedWithSecurityGroup(*id); err != nil { - return errors.WithStackTrace(err) + return cerrors.WithStackTrace(err) } if err := sg.detachAssociatedSecurityGroups(id); err != nil { - return errors.WithStackTrace(err) + return cerrors.WithStackTrace(err) } // check the nuking is only for default security groups, then nuke and return if sg.NukeOnlyDefault { // RevokeSecurityGroupIngress if err := revokeSecurityGroupIngress(sg.Client, id); err != nil { - return errors.WithStackTrace(err) + return cerrors.WithStackTrace(err) } // RevokeSecurityGroupEgress if err := revokeSecurityGroupEgress(sg.Client, id); err != nil { - return errors.WithStackTrace(err) + return cerrors.WithStackTrace(err) } // RevokeIPv6SecurityGroupEgress if err := sg.RevokeIPv6SecurityGroupEgress(*id); err != nil { - return errors.WithStackTrace(err) + return cerrors.WithStackTrace(err) } return nil @@ -188,13 +188,13 @@ func (sg *SecurityGroup) nuke(id *string) error { // nuke the securiy group which is not default one if err := nukeSecurityGroup(sg.Client, id); err != nil { - return errors.WithStackTrace(err) + return cerrors.WithStackTrace(err) } return nil } func revokeSecurityGroupIngress(client SecurityGroupAPI, id *string) error { - logging.Debug(fmt.Sprintf("Start revoking security groups ingress rule : %s", awsgo.ToString(id))) + logging.Debugf("[revokeSecurityGroupIngress] Start revoking security group ingress rule: %s", awsgo.ToString(id)) _, err := client.RevokeSecurityGroupIngress(context.TODO(), &ec2.RevokeSecurityGroupIngressInput{ GroupId: id, IpPermissions: []types.IpPermission{ @@ -207,23 +207,23 @@ func revokeSecurityGroupIngress(client SecurityGroupAPI, id *string) error { }, }) if err != nil { - if util.TransformAWSError(err) == util.ErrInvalidPermisionNotFound { - logging.Debugf("Ingress rule not present (ok)") + if errors.Is(util.TransformAWSError(err), util.ErrInvalidPermisionNotFound) { + logging.Debugf("[revokeSecurityGroupIngress] Ingress rule not present (ok)") return nil } - logging.Debugf("[Security Group] Failed to revoke security group ingress associated with security group %s: %s", awsgo.ToString(id), err) - return errors.WithStackTrace(err) + logging.Debugf("[revokeSecurityGroupIngress] Failed to revoke ingress rule associated with security group %s: %s", awsgo.ToString(id), err) + return cerrors.WithStackTrace(err) } - logging.Debugf("Successfully revoked security group ingress rule: %s", awsgo.ToString(id)) + logging.Debugf("[revokeSecurityGroupIngress] Successfully revoked ingress rule: %s", awsgo.ToString(id)) return nil } func revokeSecurityGroupEgress(client SecurityGroupAPI, id *string) error { - logging.Debugf("Start revoking security groups ingress rule : %s", awsgo.ToString(id)) + logging.Debugf("[revokeSecurityGroupEgress] Start revoking security group egress rule: %s", awsgo.ToString(id)) _, err := client.RevokeSecurityGroupEgress(context.TODO(), &ec2.RevokeSecurityGroupEgressInput{ - GroupId: (id), + GroupId: id, IpPermissions: []types.IpPermission{ { IpProtocol: awsgo.String("-1"), @@ -234,21 +234,22 @@ func revokeSecurityGroupEgress(client SecurityGroupAPI, id *string) error { }, }) if err != nil { - if util.TransformAWSError(err) == util.ErrInvalidPermisionNotFound { - logging.Debugf("Egress rule not present (ok)") + if errors.Is(util.TransformAWSError(err), util.ErrInvalidPermisionNotFound) { + logging.Debugf("[revokeSecurityGroupEgress] Egress rule not present (ok)") return nil } - logging.Debugf("[Security Group] Failed to revoke security group egress associated with security group %s: %s", awsgo.ToString(id), err) - return errors.WithStackTrace(err) + logging.Debugf("[revokeSecurityGroupEgress] Failed to revoke egress rule associated with security group %s: %s", awsgo.ToString(id), err) + return cerrors.WithStackTrace(err) } - logging.Debugf("Successfully revoked security group egress rule: %s", awsgo.ToString(id)) + logging.Debugf("[revokeSecurityGroupEgress] Successfully revoked egress rule: %s", awsgo.ToString(id)) return nil } func (sg *SecurityGroup) RevokeIPv6SecurityGroupEgress(id string) error { + logging.Debugf("[RevokeIPv6SecurityGroupEgress] Start revoking IPv6 security group egress rule: %s", id) _, err := sg.Client.RevokeSecurityGroupEgress(sg.Context, &ec2.RevokeSecurityGroupEgressInput{ GroupId: awsgo.String(id), IpPermissions: []types.IpPermission{ @@ -261,15 +262,17 @@ func (sg *SecurityGroup) RevokeIPv6SecurityGroupEgress(id string) error { }, }) if err != nil { - if util.TransformAWSError(err) == util.ErrInvalidPermisionNotFound { - logging.Debugf("Ingress rule not present (ok)") + if errors.Is(util.TransformAWSError(err), util.ErrInvalidPermisionNotFound) { + logging.Debugf("[RevokeIPv6SecurityGroupEgress] IPv6 egress rule not present (ok)") return nil } - logging.Debugf("[Security Group] Failed to revoke security group egress associated with security group %s: %s", id, err) - return errors.WithStackTrace(err) + logging.Debugf("[RevokeIPv6SecurityGroupEgress] Failed to revoke IPv6 egress rule associated with security group %s: %s", id, err) + return cerrors.WithStackTrace(err) } + logging.Debugf("[RevokeIPv6SecurityGroupEgress] Successfully revoked IPv6 egress rule: %s", id) + return nil } @@ -284,8 +287,8 @@ func (sg *SecurityGroup) terminateInstancesAssociatedWithSecurityGroup(id string }, }) if err != nil { - logging.Debugf("[Security Group] Failed to describe instances associated with security group %s: %s", id, err) - return errors.WithStackTrace(err) + logging.Debugf("[terminateInstancesAssociatedWithSecurityGroup] Failed to describe instances associated with security group %s: %s", id, err) + return cerrors.WithStackTrace(err) } for _, reservation := range resp.Reservations { @@ -294,31 +297,31 @@ func (sg *SecurityGroup) terminateInstancesAssociatedWithSecurityGroup(id string // Needs to release the elastic ips attached on the instance before nuking if err := sg.releaseEIPs([]*string{instance.InstanceId}); err != nil { - logging.Debugf("[Failed EIP release] %s", err) - return errors.WithStackTrace(err) + logging.Debugf("[terminateInstancesAssociatedWithSecurityGroup] Failed EIP release for instance %s: %s", instanceID, err) + return cerrors.WithStackTrace(err) } // terminating the instances which used this security group if _, err := sg.Client.TerminateInstances(sg.Context, &ec2.TerminateInstancesInput{ InstanceIds: []string{instanceID}, }); err != nil { - logging.Debugf("[Failed] Ec2 termination %s", err) - return errors.WithStackTrace(err) + logging.Debugf("[terminateInstancesAssociatedWithSecurityGroup] Failed to terminate instance %s: %s", instanceID, err) + return cerrors.WithStackTrace(err) } - logging.Debugf("[Instance Termination] waiting to terminate instance %s", instanceID) + logging.Debugf("[terminateInstancesAssociatedWithSecurityGroup] Waiting to terminate instance %s", instanceID) ec2Client, ok := sg.Client.(*ec2.Client) if !ok { - return errors.WithStackTrace(err) + return cerrors.WithStackTrace(err) } // wait until the instance terminated. err = waitUntilInstanceTerminated(ec2Client, sg.Context, instanceID) if err != nil { - logging.Debugf("[Security Group] Failed to terminate instance %s associated with security group %s: %s", instanceID, id, err) - return errors.WithStackTrace(err) + logging.Debugf("[terminateInstancesAssociatedWithSecurityGroup] Failed to terminate instance %s associated with security group %s: %s", instanceID, id, err) + return cerrors.WithStackTrace(err) } - logging.Debugf("Terminated instance %s associated with security group %s", instanceID, id) + logging.Debugf("[terminateInstancesAssociatedWithSecurityGroup] Terminated instance %s associated with security group %s", instanceID, id) } } @@ -326,7 +329,7 @@ func (sg *SecurityGroup) terminateInstancesAssociatedWithSecurityGroup(id string } func (sg *SecurityGroup) releaseEIPs(instanceIds []*string) error { - logging.Debugf("Releasing Elastic IP address(s) associated on instances") + logging.Debugf("[releaseEIPs] Releasing Elastic IP address(es) associated with instances") for _, instanceID := range instanceIds { // get the elastic ip's associated with the EC2's @@ -341,6 +344,7 @@ func (sg *SecurityGroup) releaseEIPs(instanceIds []*string) error { }, }) if err != nil { + logging.Debugf("[releaseEIPs] Failed to describe Elastic IPs for instance %s: %s", *instanceID, err) return err } @@ -348,11 +352,11 @@ func (sg *SecurityGroup) releaseEIPs(instanceIds []*string) error { if _, err := sg.Client.ReleaseAddress(sg.Context, &ec2.ReleaseAddressInput{ AllocationId: address.AllocationId, }); err != nil { - logging.Debugf("An error happened while releasing the elastic ip address %s, error %v", *address.AllocationId, err) + logging.Debugf("[releaseEIPs] Error releasing Elastic IP address %s for instance %s: %v", *address.AllocationId, *instanceID, err) continue } - logging.Debugf("Released Elastic IP address %s from instance %s", *address.AllocationId, *instanceID) + logging.Debugf("[releaseEIPs] Released Elastic IP address %s from instance %s", *address.AllocationId, *instanceID) } } @@ -360,15 +364,15 @@ func (sg *SecurityGroup) releaseEIPs(instanceIds []*string) error { } func nukeSecurityGroup(client SecurityGroupAPI, id *string) error { - logging.Debugf("Deleting security group %s", awsgo.ToString(id)) + logging.Debugf("[nukeSecurityGroup] Deleting security group %s", awsgo.ToString(id)) if _, err := client.DeleteSecurityGroup(context.TODO(), &ec2.DeleteSecurityGroupInput{ GroupId: id, }); err != nil { - logging.Debugf("[Security Group] Failed to delete security group %s: %s", awsgo.ToString(id), err) - return errors.WithStackTrace(err) + logging.Debugf("[nukeSecurityGroup] Failed to delete security group %s: %s", awsgo.ToString(id), err) + return cerrors.WithStackTrace(err) } - logging.Debugf("Deleted security group %s", awsgo.ToString(id)) + logging.Debugf("[nukeSecurityGroup] Successfully deleted security group %s", awsgo.ToString(id)) return nil }