add support for multiple domains
This commit is contained in:
parent
057713b443
commit
c3630e87f1
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
0
LICENSE.md
Normal file → Executable file
0
LICENSE.md
Normal file → Executable file
24
README.md
Normal file → Executable file
24
README.md
Normal file → Executable file
@ -4,7 +4,8 @@ A simple script in Go language to automatically update Digital ocean DNS records
|
||||
## requirements
|
||||
Requires Git and Go for building.
|
||||
|
||||
Requires that the record already exists in DigitalOcean's DNS.
|
||||
Requires that the record already exists in DigitalOcean's DNS so that it can be updated.
|
||||
(manually find your IP and add it to DO's DNS it will later be updated)
|
||||
|
||||
## Usage
|
||||
```bash
|
||||
@ -15,11 +16,24 @@ create a file ".digitalocean-dynamic-ip.json"(dot prefix to hide the file) and p
|
||||
```json
|
||||
{
|
||||
"apikey": "samplekeydasjkdhaskjdhrwofihsamplekey",
|
||||
"domain": "example.com",
|
||||
"records": [
|
||||
"domains": [
|
||||
{
|
||||
"name": "subdomain",
|
||||
"type": "A"
|
||||
"domain": "example.com",
|
||||
"records": [
|
||||
{
|
||||
"name": "subdomainOrRecord",
|
||||
"type": "A"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"domain": "example2.com",
|
||||
"records": [
|
||||
{
|
||||
"name": "subdomainOrRecord2",
|
||||
"type": "A"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
70
digitalocean-dynamic-ip.go
Normal file → Executable file
70
digitalocean-dynamic-ip.go
Normal file → Executable file
@ -13,15 +13,20 @@ import (
|
||||
|
||||
func checkError(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// ClientConfig : configuration json
|
||||
type ClientConfig struct {
|
||||
APIKey string `json:"apiKey"`
|
||||
Domain string `json:"domain"`
|
||||
Record []DNSRecord `json:"records"`
|
||||
APIKey string `json:"apiKey"`
|
||||
Domains []Domain `json:"domains"`
|
||||
}
|
||||
|
||||
// Domain : domains to be changed
|
||||
type Domain struct {
|
||||
Domain string `json:"domain"`
|
||||
Records []DNSRecord `json:"records"`
|
||||
}
|
||||
|
||||
// DNSRecord : Modifyiable DNS record
|
||||
@ -37,7 +42,8 @@ type DOResponse struct {
|
||||
DomainRecords []DNSRecord `json:"domain_records"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
//GetConfig : get configuration file ~/.digitalocean-dynamic-ip.json
|
||||
func GetConfig() ClientConfig {
|
||||
homeDirectory, err := homedir.Dir()
|
||||
checkError(err)
|
||||
getfile, err := ioutil.ReadFile(homeDirectory + "/.digitalocean-dynamic-ip.json")
|
||||
@ -45,52 +51,70 @@ func main() {
|
||||
var config ClientConfig
|
||||
json.Unmarshal(getfile, &config)
|
||||
checkError(err)
|
||||
return config
|
||||
}
|
||||
|
||||
// check current local ip
|
||||
|
||||
//CheckLocalIP : get current IP of server.
|
||||
func CheckLocalIP() string {
|
||||
currentIPRequest, err := http.Get("https://diagnostic.opendns.com/myip")
|
||||
checkError(err)
|
||||
defer currentIPRequest.Body.Close()
|
||||
currentIPRequestParse, err := ioutil.ReadAll(currentIPRequest.Body)
|
||||
checkError(err)
|
||||
currentIP := string(currentIPRequestParse)
|
||||
|
||||
// get current dns record ip
|
||||
return string(currentIPRequestParse)
|
||||
}
|
||||
|
||||
//GetDomainRecords : Get DNS records of current domain.
|
||||
func GetDomainRecords(apiKey string, domain string) DOResponse {
|
||||
client := &http.Client{}
|
||||
request, err := http.NewRequest("GET",
|
||||
"https://api.digitalocean.com/v2/domains/"+string(config.Domain)+"/records",
|
||||
"https://api.digitalocean.com/v2/domains/"+domain+"/records",
|
||||
nil)
|
||||
checkError(err)
|
||||
request.Header.Add("Content-type", "Application/json")
|
||||
request.Header.Add("Authorization", "Bearer "+string(config.APIKey))
|
||||
request.Header.Add("Authorization", "Bearer "+apiKey)
|
||||
response, err := client.Do(request)
|
||||
checkError(err)
|
||||
defer response.Body.Close()
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
var jsonResponse DOResponse
|
||||
e := json.Unmarshal(body, &jsonResponse)
|
||||
var jsonDOResponse DOResponse
|
||||
e := json.Unmarshal(body, &jsonDOResponse)
|
||||
checkError(e)
|
||||
return jsonDOResponse
|
||||
}
|
||||
|
||||
// update ip by matching dns records and config
|
||||
|
||||
for _, record := range jsonResponse.DomainRecords {
|
||||
for _, configRecord := range config.Record {
|
||||
if configRecord.Name == record.Name && configRecord.Type == record.Type && currentIP != record.Data {
|
||||
update := []byte(`{"type":"` + configRecord.Type + `","data":"` + currentIP + `"}`)
|
||||
// UpdateRecords : Update DNS records of domain
|
||||
func UpdateRecords(apiKey string, domain string, currentIP string, currentRecords DOResponse, toUpdateRecords []DNSRecord) {
|
||||
for _, currentRecord := range currentRecords.DomainRecords {
|
||||
for _, toUpdateRecord := range toUpdateRecords {
|
||||
if toUpdateRecord.Name == currentRecord.Name && toUpdateRecord.Type == currentRecord.Type && currentIP != currentRecord.Data {
|
||||
update := []byte(`{"type":"` + toUpdateRecord.Type + `","data":"` + currentIP + `"}`)
|
||||
client := &http.Client{}
|
||||
request, err := http.NewRequest("PUT",
|
||||
"https://api.digitalocean.com/v2/domains/"+string(config.Domain)+"/records/"+strconv.FormatInt(int64(record.ID), 10),
|
||||
"https://api.digitalocean.com/v2/domains/"+domain+"/records/"+strconv.FormatInt(int64(currentRecord.ID), 10),
|
||||
bytes.NewBuffer(update))
|
||||
checkError(err)
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
request.Header.Add("Authorization", "Bearer "+string(config.APIKey))
|
||||
request.Header.Add("Authorization", "Bearer "+apiKey)
|
||||
response, err := client.Do(request)
|
||||
checkError(err)
|
||||
defer response.Body.Close()
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
log.Printf("DO update response for %s: %s", record.Name, string(body))
|
||||
log.Printf("DO update response for %s: %s\n", currentRecord.Name, string(body))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
config := GetConfig()
|
||||
currentIP := CheckLocalIP()
|
||||
|
||||
for _, domains := range config.Domains {
|
||||
domainName := domains.Domain
|
||||
apiKey := config.APIKey
|
||||
currentDomainRecords := GetDomainRecords(apiKey, domainName)
|
||||
log.Println(domainName)
|
||||
UpdateRecords(apiKey, domainName, currentIP, currentDomainRecords, domains.Records)
|
||||
}
|
||||
}
|
||||
|
21
digitalocean-dynamic-ip.sample.json
Normal file → Executable file
21
digitalocean-dynamic-ip.sample.json
Normal file → Executable file
@ -1,10 +1,23 @@
|
||||
{
|
||||
"apikey": "samplekeydasjkdhaskjdhrwofihsamplekey",
|
||||
"domain": "example.com",
|
||||
"records": [
|
||||
"domains": [
|
||||
{
|
||||
"name": "subdomain",
|
||||
"type": "A"
|
||||
"domain": "example.com",
|
||||
"records": [
|
||||
{
|
||||
"name": "subdomainOrRecord",
|
||||
"type": "A"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"domain": "example2.com",
|
||||
"records": [
|
||||
{
|
||||
"name": "subdomainOrRecord2",
|
||||
"type": "A"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user