diff --git a/pkg/cleanup/cleanup.go b/pkg/cleanup/cleanup.go index eabdef63..c3b8a0b5 100644 --- a/pkg/cleanup/cleanup.go +++ b/pkg/cleanup/cleanup.go @@ -23,6 +23,7 @@ import ( "net/http" "os" "regexp" + "strings" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -655,6 +656,12 @@ func (c *Cleaner) deleteVPC(ctx context.Context, vpcID string) error { return nil } + // VPC already deleted — treat as success + if strings.Contains(err.Error(), "InvalidVpcID.NotFound") { + c.log.Info("VPC %s already deleted", vpcID) + return nil + } + attempts++ if attempts < maxAttempts { c.log.Warning("Failed to delete VPC %s (attempt %d/%d): %v. Retrying in %v...", diff --git a/pkg/cleanup/cleanup_ginkgo_test.go b/pkg/cleanup/cleanup_ginkgo_test.go index 6178441c..5bd53a89 100644 --- a/pkg/cleanup/cleanup_ginkgo_test.go +++ b/pkg/cleanup/cleanup_ginkgo_test.go @@ -21,6 +21,7 @@ import ( "context" "encoding/json" "errors" + "fmt" "os" "github.com/aws/aws-sdk-go-v2/aws" @@ -614,6 +615,20 @@ var _ = Describe("Cleanup Package", func() { Expect(deletedSGs).To(ConsistOf("sg-cp", "sg-worker")) }) + It("should treat InvalidVpcID.NotFound as success", func() { + mockEC.DeleteVpcFunc = func(ctx context.Context, + params *ec2.DeleteVpcInput, + optFns ...func(*ec2.Options)) (*ec2.DeleteVpcOutput, error) { + return nil, fmt.Errorf("operation error EC2: DeleteVpc, https response error StatusCode: 400, api error InvalidVpcID.NotFound: The vpc ID '%s' does not exist", *params.VpcId) + } + + cleaner, err := New(log, "us-west-2", WithEC2Client(mockEC)) + Expect(err).NotTo(HaveOccurred()) + + err = cleaner.DeleteVPCResources(context.Background(), "vpc-already-gone") + Expect(err).NotTo(HaveOccurred()) + }) + It("should handle VPC deletion failure with retries", func() { deleteAttempts := 0 mockEC.DeleteVpcFunc = func(ctx context.Context,