Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions documentation/provider/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ Jump to a table:
| [`AZURE_DNS`](azure_dns.md) | ❔ | ❌ | ✅ | ❔ |
| [`AZURE_PRIVATE_DNS`](azure_private_dns.md) | ❔ | ❌ | ✅ | ❔ |
| [`BIND`](bind.md) | ✅ | ✅ | ✅ | ✅ |
| [`BUNNY_DNS`](bunny_dns.md) | ❌ | ❌ | ✅ | |
| [`BUNNY_DNS`](bunny_dns.md) | ❌ | ❌ | ✅ | |
| [`CLOUDFLAREAPI`](cloudflareapi.md) | ❔ | ✅ | ✅ | ✅ |
| [`CLOUDNS`](cloudns.md) | ❌ | ✅ | ✅ | ❌ |
| [`CNR`](cnr.md) | ❌ | ✅ | ✅ | ❌ |
Expand Down Expand Up @@ -273,7 +273,7 @@ Jump to a table:
| [`AZURE_DNS`](azure_dns.md) | ✅ | ❔ | ❔ | ❌ | ❌ |
| [`AZURE_PRIVATE_DNS`](azure_private_dns.md) | ❌ | ❔ | ❔ | ❌ | ❌ |
| [`BIND`](bind.md) | ✅ | ✅ | ✅ | ✅ | ✅ |
| [`BUNNY_DNS`](bunny_dns.md) | ✅ | | ❔ | ❌ | ❌ |
| [`BUNNY_DNS`](bunny_dns.md) | ✅ | | ❔ | ❌ | ❌ |
| [`CLOUDFLAREAPI`](cloudflareapi.md) | ✅ | ✅ | ❔ | ✅ | ✅ |
| [`CLOUDNS`](cloudns.md) | ✅ | ❌ | ❔ | ✅ | ✅ |
| [`CNR`](cnr.md) | ✅ | ❌ | ❔ | ✅ | ✅ |
Expand Down
2 changes: 2 additions & 0 deletions providers/bunnydns/bunnydnsProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ var features = providers.DocumentationNotes{
providers.CanUseDHCID: providers.Cannot(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseHTTPS: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Cannot(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSOA: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Cannot(),
providers.CanUseSVCB: providers.Can(),
providers.CanUseTLSA: providers.Cannot(),
providers.DocCreateDomains: providers.Can(),
providers.DocDualHost: providers.Cannot(),
Expand Down
39 changes: 33 additions & 6 deletions providers/bunnydns/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
"golang.org/x/exp/slices"
)

var fqdnTypes = []recordType{recordTypeCNAME, recordTypeMX, recordTypeNS, recordTypePTR, recordTypeSRV}
var fqdnTypes = []recordType{recordTypeCNAME, recordTypeHTTPS, recordTypeMX, recordTypeNS, recordTypePTR, recordTypeSRV, recordTypeSVCB}
var nullTypes = []recordType{recordTypeHTTPS, recordTypeMX, recordTypeSVCB}

func fromRecordConfig(rc *models.RecordConfig) (*record, error) {
r := record{
Expand All @@ -33,15 +34,24 @@ func fromRecordConfig(rc *models.RecordConfig) (*record, error) {
r.Tag = rc.CaaTag
case recordTypeMX:
r.Priority = rc.MxPreference
case recordTypeSVCB, recordTypeHTTPS:
r.Priority = rc.SvcPriority
}

// While Bunny DNS does not use trailing dots, it still accepts and even preserves them for certain record types.
// To avoid confusion, any trailing dots are removed from the record value, except when managing a NullMX record.
isNullMX := r.Type == recordTypeMX && r.Priority == 0 && r.Value == "."
if slices.Contains(fqdnTypes, r.Type) && strings.HasSuffix(r.Value, ".") && !isNullMX {
// To avoid confusion, any trailing dots are removed from the record value, except when managing a NullMX or a self-pointing HTTPS/SVCB record.
isNullRecord := slices.Contains(nullTypes, r.Type) && r.Value == "."
if slices.Contains(fqdnTypes, r.Type) && strings.HasSuffix(r.Value, ".") && !isNullRecord {
r.Value = strings.TrimSuffix(r.Value, ".")
}

// In the case of SVCB/HTTPS records, the Target is part of the Value.
// After removing trailing dots for said target, we can add the params to the value.
switch r.Type {
case recordTypeSVCB, recordTypeHTTPS:
r.Value = fmt.Sprintf("%s %s", r.Value, rc.SvcParams)
}

return &r, nil
}

Expand All @@ -56,8 +66,13 @@ func toRecordConfig(domain string, r *record) (*models.RecordConfig, error) {
// Bunny DNS always operates with fully-qualified names and does not use any trailing dots.
// If a record already contains a trailing dot, which the provider UI also accepts, the record value is left as-is.
recordValue := r.Value
if slices.Contains(fqdnTypes, r.Type) && !strings.HasSuffix(r.Value, ".") {
recordValue = dnsutil.AddOrigin(r.Value+".", domain)

// Bunny DNS has the Target and Params on the same Value, so we have to split them
recordParts := strings.SplitN(recordValue, " ", 2)

if slices.Contains(fqdnTypes, r.Type) && !strings.HasSuffix(recordParts[0], ".") {
recordParts[0] = dnsutil.AddOrigin(recordParts[0]+".", domain)
recordValue = strings.Join(recordParts, " ")
}

var err error
Expand All @@ -70,6 +85,8 @@ func toRecordConfig(domain string, r *record) (*models.RecordConfig, error) {
err = rc.SetTargetMX(r.Priority, recordValue)
case "SRV":
err = rc.SetTargetSRV(r.Priority, r.Weight, r.Port, recordValue)
case "SVCB", "HTTPS":
err = rc.SetTargetSVCBString(r.Name, fmt.Sprintf("%d %s", r.Priority, recordValue))
default:
err = rc.PopulateFromStringFunc(rc.Type, recordValue, domain, nil)
}
Expand All @@ -96,6 +113,8 @@ const (
recordTypePTR recordType = 10
recordTypeScript recordType = 11
recordTypeNS recordType = 12
recordTypeSVCB recordType = 13
recordTypeHTTPS recordType = 14
)

func recordTypeFromString(t string) recordType {
Expand Down Expand Up @@ -124,6 +143,10 @@ func recordTypeFromString(t string) recordType {
return recordTypeScript
case "NS":
return recordTypeNS
case "SVCB":
return recordTypeSVCB
case "HTTPS":
return recordTypeHTTPS
case "BUNNY_DNS_RDR":
return recordTypeRedirect
default:
Expand Down Expand Up @@ -159,6 +182,10 @@ func recordTypeToString(t recordType) string {
return "SCRIPT"
case recordTypeNS:
return "NS"
case recordTypeSVCB:
return "SVCB"
case recordTypeHTTPS:
return "HTTPS"
default:
panic(fmt.Errorf("BUNNY_DNS: native rtype %v unimplemented", t))
}
Expand Down