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 }