github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/imagepublishers/amipublisher/delete.go (about)

     1  package amipublisher
     2  
     3  import (
     4  	"errors"
     5  	"path"
     6  
     7  	"github.com/Cloud-Foundations/Dominator/lib/awsutil"
     8  	"github.com/Cloud-Foundations/Dominator/lib/log"
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/session"
    11  	"github.com/aws/aws-sdk-go/service/ec2"
    12  	"github.com/aws/aws-sdk-go/service/s3"
    13  )
    14  
    15  func deleteResources(resources []Resource, logger log.Logger) error {
    16  	cs, err := awsutil.LoadCredentials()
    17  	if err != nil {
    18  		return err
    19  	}
    20  	return forEachResource(resources, false,
    21  		func(session *session.Session, awsService *ec2.EC2, resource Resource,
    22  			logger log.Logger) error {
    23  			return deleteResource(cs, session, awsService, resource, logger)
    24  		},
    25  		logger)
    26  }
    27  
    28  func deleteResource(cs *awsutil.CredentialsStore, session *session.Session,
    29  	awsService *ec2.EC2, resource Resource, logger log.Logger) error {
    30  	if resource.SharedFrom != "" {
    31  		return nil
    32  	}
    33  	var firstError error
    34  	if resource.AmiId != "" {
    35  		if resource.SnapshotId == "" && resource.S3Bucket == "" {
    36  			out, err := awsService.DescribeImages(
    37  				&ec2.DescribeImagesInput{
    38  					ImageIds: aws.StringSlice([]string{resource.AmiId})})
    39  			if err != nil {
    40  				return err
    41  			}
    42  			if len(out.Images) != 1 {
    43  				return errors.New("did not get one image")
    44  			}
    45  			err = deleteImage(cs, resource.AccountName, resource.Region,
    46  				out.Images[0])
    47  			if err != nil {
    48  				logger.Printf("error deleting: %s: %s\n", resource.AmiId, err)
    49  			} else {
    50  				logger.Printf("deleted: %s\n", resource.AmiId)
    51  				return nil
    52  			}
    53  		}
    54  		if err := deregisterAmi(awsService, resource.AmiId); err != nil {
    55  			logger.Printf("error deleting: %s: %s\n", resource.AmiId, err)
    56  			if firstError == nil {
    57  				firstError = err
    58  			}
    59  		} else {
    60  			logger.Printf("deleted: %s\n", resource.AmiId)
    61  		}
    62  	}
    63  	if resource.SnapshotId != "" {
    64  		if err := deleteSnapshot(awsService, resource.SnapshotId); err != nil {
    65  			logger.Printf("error deleting: %s: %s\n", resource.SnapshotId, err)
    66  			if firstError == nil {
    67  				firstError = err
    68  			}
    69  		} else {
    70  			logger.Printf("deleted: %s\n", resource.SnapshotId)
    71  		}
    72  	}
    73  	if resource.S3Bucket != "" {
    74  		s3Client := s3.New(session,
    75  			&aws.Config{Region: aws.String(resource.Region)})
    76  		err := deleteS3Directory(s3Client, resource.S3Bucket,
    77  			path.Dir(resource.S3ManifestFile))
    78  		if err != nil {
    79  			logger.Printf("error deleting bundle: %s: %s\n",
    80  				resource.S3ManifestFile, err)
    81  			if firstError == nil {
    82  				firstError = err
    83  			}
    84  		}
    85  	}
    86  	return firstError
    87  }
    88  
    89  func deleteTags(resources []Resource, tagKeys []string,
    90  	logger log.Logger) error {
    91  	return forEachResource(resources, false,
    92  		func(session *session.Session, awsService *ec2.EC2, resource Resource,
    93  			logger log.Logger) error {
    94  			return deleteTagsForResource(awsService, resource, tagKeys, logger)
    95  		},
    96  		logger)
    97  }
    98  
    99  func deleteTagsForResource(awsService *ec2.EC2, resource Resource,
   100  	tagKeys []string, logger log.Logger) error {
   101  	err := deleteTagsFromResources(awsService, tagKeys, resource.AmiId,
   102  		resource.SnapshotId)
   103  	if err != nil {
   104  		logger.Println("error deleting tag(s)")
   105  	}
   106  	return err
   107  }
   108  
   109  func deleteTagsOnUnpackers(targets awsutil.TargetList,
   110  	skipList awsutil.TargetList, name string, tagKeys []string,
   111  	logger log.Logger) error {
   112  	if len(tagKeys) < 1 {
   113  		return nil
   114  	}
   115  	resultsChannel := make(chan error, 1)
   116  	numTargets, err := awsutil.ForEachTarget(targets, skipList,
   117  		func(awsService *ec2.EC2, account, region string, logger log.Logger) {
   118  			err := deleteTagsInTarget(awsService, name, tagKeys, logger)
   119  			if err != nil {
   120  				logger.Println(err)
   121  			}
   122  			resultsChannel <- err
   123  		},
   124  		logger)
   125  	// Collect results.
   126  	for i := 0; i < numTargets; i++ {
   127  		e := <-resultsChannel
   128  		if e != nil && err == nil {
   129  			err = e
   130  		}
   131  	}
   132  	return err
   133  }
   134  
   135  func deleteTagsInTarget(awsService *ec2.EC2, name string, tagKeys []string,
   136  	logger log.Logger) error {
   137  	instances, err := getInstances(awsService, name)
   138  	if err != nil {
   139  		return err
   140  	}
   141  	if len(instances) < 1 {
   142  		return nil
   143  	}
   144  	return deleteTagsFromResources(awsService, tagKeys,
   145  		getInstanceIds(instances)...)
   146  }