diff --git a/providers/hetzner/api.go b/providers/hetzner/api.go
index ce5039ceb5..02f6470bf4 100644
--- a/providers/hetzner/api.go
+++ b/providers/hetzner/api.go
@@ -11,6 +11,7 @@ import (
"time"
"github.com/StackExchange/dnscontrol/v4/pkg/printer"
+ "github.com/StackExchange/dnscontrol/v4/pkg/zoneCache"
)
const (
@@ -19,8 +20,7 @@ const (
type hetznerProvider struct {
apiKey string
- mu sync.Mutex
- cachedZones map[string]zone
+ zoneCache zoneCache.ZoneCache[zone]
requestRateLimiter requestRateLimiter
}
@@ -62,7 +62,13 @@ func (api *hetznerProvider) createZone(name string) error {
request := createZoneRequest{
Name: name,
}
- return api.request("/zones", "POST", request, nil, nil)
+ response := createZoneResponse{}
+ err := api.request("/zones", "POST", request, &response, nil)
+ if err != nil {
+ return err
+ }
+ api.zoneCache.SetZone(name, response.Zone)
+ return nil
}
func (api *hetznerProvider) deleteRecord(record *record) error {
@@ -71,7 +77,7 @@ func (api *hetznerProvider) deleteRecord(record *record) error {
}
func (api *hetznerProvider) getAllRecords(domain string) ([]record, error) {
- z, err := api.getZone(domain)
+ z, err := api.zoneCache.GetZone(domain)
if err != nil {
return nil, err
}
@@ -105,18 +111,7 @@ func (api *hetznerProvider) getAllRecords(domain string) ([]record, error) {
return records, nil
}
-func (api *hetznerProvider) resetZoneCache() {
- api.mu.Lock()
- defer api.mu.Unlock()
- api.cachedZones = nil
-}
-
-func (api *hetznerProvider) getAllZones() (map[string]zone, error) {
- api.mu.Lock()
- defer api.mu.Unlock()
- if api.cachedZones != nil {
- return api.cachedZones, nil
- }
+func (api *hetznerProvider) fetchAllZones() (map[string]zone, error) {
var zones map[string]zone
page := 1
statusOK := func(code int) bool {
@@ -148,22 +143,9 @@ func (api *hetznerProvider) getAllZones() (map[string]zone, error) {
}
page++
}
- api.cachedZones = zones
return zones, nil
}
-func (api *hetznerProvider) getZone(name string) (*zone, error) {
- zones, err := api.getAllZones()
- if err != nil {
- return nil, err
- }
- z, ok := zones[name]
- if !ok {
- return nil, fmt.Errorf("%q is not a zone in this HETZNER account", name)
- }
- return &z, nil
-}
-
func (api *hetznerProvider) request(endpoint string, method string, request interface{}, target interface{}, statusOK func(code int) bool) error {
if statusOK == nil {
statusOK = func(code int) bool {
diff --git a/providers/hetzner/hetznerProvider.go b/providers/hetzner/hetznerProvider.go
index b92db3f5bd..62b443105c 100644
--- a/providers/hetzner/hetznerProvider.go
+++ b/providers/hetzner/hetznerProvider.go
@@ -7,6 +7,7 @@ import (
"github.com/StackExchange/dnscontrol/v4/models"
"github.com/StackExchange/dnscontrol/v4/pkg/diff"
+ "github.com/StackExchange/dnscontrol/v4/pkg/zoneCache"
"github.com/StackExchange/dnscontrol/v4/providers"
)
@@ -50,28 +51,20 @@ func New(settings map[string]string, _ json.RawMessage) (providers.DNSServicePro
return nil, errors.New("missing HETZNER api_key")
}
- return &hetznerProvider{
- apiKey: apiKey,
- }, nil
+ api := &hetznerProvider{apiKey: apiKey}
+ api.zoneCache = zoneCache.New(api.fetchAllZones)
+ return api, nil
}
// EnsureZoneExists creates a zone if it does not exist
func (api *hetznerProvider) EnsureZoneExists(domain string) error {
- domains, err := api.ListZones()
- if err != nil {
+ if ok, err := api.zoneCache.HasZone(domain); err != nil || ok {
return err
}
- for _, d := range domains {
- if d == domain {
- return nil
- }
- }
-
- if err = api.createZone(domain); err != nil {
+ if err := api.createZone(domain); err != nil {
return err
}
- api.resetZoneCache()
return nil
}
@@ -86,7 +79,7 @@ func (api *hetznerProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, e
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)
- z, err := api.getZone(domain)
+ z, err := api.zoneCache.GetZone(domain)
if err != nil {
return nil, 0, err
}
@@ -143,7 +136,7 @@ func (api *hetznerProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, e
// GetNameservers returns the nameservers for a domain.
func (api *hetznerProvider) GetNameservers(domain string) ([]*models.Nameserver, error) {
- z, err := api.getZone(domain)
+ z, err := api.zoneCache.GetZone(domain)
if err != nil {
return nil, err
}
@@ -169,13 +162,5 @@ func (api *hetznerProvider) GetZoneRecords(domain string, meta map[string]string
// ListZones lists the zones on this account.
func (api *hetznerProvider) ListZones() ([]string, error) {
- zones, err := api.getAllZones()
- if err != nil {
- return nil, err
- }
- domains := make([]string, 0, len(zones))
- for domain := range zones {
- domains = append(domains, domain)
- }
- return domains, nil
+ return api.zoneCache.GetZoneNames()
}
diff --git a/providers/hetzner/types.go b/providers/hetzner/types.go
index 61125a5d99..40b17ad436 100644
--- a/providers/hetzner/types.go
+++ b/providers/hetzner/types.go
@@ -17,6 +17,10 @@ type createZoneRequest struct {
Name string `json:"name"`
}
+type createZoneResponse struct {
+ Zone zone `json:"zone"`
+}
+
type getAllRecordsResponse struct {
Records []record `json:"records"`
Meta struct {
@@ -53,7 +57,7 @@ type zone struct {
TTL uint32 `json:"ttl"`
}
-func fromRecordConfig(in *models.RecordConfig, zone *zone) record {
+func fromRecordConfig(in *models.RecordConfig, zone zone) record {
r := record{
Name: in.GetLabel(),
Type: in.Type,