Skip to content

Commit

Permalink
Merge pull request #2 from Artheriom/v2
Browse files Browse the repository at this point in the history
v2 for Scaleway DynDNS updater.
  • Loading branch information
Florian Forestier / Artheriom authored Oct 4, 2022
2 parents 8154f93 + a685f0b commit de2661b
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 138 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea/*
.idea
28 changes: 0 additions & 28 deletions bash/OnlineDynDNS.sh

This file was deleted.

7 changes: 0 additions & 7 deletions bash/README.md

This file was deleted.

19 changes: 19 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"github.com/Artheriom/ScalewayDynDNS/internal/connectors"
"github.com/Artheriom/ScalewayDynDNS/internal/helpers"
"github.com/sirupsen/logrus"
)

func main() {

ip, kind, err := connectors.GetIPAddress()
if err != nil {
logrus.Fatalln(err.Error())
}

for k, v := range helpers.Domains {
_ = connectors.UpdateScalewayDomain(k, v, ip, kind)
}
}
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/Artheriom/ScalewayDynDNS

go 1.19

require github.com/sirupsen/logrus v1.9.0

require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
15 changes: 15 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
6 changes: 0 additions & 6 deletions golang/README.md

This file was deleted.

94 changes: 0 additions & 94 deletions golang/main/main.go

This file was deleted.

39 changes: 39 additions & 0 deletions internal/connectors/get_ip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package connectors

import (
"errors"
"github.com/sirupsen/logrus"
"io"
"net/http"
"strings"
"time"
)

func GetIPAddress() (ip string, addressType string, err error) {
//Get IP on ifconfig.me
doConfigCall, _ := http.NewRequest("GET", "https://ifconfig.me", nil)
client := &http.Client{Timeout: time.Second * 20}

ipAnswer, err := client.Do(doConfigCall)
if err != nil {
logrus.Warnf("An error occurred while fetching IP from ifconfig.me: %s.", err.Error())
return
}
if ipAnswer.StatusCode != 200 {
logrus.Warnf("ifconfig.me returned invalid status code: %d.", ipAnswer.StatusCode)
return "", "", errors.New("invalid status code")
}

body, _ := io.ReadAll(ipAnswer.Body)
ip = string(body)

//Define addressType
addressType = "AAAA"
if len(strings.Split(ip, ".")) > 1 {
addressType = "A"
}

logrus.Infof("Detected IP for your home is %s (which will create and/or update %s records)", ip, addressType)

return
}
45 changes: 45 additions & 0 deletions internal/connectors/update_scaleway_domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package connectors

import (
"encoding/json"
"github.com/Artheriom/ScalewayDynDNS/internal/helpers"
"github.com/Artheriom/ScalewayDynDNS/internal/structures"
"github.com/sirupsen/logrus"
"net/http"
"strings"
"time"
)

func UpdateScalewayDomain(domainName string, subdomains []string, newIp string, ipKind string) (err error) {

logrus.Infof("Updating domain %s and its subdomains.", domainName)

//Building request to Scaleway API
var contentToSend []structures.Connect
var records []structures.Records

for _, k := range subdomains {
records = append(records, structures.Records{Name: k, Type: ipKind, Priority: 0, TTL: 3600, Data: newIp})
contentToSend = append(contentToSend, structures.Connect{Name: k, ChangeType: "REPLACE", Type: ipKind, Records: records})
records = []structures.Records{}
}

marshalled, _ := json.Marshal(contentToSend)

readyToSend := strings.NewReader(string(marshalled))
res2, _ := http.NewRequest("PATCH", "https://api.online.net/api/v1/domain/"+domainName+"/version/active", readyToSend)
res2.Header.Set("Authorization", "Bearer "+helpers.Key)

client := &http.Client{Timeout: time.Second * 20}

resp, err := client.Do(res2)
if err != nil {
logrus.Warnf("Error while trying to PATCH online DNS. Error was: %s", err.Error())
} else if resp.StatusCode != 204 {
logrus.Warnf("Server responded %d on PATCH for domain %s.", resp.StatusCode, domainName)
} else {
logrus.Infof("%s and its subdomains have been updated to new IP %s.", domainName, newIp)
}

return
}
46 changes: 46 additions & 0 deletions internal/helpers/configuration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package helpers

import (
"flag"
"github.com/sirupsen/logrus"
"log"
"os"
"strings"
)

var Domains = map[string][]string{}
var Key = ""

func init() {
logrus.Infof("Acquiring configuration...")
var onlineDomain string

flag.StringVar(&onlineDomain, "domain", "", "Define the domain or subdomain to update (eg github.com or example.github.com)")
flag.StringVar(&Key, "key", "", "Set the key for your Online API access")
flag.Parse()

if onlineDomain == "" {
// Try to get variable through environment
onlineDomain = os.Getenv("SCALEWAY_DYNDNS_DOMAIN")
if onlineDomain == "" {
log.Fatal("No domain given, abort")
}
}
if Key == "" {
// Try to get variable through environment
Key = os.Getenv("SCALEWAY_API_KEY")
if Key == "" {
log.Fatal("No API key given, abort")
}
}

// Explode domains through ";"
list := strings.Split(onlineDomain, ";")
for _, k := range list {
exploded := strings.Split(k, ".")
domain := exploded[len(exploded)-2] + "." + exploded[len(exploded)-1]
Domains[domain] = append(Domains[domain], k+".")
}

logrus.Infof("Configuration loaded.")
}
16 changes: 16 additions & 0 deletions internal/structures/structures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package structures

type Connect struct {
Name string `json:"name"`
Type string `json:"type"`
ChangeType string `json:"changeType"`
Records []Records `json:"records"`
}

type Records struct {
Name string `json:"name"`
Type string `json:"type"`
Priority int `json:"priority"`
TTL int `json:"ttl"`
Data string `json:"data"`
}
11 changes: 8 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

This little project offer tools to help people who want to set a DNS dynamically. For example, for people who are self-hosting their stuff at home.

You will find some implementations into the dedicated subfolders.

You are free to contribute, but please : Keep it Simple.
## How to use
1. Build the go program : `go build -o dyndns-scaleway ./cmd`, or take it from Release page.
2. Start the program with `domain` and `key` parameter.
* Example : `./dyndns-scaleway -domain "my.domain.that.i.want" -key "OnlineToken"`.
* You can use `SCALEWAY_DYNDNS_DOMAIN` and `SCALEWAY_API_KEY` environment variables to replace command-line arguments.
* You can specify multiple domains, BUT they must belong to the same user (because you can define only one API key). Simply separate each domain by a semicolon.
* Example : `SCALEWAY_DYNDNS_DOMAIN="my_subdomain.artheriom.fr;my_other_subdomain.artheriom.fr" ./dyndns-scaleway`
3. Use a crontab to call automatically the program on a regular basis

## Licence

Expand Down

0 comments on commit de2661b

Please sign in to comment.