ddns-updater icon indicating copy to clipboard operation
ddns-updater copied to clipboard

Feature request: PowerDNS-Admin

Open bohemtucsok opened this issue 1 year ago • 4 comments

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 avatar Aug 12 '23 08:08 bohemtucsok

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)
	}
}

bohemtucsok avatar Aug 13 '23 12:08 bohemtucsok

+1 for the ability to update PowerDNS records

gitwittidbit avatar Oct 31 '23 07:10 gitwittidbit

@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!!

qdm12 avatar Jan 19 '24 20:01 qdm12

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.

bohemtucsok avatar Jan 20 '24 15:01 bohemtucsok