Skip to content

Instantly share code, notes, and snippets.

@emptyhua
Created January 4, 2019 02:35
Show Gist options
  • Save emptyhua/91aaf592380c90012f47c60b0c39bee7 to your computer and use it in GitHub Desktop.
Save emptyhua/91aaf592380c90012f47c60b0c39bee7 to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"flag"
"fmt"
"io"
"log"
"net/http"
"net/url"
"path"
"strings"
)
func main() {
var httpBind string
var httpToken string
var apiServer string
var apiKey string
var ttl int
flag.StringVar(&httpBind, "bind", ":3741", "address and port http server bind at")
flag.StringVar(&httpToken, "token", "", "http auth token")
flag.StringVar(&apiServer, "pdns_api", "", "pdns api server")
flag.StringVar(&apiKey, "pdns_key", "", "pdns key")
flag.IntVar(&ttl, "ttl", 300, "record ttl")
flag.Parse()
if tmp, err := url.Parse(apiServer); err != nil {
log.Fatal("invalid pdsn_api", apiServer, err)
return
} else {
tmp.Path = ""
apiServer = tmp.String()
}
http.HandleFunc("/ddns.update", func(w http.ResponseWriter, r *http.Request) {
token := r.URL.Query().Get("token")
domain := r.URL.Query().Get("domain")
record := r.URL.Query().Get("record")
ipv4 := r.URL.Query().Get("ipv4")
ipv6 := r.URL.Query().Get("ipv6")
if token != httpToken {
w.WriteHeader(401)
fmt.Fprintf(w, "invalid http auth token")
return
}
if !strings.HasSuffix(domain, ".") {
domain = domain + "."
}
if !strings.HasSuffix(record, ".") {
record = record + "."
}
apiURL := apiServer + path.Join("/api/v1/servers/localhost/zones", domain)
log.Print("req: ", apiURL)
client := &http.Client{}
postData := `{"rrsets": [`
if ipv4 != "" {
postData += fmt.Sprintf(`
{"name": "%s",
"type": "A",
"ttl": %d,
"changetype": "REPLACE",
"records": [ {"content": "%s", "disabled": false} ]
}`, record, ttl, ipv4)
if ipv6 != "" {
postData += ","
}
}
if ipv6 != "" {
postData += fmt.Sprintf(`
{"name": "%s",
"type": "AAAA",
"ttl": %d,
"changetype": "REPLACE",
"records": [ {"content": "%s", "disabled": false} ]
}`, record, ttl, ipv6)
}
postData += `]}`
log.Print(postData, "\n")
req, err := http.NewRequest("PATCH", apiURL, bytes.NewBufferString(postData))
if err != nil {
fmt.Fprintf(w, "%v", err)
return
}
req.Header.Add("X-API-Key", apiKey)
resp, err := client.Do(req)
if err != nil {
fmt.Fprintf(w, "%v", err)
return
}
defer resp.Body.Close()
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
})
fmt.Printf("Start http server at %s\n", httpBind)
log.Fatal(http.ListenAndServe(httpBind, nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment