// This is a simple example package cloudflare import ( "encoding/json" "io/ioutil" "net/http" "go.wit.com/log" ) /* This function should run each time the user chanegs anything in the GUi or each time something in general changes It returns a RR record which then can be turned into JSON and sent via http to cloudflare's API */ func DoChange() *RRT { var dnsRow *RRT dnsRow = new(RRT) log.Log(INFO, "DoChange() START") if CFdialog.proxyNode.String() == "On" { dnsRow.Proxied = true } else { dnsRow.Proxied = false } dnsRow.Auth = CFdialog.apiNode.String() dnsRow.Email = CFdialog.emailNode.String() dnsRow.Domain = CFdialog.zoneNode.String() dnsRow.ZoneID = CFdialog.zoneIdNode.String() dnsRow.ID = CFdialog.rrNode.String() dnsRow.Content = CFdialog.ValueNode.String() dnsRow.Name = CFdialog.NameNode.String() dnsRow.Type = CFdialog.TypeNode.String() dnsRow.url = CFdialog.urlNode.String() dnsRow.data = makeJSON(dnsRow) // show the JSON log.Log(INFO, dnsRow) if CFdialog.curlNode != nil { pretty, _ := FormatJSON(dnsRow.data) log.Log(INFO, "http PUT curl =", pretty) CFdialog.curlNode.SetText(pretty) } return dnsRow } func SetRow(dnsRow *RRT) { log.Log(INFO, "Look for changes in row", dnsRow.ID) if CFdialog.proxyNode != nil { log.Log(INFO, "Proxy", dnsRow.Proxied, "vs", CFdialog.proxyNode.String()) if dnsRow.Proxied == true { CFdialog.proxyNode.SetText("On") } else { CFdialog.proxyNode.SetText("Off") } } if CFdialog.zoneNode != nil { CFdialog.zoneNode.SetText(dnsRow.Domain) } if CFdialog.zoneIdNode != nil { CFdialog.zoneIdNode.SetText(dnsRow.ZoneID) } log.Log(INFO, "zoneIdNode =", dnsRow.ZoneID) if CFdialog.rrNode != nil { CFdialog.rrNode.SetText(dnsRow.ID) } if CFdialog.ValueNode != nil { log.Log(INFO, "Content", dnsRow.Content, "vs", CFdialog.ValueNode.String()) CFdialog.ValueNode.SetText(dnsRow.Content) } if CFdialog.NameNode != nil { CFdialog.NameNode.SetText(dnsRow.Name) } if CFdialog.TypeNode != nil { CFdialog.TypeNode.SetText(dnsRow.Type) } if CFdialog.urlNode != nil { url := cloudflareURL + dnsRow.ZoneID + "/dns_records/" + dnsRow.ID CFdialog.urlNode.SetText(url) } // show the JSON tmp := makeJSON(dnsRow) log.Spew(tmp) if CFdialog.curlNode != nil { pretty, _ := FormatJSON(tmp) log.Spew("http PUT curl =", pretty) CFdialog.curlNode.SetText(pretty) } } func GetZonefile(c *ConfigT) *DNSRecords { var url = cloudflareURL + c.ZoneID + "/dns_records/?per_page=100" log.Log(ZONE, "getZonefile()", c.Domain, url) req, err := http.NewRequest("GET", url, nil) if err != nil { log.Error(err, "http.NewRequest error") return nil } // Set headers req.Header.Set("Authorization", "Bearer "+c.Auth) // req.Header.Set("X-Auth-Key", c.Auth) // req.Header.Set("X-Auth-Email", c.Email) log.Log(ZONE, "getZonefile() auth, email", c.Auth, c.Email) client := &http.Client{} resp, err := client.Do(req) // log.Spew("SPEWING", resp) if err != nil { log.Error(err, "http.Client error") return nil } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Error(err, "ioutil.ReadAll() error") return nil } log.Spew("SPEWING", body) pretty, err := FormatJSON(string(body)) if err != nil { log.Error(err, "FormatJSON error") } else { log.Warn(pretty) } var records DNSRecords if err := json.Unmarshal(body, &records); err != nil { log.Error(err, "json.Unmarshal() error") return nil } log.Log(ZONE, "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 makeJSON(dnsRow *RRT) string { // make a json record to send on port 80 to cloudflare var tmp string tmp = `{"content": "` + dnsRow.Content + `", ` tmp += `"name": "` + dnsRow.Name + `", ` tmp += `"type": "` + dnsRow.Type + `", ` tmp += `"ttl": "` + "1" + `", ` tmp += `"comment": "WIT DNS Control Panel"` tmp += `}` return tmp } // https://api.cloudflare.com/client/v4/zones func GetZones(auth, email string) *DNSRecords { var url = "https://api.cloudflare.com/client/v4/zones?per_page=100" log.Log(ZONE, "getZones()", url) req, err := http.NewRequest("GET", url, nil) if err != nil { log.Error(err, "http.NewRequest error") return nil } // Set headers req.Header.Set("Authorization", "Bearer "+auth) // req.Header.Set("X-Auth-Key", auth) // req.Header.Set("X-Auth-Email", email) log.Log(ZONE, "getZones() auth, email", auth, email) client := &http.Client{} resp, err := client.Do(req) if err != nil { log.Error(err, "getZones() http.Client error") return nil } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Error(err, "getZones() ioutil.ReadAll() error") return nil } var records DNSRecords if err := json.Unmarshal(body, &records); err != nil { log.Error(err, "getZones() json.Unmarshal() error") return nil } pretty, err := FormatJSON(string(body)) if err != nil { log.Error(err, "FormatJSON error") } else { log.Warn(pretty) } /* 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\"" } */ for _, record := range records.Result { log.Spew("spew record:", record) log.Info("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 log.Log(ZONE, "zonedrop.AddText:", record.Name, record.ID) } for d, _ := range Config { log.Log(ZONE, "Config entry:", d) } return &records }