mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
@@ -294,7 +294,9 @@
|
|||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td class="success">
|
||||||
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
</td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
<td class="success">
|
<td class="success">
|
||||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
|
|||||||
@@ -60,6 +60,18 @@ type DNSProviderConfig struct {
|
|||||||
// NameFQDN:
|
// NameFQDN:
|
||||||
// This is the FQDN version of Name.
|
// This is the FQDN version of Name.
|
||||||
// It should never have a trailiing ".".
|
// It should never have a trailiing ".".
|
||||||
|
// Valid types:
|
||||||
|
// A
|
||||||
|
// AAAA
|
||||||
|
// ANAME
|
||||||
|
// CAA
|
||||||
|
// CNAME
|
||||||
|
// MX
|
||||||
|
// NS
|
||||||
|
// SRV
|
||||||
|
// TXT
|
||||||
|
// PAGE_RULE // pseudo rtype
|
||||||
|
// TODO(tal): Add all the pseudo types
|
||||||
type RecordConfig struct {
|
type RecordConfig struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"` // The short name. See below.
|
Name string `json:"name"` // The short name. See below.
|
||||||
@@ -418,6 +430,32 @@ func SplitCombinedSrvValue(s string) (priority, weight, port uint16, target stri
|
|||||||
return uint16(priorityconv), uint16(weightconv), uint16(portconv), parts[3], nil
|
return uint16(priorityconv), uint16(weightconv), uint16(portconv), parts[3], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SplitCombinedCaaValue(s string) (tag string, flag uint8, value string, err error) {
|
||||||
|
|
||||||
|
splitData := strings.SplitN(s, " ", 3)
|
||||||
|
if len(splitData) != 3 {
|
||||||
|
err = fmt.Errorf("Unexpected data for CAA record returned by Vultr")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lflag, err := strconv.ParseUint(splitData[0], 10, 8)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
flag = uint8(lflag)
|
||||||
|
|
||||||
|
tag = splitData[1]
|
||||||
|
|
||||||
|
value = splitData[2]
|
||||||
|
if strings.HasPrefix(value, `"`) && strings.HasSuffix(value, `"`) {
|
||||||
|
value = value[1 : len(value)-1]
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(value, `'`) && strings.HasSuffix(value, `'`) {
|
||||||
|
value = value[1 : len(value)-1]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func copyObj(input interface{}, output interface{}) error {
|
func copyObj(input interface{}, output interface{}) error {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
enc := gob.NewEncoder(buf)
|
enc := gob.NewEncoder(buf)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ var docNotes = providers.DocumentationNotes{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
providers.RegisterDomainServiceProviderType("CLOUDFLAREAPI", newCloudflare, providers.CanUseSRV, providers.CanUseAlias, docNotes)
|
providers.RegisterDomainServiceProviderType("CLOUDFLAREAPI", newCloudflare, providers.CanUseSRV, providers.CanUseAlias, providers.CanUseCAA, docNotes)
|
||||||
providers.RegisterCustomRecordType("CF_REDIRECT", "CLOUDFLAREAPI", "")
|
providers.RegisterCustomRecordType("CF_REDIRECT", "CLOUDFLAREAPI", "")
|
||||||
providers.RegisterCustomRecordType("CF_TEMP_REDIRECT", "CLOUDFLAREAPI", "")
|
providers.RegisterCustomRecordType("CF_TEMP_REDIRECT", "CLOUDFLAREAPI", "")
|
||||||
}
|
}
|
||||||
@@ -333,13 +333,16 @@ func newCloudflare(m map[string]string, metadata json.RawMessage) (providers.DNS
|
|||||||
|
|
||||||
// Used on the "existing" records.
|
// Used on the "existing" records.
|
||||||
type cfRecData struct {
|
type cfRecData struct {
|
||||||
Service string `json:"service"`
|
|
||||||
Proto string `json:"proto"`
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Priority uint16 `json:"priority"`
|
|
||||||
Weight uint16 `json:"weight"`
|
|
||||||
Port uint16 `json:"port"`
|
|
||||||
Target string `json:"target"`
|
Target string `json:"target"`
|
||||||
|
Service string `json:"service"` // SRV
|
||||||
|
Proto string `json:"proto"` // SRV
|
||||||
|
Priority uint16 `json:"priority"` // SRV
|
||||||
|
Weight uint16 `json:"weight"` // SRV
|
||||||
|
Port uint16 `json:"port"` // SRV
|
||||||
|
Tag string `json:"tag"` // CAA
|
||||||
|
Flags uint8 `json:"flags"` // CAA
|
||||||
|
Value string `json:"value"` // CAA
|
||||||
}
|
}
|
||||||
|
|
||||||
type cfRecord struct {
|
type cfRecord struct {
|
||||||
@@ -368,17 +371,32 @@ func (c *cfRecord) toRecord(domain string) *models.RecordConfig {
|
|||||||
NameFQDN: c.Name,
|
NameFQDN: c.Name,
|
||||||
Type: c.Type,
|
Type: c.Type,
|
||||||
Target: c.Content,
|
Target: c.Content,
|
||||||
MxPreference: c.Priority,
|
|
||||||
TTL: c.TTL,
|
TTL: c.TTL,
|
||||||
Original: c,
|
Original: c,
|
||||||
}
|
}
|
||||||
if c.Type == "SRV" {
|
switch c.Type { // #rtype_variations
|
||||||
|
case "A", "AAAA", "ANAME", "CNAME", "NS", "TXT":
|
||||||
|
// nothing additional needed.
|
||||||
|
case "CAA":
|
||||||
|
var err error
|
||||||
|
rc.CaaTag, rc.CaaFlag, rc.Target, err = models.SplitCombinedCaaValue(c.Content)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
case "MX":
|
||||||
|
rc.MxPreference = c.Priority
|
||||||
|
case "SRV":
|
||||||
data := *c.Data
|
data := *c.Data
|
||||||
rc.SrvPriority = data.Priority
|
rc.SrvPriority = data.Priority
|
||||||
rc.SrvWeight = data.Weight
|
rc.SrvWeight = data.Weight
|
||||||
rc.SrvPort = data.Port
|
rc.SrvPort = data.Port
|
||||||
rc.Target = dnsutil.AddOrigin(data.Target+".", domain)
|
rc.Target = dnsutil.AddOrigin(data.Target+".", domain)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("toRecord unimplemented rtype %v", c.Type))
|
||||||
|
// We panic so that we quickly find any switch statements
|
||||||
|
// that have not been updated for a new RR type.
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc
|
return rc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ func (c *CloudflareApi) getRecordsForDomain(id string, domain string) ([]*models
|
|||||||
return nil, fmt.Errorf("Error fetching record list cloudflare: %s", stringifyErrors(data.Errors))
|
return nil, fmt.Errorf("Error fetching record list cloudflare: %s", stringifyErrors(data.Errors))
|
||||||
}
|
}
|
||||||
for _, rec := range data.Result {
|
for _, rec := range data.Result {
|
||||||
|
//fmt.Printf("REC: %+v\n", rec)
|
||||||
records = append(records, rec.toRecord(domain))
|
records = append(records, rec.toRecord(domain))
|
||||||
}
|
}
|
||||||
ri := data.ResultInfo
|
ri := data.ResultInfo
|
||||||
@@ -75,6 +76,7 @@ func (c *CloudflareApi) getRecordsForDomain(id string, domain string) ([]*models
|
|||||||
}
|
}
|
||||||
page++
|
page++
|
||||||
}
|
}
|
||||||
|
//fmt.Printf("DEBUG REORDS=%v\n", records)
|
||||||
return records, nil
|
return records, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +131,14 @@ func cfSrvData(rec *models.RecordConfig) *cfRecData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cfCaaData(rec *models.RecordConfig) *cfRecData {
|
||||||
|
return &cfRecData{
|
||||||
|
Tag: rec.CaaTag,
|
||||||
|
Flags: rec.CaaFlag,
|
||||||
|
Value: rec.Target,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *CloudflareApi) createRec(rec *models.RecordConfig, domainID string) []*models.Correction {
|
func (c *CloudflareApi) createRec(rec *models.RecordConfig, domainID string) []*models.Correction {
|
||||||
type createRecord struct {
|
type createRecord struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
@@ -161,6 +171,10 @@ func (c *CloudflareApi) createRec(rec *models.RecordConfig, domainID string) []*
|
|||||||
if rec.Type == "SRV" {
|
if rec.Type == "SRV" {
|
||||||
cf.Data = cfSrvData(rec)
|
cf.Data = cfSrvData(rec)
|
||||||
cf.Name = rec.NameFQDN
|
cf.Name = rec.NameFQDN
|
||||||
|
} else if rec.Type == "CAA" {
|
||||||
|
cf.Data = cfCaaData(rec)
|
||||||
|
cf.Name = rec.NameFQDN
|
||||||
|
cf.Content = ""
|
||||||
}
|
}
|
||||||
endpoint := fmt.Sprintf(recordsURL, domainID)
|
endpoint := fmt.Sprintf(recordsURL, domainID)
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
@@ -204,6 +218,10 @@ func (c *CloudflareApi) modifyRecord(domainID, recID string, proxied bool, rec *
|
|||||||
if rec.Type == "SRV" {
|
if rec.Type == "SRV" {
|
||||||
r.Data = cfSrvData(rec)
|
r.Data = cfSrvData(rec)
|
||||||
r.Name = rec.NameFQDN
|
r.Name = rec.NameFQDN
|
||||||
|
} else if rec.Type == "CAA" {
|
||||||
|
r.Data = cfCaaData(rec)
|
||||||
|
r.Name = rec.NameFQDN
|
||||||
|
r.Content = ""
|
||||||
}
|
}
|
||||||
endpoint := fmt.Sprintf(singleRecordURL, domainID, recID)
|
endpoint := fmt.Sprintf(singleRecordURL, domainID, recID)
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
|||||||
@@ -255,6 +255,11 @@ func toRecordConfig(dc *models.DomainConfig, r *vultr.DNSRecord) (*models.Record
|
|||||||
|
|
||||||
if r.Type == "CAA" {
|
if r.Type == "CAA" {
|
||||||
// Vultr returns in the format "[flag] [tag] [value]"
|
// Vultr returns in the format "[flag] [tag] [value]"
|
||||||
|
// TODO(tal): I copied this code into models/dns.go. At this point
|
||||||
|
// we can probably replace the code below with:
|
||||||
|
// rc.CaaFlag, rc.CaaTag, rc.Target, err := models.SplitCombinedCaaValue(rc.Target)
|
||||||
|
// return rc, err
|
||||||
|
|
||||||
splitData := strings.SplitN(rc.Target, " ", 3)
|
splitData := strings.SplitN(rc.Target, " ", 3)
|
||||||
if len(splitData) != 3 {
|
if len(splitData) != 3 {
|
||||||
return nil, fmt.Errorf("Unexpected data for CAA record returned by Vultr")
|
return nil, fmt.Errorf("Unexpected data for CAA record returned by Vultr")
|
||||||
|
|||||||
Reference in New Issue
Block a user