refactoring

This commit is contained in:
Laurent Le Houerou 2020-10-26 13:36:59 +04:00
parent e780362dfb
commit 7903239e4f
10 changed files with 151 additions and 123 deletions

View File

@ -1,51 +0,0 @@
kind: pipeline
type: docker
name: staging
trigger:
branches:
- master
event:
- push
steps:
- name: test
image: golang:1.13.5
commands:
- go test ./...
- name: build
image: plugins/docker
settings:
username:
from_secret: dockerlogin
password:
from_secret: dockerpassword
repo: llehouerou/dnsupdater
tags: latest
---
kind: pipeline
type: ssh
name: deploy
server:
host:
from_secret: host
user:
from_secret: username
ssh_key:
from_secret: ssh_key
clone:
disable: true
steps:
- name: deploy
commands:
- cd /home/laurent/docker/
- docker-compose pull dnsupdater
- docker-compose up -d dnsupdater
depends_on:
- staging

View File

@ -4,13 +4,18 @@ import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
"regexp"
"time"
"gitlab.lehouerou.net/laurent/dnsupdater/internal/outboundip/ddwrt"
"gitlab.lehouerou.net/laurent/dnsupdater/internal/outboundip"
"gitlab.lehouerou.net/laurent/dnsupdater/internal/config"
"gitlab.lehouerou.net/laurent/dnsupdater/internal/dns/gandi"
"golang.org/x/xerrors"
"cdr.dev/slog"
@ -22,34 +27,8 @@ import (
"gopkg.in/gomail.v2"
)
type Configuration struct {
Username string `json:"name"`
Email string `json:"email"`
GandiKey string `json:"gandikey"`
Domains []string `json:"domains"`
RouterLogin string `json:"router_login"`
RouterPassword string `json:"router_password"`
RouterStatusUrl string `json:"router_status_url"`
WanIPRegex string `json:"wan_ip_regex"`
MailSettings *struct {
Sender string `json:"sender"`
To []string `json:"to"`
SmtpHost string `json:"smtp_host"`
SmtpLogin string `json:"smtp_login"`
SmtpPassword string `json:"smtp_password"`
SmtpPort int `json:"smtp_port"`
} `json:"mail_settings"`
}
type DnsResponse struct {
RecordType string `json:"rrset_type"`
Ttl int `json:"rrset_ttl"`
Name string `json:"rrset_name"`
Values []string `json:"rrset_values"`
}
var (
configuration Configuration
configuration config.Configuration
configPath string
base *sling.Sling
)
@ -91,7 +70,7 @@ func before(c *cli.Context) error {
}
defer file.Close()
decoder := json.NewDecoder(file)
configuration = Configuration{}
configuration = config.Configuration{}
err = decoder.Decode(&configuration)
if err != nil {
return err
@ -107,18 +86,23 @@ func before(c *cli.Context) error {
func start(*cli.Context) error {
ctx := context.Background()
if err := update(ctx); err != nil {
outboundIpRequester := ddwrt.NewIpRequester(configuration.RouterStatusUrl,
configuration.RouterLogin,
configuration.RouterPassword)
if err := update(ctx, outboundIpRequester); err != nil {
SendStatusMail(ctx, fmt.Sprintf("Error during update process : %s", err))
return err
}
return nil
}
func update(ctx context.Context) error {
newIp, err := GetOutboundIP()
if err != nil {
return fmt.Errorf("getting outbound ip: %v", err)
func update(ctx context.Context, requester outboundip.IpRequester) error {
newIpResult := <-requester.GetOutboundIp()
if newIpResult.Error != nil {
return fmt.Errorf("getting outbound ip: %v", newIpResult.Error)
}
newIp := newIpResult.Ip
updatedDomains := ""
for _, domain := range configuration.Domains {
@ -181,7 +165,7 @@ func GetCurrentIp(ctx context.Context, domain string) (string, error) {
err := try.Do(func(attempt int) (bool, error) {
var err error
value, err = func(domain string) (string, error) {
dnsresponse := DnsResponse{}
dnsresponse := gandi.DnsResponse{}
resp, err := base.New().Get(fmt.Sprintf(GandiARecordUrl, domain)).
ReceiveSuccess(&dnsresponse)
if err != nil {
@ -224,37 +208,3 @@ func SetCurrentIp(newip string, domain string) error {
}
return nil
}
func GetOutboundIP() (string, error) {
url := configuration.RouterStatusUrl
if url == "" {
url = "http://192.168.1.1/Status_Internet.live.asp"
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", fmt.Errorf("creating http request: %v", err)
}
if configuration.RouterLogin != "" && configuration.RouterPassword != "" {
req.SetBasicAuth(configuration.RouterLogin, configuration.RouterPassword)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return "", fmt.Errorf("executing http request: %v", err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", fmt.Errorf("reading response body: %v", err)
}
wanipregex := configuration.WanIPRegex
if wanipregex == "" {
wanipregex = "wan_ipaddr::([0-9.]*)}"
}
r := regexp.MustCompile(wanipregex)
matches := r.FindStringSubmatch(string(body))
if len(matches) < 2 {
return "", fmt.Errorf("unable to find WAN IP with regex %s in %s", wanipregex, string(body))
}
return matches[1], nil
}

View File

@ -1,4 +1,4 @@
#!bin/sh
#!/usr/bin/env sh
echo "Starting container ..."
echo "Setup check cron job with cron expression CHECK_CRON: ${CHECK_CRON}"

3
go.mod
View File

@ -1,4 +1,4 @@
module gogs.lehouerou.net/Laurent/dnsupdater
module gitlab.lehouerou.net/laurent/dnsupdater
go 1.13
@ -7,6 +7,7 @@ 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/pkg/errors v0.8.1
github.com/urfave/cli v1.20.0
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect

1
go.sum
View File

@ -103,6 +103,7 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

20
internal/config/config.go Normal file
View File

@ -0,0 +1,20 @@
package config
type Configuration struct {
Username string `json:"name"`
Email string `json:"email"`
GandiKey string `json:"gandikey"`
Domains []string `json:"domains"`
RouterLogin string `json:"router_login"`
RouterPassword string `json:"router_password"`
RouterStatusUrl string `json:"router_status_url"`
WanIPRegex string `json:"wan_ip_regex"`
MailSettings *struct {
Sender string `json:"sender"`
To []string `json:"to"`
SmtpHost string `json:"smtp_host"`
SmtpLogin string `json:"smtp_login"`
SmtpPassword string `json:"smtp_password"`
SmtpPort int `json:"smtp_port"`
} `json:"mail_settings"`
}

View File

@ -0,0 +1,8 @@
package gandi
type DnsResponse struct {
RecordType string `json:"rrset_type"`
Ttl int `json:"rrset_ttl"`
Name string `json:"rrset_name"`
Values []string `json:"rrset_values"`
}

View File

@ -0,0 +1,74 @@
package ddwrt
import (
"io/ioutil"
"net/http"
"regexp"
"github.com/pkg/errors"
"gitlab.lehouerou.net/laurent/dnsupdater/internal/outboundip"
)
const (
DefaultUrl = "http://192.168.1.1/Status_Internet.live.asp"
WanIpRegex = "wan_ipaddr::([0-9.]*)}"
)
type IpRequester struct {
statusUrl string
login string
password string
}
func NewIpRequester(statusUrl string, login string, password string) *IpRequester {
return &IpRequester{statusUrl: statusUrl, login: login, password: password}
}
func (r IpRequester) GetOutboundIp() <-chan outboundip.IpRequestResult {
result := make(chan outboundip.IpRequestResult)
go func() {
defer close(result)
url := r.statusUrl
if url == "" {
url = DefaultUrl
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
result <- outboundip.IpRequestResult{
Error: errors.Wrap(err, "creating http request"),
}
return
}
if r.login != "" && r.password != "" {
req.SetBasicAuth(r.login, r.password)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
result <- outboundip.IpRequestResult{
Error: errors.Wrap(err, "executing http request"),
}
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
result <- outboundip.IpRequestResult{
Error: errors.Wrap(err, "reading response body"),
}
return
}
matches := regexp.MustCompile(WanIpRegex).FindStringSubmatch(string(body))
if len(matches) < 2 {
result <- outboundip.IpRequestResult{
Error: errors.Errorf("unable to find WAN IP with regex %s in %s", WanIpRegex, string(body)),
}
return
}
result <- outboundip.IpRequestResult{Ip: matches[1]}
}()
return result
}

View File

@ -0,0 +1,15 @@
package ddwrt
import (
"fmt"
"testing"
)
func TestRequester_GetOutboundIp(t *testing.T) {
requester := NewIpRequester("", "laurent", "&951753seiko38613861")
result := <-requester.GetOutboundIp()
fmt.Printf("%+v\n", result)
if result.Error != nil {
t.Error(result.Error)
}
}

View File

@ -0,0 +1,10 @@
package outboundip
type IpRequestResult struct {
Ip string
Error error
}
type IpRequester interface {
GetOutboundIp() <-chan IpRequestResult
}