1
0

add support for multiple domains

This commit is contained in:
Sai Kiran Anagani 2017-11-12 19:16:49 +05:30
parent 057713b443
commit c3630e87f1
5 changed files with 83 additions and 32 deletions

0
.gitignore vendored Normal file → Executable file
View File

0
LICENSE.md Normal file → Executable file
View File

24
README.md Normal file → Executable file
View 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
View 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
View 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"
}
]
}
]
}