qdm12 / ddns-updater

Container to update DNS records periodically with WebUI for many DNS providers
https://hub.docker.com/r/qmcgaw/ddns-updater/
MIT License
1.6k stars 154 forks source link

Feature request: PowerDNS-Admin #518

Open bohemtucsok opened 1 year ago

bohemtucsok commented 1 year ago

Hello

We really like this program, it makes our lives a lot easier :)

Thanks for :)

The question would be who could make up the current list of providers with PowerDNS-Admin as a whole.

Powerdns can be updated with a simple curl call

a simple working example:

curl -H 'Content-Type: application/json' -X PATCH --data '{"rrsets": [ {"name": "xxxx.DOMAIN.COM.", "type": "A", "ttl": 86400, "changetype": "REPLACE", "records": [ {"content": "1.1.1.1", "disabled": false, "name": "xxxx.DOMAIN.COM.", "ttl": 86400, "type": "A"}]}]}' -H 'X-API-Key: WDVaRHNxxxxxxxxx' https://POWERDNS-ADMIN-WEB.COM/api/v1/servers/localhost/zones/DOMAIN.COM | jq .

there could be a way for this to be included among the service providers.

I can help with testing

:)

bohemtucsok commented 1 year ago

I have provided a code that can help you integrate pdns-admin

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "strconv"
    "time"
)

func getPreviousIP() string {
    previousIP, err := ioutil.ReadFile("previous_ip.txt")
    if err != nil {
        return ""
    }
    return string(previousIP)
}

func saveCurrentIP(ip string) {
    err := ioutil.WriteFile("previous_ip.txt", []byte(ip), 0644)
    if err != nil {
        fmt.Println("Error saving current IP:", err)
    }
}

func getCurrentIP() (string, error) {
    resp, err := http.Get("https://api64.ipify.org?format=text")
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    ip, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }
    return string(ip), nil
}

func updateDNSRecord(newIP string) error {
    url := os.Getenv("POWERDNS_ADMIN_URL") + os.Getenv("DNS_DOMAIN")
    apiKey := os.Getenv("POWERDNS_API_KEY")

    payload := `{
        "rrsets": [
            {
                "name": "` + os.Getenv("DNS_RECORD_NAME") + `.` + os.Getenv("DNS_DOMAIN") + `.",
                "type": "` + os.Getenv("DNS_RECORD_TYPE") + `",
                "ttl": ` + os.Getenv("DNS_RECORD_TTL") + `,
                "changetype": "REPLACE",
                "records": [
                    {
                        "content": "` + newIP + `",
                        "disabled": false,
                        "name": "` + os.Getenv("DNS_RECORD_NAME") + `.` + os.Getenv("DNS_DOMAIN") + `.",
                        "ttl": ` + os.Getenv("DNS_RECORD_TTL") + `,
                        "type": "` + os.Getenv("DNS_RECORD_TYPE") + `"
                    }
                ]
            }
        ]
    }`

    req, err := http.NewRequest("PATCH", url, nil)
    if err != nil {
        return err
    }
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-API-Key", apiKey)

    client := &http.Client{}
    req.Body = ioutil.NopCloser(strings.NewReader(payload))
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return err
    }
    fmt.Println(string(body))

    return nil
}

func main() {
    for {
        previousIP := getPreviousIP()
        currentIP, err := getCurrentIP()
        if err != nil {
            fmt.Println("Error getting current IP:", err)
            time.Sleep(60 * time.Second)
            continue
        }

        if currentIP != previousIP {
            fmt.Println("IP address has changed. Updating DNS record...")
            err := updateDNSRecord(currentIP)
            if err == nil {
                fmt.Println("DNS record update successful!")
                saveCurrentIP(currentIP)
            } else {
                fmt.Println("DNS record update failed:", err)
            }
        } else {
            fmt.Println("IP address has not changed.")
        }

        time.Sleep(time.Duration(CHECK_INTERVAL) * time.Second)
    }
}
gitwittidbit commented 10 months ago

+1 for the ability to update PowerDNS records

qdm12 commented 7 months ago

@bohemtucsok Thanks for the piece of code 💯 I'll get to this real soon after releasing 2.6. Regarding #299 should it be done before or is it unrelated? Thanks!!

bohemtucsok commented 7 months ago

Hi, @qdm12 #299 is the same, the request was created twice and can be deleted, it would be great if it was included :) if you need help with testing, please let me know.