github.com/openshift/installer@v1.4.17/pkg/destroy/ibmcloud/dns.go (about) 1 package ibmcloud 2 3 import ( 4 "fmt" 5 "net/http" 6 "regexp" 7 8 "github.com/pkg/errors" 9 ) 10 11 const dnsRecordTypeName = "dns record" 12 13 // listDNSRecords lists DNS records for the cluster for CIS or DNS Service 14 func (o *ClusterUninstaller) listDNSRecords() (cloudResources, error) { 15 if len(o.CISInstanceCRN) > 0 { 16 return o.listCISDNSRecords() 17 } 18 return o.listDNSSvcDNSRecords() 19 } 20 21 // listCISDNSRecords lists CIS DNS records for the cluster 22 func (o *ClusterUninstaller) listCISDNSRecords() (cloudResources, error) { 23 o.Logger.Debug("Listing CIS DNS records") 24 ctx, cancel := o.contextWithTimeout() 25 defer cancel() 26 27 result := []cloudResource{} 28 moreData := true 29 for moreData { 30 options := o.dnsRecordsSvc.NewListAllDnsRecordsOptions() 31 resources, _, err := o.dnsRecordsSvc.ListAllDnsRecordsWithContext(ctx, options) 32 33 if err != nil { 34 return nil, errors.Wrapf(err, "Failed to list DNS records") 35 } 36 37 for _, record := range resources.Result { 38 // Match all of the cluster's DNS records 39 exp := fmt.Sprintf(`.*\Q.%s.%s\E$`, o.ClusterName, o.BaseDomain) 40 nameMatches, _ := regexp.Match(exp, []byte(*record.Name)) 41 contentMatches, _ := regexp.Match(exp, []byte(*record.Content)) 42 if nameMatches || contentMatches { 43 result = append(result, cloudResource{ 44 key: *record.ID, 45 name: *record.Name, 46 status: "", 47 typeName: dnsRecordTypeName, 48 id: *record.ID, 49 }) 50 } 51 } 52 53 resultInfo := *resources.ResultInfo 54 moreData = (*resultInfo.PerPage * *resultInfo.Page) < *resultInfo.Count 55 } 56 57 return cloudResources{}.insert(result...), nil 58 } 59 60 // listDNSSvcDNSRecords lists DNS Services DNS records for the cluster 61 func (o *ClusterUninstaller) listDNSSvcDNSRecords() (cloudResources, error) { 62 o.Logger.Debug("Listing DNS Services DNS records") 63 ctx, cancel := o.contextWithTimeout() 64 defer cancel() 65 66 result := []cloudResource{} 67 resourceRecordsRemaining := true 68 viewedResourceRecords := int64(0) 69 for resourceRecordsRemaining { 70 options := o.dnsServicesSvc.NewListResourceRecordsOptions(o.DNSInstanceID, o.zoneID) 71 options = options.SetOffset(viewedResourceRecords) 72 resources, _, err := o.dnsServicesSvc.ListResourceRecordsWithContext(ctx, options) 73 74 if err != nil { 75 return nil, errors.Wrap(err, "Failed to list DNS records") 76 } 77 78 for _, record := range resources.ResourceRecords { 79 // Match all of the cluster's DNS records 80 exp := fmt.Sprintf(`.*\Q.%s.%s\E$`, o.ClusterName, o.BaseDomain) 81 if nameMatches, _ := regexp.Match(exp, []byte(*record.Name)); nameMatches { 82 result = append(result, cloudResource{ 83 key: *record.ID, 84 name: *record.Name, 85 status: "", 86 typeName: dnsRecordTypeName, 87 id: *record.ID, 88 }) 89 } 90 } 91 92 viewedResourceRecords += *resources.Limit 93 resourceRecordsRemaining = viewedResourceRecords < *resources.TotalCount 94 } 95 96 return cloudResources{}.insert(result...), nil 97 } 98 99 // deleteDNSRecord deletes a CIS or DNS Services DNS Record 100 func (o *ClusterUninstaller) deleteDNSRecord(item cloudResource) error { 101 if len(o.CISInstanceCRN) > 0 { 102 return o.deleteCISDNSRecord(item) 103 } 104 return o.deleteDNSSvcDNSRecord(item) 105 } 106 107 // deleteCISDNSRecord deletes a CIS DNS Record 108 func (o *ClusterUninstaller) deleteCISDNSRecord(item cloudResource) error { 109 o.Logger.Debugf("Deleting DNS record %q", item.name) 110 ctx, cancel := o.contextWithTimeout() 111 defer cancel() 112 113 options := o.dnsRecordsSvc.NewDeleteDnsRecordOptions(item.id) 114 _, details, err := o.dnsRecordsSvc.DeleteDnsRecordWithContext(ctx, options) 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 DNS record %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 DNS record %s", item.name) 125 } 126 127 return nil 128 } 129 130 // deleteDNSSvcDNSRecord deletes a DNS Services DNS Record 131 func (o *ClusterUninstaller) deleteDNSSvcDNSRecord(item cloudResource) error { 132 o.Logger.Debugf("Deleting DNS record %q", item.name) 133 ctx, cancel := o.contextWithTimeout() 134 defer cancel() 135 136 options := o.dnsServicesSvc.NewDeleteResourceRecordOptions(o.DNSInstanceID, o.zoneID, item.id) 137 details, err := o.dnsServicesSvc.DeleteResourceRecordWithContext(ctx, options) 138 139 if err != nil && details != nil && details.StatusCode == http.StatusNotFound { 140 // The resource is gone 141 o.deletePendingItems(item.typeName, []cloudResource{item}) 142 o.Logger.Infof("Deleted DNS record %q", item.name) 143 return nil 144 } 145 146 if err != nil && details != nil && details.StatusCode != http.StatusNotFound { 147 return errors.Wrapf(err, "Failed to delete DNS record %s", item.name) 148 } 149 return nil 150 } 151 152 // destroyDNSRecords removes all DNS record resources that have a name containing 153 // the cluster's infra ID. 154 func (o *ClusterUninstaller) destroyDNSRecords() error { 155 // If neither CIS CRN or DNS Services ID is not set, skip DNS records cleanup 156 if len(o.CISInstanceCRN) == 0 && len(o.DNSInstanceID) == 0 { 157 o.Logger.Info("Skipping deletion of DNS Records, no CIS CRN or DNS Instance ID found") 158 return nil 159 } 160 161 found, err := o.listDNSRecords() 162 if err != nil { 163 return err 164 } 165 166 items := o.insertPendingItems(dnsRecordTypeName, found.list()) 167 168 for _, item := range items { 169 if _, ok := found[item.key]; !ok { 170 // This item has finished deletion. 171 o.deletePendingItems(item.typeName, []cloudResource{item}) 172 o.Logger.Infof("Deleted DNS record %q", item.name) 173 continue 174 } 175 err = o.deleteDNSRecord(item) 176 if err != nil { 177 o.errorTracker.suppressWarning(item.key, err, o.Logger) 178 } 179 } 180 181 if items = o.getPendingItems(dnsRecordTypeName); len(items) > 0 { 182 return errors.Errorf("%d items pending", len(items)) 183 } 184 return nil 185 }