github.com/openshift/installer@v1.4.17/pkg/destroy/powervs/power-subnet.go (about)

     1  package powervs
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math"
     7  	"strings"
     8  	"time"
     9  
    10  	"k8s.io/apimachinery/pkg/util/wait"
    11  )
    12  
    13  const powerSubnetTypeName = "powerSubnet"
    14  
    15  // listPowerSubnets lists subnets in the Power Server.
    16  func (o *ClusterUninstaller) listPowerSubnets() (cloudResources, error) {
    17  	o.Logger.Debugf("Listing Power Server Subnets")
    18  
    19  	if o.instanceClient == nil {
    20  		o.Logger.Infof("Skipping deleting Power service subnets because no service instance was found")
    21  		result := []cloudResource{}
    22  		return cloudResources{}.insert(result...), nil
    23  	}
    24  
    25  	networks, err := o.networkClient.GetAll()
    26  	if err != nil {
    27  		o.Logger.Warnf("Error networkClient.GetAll: %v", err)
    28  		return nil, err
    29  	}
    30  
    31  	result := []cloudResource{}
    32  	for _, network := range networks.Networks {
    33  		if strings.Contains(*network.Name, o.InfraID) {
    34  			o.Logger.Debugf("listPowerSubnets: FOUND: %s, %s", *network.NetworkID, *network.Name)
    35  			result = append(result, cloudResource{
    36  				key:      *network.NetworkID,
    37  				name:     *network.Name,
    38  				status:   "",
    39  				typeName: powerSubnetTypeName,
    40  				id:       *network.NetworkID,
    41  			})
    42  		}
    43  	}
    44  	if len(result) == 0 {
    45  		o.Logger.Debugf("listPowerSubnets: NO matching subnet against: %s", o.InfraID)
    46  		for _, network := range networks.Networks {
    47  			o.Logger.Debugf("listPowerSubnets: network: %s", *network.Name)
    48  		}
    49  	}
    50  
    51  	return cloudResources{}.insert(result...), nil
    52  }
    53  
    54  func (o *ClusterUninstaller) deletePowerSubnet(item cloudResource) error {
    55  	if _, err := o.networkClient.Get(item.id); err != nil {
    56  		o.deletePendingItems(item.typeName, []cloudResource{item})
    57  		o.Logger.Infof("Deleted Power Network %q", item.name)
    58  		return nil
    59  	}
    60  
    61  	o.Logger.Debugf("Deleting Power Network %q", item.name)
    62  
    63  	if err := o.networkClient.Delete(item.id); err != nil {
    64  		o.Logger.Infof("Error: o.networkClient.Delete: %q", err)
    65  		return err
    66  	}
    67  
    68  	o.deletePendingItems(item.typeName, []cloudResource{item})
    69  	o.Logger.Infof("Deleted Power Network %q", item.name)
    70  
    71  	return nil
    72  }
    73  
    74  // destroyPowerSubnets removes all subnet resources that have a name prefixed
    75  // with the cluster's infra ID.
    76  func (o *ClusterUninstaller) destroyPowerSubnets() error {
    77  	firstPassList, err := o.listPowerSubnets()
    78  	if err != nil {
    79  		return err
    80  	}
    81  
    82  	if len(firstPassList.list()) == 0 {
    83  		return nil
    84  	}
    85  
    86  	items := o.insertPendingItems(powerSubnetTypeName, firstPassList.list())
    87  
    88  	ctx, cancel := o.contextWithTimeout()
    89  	defer cancel()
    90  
    91  	for _, item := range items {
    92  		select {
    93  		case <-ctx.Done():
    94  			o.Logger.Debugf("destroyPowerSubnets: case <-ctx.Done()")
    95  			return o.Context.Err() // we're cancelled, abort
    96  		default:
    97  		}
    98  
    99  		backoff := wait.Backoff{
   100  			Duration: 15 * time.Second,
   101  			Factor:   1.1,
   102  			Cap:      leftInContext(ctx),
   103  			Steps:    math.MaxInt32}
   104  		err = wait.ExponentialBackoffWithContext(ctx, backoff, func(context.Context) (bool, error) {
   105  			err2 := o.deletePowerSubnet(item)
   106  			if err2 == nil {
   107  				return true, err2
   108  			}
   109  			o.errorTracker.suppressWarning(item.key, err2, o.Logger)
   110  			return false, err2
   111  		})
   112  		if err != nil {
   113  			o.Logger.Fatal("destroyPowerSubnets: ExponentialBackoffWithContext (destroy) returns ", err)
   114  		}
   115  	}
   116  
   117  	if items = o.getPendingItems(powerSubnetTypeName); len(items) > 0 {
   118  		for _, item := range items {
   119  			o.Logger.Debugf("destroyPowerSubnets: found %s in pending items", item.name)
   120  		}
   121  		return fmt.Errorf("destroyPowerSubnets: %d undeleted items pending", len(items))
   122  	}
   123  
   124  	backoff := wait.Backoff{
   125  		Duration: 15 * time.Second,
   126  		Factor:   1.1,
   127  		Cap:      leftInContext(ctx),
   128  		Steps:    math.MaxInt32}
   129  	err = wait.ExponentialBackoffWithContext(ctx, backoff, func(context.Context) (bool, error) {
   130  		secondPassList, err2 := o.listPowerSubnets()
   131  		if err2 != nil {
   132  			return false, err2
   133  		}
   134  		if len(secondPassList) == 0 {
   135  			// We finally don't see any remaining instances!
   136  			return true, nil
   137  		}
   138  		for _, item := range secondPassList {
   139  			o.Logger.Debugf("destroyPowerSubnets: found %s in second pass", item.name)
   140  		}
   141  		return false, nil
   142  	})
   143  	if err != nil {
   144  		o.Logger.Fatal("destroyPowerSubnets: ExponentialBackoffWithContext (list) returns ", err)
   145  	}
   146  
   147  	return nil
   148  }