mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-11-14 12:15:06 +08:00
105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
package gcore
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"path"
|
|
"strings"
|
|
|
|
dnssdk "github.com/G-Core/gcore-dns-sdk-go"
|
|
)
|
|
|
|
type gcoreRRSets struct {
|
|
RRSets []gcoreRRSetExtended `json:"rrsets"`
|
|
}
|
|
|
|
// Extended attributes over dnssdk.RRSet
|
|
type gcoreRRSetExtended struct {
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
|
|
// Original
|
|
TTL int `json:"ttl"`
|
|
Records []dnssdk.ResourceRecord `json:"resource_records"`
|
|
Filters []dnssdk.RecordFilter `json:"filters"`
|
|
}
|
|
|
|
func dnssdkDo(ctx context.Context, c *dnssdk.Client, apiKey string, method, uri string, bodyParams interface{}, dest interface{}) error {
|
|
// Adapted from https://github.com/G-Core/gcore-dns-sdk-go/blob/main/client.go#L289
|
|
// No way to reflect a private method in Golang
|
|
|
|
var bs []byte
|
|
if bodyParams != nil {
|
|
var err error
|
|
bs, err = json.Marshal(bodyParams)
|
|
if err != nil {
|
|
return fmt.Errorf("encode bodyParams: %w", err)
|
|
}
|
|
}
|
|
|
|
endpoint, err := c.BaseURL.Parse(path.Join(c.BaseURL.Path, uri))
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse endpoint: %w", err)
|
|
}
|
|
|
|
if c.Debug {
|
|
log.Printf("[DEBUG] dns api request: %s %s %s \n", method, uri, bs)
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(ctx, method, endpoint.String(), strings.NewReader(string(bs)))
|
|
if err != nil {
|
|
return fmt.Errorf("new request: %w", err)
|
|
}
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Authorization", fmt.Sprintf("APIKey %s", apiKey))
|
|
if c.UserAgent != "" {
|
|
req.Header.Set("User-Agent", c.UserAgent)
|
|
}
|
|
|
|
resp, err := c.HTTPClient.Do(req)
|
|
if err != nil {
|
|
return fmt.Errorf("send request: %w", err)
|
|
}
|
|
|
|
defer func() { _ = resp.Body.Close() }()
|
|
|
|
if resp.StatusCode >= http.StatusMultipleChoices {
|
|
all, _ := io.ReadAll(resp.Body)
|
|
e := dnssdk.APIError{
|
|
StatusCode: resp.StatusCode,
|
|
}
|
|
err := json.Unmarshal(all, &e)
|
|
if err != nil {
|
|
e.Message = string(all)
|
|
}
|
|
return e
|
|
}
|
|
|
|
if dest == nil {
|
|
return nil
|
|
}
|
|
|
|
// nolint: wrapcheck
|
|
return json.NewDecoder(resp.Body).Decode(dest)
|
|
}
|
|
|
|
func (c *gcoreProvider) dnssdkRRSets(domain string) (gcoreRRSets, error) {
|
|
// Turns out G-Core has a hidden parameter "all=true"
|
|
// https://github.com/octodns/octodns-gcore/blob/main/octodns_gcore/__init__.py#L105
|
|
// But this isn't exposed with their API, need to manually call it
|
|
|
|
var result gcoreRRSets
|
|
url := fmt.Sprintf("/v2/zones/%s/rrsets?all=true", domain)
|
|
|
|
err := dnssdkDo(c.ctx, c.provider, c.apiKey, http.MethodGet, url, nil, &result)
|
|
if err != nil {
|
|
return gcoreRRSets{}, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|