-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* implement hetzner api, service and config * improve logging in get records * fix map error in service * fix error when updating records * update readme * fix json in readme
- Loading branch information
1 parent
0e5ab92
commit 3405499
Showing
12 changed files
with
269 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package godaddy | ||
|
||
type GodaddyApiFake struct { | ||
DomainDetail DomainDetail | ||
ExistingRecords map[string][]DnsRecord | ||
Error error | ||
|
||
CreateRecordCalledWith DnsRecord | ||
UpdateRecordCalledWith DnsRecord | ||
} | ||
|
||
func (self *GodaddyApiFake) GetDomainDetail() (DomainDetail, error) { | ||
return self.DomainDetail, self.Error | ||
} | ||
|
||
func (self *GodaddyApiFake) GetRecords(host string) ([]DnsRecord, error) { | ||
return self.ExistingRecords[host], self.Error | ||
} | ||
|
||
func (self *GodaddyApiFake) CreateRecord(record DnsRecord) error { | ||
self.CreateRecordCalledWith = record | ||
return self.Error | ||
} | ||
|
||
func (self *GodaddyApiFake) UpdateRecord(record DnsRecord) error { | ||
self.UpdateRecordCalledWith = record | ||
return self.Error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package models | ||
package godaddy | ||
|
||
type DnsRecord struct { | ||
Data string `json:"data"` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package hetzner | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/leonlatsch/go-resolve/internal/http" | ||
"github.com/leonlatsch/go-resolve/internal/models" | ||
"github.com/leonlatsch/go-resolve/internal/serialization" | ||
) | ||
|
||
type HetznerApi interface { | ||
GetRecords() ([]Record, error) | ||
BulkUpdate(records []Record) error | ||
} | ||
|
||
type HetznerApiImpl struct { | ||
Config *models.Config | ||
HttpClient http.HttpClient | ||
} | ||
|
||
const BASE_URL = "https://dns.hetzner.com/api/v1" | ||
|
||
func (api *HetznerApiImpl) GetRecords() ([]Record, error) { | ||
var records []Record | ||
var recordsWrapper RecordsWrapper | ||
|
||
url := fmt.Sprintf("%v/records?zone_id=%v", BASE_URL, api.Config.HetznerConfig.ZoneId) | ||
recordsJson, err := api.HttpClient.Get(url, api.getHeaders()) | ||
|
||
if err != nil { | ||
return records, err | ||
} | ||
|
||
if err := serialization.FromJson(recordsJson, &recordsWrapper); err != nil { | ||
return records, err | ||
} | ||
|
||
return recordsWrapper.Records, nil | ||
} | ||
|
||
func (api *HetznerApiImpl) BulkUpdate(records []Record) error { | ||
recordsWrapper := RecordsWrapper{ | ||
Records: records, | ||
} | ||
|
||
url := fmt.Sprintf("%v/records/bulk", BASE_URL) | ||
|
||
if _, err := api.HttpClient.Put(url, api.getHeaders(), recordsWrapper); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (api *HetznerApiImpl) getHeaders() map[string]string { | ||
headers := make(map[string]string) | ||
headers["Auth-API-Token"] = api.Config.HetznerConfig.ApiToken | ||
return headers | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package hetzner | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"log" | ||
|
||
"github.com/leonlatsch/go-resolve/internal/models" | ||
"github.com/leonlatsch/go-resolve/internal/service" | ||
) | ||
|
||
type HetznerService struct { | ||
Config *models.Config | ||
HetznerApi HetznerApi | ||
IpObserverService service.IpObserverService | ||
|
||
RecordIds map[string]RecordId | ||
} | ||
|
||
func (service *HetznerService) PreloadRecordIds() error { | ||
recordIds := make(map[string]RecordId) | ||
|
||
records, err := service.HetznerApi.GetRecords() | ||
if err != nil { | ||
log.Println("Could not preload records ids. Please check your config") | ||
return err | ||
} | ||
|
||
for _, record := range records { | ||
for _, host := range service.Config.Hosts { | ||
if host == record.Name { | ||
log.Printf("Loaded record id %v for %v", record.Id, host) | ||
recordIds[host] = record.Id | ||
} | ||
} | ||
} | ||
|
||
if len(recordIds) <= 0 { | ||
return errors.New("Could not find configured records in dns entries") | ||
} | ||
|
||
service.RecordIds = recordIds | ||
return nil | ||
} | ||
|
||
func (service *HetznerService) ObserveAndUpdateDns() { | ||
log.Println("Running for hetzner") | ||
service.IpObserverService.ObserveIp(func(ip string) { | ||
service.UpdateDns(ip) | ||
}) | ||
} | ||
|
||
func (service *HetznerService) UpdateDns(ip string) { | ||
log.Println("Ip changed: " + ip) | ||
|
||
if len(service.RecordIds) <= 0 { | ||
log.Println("No records ids loaded. Not updating.") | ||
return | ||
} | ||
|
||
records := []Record{} | ||
for _, host := range service.Config.Hosts { | ||
record := Record{ | ||
Id: service.RecordIds[host], | ||
Value: ip, | ||
Type: "A", | ||
Name: host, | ||
ZoneId: ZoneId(service.Config.HetznerConfig.ZoneId), | ||
} | ||
records = append(records, record) | ||
} | ||
|
||
log.Println(fmt.Sprintf("Updating %v records for %v", len(records), service.Config.Domain)) | ||
if err := service.HetznerApi.BulkUpdate(records); err != nil { | ||
log.Println("Bulk update failed. Not caching ip") | ||
log.Println(err) | ||
return | ||
} | ||
|
||
log.Println("Successfully updated all records. Caching " + ip) | ||
service.IpObserverService.LastIp = ip | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package hetzner | ||
|
||
type ZoneId string | ||
type RecordId string | ||
|
||
type Record struct { | ||
Id RecordId `json:"id"` | ||
Value string `json:"value"` | ||
Type string `json:"type"` | ||
Name string `json:"name"` | ||
ZoneId ZoneId `json:"zone_id"` | ||
} | ||
|
||
type RecordsWrapper struct { | ||
Records []Record `json:"records"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.