CLOUDNS: implement AutoDNSSEC (#747) (#3114)

This commit is contained in:
Hamish Moffatt 2024-09-18 15:48:08 +00:00 committed by GitHub
parent 269542c5cf
commit dcba570bf1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 73 additions and 1 deletions

View file

@ -22,7 +22,7 @@ If a feature is definitively not supported for whatever reason, we would also li
| [`BIND`](provider/bind.md) | ✅ | ✅ | ❌ | ❌ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [`BUNNY_DNS`](provider/bunny_dns.md) | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ❔ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❔ | ❌ | ❌ | ❌ | ❔ | ❔ | ❌ | ✅ | ✅ |
| [`CLOUDFLAREAPI`](provider/cloudflareapi.md) | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❔ | ✅ | ❌ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ✅ |
| [`CLOUDNS`](provider/cloudns.md) | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ | | ❔ | ❌ | ❔ | ✅ | ❔ | ✅ | ✅ | ❔ | ✅ | ❔ | ❔ | ✅ | ❔ | ❔ | ✅ | ✅ |
| [`CLOUDNS`](provider/cloudns.md) | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ | | ❔ | ❌ | ❔ | ✅ | ❔ | ✅ | ✅ | ❔ | ✅ | ❔ | ❔ | ✅ | ❔ | ❔ | ✅ | ✅ |
| [`CSCGLOBAL`](provider/cscglobal.md) | ✅ | ✅ | ✅ | ✅ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❌ | ✅ |
| [`DESEC`](provider/desec.md) | ❌ | ✅ | ❌ | ✅ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ❔ | ❔ | ✅ | ❔ | ✅ | ✅ |
| [`DIGITALOCEAN`](provider/digitalocean.md) | ❌ | ✅ | ❌ | ❌ | ❔ | ✅ | ❔ | ❔ | ❌ | ❔ | ❔ | ❔ | ✅ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ❔ | ✅ | ✅ |

View file

@ -196,6 +196,43 @@ func (c *cloudnsProvider) getRecords(id string) ([]domainRecord, error) {
return records, nil
}
func (c *cloudnsProvider) isDnssecEnabled(id string) (bool, error) {
params := requestParams{"domain-name": id}
var bodyString, err = c.get("/dns/get-dnssec-ds-records.json", params)
if err != nil {
// DNSSEC disabled is indicated by an error fetching the DS records.
var errResp errorResponse
err = json.Unmarshal(bodyString, &errResp)
if err == nil {
if errResp.Description == "The DNSSEC is not active." {
return false, nil
}
return false, fmt.Errorf("failed fetching DS records from ClouDNS: %s", err)
}
}
return true, nil
}
func (c *cloudnsProvider) setDnssec(id string, enabled bool) error {
params := requestParams{"domain-name": id}
var endpoint string
if enabled {
endpoint = "/dns/activate-dnssec.json"
} else {
endpoint = "/dns/deactivate-dnssec.json"
}
var _, err = c.get(endpoint, params)
if err != nil {
return fmt.Errorf("failed setting DNSSEC at ClouDNS: %s", err)
}
return nil
}
func (c *cloudnsProvider) get(endpoint string, params requestParams) ([]byte, error) {
client := &http.Client{}
req, _ := http.NewRequest("GET", "https://api.cloudns.net"+endpoint, nil)

View file

@ -40,6 +40,7 @@ func NewCloudns(m map[string]string, metadata json.RawMessage) (providers.DNSSer
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Cannot(),
providers.CanUseAlias: providers.Can(),
@ -134,12 +135,18 @@ func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi
record.TTL = fixTTL(record.TTL)
}
dnssecFixes, err := c.getDNSSECCorrections(dc)
if err != nil {
return nil, 0, err
}
toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, 0, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)
corrections = append(corrections, dnssecFixes...)
// Deletes first so changing type works etc.
for _, m := range del {
@ -225,6 +232,34 @@ func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi
}
// getDNSSECCorrections returns corrections that update a domain's DNSSEC state.
func (c *cloudnsProvider) getDNSSECCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
enabled, err := c.isDnssecEnabled(dc.Name)
if err != nil {
return nil, err
}
if enabled && dc.AutoDNSSEC == "off" {
return []*models.Correction{
{
Msg: "Disable DNSSEC",
F: func() error { err := c.setDnssec(dc.Name, false); return err },
},
}, nil
}
if !enabled && dc.AutoDNSSEC == "on" {
return []*models.Correction{
{
Msg: "Enable DNSSEC",
F: func() error { err := c.setDnssec(dc.Name, true); return err },
},
}, nil
}
return []*models.Correction{}, nil
}
// GetZoneRecords gets the records of a zone and returns them in RecordConfig format.
func (c *cloudnsProvider) GetZoneRecords(domain string, meta map[string]string) (models.Records, error) {
records, err := c.getRecords(domain)