mirror of
https://github.com/AmanTahiliani/cloudflare-dns-updater.git
synced 2026-08-07 11:53:08 -04:00
Initial Commit
This commit is contained in:
184
dns.go
Normal file
184
dns.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type IpResponse struct {
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
|
||||
type DnsRecord struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Content string `json:"content"`
|
||||
Ttl int `json:"ttl"`
|
||||
Proxied bool `json:"proxied"`
|
||||
}
|
||||
|
||||
type DnsRecords struct {
|
||||
Result []DnsRecord `json:"result"`
|
||||
}
|
||||
|
||||
func getIp() (string, error) {
|
||||
// Get IP from ipify and return it as a IpResponse
|
||||
|
||||
ipUrl := "https://api.ipify.org?format=json"
|
||||
resp, err := http.Get(ipUrl)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var ipResponse IpResponse
|
||||
if err := json.Unmarshal(body, &ipResponse); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ipResponse.Ip, nil
|
||||
|
||||
}
|
||||
|
||||
type DnsUpdater struct {
|
||||
config *Config
|
||||
}
|
||||
|
||||
func (d *DnsUpdater) CheckIfRecordsExist(recordName string) (DnsRecord, error) {
|
||||
cloudFlareUrl := "https://api.cloudflare.com/client/v4/zones/" + d.config.ZoneID + "/dns_records?name=" + recordName + "&type=A"
|
||||
log.Printf("CloudFlare URL: %s", cloudFlareUrl)
|
||||
|
||||
req, err := http.NewRequest("GET", cloudFlareUrl, nil)
|
||||
if err != nil {
|
||||
return DnsRecord{}, err
|
||||
}
|
||||
req.Header.Set("X-Auth-Email", d.config.Email)
|
||||
req.Header.Set("Authorization", "Bearer "+d.config.AuthKey)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return DnsRecord{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return DnsRecord{}, err
|
||||
}
|
||||
|
||||
log.Printf("Body: %s", string(body))
|
||||
|
||||
var dnsRecords DnsRecords
|
||||
if err := json.Unmarshal(body, &dnsRecords); err != nil {
|
||||
return DnsRecord{}, err
|
||||
}
|
||||
log.Printf("DNS Records: %+v", dnsRecords)
|
||||
|
||||
// Check if the record exists
|
||||
for _, record := range dnsRecords.Result {
|
||||
if record.Name == recordName && record.Type == "A" {
|
||||
return record, nil
|
||||
}
|
||||
}
|
||||
return DnsRecord{}, nil
|
||||
}
|
||||
|
||||
func (d *DnsUpdater) Update(record DnsRecord) error {
|
||||
ip, err := getIp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.config.ForceIP != "" {
|
||||
ip = d.config.ForceIP
|
||||
}
|
||||
if record.Content == ip {
|
||||
return nil
|
||||
}
|
||||
|
||||
record.Content = ip
|
||||
record.Ttl = 3600
|
||||
|
||||
cloudFlareUrl := "https://api.cloudflare.com/client/v4/zones/" + d.config.ZoneID + "/dns_records/" + record.Id
|
||||
|
||||
body, err := json.Marshal(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("PATCH", cloudFlareUrl, bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("X-Auth-Email", d.config.Email)
|
||||
req.Header.Set("Authorization", "Bearer "+d.config.AuthKey)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return fmt.Errorf("failed to update DNS: %s", string(body))
|
||||
}
|
||||
log.Printf("Updated DNS: %s", string(body))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DnsUpdater) Create(recordName string) error {
|
||||
ip, err := getIp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.config.ForceIP != "" {
|
||||
ip = d.config.ForceIP
|
||||
}
|
||||
record := DnsRecord{
|
||||
Name: recordName,
|
||||
Type: "A",
|
||||
Content: ip,
|
||||
Ttl: 3600,
|
||||
Proxied: false,
|
||||
}
|
||||
|
||||
cloudFlareUrl := "https://api.cloudflare.com/client/v4/zones/" + d.config.ZoneID + "/dns_records"
|
||||
|
||||
body, err := json.Marshal(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", cloudFlareUrl, bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("X-Auth-Email", d.config.Email)
|
||||
req.Header.Set("Authorization", "Bearer "+d.config.AuthKey)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return fmt.Errorf("failed to create DNS: %s", string(body))
|
||||
}
|
||||
log.Printf("Created DNS: %s", string(body))
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user