summaryrefslogtreecommitdiff
path: root/cloudflare/cloudflare.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2023-12-20 03:13:43 -0600
committerJeff Carr <[email protected]>2023-12-20 03:13:43 -0600
commit382cc8dd171731cc333dd05b7b0b798340162a32 (patch)
tree946e99e434183b3eb1272180799c3678f5c7e037 /cloudflare/cloudflare.go
parentbbf96ee7fa67a6d50ea1d1b3a23a3f44f136a30e (diff)
make a cloudflare packagev0.1.2
move cloudflare stuff to a package display cloudflare API values dns protobuf example sort output, but gocli formatting is bad cloudflare window can be closed first time success pushing AAAA records for my box enable a cloudflare button RFC 8482. DNS servers we use should respond to ANY We should support ANY requests via DNS as long as we enforce TCP over UDP populate the API provider domain NS record changes are tracked check hostname OS configuration detect domain name changes lookup of NS records for my domain name button to investigate port 53 daemon start dns resolver detection and debugging measure dns resolution speed sort todo items Signed-off-by: Jeff Carr <[email protected]>
Diffstat (limited to 'cloudflare/cloudflare.go')
-rw-r--r--cloudflare/cloudflare.go257
1 files changed, 257 insertions, 0 deletions
diff --git a/cloudflare/cloudflare.go b/cloudflare/cloudflare.go
new file mode 100644
index 0000000..de08fae
--- /dev/null
+++ b/cloudflare/cloudflare.go
@@ -0,0 +1,257 @@
+// This is a simple example
+package cloudflare
+
+import (
+ "log"
+ "os"
+ "bytes"
+ "io/ioutil"
+ "net/http"
+
+ "git.wit.org/wit/gui"
+)
+
+/*
+curl --request POST \
+ --url https://api.cloudflare.com/client/v4/zones/zone_identifier/dns_records \
+ --header 'Content-Type: application/json' \
+ --header 'X-Auth-Email: ' \
+ --data '{
+ "content": "198.51.100.4",
+ "name": "example.com",
+ "proxied": false,
+ "type": "A",
+ "comment": "Domain verification record",
+ "tags": [
+ "owner:dns-team"
+ ],
+ "ttl": 3600
+}'
+*/
+
+// CFdialog is everything you need forcreating
+// a new record: name, TTL, type (CNAME, A, etc)
+var CFdialog RRT
+
+// Resource Record (used in a DNS zonefile)
+type RRT struct {
+ cloudflareW *gui.Node // the window node
+ cloudflareB *gui.Node // the cloudflare button
+
+ TypeNode *gui.Node // CNAME, A, AAAA, ...
+ NameNode *gui.Node // www, mail, ...
+ ValueNode *gui.Node // 4.2.2.2, "dkim stuff", etc
+
+ proxyNode *gui.Node // If cloudflare is a port 80 & 443 proxy
+ ttlNode *gui.Node // just set to 1 which means automatic to cloudflare
+ curlNode *gui.Node // shows you what you could run via curl
+ resultNode *gui.Node // what the cloudflare API returned
+ saveNode *gui.Node // button to send it to cloudflare
+
+ zoneNode *gui.Node // "wit.com"
+ zoneIdNode *gui.Node // cloudflare zone ID
+ apiNode *gui.Node // cloudflare API key (from environment var CF_API_KEY)
+ emailNode *gui.Node // cloudflare email (from environment var CF_API_EMAIL)
+
+ ID string
+ Type string
+ Name string
+ Content string
+ ProxyS string
+ Proxied bool
+ Proxiable bool
+ Ttl string
+}
+
+func CreateRR(myGui *gui.Node, zone string, zoneID string) {
+ if (CFdialog.cloudflareW != nil) {
+ // skip this if the window has already been created
+ log.Println("createRR() the cloudflare window already exists")
+ CFdialog.cloudflareB.Disable()
+ return
+ }
+ CFdialog.cloudflareW = myGui.NewWindow("cloudflare " + zone + " API")
+ CFdialog.cloudflareW.Custom = func () {
+ log.Println("createRR() don't really exit here")
+ CFdialog.cloudflareW = nil
+ CFdialog.cloudflareB.Enable()
+ }
+
+ CFdialog.ID = zoneID
+
+ group := CFdialog.cloudflareW.NewGroup("Create a new DNS Resource Record (rr)")
+
+ // make a grid 2 things wide
+ grid := group.NewGrid("gridnuts", 2, 3)
+
+ grid.NewLabel("zone")
+ CFdialog.zoneNode = grid.NewLabel("zone")
+ CFdialog.zoneNode.SetText(zone)
+
+ grid.NewLabel("zone ID")
+ CFdialog.zoneIdNode = grid.NewLabel("zoneID")
+ CFdialog.zoneIdNode.SetText(zoneID)
+
+ grid.NewLabel("shell env $CF_API_EMAIL")
+ CFdialog.emailNode = grid.NewLabel("type")
+ CFdialog.emailNode.SetText(os.Getenv("CF_API_EMAIL"))
+
+ grid.NewLabel("shell env $CF_API_KEY")
+ CFdialog.apiNode = grid.NewLabel("type")
+ CFdialog.apiNode.SetText(os.Getenv("CF_API_KEY"))
+
+ grid.NewLabel("Record Type")
+ CFdialog.TypeNode = grid.NewCombobox("type")
+ CFdialog.TypeNode.AddText("A")
+ CFdialog.TypeNode.AddText("AAAA")
+ CFdialog.TypeNode.AddText("CNAME")
+ CFdialog.TypeNode.AddText("TXT")
+ CFdialog.TypeNode.AddText("MX")
+ CFdialog.TypeNode.AddText("NS")
+ CFdialog.TypeNode.Custom = func () {
+ CreateCurlRR()
+ }
+ CFdialog.TypeNode.SetText("AAAA")
+
+ grid.NewLabel("Name (usually the hostname)")
+ CFdialog.NameNode = grid.NewCombobox("name")
+ CFdialog.NameNode.AddText("www")
+ CFdialog.NameNode.AddText("mail")
+ CFdialog.NameNode.AddText("git")
+ CFdialog.NameNode.AddText("go")
+ CFdialog.NameNode.AddText("blog")
+ CFdialog.NameNode.AddText("ns1")
+ CFdialog.NameNode.Custom = func () {
+ CreateCurlRR()
+ }
+ CFdialog.NameNode.SetText("www")
+
+ grid.NewLabel("Cloudflare Proxy")
+ CFdialog.proxyNode = grid.NewDropdown("proxy")
+ CFdialog.proxyNode.AddText("On")
+ CFdialog.proxyNode.AddText("Off")
+ CFdialog.proxyNode.Custom = func () {
+ CreateCurlRR()
+ }
+ CFdialog.proxyNode.SetText("Off")
+
+ grid.NewLabel("Value")
+ CFdialog.ValueNode = grid.NewCombobox("value")
+ CFdialog.ValueNode.AddText("127.0.0.1")
+ CFdialog.ValueNode.AddText("2001:4860:4860::8888")
+ CFdialog.ValueNode.AddText("ipv6.wit.com")
+ CFdialog.ValueNode.Custom = func () {
+ CreateCurlRR()
+ }
+ CFdialog.ValueNode.SetText("127.0.0.1")
+ CFdialog.ValueNode.Expand()
+
+ group.NewLabel("curl")
+ CFdialog.curlNode = group.NewTextbox("curl")
+ CFdialog.curlNode.Custom = func () {
+ CreateCurlRR()
+ }
+ CFdialog.curlNode.SetText("put the curl text here")
+
+ CFdialog.resultNode = group.NewTextbox("result")
+ CFdialog.resultNode.SetText("API response will show here")
+
+ CFdialog.saveNode = group.NewButton("Save", func () {
+ url, data := CreateCurlRR()
+ result := curl(url, data)
+ CFdialog.resultNode.SetText(result)
+ })
+ CFdialog.saveNode.Disable()
+
+ group.Pad()
+ grid.Pad()
+ grid.Expand()
+}
+
+func CreateCurlRR() (string, string) {
+ // enable the Save/Create Button
+ if (CFdialog.saveNode != nil) {
+ CFdialog.saveNode.Enable()
+ }
+
+ if (CFdialog.TypeNode != nil) {
+ CFdialog.Type = CFdialog.TypeNode.S
+ }
+ if (CFdialog.NameNode != nil) {
+ CFdialog.Name = CFdialog.NameNode.S
+ }
+ if (CFdialog.proxyNode != nil) {
+ if (CFdialog.proxyNode.S == "On") {
+ CFdialog.ProxyS = "true"
+ } else {
+ CFdialog.ProxyS = "false"
+ }
+ }
+ if (CFdialog.ValueNode != nil) {
+ CFdialog.Content = CFdialog.ValueNode.S
+ }
+ CFdialog.Ttl = "3600"
+
+ var url string = "https://api.cloudflare.com/client/v4/zones/" + CFdialog.ID + "/dns_records"
+ // https://api.cloudflare.com/client/v4/zones/zone_identifier/dns_records \
+ // 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": "` + CFdialog.Content + `", `
+ tmp += `"name": "` + CFdialog.Name + `", `
+ tmp += `"type": "` + CFdialog.Type + `", `
+ tmp += `"ttl": ` + CFdialog.Ttl + `, `
+ tmp += `"proxied": ` + CFdialog.ProxyS + `, `
+ 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 URL =", url)
+ log.Println("http PUT data =", pretty)
+ if (CFdialog.curlNode != nil) {
+ CFdialog.curlNode.SetText("URL: " + url + "\n" + pretty)
+ }
+
+ return url, tmp
+}
+
+func curl(url string, tmp string) string {
+ var authKey string = CFdialog.apiNode.S
+ var email string = CFdialog.emailNode.S
+
+ log.Println("curl() START")
+ data := []byte(tmp)
+ req, err := http.NewRequest(http.MethodPost, 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 ""
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ log.Println(err)
+ return ""
+ }
+ // log.Println("http PUT body =", body)
+ // spew.Dump(body)
+
+ log.Println("result =", string(body))
+ log.Println("curl() END")
+ pretty, _ := formatJSON(string(body))
+ return pretty
+}