github.com/openshift/installer@v1.4.17/pkg/destroy/gcp/cloudcontroller.go (about)

     1  package gcp
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	compute "google.golang.org/api/compute/v1"
     8  	"k8s.io/apimachinery/pkg/util/sets"
     9  )
    10  
    11  // listCloudControllerInstanceGroups returns instance groups created by the cloud controller.
    12  // It list all instance groups matching the cloud controller name convention.
    13  // https://github.com/openshift/kubernetes/blob/1e5983903742f64bca36a464582178c940353e9a/pkg/cloudprovider/providers/gce/gce_loadbalancer_naming.go#L33-L40
    14  // https://github.com/openshift/kubernetes/blob/1e5983903742f64bca36a464582178c940353e9a/pkg/cloudprovider/providers/gce/gce_clusterid.go#L210-L238
    15  func (o *ClusterUninstaller) listCloudControllerInstanceGroups(ctx context.Context) ([]cloudResource, error) {
    16  	filter := fmt.Sprintf("name eq \"k8s-ig--%s\"", o.cloudControllerUID)
    17  	return o.listInstanceGroupsWithFilter(ctx, "items/*/instanceGroups(name,selfLink,zone),nextPageToken", filter, nil)
    18  }
    19  
    20  // listCloudControllerBackendServices returns backend services created by the cloud controller.
    21  // It list all backend services matching the cloud controller name convention that contain
    22  // only cluster instance groups.
    23  func (o *ClusterUninstaller) listCloudControllerBackendServices(ctx context.Context, instanceGroups []cloudResource) ([]cloudResource, error) {
    24  	urls := sets.NewString()
    25  	for _, instanceGroup := range instanceGroups {
    26  		urls.Insert(instanceGroup.url)
    27  	}
    28  	filter := "name eq \"a[0-9a-f]{30,50}\""
    29  	return o.listBackendServicesWithFilter(ctx, "items(name,backends),nextPageToken", filter, func(item *compute.BackendService) bool {
    30  		if len(item.Backends) == 0 {
    31  			return false
    32  		}
    33  		for _, backend := range item.Backends {
    34  			if !urls.Has(backend.Group) {
    35  				return false
    36  			}
    37  		}
    38  		return true
    39  	}, gcpRegionalResource)
    40  }
    41  
    42  // listCloudControllerTargetPools returns target pools created by the cloud controller or owned by the cloud controller.
    43  // It lists all target pools matching the cloud controller name convention that contain
    44  // only cluster instances or cluster instances that were owned by the cluster.
    45  func (o *ClusterUninstaller) listCloudControllerTargetPools(ctx context.Context, instances []cloudResource) ([]cloudResource, error) {
    46  	filter := "name eq \"a[0-9a-f]{30,50}\""
    47  	return o.listTargetPoolsWithFilter(ctx, "items(name,instances),nextPageToken", filter, func(pool *compute.TargetPool) bool {
    48  		if len(pool.Instances) == 0 {
    49  			return false
    50  		}
    51  		for _, instanceURL := range pool.Instances {
    52  			name, _ := o.getInstanceNameAndZone(instanceURL)
    53  			if !o.isClusterResource(name) {
    54  				foundClusterResource := false
    55  				for _, instance := range instances {
    56  					if instance.name == name {
    57  						foundClusterResource = true
    58  						break
    59  					}
    60  				}
    61  
    62  				if !foundClusterResource {
    63  					o.Logger.Debugf("Skipping target pool instance %s because it is not a cluster resource", pool.Name)
    64  					return false
    65  				}
    66  			}
    67  		}
    68  		return true
    69  	})
    70  }
    71  
    72  // DiscoverCloudControllerLoadBalancerResources follows a similar procedure as:
    73  // https://github.com/openshift/kubernetes/blob/1e5983903742f64bca36a464582178c940353e9a/pkg/cloudprovider/providers/gce/gce_loadbalancer_internal.go#L222
    74  // https://github.com/openshift/kubernetes/blob/1e5983903742f64bca36a464582178c940353e9a/pkg/cloudprovider/providers/gce/gce_loadbalancer_external.go#L289
    75  func (o *ClusterUninstaller) discoverCloudControllerLoadBalancerResources(ctx context.Context, loadBalancerName string) error {
    76  	loadBalancerNameFilter := fmt.Sprintf("name eq \"%s\"", loadBalancerName)
    77  
    78  	// Discover associated addresses: loadBalancerName
    79  	found, err := o.listAddressesWithFilter(ctx, "items(name),nextPageToken", loadBalancerNameFilter, nil, gcpRegionalResource)
    80  	if err != nil {
    81  		return err
    82  	}
    83  	o.insertPendingItems("address", found)
    84  
    85  	// Discover associated firewall rules: loadBalancerName
    86  	found, err = o.listFirewallsWithFilter(ctx, "items(name),nextPageToken", loadBalancerNameFilter, nil)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	o.insertPendingItems("firewall", found)
    91  
    92  	// Discover associated firewall rules: loadBalancerName-hc
    93  	filter := fmt.Sprintf("name eq \"%s-hc\"", loadBalancerName)
    94  	found, err = o.listFirewallsWithFilter(ctx, "items(name),nextPageToken", filter, nil)
    95  	if err != nil {
    96  		return err
    97  	}
    98  	o.insertPendingItems("firewall", found)
    99  
   100  	// Discover associated firewall rules: k8s-fw-loadBalancerName
   101  	filter = fmt.Sprintf("name eq \"k8s-fw-%s\"", loadBalancerName)
   102  	found, err = o.listFirewallsWithFilter(ctx, "items(name),nextPageToken", filter, nil)
   103  	if err != nil {
   104  		return err
   105  	}
   106  	o.insertPendingItems("firewall", found)
   107  
   108  	// Discover associated firewall rules: k8s-loadBalancerName-http-hc
   109  	filter = fmt.Sprintf("name eq \"k8s-%s-http-hc\"", loadBalancerName)
   110  	found, err = o.listFirewallsWithFilter(ctx, "items(name),nextPageToken", filter, nil)
   111  	if err != nil {
   112  		return err
   113  	}
   114  	o.insertPendingItems("firewall", found)
   115  
   116  	// Discover associated forwarding rules: loadBalancerName
   117  	found, err = o.listForwardingRulesWithFilter(ctx, "items(name),nextPageToken", loadBalancerNameFilter, nil, gcpRegionalResource)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	o.insertPendingItems("forwardingrule", found)
   122  
   123  	// Discover associated health checks: loadBalancerName
   124  	found, err = o.listHealthChecksWithFilter(ctx, "healthcheck", "items(name),nextPageToken", loadBalancerNameFilter, o.healthCheckList)
   125  	if err != nil {
   126  		return err
   127  	}
   128  	o.insertPendingItems("healthcheck", found)
   129  
   130  	// Discover associated http health checks: loadBalancerName
   131  	found, err = o.listHTTPHealthChecksWithFilter(ctx, "items(name),nextPageToken", loadBalancerNameFilter, nil)
   132  	if err != nil {
   133  		return err
   134  	}
   135  	o.insertPendingItems("httphealthcheck", found)
   136  
   137  	return nil
   138  }
   139  
   140  // discoverCloudControllerResources finds resources associated with internal load balancers
   141  // created by the kube cloud controller. It first finds instance groups associated with instances
   142  // belonging to this cluster, then finds backend resources that point to these instance groups.
   143  // For each of those backend services, resources like forwarding rules, firewalls, health checks and
   144  // backend services are added to pendingItems
   145  func (o *ClusterUninstaller) discoverCloudControllerResources(ctx context.Context) error {
   146  	o.Logger.Debugf("Discovering cloud controller resources")
   147  	errs := []error{}
   148  
   149  	// Instance group related items
   150  	instanceGroups, err := o.listCloudControllerInstanceGroups(ctx)
   151  	if err != nil {
   152  		return err
   153  	}
   154  	installerInstanceGroups, err := o.listInstanceGroups(ctx)
   155  	if err != nil {
   156  		return err
   157  	}
   158  	clusterInstanceGroups := append(instanceGroups, installerInstanceGroups...)
   159  	if len(clusterInstanceGroups) != 0 {
   160  		backends, err := o.listCloudControllerBackendServices(ctx, clusterInstanceGroups)
   161  		if err != nil {
   162  			return err
   163  		}
   164  		for _, backend := range backends {
   165  			o.Logger.Debugf("Discovering cloud controller resources for %s", backend.name)
   166  			err := o.discoverCloudControllerLoadBalancerResources(ctx, backend.name)
   167  			if err != nil {
   168  				errs = append(errs, err)
   169  			}
   170  		}
   171  		o.insertPendingItems("backendservice", backends)
   172  	}
   173  	o.insertPendingItems("instancegroup", instanceGroups)
   174  
   175  	// Get a list of known cluster instances
   176  	instances, err := o.listInstances(ctx)
   177  	if err != nil {
   178  		return err
   179  	}
   180  
   181  	// Target pool related items
   182  	pools, err := o.listCloudControllerTargetPools(ctx, instances)
   183  	if err != nil {
   184  		return err
   185  	}
   186  	for _, pool := range pools {
   187  		o.Logger.Debugf("Discovering cloud controller resources for %s", pool.name)
   188  		err := o.discoverCloudControllerLoadBalancerResources(ctx, pool.name)
   189  		if err != nil {
   190  			errs = append(errs, err)
   191  		}
   192  	}
   193  	o.insertPendingItems("targetpool", pools)
   194  
   195  	// cloudControllerUID related items
   196  	if len(o.cloudControllerUID) > 0 {
   197  		// Discover Cloud Controller health checks: k8s-cloudControllerUID-node
   198  		filter := fmt.Sprintf("name eq \"k8s-%s-node\"", o.cloudControllerUID)
   199  		found, err := o.listHealthChecksWithFilter(ctx, "healthcheck", "items(name),nextPageToken", filter, o.healthCheckList)
   200  		if err != nil {
   201  			return err
   202  		}
   203  		o.insertPendingItems("healthcheck", found)
   204  
   205  		// Discover Cloud Controller http health checks: k8s-cloudControllerUID-node
   206  		found, err = o.listHTTPHealthChecksWithFilter(ctx, "items(name),nextPageToken", filter, nil)
   207  		if err != nil {
   208  			return err
   209  		}
   210  		o.insertPendingItems("httphealthcheck", found)
   211  
   212  		// Discover Cloud Controller firewall rules: k8s-cloudControllerUID-node-hc, k8s-cloudControllerUID-node-http-hc
   213  		filter = fmt.Sprintf("name eq \"k8s-%s-node-hc\"", o.cloudControllerUID)
   214  		found, err = o.listFirewallsWithFilter(ctx, "items(name),nextPageToken", filter, nil)
   215  		if err != nil {
   216  			return err
   217  		}
   218  		o.insertPendingItems("firewall", found)
   219  
   220  		filter = fmt.Sprintf("name eq \"k8s-%s-node-http-hc\"", o.cloudControllerUID)
   221  		found, err = o.listFirewallsWithFilter(ctx, "items(name),nextPageToken", filter, nil)
   222  		if err != nil {
   223  			return err
   224  		}
   225  		o.insertPendingItems("firewall", found)
   226  	}
   227  
   228  	return aggregateError(errs, 0)
   229  }