golang 1.13
use sling for gandi requests
This commit is contained in:
parent
8272d2d934
commit
41af5fb5cd
5
go.mod
5
go.mod
@ -1,10 +1,13 @@
|
|||||||
module gogs.lehouerou.net/Laurent/dnsupdater
|
module gogs.lehouerou.net/Laurent/dnsupdater
|
||||||
|
|
||||||
go 1.12
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 // indirect
|
||||||
|
github.com/dghubble/sling v1.3.0
|
||||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2
|
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2
|
||||||
github.com/sirupsen/logrus v1.4.2
|
github.com/sirupsen/logrus v1.4.2
|
||||||
github.com/urfave/cli v1.20.0
|
github.com/urfave/cli v1.20.0
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
)
|
)
|
||||||
|
6
go.sum
6
go.sum
@ -1,5 +1,11 @@
|
|||||||
|
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 h1:SKI1/fuSdodxmNNyVBR8d7X/HuLnRpvvFO0AgyQk764=
|
||||||
|
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dghubble/sling v1.3.0 h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU=
|
||||||
|
github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY=
|
||||||
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2 h1:JAEbJn3j/FrhdWA9jW8B5ajsLIjeuEHLi8xE4fk997o=
|
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2 h1:JAEbJn3j/FrhdWA9jW8B5ajsLIjeuEHLi8xE4fk997o=
|
||||||
|
119
main.go
119
main.go
@ -1,19 +1,20 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/matryer/try"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
"gopkg.in/gomail.v2"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/dghubble/sling"
|
||||||
|
"github.com/matryer/try"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
"gopkg.in/gomail.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Configuration struct {
|
type Configuration struct {
|
||||||
@ -43,12 +44,14 @@ type DnsResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configuration *Configuration
|
configuration Configuration
|
||||||
configPath string
|
configPath string
|
||||||
|
base *sling.Sling
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GandiARecordUrl = "https://dns.api.gandi.net/api/v5/domains/%s/records/@/A"
|
GandiApiUrl = "https://dns.api.gandi.net/api/v5/"
|
||||||
|
GandiARecordUrl = "domains/%s/records/@/A"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -83,15 +86,21 @@ func before(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
decoder := json.NewDecoder(file)
|
decoder := json.NewDecoder(file)
|
||||||
configuration = &Configuration{}
|
configuration = Configuration{}
|
||||||
err = decoder.Decode(configuration)
|
err = decoder.Decode(&configuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base = sling.New().Client(&http.Client{
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
}).Base(GandiApiUrl).
|
||||||
|
Set("X-Api-Key", configuration.GandiKey)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func start(c *cli.Context) error {
|
func start(*cli.Context) error {
|
||||||
if err := update(); err != nil {
|
if err := update(); err != nil {
|
||||||
SendStatusMail(fmt.Sprintf("Error during update process : %s", err))
|
SendStatusMail(fmt.Sprintf("Error during update process : %s", err))
|
||||||
return err
|
return err
|
||||||
@ -102,25 +111,25 @@ func start(c *cli.Context) error {
|
|||||||
func update() error {
|
func update() error {
|
||||||
newIp, err := GetOutboundIP()
|
newIp, err := GetOutboundIP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("getting outbound ip: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedDomains := ""
|
updatedDomains := ""
|
||||||
for _, domain := range configuration.Domains {
|
for _, domain := range configuration.Domains {
|
||||||
currentIp, err := GetCurrentIp(*configuration, domain)
|
currentIp, err := GetCurrentIp(domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("getting current ip: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentIp == newIp {
|
if currentIp == newIp {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infoln(fmt.Sprintf("%s -> Ip has changed %s -> %s", domain, currentIp, newIp))
|
log.Infof(fmt.Sprintf("%s -> Ip has changed %s -> %s", domain, currentIp, newIp))
|
||||||
|
|
||||||
err = SetCurrentIp(newIp, domain, *configuration)
|
err = SetCurrentIp(newIp, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("setting current ip: %v", err)
|
||||||
}
|
}
|
||||||
updatedDomains += fmt.Sprintf("\t- %s\n", domain)
|
updatedDomains += fmt.Sprintf("\t- %s\n", domain)
|
||||||
}
|
}
|
||||||
@ -138,14 +147,14 @@ func SendStatusMail(messageText string) {
|
|||||||
|
|
||||||
settings := configuration.MailSettings
|
settings := configuration.MailSettings
|
||||||
if settings == nil {
|
if settings == nil {
|
||||||
log.Warnln("no smtp settings defined > status mail not sent")
|
log.Warnf("no smtp settings defined > status mail not sent")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
d := gomail.NewDialer(settings.SmtpHost, settings.SmtpPort, settings.SmtpLogin, settings.SmtpPassword)
|
d := gomail.NewDialer(settings.SmtpHost, settings.SmtpPort, settings.SmtpLogin, settings.SmtpPassword)
|
||||||
s, err := d.Dial()
|
s, err := d.Dial()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(fmt.Sprintf("error while dialing smtp server : %v", err))
|
log.Errorf(fmt.Sprintf("error while dialing smtp server : %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,38 +166,31 @@ func SendStatusMail(messageText string) {
|
|||||||
m.SetBody("text/plain", messageText)
|
m.SetBody("text/plain", messageText)
|
||||||
|
|
||||||
if err := gomail.Send(s, m); err != nil {
|
if err := gomail.Send(s, m); err != nil {
|
||||||
log.Warnln(fmt.Sprintf("could not send email to %q: %v", r, err))
|
log.Warnf(fmt.Sprintf("could not send email to %q: %v", r, err))
|
||||||
}
|
}
|
||||||
m.Reset()
|
m.Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCurrentIp(configuration Configuration, domain string) (string, error) {
|
func GetCurrentIp(domain string) (string, error) {
|
||||||
var value string
|
var value string
|
||||||
err := try.Do(func(attempt int) (bool, error) {
|
err := try.Do(func(attempt int) (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
value, err = func(configuration Configuration, domain string) (string, error) {
|
value, err = func(domain string) (string, error) {
|
||||||
url := fmt.Sprintf(GandiARecordUrl, domain)
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
req.Header.Set("X-Api-Key", configuration.GandiKey)
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
decoder := json.NewDecoder(resp.Body)
|
|
||||||
dnsresponse := DnsResponse{}
|
dnsresponse := DnsResponse{}
|
||||||
err = decoder.Decode(&dnsresponse)
|
resp, err := base.New().Get(fmt.Sprintf(GandiARecordUrl, domain)).
|
||||||
|
ReceiveSuccess(&dnsresponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("requesting gandi dns info: %v", err)
|
||||||
|
}
|
||||||
|
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||||
|
return "", fmt.Errorf("requesting gandi dns info, no 2xx http status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
if len(dnsresponse.Values) == 0 {
|
||||||
|
return "", fmt.Errorf("no values in dnsresponse")
|
||||||
}
|
}
|
||||||
return dnsresponse.Values[0], nil
|
return dnsresponse.Values[0], nil
|
||||||
}(configuration, domain)
|
}(domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnln(fmt.Sprintf("Error while getting current ip from gandi : %v", err))
|
log.Warnln(fmt.Sprintf("Error while getting current ip from gandi : %v", err))
|
||||||
time.Sleep(30 * time.Second)
|
time.Sleep(30 * time.Second)
|
||||||
@ -201,31 +203,21 @@ func GetCurrentIp(configuration Configuration, domain string) (string, error) {
|
|||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetCurrentIp(newip string, domain string, configuration Configuration) error {
|
func SetCurrentIp(newip string, domain string) error {
|
||||||
url := fmt.Sprintf(GandiARecordUrl, domain)
|
resp, err := base.New().Put(fmt.Sprintf(GandiARecordUrl, domain)).
|
||||||
log.Infoln("URL:>", url)
|
BodyJSON(struct {
|
||||||
|
TTL int `json:"rrset_ttl"`
|
||||||
var str = fmt.Sprintf("{\"rrset_ttl\": %d,\"rrset_values\": [\"%s\"]}", 600, newip)
|
Values []string `json:"rrset_values"`
|
||||||
log.Infoln("json:", str)
|
}{
|
||||||
var jsonStr = []byte(str)
|
TTL: 600,
|
||||||
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonStr))
|
Values: []string{newip},
|
||||||
|
}).ReceiveSuccess(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("setting gandi dns info: %v", err)
|
||||||
}
|
}
|
||||||
req.Header.Set("X-Api-Key", configuration.GandiKey)
|
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||||
req.Header.Set("Content-Type", "application/json")
|
return fmt.Errorf("setting gandi dns info, no 2xx http status code: %d", resp.StatusCode)
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
log.Debugln("response Status:", resp.Status)
|
|
||||||
log.Debugln("response Headers:", resp.Header)
|
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
log.Debugln("response Body:", string(body))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,22 +228,21 @@ func GetOutboundIP() (string, error) {
|
|||||||
}
|
}
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("creating http request: %v", err)
|
||||||
}
|
}
|
||||||
if configuration.RouterLogin != "" && configuration.RouterPassword != "" {
|
if configuration.RouterLogin != "" && configuration.RouterPassword != "" {
|
||||||
req.SetBasicAuth(configuration.RouterLogin, configuration.RouterPassword)
|
req.SetBasicAuth(configuration.RouterLogin, configuration.RouterPassword)
|
||||||
}
|
}
|
||||||
res, err := http.DefaultClient.Do(req)
|
res, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("executing http request: %v", err)
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("reading response body: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugln(string(body))
|
|
||||||
wanipregex := configuration.WanIPRegex
|
wanipregex := configuration.WanIPRegex
|
||||||
if wanipregex == "" {
|
if wanipregex == "" {
|
||||||
wanipregex = "wan_ipaddr::([0-9.]*)}"
|
wanipregex = "wan_ipaddr::([0-9.]*)}"
|
||||||
|
Loading…
Reference in New Issue
Block a user