github.com/franciscocpg/up@v0.1.10/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}
    41  		d.Zones = append(d.Zones, zone)
    42  		for _, record := range records {
    43  			zone.Records = append(zone.Records, record)
    44  		}
    45  	}
    46  
    47  	return nil
    48  }
    49  
    50  // Default implementation.
    51  func (d *DNS) Default() error {
    52  	for _, z := range d.Zones {
    53  		if err := z.Default(); err != nil {
    54  			return errors.Wrapf(err, "zone %s", z.Name)
    55  		}
    56  	}
    57  
    58  	return nil
    59  }
    60  
    61  // Validate implementation.
    62  func (d *DNS) Validate() error {
    63  	for _, z := range d.Zones {
    64  		if err := z.Validate(); err != nil {
    65  			return errors.Wrapf(err, "zone %s", z.Name)
    66  		}
    67  	}
    68  
    69  	return nil
    70  }
    71  
    72  // Zone is a DNS zone.
    73  type Zone struct {
    74  	Name    string   `json:"name"`
    75  	Records []Record `json:"records"`
    76  }
    77  
    78  // Default implementation.
    79  func (z *Zone) Default() error {
    80  	for i, r := range z.Records {
    81  		if err := r.Default(); err != nil {
    82  			return errors.Wrapf(err, "record %d", i)
    83  		}
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  // Validate implementation.
    90  func (z *Zone) Validate() error {
    91  	for i, r := range z.Records {
    92  		if err := r.Validate(); err != nil {
    93  			return errors.Wrapf(err, "record %d", i)
    94  		}
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  // Record is a DNS record.
   101  type Record struct {
   102  	Name  string   `json:"name"`
   103  	Type  string   `json:"type"`
   104  	TTL   int      `json:"ttl"`
   105  	Value []string `json:"value"`
   106  }
   107  
   108  // Validate implementation.
   109  func (r *Record) Validate() error {
   110  	if err := validate.List(r.Type, recordTypes); err != nil {
   111  		return errors.Wrap(err, ".type")
   112  	}
   113  
   114  	if err := validate.RequiredString(r.Name); err != nil {
   115  		return errors.Wrap(err, ".name")
   116  	}
   117  
   118  	if err := validate.RequiredStrings(r.Value); err != nil {
   119  		return errors.Wrap(err, ".value")
   120  	}
   121  
   122  	if err := validate.MinStrings(r.Value, 1); err != nil {
   123  		return errors.Wrap(err, ".value")
   124  	}
   125  
   126  	return nil
   127  }
   128  
   129  // Default implementation.
   130  func (r *Record) Default() error {
   131  	if r.TTL == 0 {
   132  		r.TTL = 300
   133  	}
   134  
   135  	return nil
   136  }