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

     1  package ibmcloud
     2  
     3  import (
     4  	"net/http"
     5  	"strings"
     6  
     7  	"github.com/IBM/go-sdk-core/v5/core"
     8  	"github.com/IBM/vpc-go-sdk/vpcv1"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  const (
    13  	dedicatedHostTypeName      = "dedicated host"
    14  	dedicatedHostGroupTypeName = "dedicated host group"
    15  )
    16  
    17  // listDedicatedHosts searches for dedicated host that have a name that
    18  // starts with the cluster's infra ID.
    19  func (o *ClusterUninstaller) listDedicatedHosts() (cloudResources, error) {
    20  	o.Logger.Debugf("Listing dedicated hosts")
    21  	ctx, cancel := o.contextWithTimeout()
    22  	defer cancel()
    23  
    24  	resourceGroupID, err := o.ResourceGroupID()
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  
    29  	options := o.vpcSvc.NewListDedicatedHostsOptions()
    30  	options.SetResourceGroupID(resourceGroupID)
    31  	resources, _, err := o.vpcSvc.ListDedicatedHostsWithContext(ctx, options)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	result := []cloudResource{}
    37  	for _, dhost := range resources.DedicatedHosts {
    38  		if strings.HasPrefix(*dhost.Name, o.InfraID) {
    39  			result = append(result, cloudResource{
    40  				key:      *dhost.ID,
    41  				name:     *dhost.Name,
    42  				status:   *dhost.State,
    43  				typeName: dedicatedHostTypeName,
    44  				id:       *dhost.ID,
    45  			})
    46  		}
    47  	}
    48  
    49  	return cloudResources{}.insert(result...), nil
    50  }
    51  
    52  // listDedicatedHostGroups searches for dedicated host groups that have a name
    53  // that starts with the cluster's infra ID.
    54  func (o *ClusterUninstaller) listDedicatedHostGroups() (cloudResources, error) {
    55  	o.Logger.Debugf("Listing dedicated host groups")
    56  	ctx, cancel := o.contextWithTimeout()
    57  	defer cancel()
    58  
    59  	resourceGroupID, err := o.ResourceGroupID()
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	options := o.vpcSvc.NewListDedicatedHostGroupsOptions()
    65  	options.SetResourceGroupID(resourceGroupID)
    66  	resources, _, err := o.vpcSvc.ListDedicatedHostGroupsWithContext(ctx, options)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	result := []cloudResource{}
    72  	for _, dgroup := range resources.Groups {
    73  		if strings.HasPrefix(*dgroup.Name, o.InfraID) {
    74  			result = append(result, cloudResource{
    75  				key:      *dgroup.ID,
    76  				name:     *dgroup.Name,
    77  				status:   "",
    78  				typeName: dedicatedHostGroupTypeName,
    79  				id:       *dgroup.ID,
    80  			})
    81  		}
    82  	}
    83  
    84  	return cloudResources{}.insert(result...), nil
    85  }
    86  
    87  // deleteDedicatedHosts disables and deletes a dedicated host
    88  func (o *ClusterUninstaller) deleteDedicatedHost(item cloudResource) error {
    89  	if item.status == vpcv1.DedicatedHostLifecycleStateDeletingConst {
    90  		o.Logger.Debugf("Waiting for dedicated host %q to delete", item.name)
    91  		return nil
    92  	}
    93  
    94  	ctx, cancel := o.contextWithTimeout()
    95  	defer cancel()
    96  
    97  	o.Logger.Debugf("Getting dedicated host %q", item.name)
    98  
    99  	getOpts := o.vpcSvc.NewGetDedicatedHostOptions(item.id)
   100  	resource, _, err := o.vpcSvc.GetDedicatedHostWithContext(ctx, getOpts)
   101  	if err != nil {
   102  		return errors.Wrapf(err, "Failed to get dedicated host %q", item.name)
   103  	}
   104  
   105  	if *resource.InstancePlacementEnabled {
   106  		if err := o.disableDedicatedHost(item); err != nil {
   107  			return err
   108  		}
   109  	}
   110  
   111  	o.Logger.Debugf("Deleting dedicated host %q", item.name)
   112  
   113  	deleteOpts := o.vpcSvc.NewDeleteDedicatedHostOptions(item.id)
   114  	details, err := o.vpcSvc.DeleteDedicatedHostWithContext(ctx, deleteOpts)
   115  
   116  	if err != nil && details != nil && details.StatusCode == http.StatusNotFound {
   117  		// The resource is gone
   118  		o.deletePendingItems(item.typeName, []cloudResource{item})
   119  		o.Logger.Infof("Deleted dedicated host %q", item.name)
   120  		return nil
   121  	}
   122  
   123  	if err != nil && details != nil && details.StatusCode != http.StatusNotFound {
   124  		return errors.Wrapf(err, "Failed to delete dedicated host %q", item.name)
   125  	}
   126  
   127  	return nil
   128  }
   129  
   130  // deleteDedicatedHostGroups deletes a dedicated host group
   131  func (o *ClusterUninstaller) deleteDedicatedHostGroup(item cloudResource) error {
   132  	ctx, cancel := o.contextWithTimeout()
   133  	defer cancel()
   134  
   135  	o.Logger.Debugf("Deleting dedicated host group %q", item.name)
   136  
   137  	options := o.vpcSvc.NewDeleteDedicatedHostGroupOptions(item.id)
   138  	details, err := o.vpcSvc.DeleteDedicatedHostGroupWithContext(ctx, options)
   139  
   140  	if err != nil && details != nil && details.StatusCode == http.StatusNotFound {
   141  		// The resource is gone
   142  		o.deletePendingItems(item.typeName, []cloudResource{item})
   143  		o.Logger.Infof("Deleted dedicated host group %q", item.name)
   144  		return nil
   145  	}
   146  
   147  	if err != nil && details != nil && details.StatusCode != http.StatusNotFound {
   148  		return errors.Wrapf(err, "Failed to delete dedicated host group %q", item.name)
   149  	}
   150  
   151  	return nil
   152  }
   153  
   154  // disableDedicatedHosts disables a dedicated host
   155  func (o *ClusterUninstaller) disableDedicatedHost(item cloudResource) error {
   156  	o.Logger.Debugf("Disabling dedicated host %q", item.name)
   157  	ctx, cancel := o.contextWithTimeout()
   158  	defer cancel()
   159  
   160  	options := o.vpcSvc.NewUpdateDedicatedHostOptions(item.id, map[string]interface{}{
   161  		"instance_placement_enabled": core.BoolPtr(false),
   162  	})
   163  	_, _, err := o.vpcSvc.UpdateDedicatedHostWithContext(ctx, options)
   164  	if err != nil {
   165  		return errors.Wrapf(err, "Failed to disable dedicated host %q", item.name)
   166  	}
   167  
   168  	return nil
   169  }
   170  
   171  // destroyDedicatedHosts searches for dedicated hosts that have a name
   172  // that starts with the cluster's infra ID.
   173  func (o *ClusterUninstaller) destroyDedicatedHosts() error {
   174  	found, err := o.listDedicatedHosts()
   175  	if err != nil {
   176  		return err
   177  	}
   178  
   179  	items := o.insertPendingItems(dedicatedHostTypeName, found.list())
   180  	for _, item := range items {
   181  		if _, ok := found[item.key]; !ok {
   182  			// This item has finished deletion.
   183  			o.deletePendingItems(item.typeName, []cloudResource{item})
   184  			o.Logger.Infof("Deleted dedicated host %q", item.name)
   185  			continue
   186  		}
   187  		err := o.deleteDedicatedHost(item)
   188  		if err != nil {
   189  			o.errorTracker.suppressWarning(item.key, err, o.Logger)
   190  		}
   191  	}
   192  
   193  	if items = o.getPendingItems(dedicatedHostTypeName); len(items) > 0 {
   194  		return errors.Errorf("%d items pending", len(items))
   195  	}
   196  	return nil
   197  }
   198  
   199  // destroyDedicatedHostGroups searches for dedicated host groups that have
   200  // a name that starts with the cluster's infra ID.
   201  func (o *ClusterUninstaller) destroyDedicatedHostGroups() error {
   202  	found, err := o.listDedicatedHostGroups()
   203  	if err != nil {
   204  		return err
   205  	}
   206  
   207  	items := o.insertPendingItems(dedicatedHostGroupTypeName, found.list())
   208  	for _, item := range items {
   209  		if _, ok := found[item.key]; !ok {
   210  			// This item has finished deletion.
   211  			o.deletePendingItems(item.typeName, []cloudResource{item})
   212  			o.Logger.Infof("Deleted dedicated host group %q", item.name)
   213  			continue
   214  		}
   215  		err := o.deleteDedicatedHostGroup(item)
   216  		if err != nil {
   217  			o.errorTracker.suppressWarning(item.key, err, o.Logger)
   218  		}
   219  	}
   220  
   221  	if items = o.getPendingItems(dedicatedHostGroupTypeName); len(items) > 0 {
   222  		return errors.Errorf("%d items pending", len(items))
   223  	}
   224  	return nil
   225  }