mirror of
https://github.com/qdm12/ddns-updater.git
synced 2026-04-05 08:54:09 -04:00
Fixed Cloudflare and other bugs; added Cloudflare doc to readme
- Readme instructions, thanks to @Starttoaster - Clarified parameters for Cloudflare - Cloudflare must have a host parameter in the end - Fixed healthcheck (bad indexes in for loops) - Mutex for recordConfig is now a pointer to a mutex - Removed irrelevant check for listening port to not be 9999
This commit is contained in:
20
README.md
20
README.md
@@ -109,6 +109,7 @@ The following parameters are available to all DNS hosts providers:
|
||||
- `namecheap`
|
||||
- `duckdns`
|
||||
- `dreamhost`
|
||||
- `cloudflare`
|
||||
- `"domain"` is your domain name
|
||||
- `"ip_method"` is the method to obtain your public IP address and can be
|
||||
- `provider` means the public IP is automatically determined by the DNS provider (**only for DuckDNs and Namecheap**)
|
||||
@@ -132,6 +133,7 @@ Each DNS provider has a specific set of extra required parameters as follows:
|
||||
- Cloudflare:
|
||||
- `"zone_identifier"`
|
||||
- `"identifier"`
|
||||
- `"host"` is your host and can be a subdomain, `@` or `*` generally
|
||||
- Either (or both):
|
||||
- Email `"email"` and Key `"key"`
|
||||
- User service key `"user_service_key"`
|
||||
@@ -218,7 +220,23 @@ In this example, the key is `dLP4WKz5PdkS_GuUDNigHcLQFpw4CWNwAQ5` and the secret
|
||||
|
||||
### Cloudflare
|
||||
|
||||
*Awaiting a contribution*
|
||||
1. Make sure you have `curl` installed
|
||||
1. Obtain your API key from Cloudflare website ([see this](https://support.cloudflare.com/hc/en-us/articles/200167836-Where-do-I-find-my-Cloudflare-API-key-))
|
||||
1. Obtain your zone identifier for your domain name, from the domain's overview page written as *Zone ID*
|
||||
1. Find your **identifier** in the `id` field with
|
||||
|
||||
```sh
|
||||
EMAIL=example@example.com
|
||||
APIKEY=aaaaaaaaaaaaaaaaaa
|
||||
curl -X GET "https://api.cloudflare.com/client/v4/zones/945e08a9672f6da8e9c061967f3a9301/dns_records" \
|
||||
-H "X-Auth-Email: $EMAIL" \
|
||||
-H "X-Auth-Key: $APIKEY" \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
You can now fill in the necessary parameters in *config.json*
|
||||
|
||||
Special thanks to @Starttoaster for helping out with the [documentation](https://gist.github.com/Starttoaster/07d568c2a99ad7631dd776688c988326) and testing.
|
||||
|
||||
## Testing
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ func Query() {
|
||||
if err != nil {
|
||||
logging.Fatal("Cannot build HTTP request: %s", err)
|
||||
}
|
||||
client := &http.Client{Timeout: time.Duration(1000) * time.Millisecond}
|
||||
client := &http.Client{Timeout: 2 * time.Second}
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
logging.Fatal("Cannot execute HTTP request: %s", err)
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
|
||||
// RecordConfigType contains all the information to update and display a DNS record
|
||||
type RecordConfigType struct { // internal
|
||||
Settings SettingsType // fixed
|
||||
Status statusType // changes for each update
|
||||
History historyType // past information
|
||||
M sync.RWMutex // TODO inherit
|
||||
Settings SettingsType // fixed
|
||||
Status statusType // changes for each update
|
||||
History historyType // past information
|
||||
M *sync.RWMutex // TODO inherit
|
||||
}
|
||||
|
||||
// NewRecordConfig returns a new recordConfig with settings
|
||||
@@ -21,6 +21,7 @@ func NewRecordConfig(settings SettingsType, IPs []string, tSuccess time.Time) Re
|
||||
IPs: IPs,
|
||||
TSuccess: tSuccess,
|
||||
},
|
||||
M: new(sync.RWMutex),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +31,7 @@ func (conf *RecordConfigType) String() string {
|
||||
return conf.Settings.String() + ": " + conf.Status.string() + "; " + conf.History.string()
|
||||
}
|
||||
|
||||
func (conf *RecordConfigType) toHTML() HTMLRow {
|
||||
conf.M.RLock()
|
||||
defer conf.M.RUnlock()
|
||||
func (conf RecordConfigType) toHTML() HTMLRow {
|
||||
row := HTMLRow{
|
||||
Domain: conf.Settings.getHTMLDomain(),
|
||||
Host: conf.Settings.Host,
|
||||
|
||||
@@ -131,9 +131,6 @@ func (settings *SettingsType) Verify() error {
|
||||
if len(settings.Identifier) == 0 {
|
||||
return fmt.Errorf("Cloudflare identifier was not provided")
|
||||
}
|
||||
if settings.Host != "@" {
|
||||
return fmt.Errorf("the host %s can only be @ for settings %s", settings.Host, settings)
|
||||
}
|
||||
if settings.IPmethod == IPMETHODPROVIDER {
|
||||
return fmt.Errorf("the provider %s does not support the IP update method %s", settings.Provider, settings.IPmethod)
|
||||
}
|
||||
|
||||
@@ -27,8 +27,6 @@ func verifyListeningPort(listeningPort string) {
|
||||
} else if value > 49151 {
|
||||
// dynamic and/or private ports.
|
||||
logging.Warn("listening port %s is in the dynamic/private ports range (above 49151)", listeningPort)
|
||||
} else if value == 9999 {
|
||||
logging.Fatal("listening port %s cannot be set to the local healthcheck port 9999", listeningPort)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ func healthcheckHandler(recordsConfigs []models.RecordConfigType) error {
|
||||
if len(recordsConfigs[i].History.IPs) == 0 {
|
||||
return fmt.Errorf("no set IP address found")
|
||||
}
|
||||
for i := range ips {
|
||||
if ips[i].String() != recordsConfigs[i].History.IPs[0] {
|
||||
for _, ip := range ips {
|
||||
if ip.String() != recordsConfigs[i].History.IPs[0] {
|
||||
return fmt.Errorf(
|
||||
"lookup IP address of %s is not %s",
|
||||
recordsConfigs[i].Settings.BuildDomainName(),
|
||||
|
||||
@@ -60,7 +60,7 @@ func update(
|
||||
} else if recordConfig.Settings.Provider == models.PROVIDERDREAMHOST {
|
||||
err = updateDreamhost(httpClient, recordConfig.Settings.Domain, recordConfig.Settings.Key, ip, recordConfig.Settings.BuildDomainName())
|
||||
} else if recordConfig.Settings.Provider == models.PROVIDERCLOUDFLARE {
|
||||
err = updateCloudflare(httpClient, recordConfig.Settings.Domain, recordConfig.Settings.ZoneIdentifier, recordConfig.Settings.Identifier, recordConfig.Settings.Email, recordConfig.Settings.Key, recordConfig.Settings.UserServiceKey, ip)
|
||||
err = updateCloudflare(httpClient, recordConfig.Settings.ZoneIdentifier, recordConfig.Settings.Identifier, recordConfig.Settings.Host, recordConfig.Settings.Email, recordConfig.Settings.Key, recordConfig.Settings.UserServiceKey, ip)
|
||||
} else {
|
||||
err = fmt.Errorf("provider %s is not supported", recordConfig.Settings.Provider)
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func updateGoDaddy(httpClient *http.Client, host, domain, key, secret, ip string
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateCloudflare(httpClient *http.Client, domain, zoneIdentifier, identifier, email, key, userServiceKey, ip string) error {
|
||||
func updateCloudflare(httpClient *http.Client, zoneIdentifier, identifier, host, email, key, userServiceKey, ip string) error {
|
||||
if len(ip) == 0 {
|
||||
return fmt.Errorf("cannot have a DNS provider-provided IP address for Cloudflare")
|
||||
}
|
||||
@@ -189,12 +189,12 @@ func updateCloudflare(httpClient *http.Client, domain, zoneIdentifier, identifie
|
||||
Name string `json:"name"` // DNS record name i.e. example.com
|
||||
Content string `json:"content"` // ip address
|
||||
}
|
||||
URL := cloudflareURL + "/" + zoneIdentifier + "/dns_records/" + identifier
|
||||
URL := cloudflareURL + "/zones/" + zoneIdentifier + "/dns_records/" + identifier
|
||||
r, err := network.BuildHTTPPut(
|
||||
URL,
|
||||
cloudflarePutBody{
|
||||
Type: "A",
|
||||
Name: domain,
|
||||
Name: host,
|
||||
Content: ip,
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user