Skip to content

HETZNER: populate zone cache after creating zone #3336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
35 changes: 19 additions & 16 deletions providers/hetzner/api.go
Original file line number Diff line number Diff line change
@@ -62,7 +62,15 @@ 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.mu.Lock()
defer api.mu.Unlock()
api.cachedZones[name] = response.Zone
return nil
}

func (api *hetznerProvider) deleteRecord(record *record) error {
@@ -105,17 +113,11 @@ 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()
// fetchAllZonesLocked populates the zone cache.
// The caller must hold mu.
func (api *hetznerProvider) fetchAllZonesLocked() error {
if api.cachedZones != nil {
return api.cachedZones, nil
return nil
}
var zones map[string]zone
page := 1
@@ -134,7 +136,7 @@ func (api *hetznerProvider) getAllZones() (map[string]zone, error) {
response := getAllZonesResponse{}
url := fmt.Sprintf("/zones?per_page=100&page=%d", page)
if err := api.request(url, "GET", nil, &response, statusOK); err != nil {
return nil, fmt.Errorf("failed fetching zones: %w", err)
return fmt.Errorf("failed fetching zones: %w", err)
}
if zones == nil {
zones = make(map[string]zone, response.Meta.Pagination.TotalEntries)
@@ -149,15 +151,16 @@ func (api *hetznerProvider) getAllZones() (map[string]zone, error) {
page++
}
api.cachedZones = zones
return zones, nil
return nil
}

func (api *hetznerProvider) getZone(name string) (*zone, error) {
zones, err := api.getAllZones()
if err != nil {
api.mu.Lock()
defer api.mu.Unlock()
if err := api.fetchAllZonesLocked(); err != nil {
return nil, err
}
z, ok := zones[name]
z, ok := api.cachedZones[name]
if !ok {
return nil, fmt.Errorf("%q is not a zone in this HETZNER account", name)
}
9 changes: 5 additions & 4 deletions providers/hetzner/hetznerProvider.go
Original file line number Diff line number Diff line change
@@ -71,7 +71,6 @@ func (api *hetznerProvider) EnsureZoneExists(domain string) error {
if err = api.createZone(domain); err != nil {
return err
}
api.resetZoneCache()
return nil
}

@@ -169,12 +168,14 @@ 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()
api.mu.Lock()
defer api.mu.Unlock()
err := api.fetchAllZonesLocked()
if err != nil {
return nil, err
}
domains := make([]string, 0, len(zones))
for domain := range zones {
domains := make([]string, 0, len(api.cachedZones))
for domain := range api.cachedZones {
domains = append(domains, domain)
}
return domains, nil
4 changes: 4 additions & 0 deletions providers/hetzner/types.go
Original file line number Diff line number Diff line change
@@ -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 {