github.com/philhug/dnscontrol@v0.2.4-0.20180625181521-921fa9849001/models/domain.go (about)

     1  package models
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"golang.org/x/net/idna"
     7  )
     8  
     9  // DomainConfig describes a DNS domain (tecnically a  DNS zone).
    10  type DomainConfig struct {
    11  	Name             string         `json:"name"` // NO trailing "."
    12  	RegistrarName    string         `json:"registrar"`
    13  	DNSProviderNames map[string]int `json:"dnsProviders"`
    14  
    15  	Metadata      map[string]string `json:"meta,omitempty"`
    16  	Records       Records           `json:"records"`
    17  	Nameservers   []*Nameserver     `json:"nameservers,omitempty"`
    18  	KeepUnknown   bool              `json:"keepunknown,omitempty"`
    19  	IgnoredLabels []string          `json:"ignored_labels,omitempty"`
    20  
    21  	// These fields contain instantiated provider instances once everything is linked up.
    22  	// This linking is in two phases:
    23  	// 1. Metadata (name/type) is availible just from the dnsconfig. Validation can use that.
    24  	// 2. Final driver instances are loaded after we load credentials. Any actual provider interaction requires that.
    25  	RegistrarInstance    *RegistrarInstance     `json:"-"`
    26  	DNSProviderInstances []*DNSProviderInstance `json:"-"`
    27  }
    28  
    29  // Copy returns a deep copy of the DomainConfig.
    30  func (dc *DomainConfig) Copy() (*DomainConfig, error) {
    31  	newDc := &DomainConfig{}
    32  	// provider instances are interfaces that gob hates if you don't register them.
    33  	// and the specific types are not gob encodable since nothing is exported.
    34  	// should find a better solution for this now.
    35  	//
    36  	// current strategy: remove everything, gob copy it. Then set both to stored copy.
    37  	reg := dc.RegistrarInstance
    38  	dnsps := dc.DNSProviderInstances
    39  	dc.RegistrarInstance = nil
    40  	dc.DNSProviderInstances = nil
    41  	err := copyObj(dc, newDc)
    42  	dc.RegistrarInstance = reg
    43  	newDc.RegistrarInstance = reg
    44  	dc.DNSProviderInstances = dnsps
    45  	newDc.DNSProviderInstances = dnsps
    46  	return newDc, err
    47  }
    48  
    49  // HasRecordTypeName returns True if there is a record with this rtype and name.
    50  func (dc *DomainConfig) HasRecordTypeName(rtype, name string) bool {
    51  	for _, r := range dc.Records {
    52  		if r.Type == rtype && r.GetLabel() == name {
    53  			return true
    54  		}
    55  	}
    56  	return false
    57  }
    58  
    59  // Filter removes all records that don't match the filter f.
    60  func (dc *DomainConfig) Filter(f func(r *RecordConfig) bool) {
    61  	recs := []*RecordConfig{}
    62  	for _, r := range dc.Records {
    63  		if f(r) {
    64  			recs = append(recs, r)
    65  		}
    66  	}
    67  	dc.Records = recs
    68  }
    69  
    70  // Punycode will convert all records to punycode format.
    71  // It will encode:
    72  // - Name
    73  // - NameFQDN
    74  // - Target (CNAME and MX only)
    75  func (dc *DomainConfig) Punycode() error {
    76  	for _, rec := range dc.Records {
    77  		t, err := idna.ToASCII(rec.GetLabelFQDN())
    78  		if err != nil {
    79  			return err
    80  		}
    81  		rec.SetLabelFromFQDN(t, dc.Name)
    82  		switch rec.Type { // #rtype_variations
    83  		case "ALIAS", "MX", "NS", "CNAME", "PTR", "SRV", "URL", "URL301", "FRAME", "R53_ALIAS":
    84  			// These rtypes are hostnames, therefore need to be converted (unlike, for example, an AAAA record)
    85  			t, err := idna.ToASCII(rec.GetTargetField())
    86  			rec.SetTarget(t)
    87  			if err != nil {
    88  				return err
    89  			}
    90  		case "A", "AAAA", "CAA", "TXT", "TLSA":
    91  			// Nothing to do.
    92  		default:
    93  			msg := fmt.Sprintf("Punycode rtype %v unimplemented", rec.Type)
    94  			panic(msg)
    95  			// We panic so that we quickly find any switch statements
    96  			// that have not been updated for a new RR type.
    97  		}
    98  	}
    99  	return nil
   100  }