github.com/webonyx/up@v0.7.4-0.20180808230834-91b94e551323/config/dns.go (about)

     1  package config
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"github.com/apex/up/internal/validate"
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // recordTypes is a list of valid record types.
    11  var recordTypes = []string{
    12  	"ALIAS",
    13  	"A",
    14  	"AAAA",
    15  	"CNAME",
    16  	"MX",
    17  	"NAPTR",
    18  	"NS",
    19  	"PTR",
    20  	"SOA",
    21  	"SPF",
    22  	"SRV",
    23  	"TXT",
    24  }
    25  
    26  // DNS config.
    27  type DNS struct {
    28  	Zones []*Zone `json:"zones"`
    29  }
    30  
    31  // UnmarshalJSON implementation.
    32  func (d *DNS) UnmarshalJSON(b []byte) error {
    33  	var zones map[string][]*Record
    34  
    35  	if err := json.Unmarshal(b, &zones); err != nil {
    36  		return err
    37  	}
    38  
    39  	for name, records := range zones {
    40  		zone := &Zone{Name: name, Records: records}
    41  		d.Zones = append(d.Zones, zone)
    42  	}
    43  
    44  	return nil
    45  }
    46  
    47  // Default implementation.
    48  func (d *DNS) Default() error {
    49  	for _, z := range d.Zones {
    50  		if err := z.Default(); err != nil {
    51  			return errors.Wrapf(err, "zone %s", z.Name)
    52  		}
    53  	}
    54  
    55  	return nil
    56  }
    57  
    58  // Validate implementation.
    59  func (d *DNS) Validate() error {
    60  	for _, z := range d.Zones {
    61  		if err := z.Validate(); err != nil {
    62  			return errors.Wrapf(err, "zone %s", z.Name)
    63  		}
    64  	}
    65  
    66  	return nil
    67  }
    68  
    69  // Zone is a DNS zone.
    70  type Zone struct {
    71  	Name    string    `json:"name"`
    72  	Records []*Record `json:"records"`
    73  }
    74  
    75  // Default implementation.
    76  func (z *Zone) Default() error {
    77  	for i, r := range z.Records {
    78  		if err := r.Default(); err != nil {
    79  			return errors.Wrapf(err, "record %d", i)
    80  		}
    81  	}
    82  
    83  	return nil
    84  }
    85  
    86  // Validate implementation.
    87  func (z *Zone) Validate() error {
    88  	for i, r := range z.Records {
    89  		if err := r.Validate(); err != nil {
    90  			return errors.Wrapf(err, "record %d", i)
    91  		}
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  // Record is a DNS record.
    98  type Record struct {
    99  	Name  string   `json:"name"`
   100  	Type  string   `json:"type"`
   101  	TTL   int      `json:"ttl"`
   102  	Value []string `json:"value"`
   103  }
   104  
   105  // Validate implementation.
   106  func (r *Record) Validate() error {
   107  	if err := validate.List(r.Type, recordTypes); err != nil {
   108  		return errors.Wrap(err, ".type")
   109  	}
   110  
   111  	if err := validate.RequiredString(r.Name); err != nil {
   112  		return errors.Wrap(err, ".name")
   113  	}
   114  
   115  	if err := validate.RequiredStrings(r.Value); err != nil {
   116  		return errors.Wrap(err, ".value")
   117  	}
   118  
   119  	if err := validate.MinStrings(r.Value, 1); err != nil {
   120  		return errors.Wrap(err, ".value")
   121  	}
   122  
   123  	return nil
   124  }
   125  
   126  // Default implementation.
   127  func (r *Record) Default() error {
   128  	if r.TTL == 0 {
   129  		r.TTL = 300
   130  	}
   131  
   132  	return nil
   133  }