-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
102 lines (84 loc) · 2.41 KB
/
main.go
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
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/route53"
)
func main() {
const cacheFilename = "dynroute53.cache"
domain := flag.String("domain", "", "fully qualified domain name to update, eg. blog.mydomain.com")
hostedZoneID := flag.String("hostedZoneID", "", "AWS hosted zone ID (user must have permissions")
verbose := flag.Bool("verbose", true, "If false logs only when the IP must be updated on AWS (cache miss). Defaulted to true.")
flag.Parse()
if *domain == "" || *hostedZoneID == "" {
fmt.Println("Domain and hostedZoneId must be set")
return
}
ip, err := getCurrentExternalIP()
if err != nil {
log.Println("Error while retrieving external IP", err)
return
}
bytes, err := ioutil.ReadFile(cacheFilename)
if err != nil {
log.Println("Error while reading cache for external IP", err)
}
cachedIP := string(bytes)
if cachedIP == ip {
if *verbose {
log.Printf("No need to update:\t%s -> %s (cached %s)\n", *domain, ip, cachedIP)
}
return
}
if err := updateAWSRoute53(*domain, *hostedZoneID, ip); err != nil {
log.Println("Error while updating route53 record", err)
return
}
if err := ioutil.WriteFile(cacheFilename, []byte(ip), os.ModePerm); err != nil {
log.Println("Error while updating local cache", err)
}
log.Printf("Update complete:\t%s -> %s\n", *domain, ip)
}
func getCurrentExternalIP() (string, error) {
r, err := http.Get("https://api.ipify.org")
if err != nil || r.StatusCode != 200 {
return "", err
}
bodyBytes, err := ioutil.ReadAll(r.Body)
return strings.TrimSpace(string(bodyBytes)), nil
}
func updateAWSRoute53(domain string, hostedZoneID string, ip string) error {
params := route53.ChangeResourceRecordSetsInput{
ChangeBatch: &route53.ChangeBatch{
Changes: []*route53.Change{
{
Action: aws.String("UPSERT"),
ResourceRecordSet: &route53.ResourceRecordSet{
Name: aws.String(domain),
Type: aws.String("A"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String(ip),
},
},
TTL: aws.Int64(300),
},
},
},
},
HostedZoneId: aws.String(hostedZoneID),
}
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String("eu-west-1"),
}))
svc := route53.New(sess)
_, err := svc.ChangeResourceRecordSets(¶ms)
return err
}