220 lines
5.5 KiB
Go
220 lines
5.5 KiB
Go
|
// This is a simple example
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"os"
|
||
|
"log"
|
||
|
"fmt"
|
||
|
"encoding/json"
|
||
|
"io/ioutil"
|
||
|
"net/http"
|
||
|
// "strconv"
|
||
|
"bytes"
|
||
|
|
||
|
"github.com/davecgh/go-spew/spew"
|
||
|
)
|
||
|
|
||
|
func doChange(dnsRow *RRT) {
|
||
|
log.Println("Look for changes in row", dnsRow.ID)
|
||
|
log.Println("Proxy", dnsRow.Proxied, "vs", dnsRow.proxyNode.S)
|
||
|
log.Println("Content", dnsRow.Content, "vs", dnsRow.valueNode.S)
|
||
|
if (dnsRow.Content != dnsRow.valueNode.S) {
|
||
|
log.Println("UPDATE VALUE", dnsRow.nameNode.Name, dnsRow.typeNode.Name, "to", dnsRow.valueNode.S)
|
||
|
stuff, result := httpPut(dnsRow)
|
||
|
if (dnsRow.curlNode != nil) {
|
||
|
pretty, _ := formatJSON(stuff)
|
||
|
log.Println("http PUT curl =", pretty)
|
||
|
dnsRow.curlNode.SetText(pretty)
|
||
|
}
|
||
|
if (dnsRow.resultNode != nil) {
|
||
|
pretty, _ := formatJSON(result)
|
||
|
log.Println("http PUT result =", pretty)
|
||
|
dnsRow.resultNode.SetText(pretty)
|
||
|
}
|
||
|
}
|
||
|
dnsRow.saveNode.Disable()
|
||
|
}
|
||
|
|
||
|
func getZonefile(c *configT) *DNSRecords {
|
||
|
var url = cloudflareURL + c.zoneID + "/dns_records/"
|
||
|
log.Println("getZonefile()", c.domain, url)
|
||
|
req, err := http.NewRequest("GET", url, nil)
|
||
|
if err != nil {
|
||
|
log.Println("http.NewRequest error:", err)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Set headers
|
||
|
req.Header.Set("X-Auth-Key", c.auth)
|
||
|
req.Header.Set("X-Auth-Email", c.email)
|
||
|
|
||
|
log.Println("getZonefile() auth, email", c.auth, c.email)
|
||
|
|
||
|
client := &http.Client{}
|
||
|
resp, err := client.Do(req)
|
||
|
if err != nil {
|
||
|
log.Println("http.Client error:", err)
|
||
|
return nil
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
body, err := ioutil.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Println("ioutil.ReadAll() error", err)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
var records DNSRecords
|
||
|
if err := json.Unmarshal(body, &records); err != nil {
|
||
|
log.Println("json.Unmarshal() error", err)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
log.Println("getZonefile() worked", records)
|
||
|
return &records
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
pass in a DNS Resource Records (the stuff in a zonefile)
|
||
|
|
||
|
This will talk to the cloudflare API and generate a resource record in the zonefile:
|
||
|
|
||
|
For example:
|
||
|
gitea.wit.com. 3600 IN CNAME git.wit.com.
|
||
|
go.wit.com. 3600 IN A 1.1.1.9
|
||
|
test.wit.com. 3600 IN NS ns1.wit.com.
|
||
|
*/
|
||
|
func httpPut(dnsRow *RRT) (string, string) {
|
||
|
var url string = cloudflareURL + os.Getenv("CF_API_ZONEID") + "/dns_records/" + dnsRow.ID
|
||
|
var authKey string = os.Getenv("CF_API_KEY")
|
||
|
var email string = os.Getenv("CF_API_EMAIL")
|
||
|
|
||
|
// make a json record to send on port 80 to cloudflare
|
||
|
var tmp string
|
||
|
tmp = `{"content": "` + dnsRow.valueNode.S + `", `
|
||
|
tmp += `"name": "` + dnsRow.Name + `", `
|
||
|
tmp += `"type": "` + dnsRow.Type + `", `
|
||
|
tmp+= `"ttl": "` + "1" + `", `
|
||
|
tmp += `"comment": "WIT DNS Control Panel"`
|
||
|
tmp += `}`
|
||
|
data := []byte(tmp)
|
||
|
|
||
|
log.Println("http PUT url =", url)
|
||
|
// log.Println("http PUT data =", data)
|
||
|
// spew.Dump(data)
|
||
|
pretty, _ := formatJSON(string(data))
|
||
|
log.Println("http PUT data =", pretty)
|
||
|
|
||
|
req, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(data))
|
||
|
|
||
|
// Set headers
|
||
|
req.Header.Set("Content-Type", "application/json")
|
||
|
req.Header.Set("X-Auth-Key", authKey)
|
||
|
req.Header.Set("X-Auth-Email", email)
|
||
|
|
||
|
client := &http.Client{}
|
||
|
resp, err := client.Do(req)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return tmp, fmt.Sprintf("blah err =", err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
body, err := ioutil.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return tmp, fmt.Sprintf("blah err =", err)
|
||
|
}
|
||
|
// log.Println("http PUT body =", body)
|
||
|
// spew.Dump(body)
|
||
|
|
||
|
return tmp, string(body)
|
||
|
}
|
||
|
|
||
|
// https://api.cloudflare.com/client/v4/zones
|
||
|
func getZones(auth, email string) *DNSRecords {
|
||
|
var url = "https://api.cloudflare.com/client/v4/zones"
|
||
|
log.Println("getZones()", url)
|
||
|
req, err := http.NewRequest("GET", url, nil)
|
||
|
if err != nil {
|
||
|
log.Println("http.NewRequest error:", err)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Set headers
|
||
|
req.Header.Set("X-Auth-Key", auth)
|
||
|
req.Header.Set("X-Auth-Email", email)
|
||
|
|
||
|
log.Println("getZones() auth, email", auth, email)
|
||
|
|
||
|
client := &http.Client{}
|
||
|
resp, err := client.Do(req)
|
||
|
if err != nil {
|
||
|
log.Println("getZones() http.Client error:", err)
|
||
|
return nil
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
body, err := ioutil.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Println("getZones() ioutil.ReadAll() error", err)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
var records DNSRecords
|
||
|
if err := json.Unmarshal(body, &records); err != nil {
|
||
|
log.Println("getZones() json.Unmarshal() error", err)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
/* Cloudflare API returns struct[] of:
|
||
|
struct { ID string "json:\"id\""; Type string "json:\"type\""; Name string "json:\"name\"";
|
||
|
Content string "json:\"content\""; Proxied bool "json:\"proxied\"";
|
||
|
Proxiable bool "json:\"proxiable\""; TTL int "json:\"ttl\"" }
|
||
|
*/
|
||
|
|
||
|
// log.Println("getZones() worked", records)
|
||
|
// log.Println("spew dump:")
|
||
|
spew.Dump(records)
|
||
|
for _, record := range records.Result {
|
||
|
log.Println("spew record:", record)
|
||
|
log.Println("record:", record.Name, record.ID)
|
||
|
|
||
|
var newc *configT
|
||
|
newc = new(configT)
|
||
|
|
||
|
newc.domain = record.Name
|
||
|
newc.zoneID = record.ID
|
||
|
newc.auth = auth
|
||
|
newc.email = email
|
||
|
|
||
|
config[record.Name] = newc
|
||
|
zonedrop.AddText(record.Name)
|
||
|
log.Println("zonedrop.AddText:", record.Name, record.ID)
|
||
|
}
|
||
|
for d, _ := range config {
|
||
|
log.Println("config entry:", d)
|
||
|
}
|
||
|
|
||
|
return &records
|
||
|
}
|
||
|
|
||
|
// formatJSON takes an unformatted JSON string and returns a formatted version.
|
||
|
func formatJSON(unformattedJSON string) (string, error) {
|
||
|
var jsonData interface{}
|
||
|
|
||
|
// Decode the JSON string into an interface
|
||
|
err := json.Unmarshal([]byte(unformattedJSON), &jsonData)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
// Re-encode the JSON with indentation for formatting
|
||
|
formattedJSON, err := json.MarshalIndent(jsonData, "", " ")
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
return string(formattedJSON), nil
|
||
|
}
|