mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
HETZNER: handle a 404 from listing zones gracefully (#1371)
The API docs do not mention this, but we saw a case in the wild (1370). Signed-off-by: Jakob Ackermann <das7pad@outlook.com>
This commit is contained in:
@@ -78,7 +78,7 @@ func (api *hetznerProvider) bulkCreateRecords(records []record) error {
|
|||||||
request := bulkCreateRecordsRequest{
|
request := bulkCreateRecordsRequest{
|
||||||
Records: records,
|
Records: records,
|
||||||
}
|
}
|
||||||
return api.request("/records/bulk", "POST", request, nil)
|
return api.request("/records/bulk", "POST", request, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *hetznerProvider) bulkUpdateRecords(records []record) error {
|
func (api *hetznerProvider) bulkUpdateRecords(records []record) error {
|
||||||
@@ -91,7 +91,7 @@ func (api *hetznerProvider) bulkUpdateRecords(records []record) error {
|
|||||||
request := bulkUpdateRecordsRequest{
|
request := bulkUpdateRecordsRequest{
|
||||||
Records: records,
|
Records: records,
|
||||||
}
|
}
|
||||||
return api.request("/records/bulk", "PUT", request, nil)
|
return api.request("/records/bulk", "PUT", request, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *hetznerProvider) createRecord(record record) error {
|
func (api *hetznerProvider) createRecord(record record) error {
|
||||||
@@ -106,14 +106,14 @@ func (api *hetznerProvider) createRecord(record record) error {
|
|||||||
Value: record.Value,
|
Value: record.Value,
|
||||||
ZoneID: record.ZoneID,
|
ZoneID: record.ZoneID,
|
||||||
}
|
}
|
||||||
return api.request("/records", "POST", request, nil)
|
return api.request("/records", "POST", request, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *hetznerProvider) createZone(name string) error {
|
func (api *hetznerProvider) createZone(name string) error {
|
||||||
request := createZoneRequest{
|
request := createZoneRequest{
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
return api.request("/zones", "POST", request, nil)
|
return api.request("/zones", "POST", request, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *hetznerProvider) deleteRecord(record record) error {
|
func (api *hetznerProvider) deleteRecord(record record) error {
|
||||||
@@ -122,7 +122,7 @@ func (api *hetznerProvider) deleteRecord(record record) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("/records/%s", record.ID)
|
url := fmt.Sprintf("/records/%s", record.ID)
|
||||||
return api.request(url, "DELETE", nil, nil)
|
return api.request(url, "DELETE", nil, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *hetznerProvider) getAllRecords(domain string) ([]record, error) {
|
func (api *hetznerProvider) getAllRecords(domain string) ([]record, error) {
|
||||||
@@ -135,7 +135,7 @@ func (api *hetznerProvider) getAllRecords(domain string) ([]record, error) {
|
|||||||
for {
|
for {
|
||||||
response := &getAllRecordsResponse{}
|
response := &getAllRecordsResponse{}
|
||||||
url := fmt.Sprintf("/records?zone_id=%s&per_page=100&page=%d", zone.ID, page)
|
url := fmt.Sprintf("/records?zone_id=%s&per_page=100&page=%d", zone.ID, page)
|
||||||
if err := api.request(url, "GET", nil, response); err != nil {
|
if err := api.request(url, "GET", nil, response, nil); err != nil {
|
||||||
return nil, fmt.Errorf("failed fetching zone records for %q: %w", domain, err)
|
return nil, fmt.Errorf("failed fetching zone records for %q: %w", domain, err)
|
||||||
}
|
}
|
||||||
for _, record := range response.Records {
|
for _, record := range response.Records {
|
||||||
@@ -165,10 +165,21 @@ func (api *hetznerProvider) getAllZones() error {
|
|||||||
}
|
}
|
||||||
zones := map[string]zone{}
|
zones := map[string]zone{}
|
||||||
page := 1
|
page := 1
|
||||||
|
statusOK := func(code int) bool {
|
||||||
|
switch code {
|
||||||
|
case http.StatusOK:
|
||||||
|
return true
|
||||||
|
case http.StatusNotFound:
|
||||||
|
// Accept a 404 when requesting the first page
|
||||||
|
return page == 1
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
response := &getAllZonesResponse{}
|
response := &getAllZonesResponse{}
|
||||||
url := fmt.Sprintf("/zones?per_page=100&page=%d", page)
|
url := fmt.Sprintf("/zones?per_page=100&page=%d", page)
|
||||||
if err := api.request(url, "GET", nil, response); err != nil {
|
if err := api.request(url, "GET", nil, response, statusOK); err != nil {
|
||||||
return fmt.Errorf("failed fetching zones: %w", err)
|
return fmt.Errorf("failed fetching zones: %w", err)
|
||||||
}
|
}
|
||||||
for _, zone := range response.Zones {
|
for _, zone := range response.Zones {
|
||||||
@@ -195,7 +206,12 @@ func (api *hetznerProvider) getZone(name string) (*zone, error) {
|
|||||||
return &zone, nil
|
return &zone, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *hetznerProvider) request(endpoint string, method string, request interface{}, target interface{}) error {
|
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 {
|
||||||
|
return code == http.StatusOK
|
||||||
|
}
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
var requestBody io.Reader
|
var requestBody io.Reader
|
||||||
if request != nil {
|
if request != nil {
|
||||||
@@ -233,7 +249,7 @@ func (api *hetznerProvider) request(endpoint string, method string, request inte
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer cleanupResponseBody()
|
defer cleanupResponseBody()
|
||||||
if resp.StatusCode != 200 {
|
if !statusOK(resp.StatusCode) {
|
||||||
data, _ := ioutil.ReadAll(resp.Body)
|
data, _ := ioutil.ReadAll(resp.Body)
|
||||||
fmt.Println(string(data))
|
fmt.Println(string(data))
|
||||||
return fmt.Errorf("bad status code from HETZNER: %d not 200", resp.StatusCode)
|
return fmt.Errorf("bad status code from HETZNER: %d not 200", resp.StatusCode)
|
||||||
@@ -261,7 +277,7 @@ func (api *hetznerProvider) updateRecord(record record) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("/records/%s", record.ID)
|
url := fmt.Sprintf("/records/%s", record.ID)
|
||||||
return api.request(url, "PUT", record, nil)
|
return api.request(url, "PUT", record, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type requestRateLimiter struct {
|
type requestRateLimiter struct {
|
||||||
|
Reference in New Issue
Block a user