mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-01-11 18:08:57 +08:00
ba2c7f9c0e
* Enforcing formatted code Signed-off-by: Jan-Philipp Benecke <jan-philipp@bnck.me> * Show lines Signed-off-by: Jan-Philipp Benecke <jan-philipp@bnck.me> * Run check after deps are installed Signed-off-by: Jan-Philipp Benecke <jan-philipp@bnck.me>
138 lines
3.6 KiB
Go
138 lines
3.6 KiB
Go
package autodns
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"sort"
|
|
|
|
"github.com/StackExchange/dnscontrol/v3/models"
|
|
)
|
|
|
|
type ZoneListFilter struct {
|
|
Key string `json:"key"`
|
|
Value string `json:"value"`
|
|
Operator string `json:"operator"`
|
|
Link string `json:"link,omitempty"`
|
|
Filter []*ZoneListFilter `json:"filters,omitempty"`
|
|
}
|
|
|
|
type ZoneListRequest struct {
|
|
Filter []*ZoneListFilter `json:"filters"`
|
|
}
|
|
|
|
func (api *autoDnsProvider) request(method string, requestPath string, data interface{}) ([]byte, error) {
|
|
client := &http.Client{}
|
|
|
|
requestUrl := api.baseURL
|
|
requestUrl.Path = api.baseURL.Path + requestPath
|
|
|
|
request := &http.Request{
|
|
URL: &requestUrl,
|
|
Header: api.defaultHeaders,
|
|
Method: method,
|
|
}
|
|
|
|
if data != nil {
|
|
body, _ := json.Marshal(data)
|
|
buffer := bytes.NewBuffer(body)
|
|
request.Body = io.NopCloser(buffer)
|
|
}
|
|
|
|
response, error := client.Do(request)
|
|
if error != nil {
|
|
return nil, error
|
|
}
|
|
defer response.Body.Close()
|
|
|
|
responseText, _ := ioutil.ReadAll(response.Body)
|
|
if response.StatusCode != 200 {
|
|
return nil, errors.New("Request to " + requestUrl.Path + " failed: " + string(responseText))
|
|
}
|
|
|
|
return responseText, nil
|
|
}
|
|
|
|
func (api *autoDnsProvider) findZoneSystemNameServer(domain string) (*models.Nameserver, error) {
|
|
request := &ZoneListRequest{}
|
|
|
|
request.Filter = append(request.Filter, &ZoneListFilter{
|
|
Key: "name",
|
|
Value: domain,
|
|
Operator: "EQUAL",
|
|
})
|
|
|
|
responseData, err := api.request("POST", "zone/_search", request)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var responseObject JSONResponseDataZone
|
|
_ = json.Unmarshal(responseData, &responseObject)
|
|
if len(responseObject.Data) != 1 {
|
|
return nil, errors.New("Domain " + domain + " could not be found in AutoDNS")
|
|
}
|
|
|
|
systemNameServer := &models.Nameserver{Name: responseObject.Data[0].SystemNameServer}
|
|
|
|
return systemNameServer, nil
|
|
}
|
|
|
|
func (api *autoDnsProvider) getZone(domain string) (*Zone, error) {
|
|
systemNameServer, err := api.findZoneSystemNameServer(domain)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// if resolving of a systemNameServer succeeds the system contains this zone
|
|
var responseData, _ = api.request("GET", "zone/"+domain+"/"+systemNameServer.Name, nil)
|
|
var responseObject JSONResponseDataZone
|
|
// make sure that the response is valid, the zone is in AutoDNS but we're not sure the returned data meets our expectation
|
|
unmErr := json.Unmarshal(responseData, &responseObject)
|
|
if unmErr != nil {
|
|
return nil, unmErr
|
|
}
|
|
|
|
return responseObject.Data[0], nil
|
|
}
|
|
|
|
func (api *autoDnsProvider) updateZone(domain string, resourceRecords []*ResourceRecord, nameServers []*models.Nameserver, zoneTTL uint32) error {
|
|
systemNameServer, err := api.findZoneSystemNameServer(domain)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
zone, _ := api.getZone(domain)
|
|
|
|
zone.Origin = domain
|
|
zone.SystemNameServer = systemNameServer.Name
|
|
|
|
zone.IncludeWwwForMain = false
|
|
|
|
zone.Soa.TTL = zoneTTL
|
|
|
|
// empty out NameServers and ResourceRecords, add what it should be
|
|
zone.NameServers = []*models.Nameserver{}
|
|
zone.ResourceRecords = []*ResourceRecord{}
|
|
|
|
zone.ResourceRecords = append(zone.ResourceRecords, resourceRecords...)
|
|
|
|
// naive approach, the first nameserver passed should be the systemNameServer, the will be named alphabetically
|
|
sort.Slice(nameServers, func(i, j int) bool {
|
|
return nameServers[i].Name < nameServers[j].Name
|
|
})
|
|
|
|
zone.NameServers = append(zone.NameServers, nameServers...)
|
|
|
|
var _, putErr = api.request("PUT", "zone/"+domain+"/"+systemNameServer.Name, zone)
|
|
|
|
if putErr != nil {
|
|
return putErr
|
|
}
|
|
|
|
return nil
|
|
}
|