inital commit
This commit is contained in:
commit
88d02078b3
2
.env
Normal file
2
.env
Normal file
@ -0,0 +1,2 @@
|
||||
DNS_ZONE=strolap.com
|
||||
HETZNER_API_TOKEN=JnSFwq4YNXxifbRZaBHv6vsgAaz5VFmR
|
||||
31
cron_log.log
Normal file
31
cron_log.log
Normal file
File diff suppressed because one or more lines are too long
10
env/env_file.go
vendored
Normal file
10
env/env_file.go
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
package env
|
||||
|
||||
import "github.com/gofor-little/env"
|
||||
|
||||
func LoadEnv() {
|
||||
err := env.Load(".env")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
16
env/read_envs.go
vendored
Normal file
16
env/read_envs.go
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ReadZones() []string {
|
||||
zoneEnv := os.Getenv("DNS_ZONE")
|
||||
if zoneEnv == "" {
|
||||
panic("DNS_ZONE not set")
|
||||
}
|
||||
|
||||
zones := strings.Split(zoneEnv, ",")
|
||||
return zones
|
||||
}
|
||||
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module DynDNS
|
||||
|
||||
go 1.21
|
||||
|
||||
require github.com/gofor-little/env v1.0.17 // indirect
|
||||
2
go.sum
Normal file
2
go.sum
Normal file
@ -0,0 +1,2 @@
|
||||
github.com/gofor-little/env v1.0.17 h1:TAB4jwL11nH59mg+4+6uycWY8Wc7MVe7Ip2uSmT0v0Q=
|
||||
github.com/gofor-little/env v1.0.17/go.mod h1:2BE2i6c9e/C6EaGnfhpqzfNERUqkzJ+s/ApnRyl+588=
|
||||
121
hetzner/api.go
Normal file
121
hetzner/api.go
Normal file
@ -0,0 +1,121 @@
|
||||
package hetzner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func SendGetZones(token string, names ...string) []string {
|
||||
client := &http.Client{}
|
||||
|
||||
var ids []string
|
||||
|
||||
for _, name := range names {
|
||||
fmt.Println("Getting zone: ", name)
|
||||
req, err := http.NewRequest("GET", "https://dns.hetzner.com/api/v1/zones?name="+name, nil)
|
||||
req.Header.Add("Auth-API-Token", token)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
respBody, _ := io.ReadAll(resp.Body)
|
||||
|
||||
fmt.Println("response Status : ", resp.Status)
|
||||
var responseObject struct {
|
||||
Zones []Zone
|
||||
}
|
||||
|
||||
err = json.Unmarshal(respBody, &responseObject)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ids = append(ids, responseObject.Zones[0].Id)
|
||||
}
|
||||
|
||||
return ids
|
||||
}
|
||||
|
||||
func SendGetRecords(token string, zoneId string) []Record {
|
||||
client := &http.Client{}
|
||||
|
||||
req, err := http.NewRequest("GET", "https://dns.hetzner.com/api/v1/records?zone_id="+zoneId, nil)
|
||||
req.Header.Add("Auth-API-Token", token)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
fmt.Println("Failure : ", err)
|
||||
}
|
||||
|
||||
respBody, _ := io.ReadAll(resp.Body)
|
||||
|
||||
fmt.Println("Response Status : ", resp.Status)
|
||||
|
||||
var responseObject struct {
|
||||
Records []Record
|
||||
}
|
||||
|
||||
err = json.Unmarshal(respBody, &responseObject)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Records: ", responseObject.Records)
|
||||
|
||||
return responseObject.Records
|
||||
}
|
||||
|
||||
func SendUpdateRecords(token string, records []Record) {
|
||||
client := &http.Client{}
|
||||
|
||||
var recordsReq struct {
|
||||
Records []Record `json:"records"`
|
||||
}
|
||||
|
||||
recordsReq.Records = records
|
||||
|
||||
jsonReq, err := json.Marshal(recordsReq)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Request: ", string(jsonReq))
|
||||
|
||||
req, err := http.NewRequest("PUT", "https://dns.hetzner.com/api/v1/records/bulk", bytes.NewBuffer(jsonReq))
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
req.Header.Add("Auth-API-Token", token)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
respBody, _ := ioutil.ReadAll(resp.Body)
|
||||
|
||||
fmt.Println("response Status: ", resp.Status)
|
||||
fmt.Println("response Body: ", string(respBody))
|
||||
|
||||
var responseObject struct {
|
||||
Records []Record `json:"records"`
|
||||
FailedRecords []Record `json:"failed_records"`
|
||||
}
|
||||
|
||||
err = json.Unmarshal(respBody, &responseObject)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(responseObject.FailedRecords) > 0 {
|
||||
fmt.Println("Failed records: ", responseObject.FailedRecords)
|
||||
panic("Failed to update records: " + string(respBody))
|
||||
}
|
||||
}
|
||||
14
hetzner/model.go
Normal file
14
hetzner/model.go
Normal file
@ -0,0 +1,14 @@
|
||||
package hetzner
|
||||
|
||||
type Zone = struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type Record = struct {
|
||||
Id string `json:"id"`
|
||||
ZoneId string `json:"zone_id"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
TTL int `json:"ttl"`
|
||||
}
|
||||
57
ip/ip.go
Normal file
57
ip/ip.go
Normal file
@ -0,0 +1,57 @@
|
||||
package ip
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func readIp() (string, error) {
|
||||
ip, err := _readIpFromIpify()
|
||||
if err == nil {
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
ip, err = _readIpFromIdentMe()
|
||||
if err == nil {
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("error getting IP from all services: %v", err)
|
||||
}
|
||||
|
||||
func _readIpFromIpify() (string, error) {
|
||||
fmt.Printf("Getting IP address from ipify ...\n")
|
||||
resp, err := http.Get("https://api.ipify.org?format=text")
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error getting IP from ipify: %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
ip, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading IP from ipify: %v", err)
|
||||
}
|
||||
|
||||
return string(ip), nil
|
||||
}
|
||||
|
||||
func _readIpFromIdentMe() (string, error) {
|
||||
fmt.Printf("Getting IP address from identme ...\n")
|
||||
resp, err := http.Get("https://4.ident.me")
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error getting IP from identme: %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
ip, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading IP from identme: %v", err)
|
||||
}
|
||||
|
||||
return string(ip), nil
|
||||
}
|
||||
57
publicIp/ip.go
Normal file
57
publicIp/ip.go
Normal file
@ -0,0 +1,57 @@
|
||||
package publicIp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func ReadIp() (string, error) {
|
||||
ip, err := _readIpFromIpify()
|
||||
if err == nil {
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
ip, err = _readIpFromIdentMe()
|
||||
if err == nil {
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("error getting IP from all services: %v", err)
|
||||
}
|
||||
|
||||
func _readIpFromIpify() (string, error) {
|
||||
fmt.Printf("Getting IP address from ipify ...\n")
|
||||
resp, err := http.Get("https://api.ipify.org?format=text")
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error getting IP from ipify: %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
ip, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading IP from ipify: %v", err)
|
||||
}
|
||||
|
||||
return string(ip), nil
|
||||
}
|
||||
|
||||
func _readIpFromIdentMe() (string, error) {
|
||||
fmt.Printf("Getting IP address from identme ...\n")
|
||||
resp, err := http.Get("https://4.ident.me")
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error getting IP from identme: %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
ip, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading IP from identme: %v", err)
|
||||
}
|
||||
|
||||
return string(ip), nil
|
||||
}
|
||||
41
service.go
Normal file
41
service.go
Normal file
@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"DynDNS/env"
|
||||
"DynDNS/hetzner"
|
||||
"DynDNS/publicIp"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
env.LoadEnv()
|
||||
|
||||
ip, err := publicIp.ReadIp()
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting IP: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("My IP is: %s\n", ip)
|
||||
|
||||
zoneNames := env.ReadZones()
|
||||
fmt.Printf("Zones: %v\n", zoneNames)
|
||||
|
||||
token := os.Getenv("HETZNER_API_TOKEN")
|
||||
zoneIds := hetzner.SendGetZones(token, zoneNames...)
|
||||
fmt.Printf("Zone IDs: %v\n", zoneIds)
|
||||
|
||||
for _, zoneId := range zoneIds {
|
||||
records := hetzner.SendGetRecords(token, zoneId)
|
||||
for i := range records {
|
||||
record := &records[i]
|
||||
if record.Type == "A" {
|
||||
fmt.Printf("Updating record: %s\n", record.Name)
|
||||
record.Value = ip
|
||||
}
|
||||
}
|
||||
|
||||
hetzner.SendUpdateRecords(token, records)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user