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) }, } }