github.com/teknogeek/dnscontrol@v0.2.8/models/t_parse.go (about) 1 package models 2 3 import ( 4 "net" 5 6 "github.com/pkg/errors" 7 ) 8 9 // PopulateFromString populates a RecordConfig given a type and string. 10 // Many providers give all the parameters of a resource record in one big 11 // string (all the parameters of an MX, SRV, CAA, etc). Rather than have 12 // each provider rewrite this code many times, here's a helper function to use. 13 // 14 // At this time, the idiom is to panic rather than continue with potentially 15 // misunderstood data. We do this panic() at the provider level. 16 // Therefore the typical calling sequence is: 17 // if err := rc.PopulateFromString(rtype, value, origin); err != nil { 18 // panic(errors.Wrap(err, "unparsable record received from provider")) 19 // } 20 func (r *RecordConfig) PopulateFromString(rtype, contents, origin string) error { 21 if r.Type != "" && r.Type != rtype { 22 panic(errors.Errorf("assertion failed: rtype already set (%s) (%s)", rtype, r.Type)) 23 } 24 switch r.Type = rtype; rtype { // #rtype_variations 25 case "A": 26 ip := net.ParseIP(contents) 27 if ip == nil || ip.To4() == nil { 28 return errors.Errorf("A record with invalid IP: %s", contents) 29 } 30 return r.SetTargetIP(ip) // Reformat to canonical form. 31 case "AAAA": 32 ip := net.ParseIP(contents) 33 if ip == nil || ip.To16() == nil { 34 return errors.Errorf("AAAA record with invalid IP: %s", contents) 35 } 36 return r.SetTargetIP(ip) // Reformat to canonical form. 37 case "ANAME", "CNAME", "NS", "PTR": 38 return r.SetTarget(contents) 39 case "CAA": 40 return r.SetTargetCAAString(contents) 41 case "MX": 42 return r.SetTargetMXString(contents) 43 case "SRV": 44 return r.SetTargetSRVString(contents) 45 case "TLSA": 46 return r.SetTargetTLSAString(contents) 47 case "TXT": 48 return r.SetTargetTXTString(contents) 49 default: 50 return errors.Errorf("Unknown rtype (%s) when parsing (%s) domain=(%s)", 51 rtype, contents, origin) 52 } 53 }