package models import ( "fmt" "net" ) // PopulateFromString populates a RecordConfig given a type and string. // Many providers give all the parameters of a resource record in one big // string (all the parameters of an MX, SRV, CAA, etc). Rather than have // each provider rewrite this code many times, here's a helper function to use. // // If this doesn't work for all rtypes, process the special cases then // call this for the remainder. func (r *RecordConfig) PopulateFromString(rtype, contents, origin string) error { if r.Type != "" && r.Type != rtype { panic(fmt.Errorf("assertion failed: rtype already set (%s) (%s)", rtype, r.Type)) } switch r.Type = rtype; rtype { // #rtype_variations case "A": ip := net.ParseIP(contents) if ip == nil || ip.To4() == nil { return fmt.Errorf("invalid IP in A record: %s", contents) } return r.SetTargetIP(ip) // Reformat to canonical form. case "AAAA": ip := net.ParseIP(contents) if ip == nil || ip.To16() == nil { return fmt.Errorf("invalid IP in AAAA record: %s", contents) } return r.SetTargetIP(ip) // Reformat to canonical form. case "AKAMAICDN", "ALIAS", "ANAME", "CNAME", "NS", "PTR": return r.SetTarget(contents) case "CAA": return r.SetTargetCAAString(contents) case "DS": return r.SetTargetDSString(contents) case "MX": return r.SetTargetMXString(contents) case "NAPTR": return r.SetTargetNAPTRString(contents) case "SRV": return r.SetTargetSRVString(contents) case "SOA": return r.SetTargetSOAString(contents) case "SSHFP": return r.SetTargetSSHFPString(contents) case "TLSA": return r.SetTargetTLSAString(contents) case "SPF", "TXT": return r.SetTargetTXTString(contents) default: return fmt.Errorf("unknown rtype (%s) when parsing (%s) domain=(%s)", rtype, contents, origin) } }