hello world
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
||||
const API_DOMAIN string = "https://api.porkbun.com"
|
||||
const ENDPOINT_GET string = "/api/json/v3/dns/retrieve/"
|
||||
const ENDPOINT_SET string = "/api/json/v3/dns/edit/"
|
||||
|
||||
// error helper
|
||||
func checkE(e error) {
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
|
||||
// http request helper
|
||||
func createBody(bodyMap map[string]string) io.Reader {
|
||||
bodyData, err := json.Marshal(bodyMap)
|
||||
checkE(err)
|
||||
body := string(bodyData)
|
||||
return strings.NewReader(body)
|
||||
}
|
||||
|
||||
// http response helper
|
||||
func readBody(res *http.Response) []byte {
|
||||
body, err := io.ReadAll(res.Body)
|
||||
res.Body.Close()
|
||||
if res.StatusCode > 299 {
|
||||
log.Fatalf("Response failed with status code: %d and\nbody: %s\n", res.StatusCode, body)
|
||||
}
|
||||
checkE(err)
|
||||
return body
|
||||
}
|
||||
|
||||
func syncDns(domain string, apiSecret string, apiKey string, serverIp string) bool {
|
||||
// construct endpoint url
|
||||
url := API_DOMAIN + ENDPOINT_GET + domain
|
||||
|
||||
// use api keys to construct request body for porkbun
|
||||
body := createBody(map[string]string{
|
||||
"secretapikey" : apiSecret,
|
||||
"apikey" : apiKey,
|
||||
})
|
||||
|
||||
// submit request for domain's DNS records
|
||||
res, err := http.Post(url, "application/json", body)
|
||||
checkE(err)
|
||||
|
||||
// parse records out from response body
|
||||
var bodyJson map[string]interface{}
|
||||
err = json.Unmarshal(readBody(res), &bodyJson)
|
||||
checkE(err)
|
||||
dnsRecords := bodyJson["records"].([]interface{})
|
||||
|
||||
// identify outdated A records
|
||||
aRecordsToUpdate := make(map[string]string)
|
||||
for i := range len(dnsRecords) {
|
||||
record := dnsRecords[i].(map[string]interface{})
|
||||
if record["type"].(string) != "A" { continue }
|
||||
if record["content"].(string) == serverIp { continue }
|
||||
aRecordsToUpdate[record["name"].(string)] = record["id"].(string)
|
||||
}
|
||||
|
||||
// we are potentially done now
|
||||
if len(aRecordsToUpdate) == 0 {
|
||||
fmt.Println(domain + " is up to date")
|
||||
return false
|
||||
}
|
||||
|
||||
// update each outdated A record
|
||||
for recordName, recordId := range aRecordsToUpdate {
|
||||
url = API_DOMAIN + ENDPOINT_SET + domain + "/" + recordId
|
||||
subdomain := strings.Split(recordName, ".")[0]
|
||||
body = createBody(map[string]string{
|
||||
"secretapikey" : apiSecret,
|
||||
"apikey" : apiKey,
|
||||
"content" : serverIp,
|
||||
"name" : subdomain,
|
||||
"type": "A",
|
||||
"ttl": "600",
|
||||
})
|
||||
|
||||
// make request to update A record
|
||||
res, err = http.Post(url, "application/json", body)
|
||||
checkE(err)
|
||||
fmt.Println("UPDATED " + recordName)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func main() {
|
||||
// open + deserialize env JSON
|
||||
envJson, err := os.ReadFile(".env")
|
||||
checkE(err)
|
||||
var env map[string]interface{}
|
||||
err = json.Unmarshal(envJson, &env)
|
||||
checkE(err)
|
||||
|
||||
// parse/organize api keys + domains to update
|
||||
apiSecret := env["secretapikey"].(string)
|
||||
apiKey := env["apikey"].(string)
|
||||
domains := env["domains"].([]interface{})
|
||||
|
||||
// determine server's current ip
|
||||
res, err := http.Get("https://api.ipify.org")
|
||||
checkE(err)
|
||||
ip := string(readBody(res))
|
||||
|
||||
fmt.Println("SERVER IP: " + ip)
|
||||
|
||||
// loop through all domains + update DNS records
|
||||
var domain string
|
||||
for i := range len(domains) {
|
||||
domain = domains[i].(string)
|
||||
fmt.Println("checking " + domain)
|
||||
syncDns(domain, apiSecret, apiKey, ip)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user