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 }