-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
143 lines (127 loc) · 4.68 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"log"
"os"
"github.com/adrg/xdg"
"github.com/djotaku/dreamhostapi/v2"
"gopkg.in/natefinch/lumberjack.v2"
)
// credentials are the credentials needed to talk to the Dreamhost API
type credentials struct {
ApiKey string `json:"api_key"`
Domains []string
}
// conditionalLog will print a log to the console if logActive true
func conditionalLog(message string, logActive bool) {
if logActive {
log.Println(message)
}
}
// getHostIpAddress gets the outside IP address of the computer it's on
func getHostIpAddress(logActive bool) string {
ipAddress, _, err := dreamhostapi.WebGet("https://api.ipify.org")
if err != nil {
logMessage := fmt.Sprintf("Error getting IP address, cannot continue. Error: %s", err)
fmt.Println(logMessage)
conditionalLog(logMessage, logActive)
log.Fatal(logMessage)
}
return string(ipAddress)
}
func getSettings(fileLogger *log.Logger, verbose *bool) *credentials {
configFilePath, err := xdg.ConfigFile("dreamhostdns/settings.json")
if err != nil {
conditionalLog(err.Error(), *verbose)
fileLogger.Fatal(err)
}
fmt.Printf("Looking for settings.jon. The file should be at the following path: %s\n", configFilePath)
settingsJson, err := os.Open(configFilePath)
// if os.Open returns an error then handle it
if err != nil {
fmt.Println("Unable to open the config file. Did you place it in the right spot?")
conditionalLog(err.Error(), *verbose)
fileLogger.Fatal(err)
}
defer func(settingsJson *os.File) {
err := settingsJson.Close()
if err != nil {
errorString := fmt.Sprintf("Couldn't close the settings file. Error: %s", err)
conditionalLog(errorString, *verbose)
fileLogger.Fatal(errorString)
}
}(settingsJson)
byteValue, _ := io.ReadAll(settingsJson)
var settings *credentials
err = json.Unmarshal(byteValue, &settings)
if err != nil {
fmt.Println("Check that you do not have errors in your JSON file.")
errorString := fmt.Sprintf("Could not unmashal json: %s\n", err)
conditionalLog(errorString, *verbose)
fileLogger.Fatal(errorString)
}
return settings
}
func main() {
logFilePath, _ := xdg.DataFile("dreamhostdns/dnsupdates.log")
logFile, err := os.OpenFile(logFilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0775)
if err != nil {
log.Printf("Error %s\n", err)
}
fileLogger := log.New(logFile, "", log.LstdFlags)
fileLogger.SetOutput(&lumberjack.Logger{
Filename: logFilePath,
MaxSize: 1, // megabytes
MaxBackups: 3,
MaxAge: 28, //days
Compress: true, // disabled by default
})
fmt.Printf("Logs can be found at: %s\n", logFilePath)
fileLogger.Println("############ NEW SESSION ################")
// parse CLI flags
verbose := flag.Bool("v", false, "prints log output to the commandline.")
flag.Parse()
settings := getSettings(fileLogger, verbose)
newIPAddress := getHostIpAddress(*verbose)
fmt.Printf("IP address outside the NAT is: %s\n", newIPAddress)
fileLogger.Printf("IP address outsite the NAT is %s\n", newIPAddress)
fmt.Printf("Domains to update are: %s\n", settings.Domains)
dnsRecords, err := dreamhostapi.GetDNSRecords(settings.ApiKey)
if err != nil {
logMessage := fmt.Sprintf("Cannot continue without DNS records. Error: %s", err)
fmt.Println(logMessage)
conditionalLog(logMessage, *verbose)
log.Fatal(logMessage)
}
currentDNSValues := make(map[string]string)
for _, record := range dnsRecords.Data {
currentDNSValues[record.Record] = record.Value
}
successMessage := "The following domains successfully updated: "
for _, myDomain := range settings.Domains {
if currentDNSValues[myDomain] == newIPAddress {
logString := fmt.Sprintf("%s is already set to IP address: %s", myDomain, newIPAddress)
fileLogger.Println(logString)
conditionalLog(logString, *verbose)
} else {
logString := fmt.Sprintf("%s has an IP of %s. (If no value listed, this is a new domain.) Will attempt to change to %s (or add in the new domain)", myDomain, currentDNSValues[myDomain], newIPAddress)
fileLogger.Printf(logString)
conditionalLog(logString, *verbose)
addResult, deleteResult, err := dreamhostapi.UpdateDNSRecord(myDomain, currentDNSValues[myDomain], newIPAddress, settings.ApiKey, "")
updateResults := fmt.Sprintf("%s: addResult: %s, deleteResult: %s", myDomain, addResult.Result, deleteResult.Result)
conditionalLog(updateResults, *verbose)
fileLogger.Printf(updateResults)
if err != nil {
logMessage := fmt.Sprintf("An error occurred during DNS update. Add result: %s. Delete result: %s. Error: %s", addResult.Result, deleteResult.Result, err)
conditionalLog(logMessage, *verbose)
log.Println(logMessage)
} else {
successMessage += fmt.Sprintf("%s, ", myDomain)
}
}
}
fmt.Println(successMessage)
}