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  }