github.com/openshift/installer@v1.4.17/pkg/destroy/ibmcloud/securitygroup.go (about)

     1  package ibmcloud
     2  
     3  import (
     4  	"net/http"
     5  	"reflect"
     6  	"strings"
     7  
     8  	"github.com/IBM/vpc-go-sdk/vpcv1"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  const (
    13  	securityGroupTypeName     = "security group"
    14  	securityGroupRuleTypeName = "security group rule"
    15  )
    16  
    17  // listSecurityGroups lists security groups in the vpc
    18  func (o *ClusterUninstaller) listSecurityGroups() (cloudResources, error) {
    19  	o.Logger.Debugf("Listing security groups")
    20  	ctx, cancel := o.contextWithTimeout()
    21  	defer cancel()
    22  
    23  	options := o.vpcSvc.NewListSecurityGroupsOptions()
    24  	resources, _, err := o.vpcSvc.ListSecurityGroupsWithContext(ctx, options)
    25  	if err != nil {
    26  		return nil, errors.Wrapf(err, "Failed to list security groups")
    27  	}
    28  
    29  	result := []cloudResource{}
    30  	for _, securityGroup := range resources.SecurityGroups {
    31  		if strings.Contains(*securityGroup.Name, o.InfraID) {
    32  			result = append(result, cloudResource{
    33  				key:      *securityGroup.ID,
    34  				name:     *securityGroup.Name,
    35  				status:   "",
    36  				typeName: securityGroupTypeName,
    37  				id:       *securityGroup.ID,
    38  			})
    39  		}
    40  	}
    41  
    42  	return cloudResources{}.insert(result...), nil
    43  }
    44  
    45  func (o *ClusterUninstaller) listSecurityGroupRules(securityGroupID string) (cloudResources, error) {
    46  	o.Logger.Debugf("Listing security group rules for %q", securityGroupID)
    47  	ctx, cancel := o.contextWithTimeout()
    48  	defer cancel()
    49  
    50  	options := o.vpcSvc.NewListSecurityGroupRulesOptions(securityGroupID)
    51  	resources, _, err := o.vpcSvc.ListSecurityGroupRulesWithContext(ctx, options)
    52  	if err != nil {
    53  		return nil, errors.Wrapf(err, "Failed to list security group rules for %q", securityGroupID)
    54  	}
    55  
    56  	result := []cloudResource{}
    57  	for _, securityGroupRule := range resources.Rules {
    58  		switch reflect.TypeOf(securityGroupRule).String() {
    59  
    60  		case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll":
    61  			{
    62  				rule := securityGroupRule.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll)
    63  				result = append(result, cloudResource{
    64  					key:      *rule.ID,
    65  					name:     *rule.ID,
    66  					status:   "",
    67  					typeName: securityGroupRuleTypeName,
    68  					id:       *rule.ID,
    69  				})
    70  			}
    71  		case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp":
    72  			{
    73  				rule := securityGroupRule.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp)
    74  				result = append(result, cloudResource{
    75  					key:      *rule.ID,
    76  					name:     *rule.ID,
    77  					status:   "",
    78  					typeName: securityGroupRuleTypeName,
    79  					id:       *rule.ID,
    80  				})
    81  			}
    82  		case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp":
    83  			{
    84  				rule := securityGroupRule.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp)
    85  				result = append(result, cloudResource{
    86  					key:      *rule.ID,
    87  					name:     *rule.ID,
    88  					status:   "",
    89  					typeName: securityGroupRuleTypeName,
    90  					id:       *rule.ID,
    91  				})
    92  			}
    93  		default:
    94  			{
    95  				o.Logger.Debugf("Unknown rule: %q", securityGroupRule)
    96  			}
    97  		}
    98  	}
    99  
   100  	return cloudResources{}.insert(result...), nil
   101  }
   102  
   103  func (o *ClusterUninstaller) deleteSecurityGroup(item cloudResource) error {
   104  	o.Logger.Debugf("Deleting security group %q", item.name)
   105  	ctx, cancel := o.contextWithTimeout()
   106  	defer cancel()
   107  
   108  	found, err := o.listSecurityGroupRules(item.id)
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	rules := o.insertPendingItems(securityGroupRuleTypeName, found.list())
   114  
   115  	for _, rule := range rules {
   116  		if _, ok := found[rule.key]; !ok {
   117  			// This item has finished deletion.
   118  			o.deletePendingItems(rule.typeName, []cloudResource{rule})
   119  			o.Logger.Infof("Deleted security group rule %q", rule.name)
   120  			continue
   121  		}
   122  		err = o.deleteSecurityGroupRule(rule, item.id)
   123  		if err != nil {
   124  			o.errorTracker.suppressWarning(rule.key, err, o.Logger)
   125  		}
   126  	}
   127  
   128  	if rules = o.getPendingItems(securityGroupRuleTypeName); len(rules) > 0 {
   129  		return errors.Errorf("%d items pending", len(rules))
   130  	}
   131  
   132  	options := o.vpcSvc.NewDeleteSecurityGroupOptions(item.id)
   133  	details, err := o.vpcSvc.DeleteSecurityGroupWithContext(ctx, options)
   134  
   135  	if err != nil && details != nil && details.StatusCode == http.StatusNotFound {
   136  		// The resource is gone
   137  		o.deletePendingItems(item.typeName, []cloudResource{item})
   138  		o.Logger.Infof("Deleted security group %q", item.name)
   139  		return nil
   140  	}
   141  
   142  	if err != nil && details != nil && details.StatusCode != http.StatusNotFound {
   143  		return errors.Wrapf(err, "Failed to delete security group %s", item.name)
   144  	}
   145  
   146  	return nil
   147  }
   148  
   149  func (o *ClusterUninstaller) deleteSecurityGroupRule(item cloudResource, securityGroupID string) error {
   150  	o.Logger.Debugf("Deleting security group rule %q", item.name)
   151  	ctx, cancel := o.contextWithTimeout()
   152  	defer cancel()
   153  
   154  	options := o.vpcSvc.NewDeleteSecurityGroupRuleOptions(securityGroupID, item.id)
   155  	details, err := o.vpcSvc.DeleteSecurityGroupRuleWithContext(ctx, options)
   156  	if err != nil && details != nil && details.StatusCode == http.StatusNotFound {
   157  		// The resource is gone
   158  		o.deletePendingItems(item.typeName, []cloudResource{item})
   159  		o.Logger.Infof("Deleted security group rule %q", item.name)
   160  		return nil
   161  	}
   162  
   163  	if err != nil && details != nil && details.StatusCode != http.StatusNotFound {
   164  		return errors.Wrapf(err, "Failed to delete security group rule %s", item.name)
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  // destroySecurityGroups removes all security group resources that have a name prefixed
   171  // with the cluster's infra ID.
   172  func (o *ClusterUninstaller) destroySecurityGroups() error {
   173  	if o.UserProvidedVPC == "" {
   174  		o.Logger.Info("Skipping deletion of security groups with generated VPC")
   175  		return nil
   176  	}
   177  
   178  	found, err := o.listSecurityGroups()
   179  	if err != nil {
   180  		return err
   181  	}
   182  
   183  	items := o.insertPendingItems(securityGroupTypeName, found.list())
   184  
   185  	for _, item := range items {
   186  		if _, ok := found[item.key]; !ok {
   187  			// This item has finished deletion.
   188  			o.deletePendingItems(item.typeName, []cloudResource{item})
   189  			o.Logger.Infof("Deleted security group %q", item.name)
   190  			continue
   191  		}
   192  		err = o.deleteSecurityGroup(item)
   193  		if err != nil {
   194  			o.errorTracker.suppressWarning(item.key, err, o.Logger)
   195  		}
   196  	}
   197  
   198  	if items = o.getPendingItems(securityGroupTypeName); len(items) > 0 {
   199  		return errors.Errorf("%d items pending", len(items))
   200  	}
   201  	return nil
   202  }