mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-02-23 23:23:05 +08:00
Co-authored-by: nyanotech <33802077+nyanotech@users.noreply.github.com> Co-authored-by: Jakob Ackermann <das7pad@outlook.com> Co-authored-by: Brice Figureau <brice@figureau.eu> Co-authored-by: Jeffrey Cafferata <jeffrey@jcid.nl> Co-authored-by: imlonghao <git@imlonghao.com>
153 lines
4 KiB
Go
153 lines
4 KiB
Go
package bunnydns
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"slices"
|
|
|
|
"github.com/StackExchange/dnscontrol/v4/models"
|
|
"github.com/StackExchange/dnscontrol/v4/pkg/diff2"
|
|
"github.com/StackExchange/dnscontrol/v4/pkg/printer"
|
|
)
|
|
|
|
func (b *bunnydnsProvider) GetZoneRecords(domain string, meta map[string]string) (models.Records, error) {
|
|
zone, err := b.findZoneByDomain(domain)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
nativeRecs, err := b.getAllRecords(zone.ID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
implicitRecs, err := b.getImplicitRecordConfigs(zone)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
recs := make(models.Records, 0, len(nativeRecs)+len(implicitRecs))
|
|
recs = append(recs, implicitRecs...)
|
|
|
|
// Define a list of record types that are currently not supported by this provider.
|
|
unsupportedTypes := []recordType{
|
|
recordTypeRedirect,
|
|
recordTypeFlatten,
|
|
recordTypePullZone,
|
|
recordTypeScript,
|
|
}
|
|
|
|
// Loop through all native records and convert them to standardized RecordConfigs
|
|
// Unsupported record types are ignored with a warning and will remain untouched in the zone.
|
|
for _, nativeRec := range nativeRecs {
|
|
if slices.Contains(unsupportedTypes, nativeRec.Type) {
|
|
printer.Warnf("BUNNY_DNS: ignoring unsupported record type %s\n", recordTypeToString(nativeRec.Type))
|
|
continue
|
|
}
|
|
|
|
rc, err := toRecordConfig(zone.Domain, nativeRec)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
recs = append(recs, rc)
|
|
}
|
|
|
|
return recs, nil
|
|
}
|
|
|
|
func (b *bunnydnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) {
|
|
// Bunny DNS never returns NS records for the apex domain, so these are artificially added when retrieving records.
|
|
// As no TTL can be configured or retrieved for these NS records, we set it to 0 to avoid unnecessary updates.
|
|
for _, rc := range dc.Records {
|
|
if rc.Name == "@" && rc.Type == "NS" {
|
|
rc.TTL = 0
|
|
}
|
|
|
|
if rc.Type == "ALIAS" {
|
|
rc.ChangeType("CNAME", dc.Name)
|
|
}
|
|
}
|
|
|
|
zone, err := b.findZoneByDomain(dc.Name)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
instructions, actualChangeCount, err := diff2.ByRecord(existing, dc, nil)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
var corrections []*models.Correction
|
|
for _, inst := range instructions {
|
|
switch inst.Type {
|
|
case diff2.REPORT:
|
|
corrections = append(corrections, &models.Correction{
|
|
Msg: inst.MsgsJoined,
|
|
})
|
|
case diff2.CREATE:
|
|
corrections = append(corrections, b.mkCreateCorrection(
|
|
zone.ID, inst.New[0], inst.Msgs[0],
|
|
))
|
|
case diff2.CHANGE:
|
|
corrections = append(corrections, b.mkChangeCorrection(
|
|
zone.ID, inst.Old[0], inst.New[0], inst.Msgs[0],
|
|
))
|
|
case diff2.DELETE:
|
|
corrections = append(corrections, b.mkDeleteCorrection(
|
|
zone.ID, inst.Old[0], inst.Msgs[0],
|
|
))
|
|
default:
|
|
panic(fmt.Sprintf("unhandled inst.Type %s", inst.Type))
|
|
}
|
|
}
|
|
|
|
return corrections, actualChangeCount, nil
|
|
}
|
|
|
|
func (b *bunnydnsProvider) mkCreateCorrection(zoneID int64, newRec *models.RecordConfig, msg string) *models.Correction {
|
|
return &models.Correction{
|
|
Msg: msg,
|
|
F: func() error {
|
|
desired, err := fromRecordConfig(newRec)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return b.createRecord(zoneID, desired)
|
|
},
|
|
}
|
|
}
|
|
|
|
func (b *bunnydnsProvider) mkChangeCorrection(zoneID int64, oldRec, newRec *models.RecordConfig, msg string) *models.Correction {
|
|
return &models.Correction{
|
|
Msg: msg,
|
|
F: func() error {
|
|
existingID := oldRec.Original.(*record).ID
|
|
if existingID == 0 {
|
|
return errors.New("BUNNY_DNS: cannot change implicit records")
|
|
}
|
|
|
|
desired, err := fromRecordConfig(newRec)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return b.modifyRecord(zoneID, existingID, desired)
|
|
},
|
|
}
|
|
}
|
|
|
|
func (b *bunnydnsProvider) mkDeleteCorrection(zoneID int64, oldRec *models.RecordConfig, msg string) *models.Correction {
|
|
return &models.Correction{
|
|
Msg: msg,
|
|
F: func() error {
|
|
existingID := oldRec.Original.(*record).ID
|
|
if existingID == 0 {
|
|
return errors.New("BUNNY_DNS: cannot delete implicit records")
|
|
}
|
|
|
|
return b.deleteRecord(zoneID, existingID)
|
|
},
|
|
}
|
|
}
|