-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
116 lines (96 loc) · 3.22 KB
/
Copy pathmain.go
File metadata and controls
116 lines (96 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"github.com/cloudflare/cloudflare-go"
)
func main() {
cloudflareApiToken := getRequiredEnvironmentVariable("DDNS_CLOUDFLARE_API_TOKEN")
cloudflareZoneName := getRequiredEnvironmentVariable("DDNS_CLOUDFLARE_ZONE_NAME")
cloudflareDdnsSubdomain := getRequiredEnvironmentVariable("DDNS_CLOUDFLARE_SUBDOMAIN")
cloudflareDdnsComment := getRequiredEnvironmentVariable("DDNS_CLOUDFLARE_COMMENT")
publicIpEndpoint := getOptionalEnvironmentVariable("DDNS_PUBLIC_IP_ENDPOINT", "https://ipinfo.io/ip")
log.Print("Running Cloudflare DDNS with the following parameters:")
log.Printf("- API Token: REDACTED")
log.Printf("- Zone Name: %s", cloudflareZoneName)
log.Printf("- Subdomain: %s", cloudflareDdnsSubdomain)
log.Printf("- Comment: %s", cloudflareDdnsComment)
log.Printf("- Public IP Endpoint: %s", publicIpEndpoint)
api, err := cloudflare.NewWithAPIToken(cloudflareApiToken)
if err != nil {
log.Fatal(err)
}
zoneId, err := api.ZoneIDByName(cloudflareZoneName)
if err != nil {
log.Fatal(err)
}
publicIp := getPublicIp(publicIpEndpoint)
log.Printf("Current public IP address is: %s", publicIp)
log.Printf("Searching existing records...")
allRecords, _, err := api.ListDNSRecords(context.Background(), cloudflare.ZoneIdentifier(zoneId), cloudflare.ListDNSRecordsParams{
Type: "A",
Name: fmt.Sprintf("%s.%s", cloudflareDdnsSubdomain, cloudflareZoneName),
})
if err != nil {
log.Fatal(err)
}
if len(allRecords) > 1 {
log.Fatalf("Found multiple records for search A %s. Aborting.", cloudflareDdnsSubdomain)
} else if len(allRecords) == 1 {
currentRecord := allRecords[0]
log.Printf("Found existing record: %s %s -> %s. Will update...", currentRecord.Type, currentRecord.Name, currentRecord.Content)
record, err := api.UpdateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneId), cloudflare.UpdateDNSRecordParams{
ID: currentRecord.ID,
Type: "A",
Name: cloudflareDdnsSubdomain,
Content: publicIp,
Comment: &cloudflareDdnsComment,
})
if err != nil {
log.Fatal(err)
}
log.Printf("Sucessfully updated record: %s %s -> %s", record.Type, record.Name, record.Content)
} else {
log.Printf("Record doesn't exist yet. Will create...")
record, err := api.CreateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneId), cloudflare.CreateDNSRecordParams{
Type: "A",
Name: cloudflareDdnsSubdomain,
Content: publicIp,
Comment: cloudflareDdnsComment,
})
if err != nil {
log.Fatal(err)
}
log.Printf("Sucessfully created record: %s %s -> %s", record.Type, record.Name, record.Content)
}
}
func getPublicIp(endpoint string) string {
req, err := http.Get(endpoint)
if err != nil {
return err.Error()
}
defer req.Body.Close()
body, err := io.ReadAll(req.Body)
if err != nil {
return err.Error()
}
return string(body)
}
func getRequiredEnvironmentVariable(name string) string {
value := os.Getenv(name)
if len(value) == 0 {
log.Fatalf("Expected environment variable %s not found or not set.", name)
}
return value
}
func getOptionalEnvironmentVariable(name string, defaultValue string) string {
value := os.Getenv(name)
if len(value) == 0 {
value = defaultValue
}
return value
}