github.com/Tyktechnologies/tyk@v2.9.5+incompatible/dnscache/storage.go (about)

     1  package dnscache
     2  
     3  import (
     4  	"net"
     5  	"time"
     6  
     7  	"fmt"
     8  
     9  	cache "github.com/pmylund/go-cache"
    10  	"github.com/sirupsen/logrus"
    11  )
    12  
    13  // DnsCacheItem represents single record in cache
    14  type DnsCacheItem struct {
    15  	Addrs []string
    16  }
    17  
    18  // DnsCacheStorage is an in-memory cache of auto-purged dns query ip responses
    19  type DnsCacheStorage struct {
    20  	cache *cache.Cache
    21  }
    22  
    23  func NewDnsCacheStorage(expiration, checkInterval time.Duration) *DnsCacheStorage {
    24  	storage := DnsCacheStorage{cache.New(expiration, checkInterval)}
    25  	return &storage
    26  }
    27  
    28  // Items returns map of non expired dns cache items
    29  func (dc *DnsCacheStorage) Items(includeExpired bool) map[string]DnsCacheItem {
    30  	var allItems = dc.cache.Items()
    31  
    32  	nonExpiredItems := map[string]DnsCacheItem{}
    33  
    34  	for k, v := range allItems {
    35  		if !includeExpired && v.Expired() {
    36  			continue
    37  		}
    38  		nonExpiredItems[k] = v.Object.(DnsCacheItem)
    39  	}
    40  
    41  	return nonExpiredItems
    42  }
    43  
    44  // Get returns non expired item from cache
    45  func (dc *DnsCacheStorage) Get(key string) (DnsCacheItem, bool) {
    46  	item, found := dc.cache.Get(key)
    47  	if !found {
    48  		return DnsCacheItem{}, false
    49  	}
    50  	return item.(DnsCacheItem), found
    51  }
    52  
    53  func (dc *DnsCacheStorage) Delete(key string) {
    54  	dc.cache.Delete(key)
    55  }
    56  
    57  // FetchItem returns list of ips from cache or resolves them and add to cache
    58  func (dc *DnsCacheStorage) FetchItem(hostName string) ([]string, error) {
    59  	if hostName == "" {
    60  		return nil, fmt.Errorf("hostName can't be empty. hostName=%v", hostName)
    61  	}
    62  
    63  	item, ok := dc.Get(hostName)
    64  	if ok {
    65  		logger.WithFields(logrus.Fields{
    66  			"hostName": hostName,
    67  			"addrs":    item.Addrs,
    68  		}).Debug("Dns record was populated from cache")
    69  		return item.Addrs, nil
    70  	}
    71  
    72  	addrs, err := dc.resolveDNSRecord(hostName)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	dc.Set(hostName, addrs)
    78  	return addrs, nil
    79  }
    80  
    81  func (dc *DnsCacheStorage) Set(key string, addrs []string) {
    82  	logger.Debugf("Adding dns record to cache: key=%q, addrs=%q", key, addrs)
    83  	dc.cache.Set(key, DnsCacheItem{addrs}, cache.DefaultExpiration)
    84  }
    85  
    86  // Clear deletes all records from cache
    87  func (dc *DnsCacheStorage) Clear() {
    88  	dc.cache.Flush()
    89  }
    90  
    91  func (dc *DnsCacheStorage) resolveDNSRecord(host string) ([]string, error) {
    92  	return net.LookupHost(host)
    93  }