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 ## requirements
Requires Git and Go for building. 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 ## Usage
```bash ```bash
@ -15,11 +16,24 @@ create a file ".digitalocean-dynamic-ip.json"(dot prefix to hide the file) and p
```json ```json
{ {
"apikey": "samplekeydasjkdhaskjdhrwofihsamplekey", "apikey": "samplekeydasjkdhaskjdhrwofihsamplekey",
"domain": "example.com", "domains": [
"records": [
{ {
"name": "subdomain", "domain": "example.com",
"type": "A" "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) { func checkError(err error) {
if err != nil { if err != nil {
panic(err) log.Fatal(err)
} }
} }
// ClientConfig : configuration json // ClientConfig : configuration json
type ClientConfig struct { type ClientConfig struct {
APIKey string `json:"apiKey"` APIKey string `json:"apiKey"`
Domain string `json:"domain"` Domains []Domain `json:"domains"`
Record []DNSRecord `json:"records"` }
// Domain : domains to be changed
type Domain struct {
Domain string `json:"domain"`
Records []DNSRecord `json:"records"`
} }
// DNSRecord : Modifyiable DNS record // DNSRecord : Modifyiable DNS record
@ -37,7 +42,8 @@ type DOResponse struct {
DomainRecords []DNSRecord `json:"domain_records"` DomainRecords []DNSRecord `json:"domain_records"`
} }
func main() { //GetConfig : get configuration file ~/.digitalocean-dynamic-ip.json
func GetConfig() ClientConfig {
homeDirectory, err := homedir.Dir() homeDirectory, err := homedir.Dir()
checkError(err) checkError(err)
getfile, err := ioutil.ReadFile(homeDirectory + "/.digitalocean-dynamic-ip.json") getfile, err := ioutil.ReadFile(homeDirectory + "/.digitalocean-dynamic-ip.json")
@ -45,52 +51,70 @@ func main() {
var config ClientConfig var config ClientConfig
json.Unmarshal(getfile, &config) json.Unmarshal(getfile, &config)
checkError(err) 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") currentIPRequest, err := http.Get("https://diagnostic.opendns.com/myip")
checkError(err) checkError(err)
defer currentIPRequest.Body.Close() defer currentIPRequest.Body.Close()
currentIPRequestParse, err := ioutil.ReadAll(currentIPRequest.Body) currentIPRequestParse, err := ioutil.ReadAll(currentIPRequest.Body)
checkError(err) checkError(err)
currentIP := string(currentIPRequestParse) return string(currentIPRequestParse)
}
// get current dns record ip
//GetDomainRecords : Get DNS records of current domain.
func GetDomainRecords(apiKey string, domain string) DOResponse {
client := &http.Client{} client := &http.Client{}
request, err := http.NewRequest("GET", request, err := http.NewRequest("GET",
"https://api.digitalocean.com/v2/domains/"+string(config.Domain)+"/records", "https://api.digitalocean.com/v2/domains/"+domain+"/records",
nil) nil)
checkError(err) checkError(err)
request.Header.Add("Content-type", "Application/json") 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) response, err := client.Do(request)
checkError(err) checkError(err)
defer response.Body.Close() defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body) body, err := ioutil.ReadAll(response.Body)
var jsonResponse DOResponse var jsonDOResponse DOResponse
e := json.Unmarshal(body, &jsonResponse) e := json.Unmarshal(body, &jsonDOResponse)
checkError(e) checkError(e)
return jsonDOResponse
}
// update ip by matching dns records and config // UpdateRecords : Update DNS records of domain
func UpdateRecords(apiKey string, domain string, currentIP string, currentRecords DOResponse, toUpdateRecords []DNSRecord) {
for _, record := range jsonResponse.DomainRecords { for _, currentRecord := range currentRecords.DomainRecords {
for _, configRecord := range config.Record { for _, toUpdateRecord := range toUpdateRecords {
if configRecord.Name == record.Name && configRecord.Type == record.Type && currentIP != record.Data { if toUpdateRecord.Name == currentRecord.Name && toUpdateRecord.Type == currentRecord.Type && currentIP != currentRecord.Data {
update := []byte(`{"type":"` + configRecord.Type + `","data":"` + currentIP + `"}`) update := []byte(`{"type":"` + toUpdateRecord.Type + `","data":"` + currentIP + `"}`)
client := &http.Client{} client := &http.Client{}
request, err := http.NewRequest("PUT", 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)) bytes.NewBuffer(update))
checkError(err) checkError(err)
request.Header.Set("Content-Type", "application/json") 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) response, err := client.Do(request)
checkError(err) checkError(err)
defer response.Body.Close() defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body) 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", "apikey": "samplekeydasjkdhaskjdhrwofihsamplekey",
"domain": "example.com", "domains": [
"records": [
{ {
"name": "subdomain", "domain": "example.com",
"type": "A" "records": [
{
"name": "subdomainOrRecord",
"type": "A"
}
]
},
{
"domain": "example2.com",
"records": [
{
"name": "subdomainOrRecord2",
"type": "A"
}
]
} }
] ]
} }