github.com/openshift/installer@v1.4.17/pkg/destroy/aws/elbhelpers.go (about)

     1  package aws
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  
     7  	"github.com/aws/aws-sdk-go/aws"
     8  	"github.com/aws/aws-sdk-go/aws/arn"
     9  	"github.com/aws/aws-sdk-go/aws/awserr"
    10  	"github.com/aws/aws-sdk-go/aws/session"
    11  	"github.com/aws/aws-sdk-go/service/elb"
    12  	"github.com/aws/aws-sdk-go/service/elbv2"
    13  	"github.com/pkg/errors"
    14  	"github.com/sirupsen/logrus"
    15  )
    16  
    17  func deleteElasticLoadBalancing(ctx context.Context, session *session.Session, arn arn.ARN, logger logrus.FieldLogger) error {
    18  	resourceType, id, err := splitSlash("resource", arn.Resource)
    19  	if err != nil {
    20  		return err
    21  	}
    22  	logger = logger.WithField("id", id)
    23  
    24  	switch resourceType {
    25  	case "loadbalancer":
    26  		segments := strings.SplitN(id, "/", 2)
    27  		if len(segments) == 1 {
    28  			return deleteElasticLoadBalancerClassic(ctx, elb.New(session), id, logger)
    29  		} else if len(segments) != 2 {
    30  			return errors.Errorf("cannot parse subresource %q into {subtype}/{id}", id)
    31  		}
    32  		subtype := segments[0]
    33  		id = segments[1]
    34  		switch subtype {
    35  		case "net":
    36  			return deleteElasticLoadBalancerV2(ctx, elbv2.New(session), arn, logger)
    37  		default:
    38  			return errors.Errorf("unrecognized elastic load balancing resource subtype %s", subtype)
    39  		}
    40  	case "targetgroup":
    41  		return deleteElasticLoadBalancerTargetGroup(ctx, elbv2.New(session), arn, logger)
    42  	case "listener":
    43  		return deleteElasticLoadBalancerListener(ctx, elbv2.New(session), arn, logger)
    44  	default:
    45  		return errors.Errorf("unrecognized elastic load balancing resource type %s", resourceType)
    46  	}
    47  }
    48  
    49  func deleteElasticLoadBalancerClassic(ctx context.Context, client *elb.ELB, name string, logger logrus.FieldLogger) error {
    50  	_, err := client.DeleteLoadBalancerWithContext(ctx, &elb.DeleteLoadBalancerInput{
    51  		LoadBalancerName: aws.String(name),
    52  	})
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	logger.Info("Deleted")
    58  	return nil
    59  }
    60  
    61  func deleteElasticLoadBalancerClassicByVPC(ctx context.Context, client *elb.ELB, vpc string, logger logrus.FieldLogger) error {
    62  	var lastError error
    63  	err := client.DescribeLoadBalancersPagesWithContext(
    64  		ctx,
    65  		&elb.DescribeLoadBalancersInput{},
    66  		func(results *elb.DescribeLoadBalancersOutput, lastPage bool) bool {
    67  			logger.Debugf("iterating over a page of %d v1 load balancers", len(results.LoadBalancerDescriptions))
    68  			for _, lb := range results.LoadBalancerDescriptions {
    69  				lbLogger := logger.WithField("classic load balancer", *lb.LoadBalancerName)
    70  
    71  				if lb.VPCId == nil {
    72  					lbLogger.Warn("classic load balancer does not have a VPC ID so could not determine whether it should be deleted")
    73  					continue
    74  				}
    75  
    76  				if *lb.VPCId != vpc {
    77  					continue
    78  				}
    79  
    80  				err := deleteElasticLoadBalancerClassic(ctx, client, *lb.LoadBalancerName, lbLogger)
    81  				if err != nil {
    82  					if lastError != nil {
    83  						logger.Debug(lastError)
    84  					}
    85  					lastError = errors.Wrapf(err, "deleting classic load balancer %s", *lb.LoadBalancerName)
    86  				}
    87  			}
    88  
    89  			return !lastPage
    90  		},
    91  	)
    92  
    93  	if lastError != nil {
    94  		return lastError
    95  	}
    96  	return err
    97  }
    98  
    99  func deleteElasticLoadBalancerTargetGroup(ctx context.Context, client *elbv2.ELBV2, arn arn.ARN, logger logrus.FieldLogger) error {
   100  	_, err := client.DeleteTargetGroupWithContext(ctx, &elbv2.DeleteTargetGroupInput{
   101  		TargetGroupArn: aws.String(arn.String()),
   102  	})
   103  	if err != nil {
   104  		return err
   105  	}
   106  
   107  	logger.Info("Deleted")
   108  	return nil
   109  }
   110  
   111  func isListenerNotFound(err interface{}) bool {
   112  	if aerr, ok := err.(awserr.Error); ok {
   113  		if aerr.Code() == elbv2.ErrCodeListenerNotFoundException {
   114  			return true
   115  		}
   116  	}
   117  	return false
   118  }
   119  
   120  func deleteElasticLoadBalancerListener(ctx context.Context, client *elbv2.ELBV2, arn arn.ARN, logger logrus.FieldLogger) error {
   121  	_, err := client.DeleteListenerWithContext(ctx, &elbv2.DeleteListenerInput{
   122  		ListenerArn: aws.String(arn.String()),
   123  	})
   124  	if err != nil {
   125  		if isListenerNotFound(err) {
   126  			logger.Info("Not found or already deleted")
   127  			return nil
   128  		}
   129  		return err
   130  	}
   131  
   132  	logger.Info("Deleted")
   133  	return nil
   134  }
   135  
   136  func deleteElasticLoadBalancerV2(ctx context.Context, client *elbv2.ELBV2, arn arn.ARN, logger logrus.FieldLogger) error {
   137  	_, err := client.DeleteLoadBalancerWithContext(ctx, &elbv2.DeleteLoadBalancerInput{
   138  		LoadBalancerArn: aws.String(arn.String()),
   139  	})
   140  	if err != nil {
   141  		return err
   142  	}
   143  
   144  	logger.Info("Deleted")
   145  	return nil
   146  }
   147  
   148  func deleteElasticLoadBalancerV2ByVPC(ctx context.Context, client *elbv2.ELBV2, vpc string, logger logrus.FieldLogger) error {
   149  	var lastError error
   150  	err := client.DescribeLoadBalancersPagesWithContext(
   151  		ctx,
   152  		&elbv2.DescribeLoadBalancersInput{},
   153  		func(results *elbv2.DescribeLoadBalancersOutput, lastPage bool) bool {
   154  			logger.Debugf("iterating over a page of %d v2 load balancers", len(results.LoadBalancers))
   155  			for _, lb := range results.LoadBalancers {
   156  				if lb.VpcId == nil {
   157  					logger.WithField("load balancer", *lb.LoadBalancerArn).Warn("load balancer does not have a VPC ID so could not determine whether it should be deleted")
   158  					continue
   159  				}
   160  
   161  				if *lb.VpcId != vpc {
   162  					continue
   163  				}
   164  
   165  				parsed, err := arn.Parse(*lb.LoadBalancerArn)
   166  				if err != nil {
   167  					if lastError != nil {
   168  						logger.Debug(lastError)
   169  					}
   170  					lastError = errors.Wrap(err, "parse ARN for load balancer")
   171  					continue
   172  				}
   173  
   174  				err = deleteElasticLoadBalancerV2(ctx, client, parsed, logger.WithField("load balancer", parsed.Resource))
   175  				if err != nil {
   176  					if lastError != nil {
   177  						logger.Debug(lastError)
   178  					}
   179  					lastError = errors.Wrapf(err, "deleting %s", parsed.String())
   180  				}
   181  			}
   182  
   183  			return !lastPage
   184  		},
   185  	)
   186  
   187  	if lastError != nil {
   188  		return lastError
   189  	}
   190  	return err
   191  }