summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2020-01-04 06:39:30 +0000
committerMike Crute <mike@crute.us>2020-08-11 02:56:10 +0000
commita810417e580890028cf725f6a71d43dbc5c02235 (patch)
tree863ea8743a94c816664ebbecc9e9a68387e2ed7a
parent8ed9671c0b4f78711858448cf3b4ee9af0eba51e (diff)
downloadgo_ddns_manager-a810417e580890028cf725f6a71d43dbc5c02235.tar.bz2
go_ddns_manager-a810417e580890028cf725f6a71d43dbc5c02235.tar.xz
go_ddns_manager-a810417e580890028cf725f6a71d43dbc5c02235.zip
Refator using le utils
-rw-r--r--Makefile4
-rw-r--r--go.mod1
-rw-r--r--go.sum10
-rw-r--r--main.go52
-rw-r--r--util/file.go19
-rw-r--r--util/gin.go (renamed from web/utils.go)61
-rw-r--r--util/http.go26
-rw-r--r--util/ip.go24
-rw-r--r--util/viper.go36
-rw-r--r--web/controllers/acme.go4
-rw-r--r--web/controllers/ddns.go4
-rw-r--r--web/controllers/reflect_ip.go4
12 files changed, 148 insertions, 97 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..0ea2c0d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,4 @@
1GO_FILES := $(shell find . -name '*.go')
2
3dns-service: main.go $(GO_FILES)
4 go build -o $@ $<
diff --git a/go.mod b/go.mod
index 53f7ef2..ccee475 100644
--- a/go.mod
+++ b/go.mod
@@ -6,5 +6,6 @@ require (
6 github.com/gin-gonic/gin v1.5.0 6 github.com/gin-gonic/gin v1.5.0
7 github.com/miekg/dns v1.1.26 7 github.com/miekg/dns v1.1.26
8 github.com/spf13/cobra v0.0.5 8 github.com/spf13/cobra v0.0.5
9 github.com/spf13/viper v1.3.2
9 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect 10 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
10) 11)
diff --git a/go.sum b/go.sum
index a6a4091..ca97a18 100644
--- a/go.sum
+++ b/go.sum
@@ -7,6 +7,7 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
7github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 8github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
9github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 9github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
10github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 11github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
11github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 12github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
12github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 13github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
@@ -19,34 +20,42 @@ github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEK
19github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= 20github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
20github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 21github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
21github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 22github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
23github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
22github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 24github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
23github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 25github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
24github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= 26github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
25github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 27github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
26github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= 28github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
27github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= 29github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
30github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
28github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 31github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
29github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= 32github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
30github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 33github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
31github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= 34github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU=
32github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= 35github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
33github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 36github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
37github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
34github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 38github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
35github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 39github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
36github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 40github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
37github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 41github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
38github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 42github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
43github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
39github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 44github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
40github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 45github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
41github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 46github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
42github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 47github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
48github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
43github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 49github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
50github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
44github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 51github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
45github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= 52github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
46github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= 53github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
54github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
47github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 55github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
48github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= 56github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
49github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 57github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
58github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
50github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= 59github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
51github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 60github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
52github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 61github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -76,6 +85,7 @@ golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7w
76golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M= 85golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M=
77golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 86golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
78golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 87golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
88golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
79golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 89golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
80golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 90golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
81golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 91golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/main.go b/main.go
index 367814d..e657062 100644
--- a/main.go
+++ b/main.go
@@ -1,44 +1,19 @@
1package main 1package main
2 2
3import ( 3import (
4 "fmt"
5 "log" 4 "log"
6 "os" 5 "os"
7 "strconv"
8 6
9 "github.com/gin-gonic/gin" 7 "github.com/gin-gonic/gin"
10 "github.com/spf13/cobra" 8 "github.com/spf13/cobra"
9 "github.com/spf13/viper"
11 10
11 "code.crute.me/mcrute/go_ddns_manager/util"
12 "code.crute.me/mcrute/go_ddns_manager/web" 12 "code.crute.me/mcrute/go_ddns_manager/web"
13 "code.crute.me/mcrute/go_ddns_manager/web/controllers" 13 "code.crute.me/mcrute/go_ddns_manager/web/controllers"
14 "code.crute.me/mcrute/go_ddns_manager/web/middleware" 14 "code.crute.me/mcrute/go_ddns_manager/web/middleware"
15) 15)
16 16
17// TODO: use from a common package
18func MustGetString(c *cobra.Command, k string) string {
19 f := c.Flags().Lookup(k)
20 if f == nil {
21 panic(fmt.Errorf("No flag named %s", k))
22 }
23
24 return f.Value.String()
25}
26
27// TODO: use from a common package
28func MustGetBool(c *cobra.Command, k string) bool {
29 f := c.Flags().Lookup(k)
30 if f == nil {
31 panic(fmt.Errorf("No flag named %s", k))
32 }
33
34 t, err := strconv.ParseBool(f.Value.String())
35 if err != nil {
36 panic(err)
37 }
38
39 return t
40}
41
42func makeServer(cfg *web.ServerConfig) *gin.Engine { 17func makeServer(cfg *web.ServerConfig) *gin.Engine {
43 router := gin.Default() 18 router := gin.Default()
44 router.Use(middleware.ConfigContextMiddleware(cfg)) 19 router.Use(middleware.ConfigContextMiddleware(cfg))
@@ -68,9 +43,9 @@ func main() {
68 Args: cobra.MinimumNArgs(1), 43 Args: cobra.MinimumNArgs(1),
69 Run: func(cmd *cobra.Command, args []string) { 44 Run: func(cmd *cobra.Command, args []string) {
70 cfg, err := web.LoadServerConfig( 45 cfg, err := web.LoadServerConfig(
71 MustGetString(cmd, "zones-config"), 46 viper.GetString("zones-config"),
72 MustGetString(cmd, "auth-config"), 47 viper.GetString("auth-config"),
73 MustGetString(cmd, "view-name"), 48 viper.GetString("view-name"),
74 args[0], 49 args[0],
75 ) 50 )
76 if err != nil { 51 if err != nil {
@@ -78,18 +53,19 @@ func main() {
78 os.Exit(1) 53 os.Exit(1)
79 } 54 }
80 55
81 web.GinRun( 56 util.GinRun(
82 makeServer(cfg), 57 makeServer(cfg),
83 MustGetBool(cmd, "debug"), 58 viper.GetBool("debug"),
84 MustGetString(cmd, "listen")) 59 viper.GetString("listen"))
85 }, 60 },
86 } 61 }
87 62
88 cmd.Flags().StringP("zones-config", "z", "cfg/zones.conf", "Bind key and zones config file") 63 util.WrapViper(cmd, "DNS_MANAGE").
89 cmd.Flags().StringP("auth-config", "a", "cfg/server_auth.json", "Server auth configuration file") 64 BindString("zones-config", "z", "cfg/zones.conf", "Bind key and zones config file").
90 cmd.Flags().StringP("view-name", "n", "external", "Name of view to update for ACME and DDNS") 65 BindString("auth-config", "a", "cfg/server_auth.json", "Server auth configuration file").
91 cmd.Flags().StringP("listen", "l", ":9090", "Listen address and port") 66 BindString("view-name", "n", "external", "Name of view to update for ACME and DDNS").
92 cmd.Flags().BoolP("debug", "d", false, "Run server in debug mode with debug logs") 67 BindString("listen", "l", ":9090", "Listen address and port").
68 BindBool("debug", "d", false, "Run server in debug mode with debug logs")
93 69
94 if err := cmd.Execute(); err != nil { 70 if err := cmd.Execute(); err != nil {
95 log.Println(err) 71 log.Println(err)
diff --git a/util/file.go b/util/file.go
new file mode 100644
index 0000000..b6fc86f
--- /dev/null
+++ b/util/file.go
@@ -0,0 +1,19 @@
1package util
2
3import (
4 "io"
5 "io/ioutil"
6)
7
8func WriteReaderToFile(filename string, data io.Reader) error {
9 d, err := ioutil.ReadAll(data)
10 if err != nil {
11 return err
12 }
13
14 if err = ioutil.WriteFile(filename, d, 0644); err != nil {
15 return err
16 }
17
18 return nil
19}
diff --git a/web/utils.go b/util/gin.go
index 5467132..9bba6ee 100644
--- a/web/utils.go
+++ b/util/gin.go
@@ -1,67 +1,16 @@
1package web 1package util
2 2
3import ( 3import (
4 "context" 4 "context"
5 "fmt"
6 "log" 5 "log"
7 "net" 6 "net"
8 "net/http" 7 "net/http"
9 "net/url"
10 "os" 8 "os"
11 "os/signal" 9 "os/signal"
12 "regexp"
13 10
14 "github.com/gin-gonic/gin" 11 "github.com/gin-gonic/gin"
15) 12)
16 13
17// Parses an IPv4 or IPv6 address with an optional port on the end. Returns
18// match groups for the addresses. The first match is the IPv6 address and the
19// second the IPv4 address.
20var ipRegexp = regexp.MustCompile(`(?:\[([0-9a-f:]+)\]|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))(?::\d+)?`)
21
22// TODO: use from a common package
23func ParseIP(s string) net.IP {
24 ips := ipRegexp.FindStringSubmatch(s)
25 if ips == nil {
26 return nil
27 }
28
29 if v6, v4 := ips[1], ips[2]; v6 != "" {
30 return net.ParseIP(v6)
31 } else {
32 return net.ParseIP(v4)
33 }
34}
35
36// TODO: use from a common package
37func GetRequestIP(c *gin.Context) net.IP {
38 if xff := c.Request.Header.Get("X-Forwarded-For"); xff != "" {
39 return ParseIP(xff)
40 }
41 return ParseIP(c.Request.RemoteAddr)
42}
43
44// TODO: use from a common package
45func MakeURL(r *http.Request, path string, subs ...interface{}) *url.URL {
46 scheme := "https"
47 if r.TLS == nil {
48 scheme = "http"
49 }
50
51 // Always defer to whatever the proxy told us it was doing because this
52 // could be a mullet-VIP in either direction.
53 if fwProto := r.Header.Get("X-Forwarded-Proto"); fwProto != "" {
54 scheme = fwProto
55 }
56
57 return &url.URL{
58 Scheme: scheme,
59 Host: r.Host,
60 Path: fmt.Sprintf(path, subs...),
61 }
62}
63
64// TODO: use from a common package
65// Copied from: https://github.com/gin-gonic/gin/blob/59ab588bf597f9f41faee4f217b5659893c2e925/utils.go#L137 14// Copied from: https://github.com/gin-gonic/gin/blob/59ab588bf597f9f41faee4f217b5659893c2e925/utils.go#L137
66func resolveAddress(addr []string) string { 15func resolveAddress(addr []string) string {
67 switch len(addr) { 16 switch len(addr) {
@@ -79,7 +28,6 @@ func resolveAddress(addr []string) string {
79 } 28 }
80} 29}
81 30
82// TODO: use from a common package
83// Runs a gin.Engine instance in a way that can be canceled by an SIGINT 31// Runs a gin.Engine instance in a way that can be canceled by an SIGINT
84func GinRun(e *gin.Engine, debug bool, a ...string) { 32func GinRun(e *gin.Engine, debug bool, a ...string) {
85 if debug { 33 if debug {
@@ -115,3 +63,10 @@ func GinRun(e *gin.Engine, debug bool, a ...string) {
115 63
116 <-idleConnsClosed 64 <-idleConnsClosed
117} 65}
66
67func GetRequestIP(c *gin.Context) net.IP {
68 if xff := c.Request.Header.Get("X-Forwarded-For"); xff != "" {
69 return ParseIP(xff)
70 }
71 return ParseIP(c.Request.RemoteAddr)
72}
diff --git a/util/http.go b/util/http.go
new file mode 100644
index 0000000..31cd94d
--- /dev/null
+++ b/util/http.go
@@ -0,0 +1,26 @@
1package util
2
3import (
4 "fmt"
5 "net/http"
6 "net/url"
7)
8
9func MakeURL(r *http.Request, path string, subs ...interface{}) *url.URL {
10 scheme := "https"
11 if r.TLS == nil {
12 scheme = "http"
13 }
14
15 // Always defer to whatever the proxy told us it was doing because this
16 // could be a mullet-VIP in either direction.
17 if fwProto := r.Header.Get("X-Forwarded-Proto"); fwProto != "" {
18 scheme = fwProto
19 }
20
21 return &url.URL{
22 Scheme: scheme,
23 Host: r.Host,
24 Path: fmt.Sprintf(path, subs...),
25 }
26}
diff --git a/util/ip.go b/util/ip.go
new file mode 100644
index 0000000..f86d5b5
--- /dev/null
+++ b/util/ip.go
@@ -0,0 +1,24 @@
1package util
2
3import (
4 "net"
5 "regexp"
6)
7
8// Parses an IPv4 or IPv6 address with an optional port on the end. Returns
9// match groups for the addresses. The first match is the IPv6 address and the
10// second the IPv4 address.
11var ipRegexp = regexp.MustCompile(`(?:\[([0-9a-f:]+)\]|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))(?::\d+)?`)
12
13func ParseIP(s string) net.IP {
14 ips := ipRegexp.FindStringSubmatch(s)
15 if ips == nil {
16 return nil
17 }
18
19 if v6, v4 := ips[1], ips[2]; v6 != "" {
20 return net.ParseIP(v6)
21 } else {
22 return net.ParseIP(v4)
23 }
24}
diff --git a/util/viper.go b/util/viper.go
new file mode 100644
index 0000000..0f08a6c
--- /dev/null
+++ b/util/viper.go
@@ -0,0 +1,36 @@
1package util
2
3import (
4 "strings"
5
6 "github.com/spf13/cobra"
7 "github.com/spf13/viper"
8)
9
10type ViperWrap struct {
11 cmd *cobra.Command
12}
13
14func WrapViper(cmd *cobra.Command, prefix string) *ViperWrap {
15 viper.SetEnvPrefix(prefix)
16 viper.AutomaticEnv()
17 return &ViperWrap{cmd}
18}
19
20func (v *ViperWrap) bindViper(name, short string, defaultv interface{}, help string) {
21 vname := strings.ReplaceAll(name, "-", "_")
22 viper.BindPFlag(vname, v.cmd.Flags().Lookup(name))
23 viper.SetDefault(vname, defaultv)
24}
25
26func (v *ViperWrap) BindString(name, short, defaultv, help string) *ViperWrap {
27 v.cmd.Flags().StringP(name, short, defaultv, help)
28 v.bindViper(name, short, defaultv, help)
29 return v
30}
31
32func (v *ViperWrap) BindBool(name, short string, defaultv bool, help string) *ViperWrap {
33 v.cmd.Flags().BoolP(name, short, defaultv, help)
34 v.bindViper(name, short, defaultv, help)
35 return v
36}
diff --git a/web/controllers/acme.go b/web/controllers/acme.go
index f40b2ec..5090b70 100644
--- a/web/controllers/acme.go
+++ b/web/controllers/acme.go
@@ -10,7 +10,7 @@ import (
10 "github.com/gin-gonic/gin" 10 "github.com/gin-gonic/gin"
11 11
12 "code.crute.me/mcrute/go_ddns_manager/dns" 12 "code.crute.me/mcrute/go_ddns_manager/dns"
13 "code.crute.me/mcrute/go_ddns_manager/web" 13 "code.crute.me/mcrute/go_ddns_manager/util"
14 "code.crute.me/mcrute/go_ddns_manager/web/middleware" 14 "code.crute.me/mcrute/go_ddns_manager/web/middleware"
15) 15)
16 16
@@ -103,7 +103,7 @@ func CreateAcmeChallenge(c *gin.Context) {
103 return 103 return
104 } 104 }
105 105
106 url := web.MakeURL(c.Request, "/acme/%s", AcmeChallengeID{ 106 url := util.MakeURL(c.Request, "/acme/%s", AcmeChallengeID{
107 Zone: zone.Name, 107 Zone: zone.Name,
108 Prefix: prefix, 108 Prefix: prefix,
109 Challenge: ch.Challenge, 109 Challenge: ch.Challenge,
diff --git a/web/controllers/ddns.go b/web/controllers/ddns.go
index 7300989..692b59f 100644
--- a/web/controllers/ddns.go
+++ b/web/controllers/ddns.go
@@ -7,7 +7,7 @@ import (
7 "github.com/gin-gonic/gin" 7 "github.com/gin-gonic/gin"
8 8
9 "code.crute.me/mcrute/go_ddns_manager/dns" 9 "code.crute.me/mcrute/go_ddns_manager/dns"
10 "code.crute.me/mcrute/go_ddns_manager/web" 10 "code.crute.me/mcrute/go_ddns_manager/util"
11 "code.crute.me/mcrute/go_ddns_manager/web/middleware" 11 "code.crute.me/mcrute/go_ddns_manager/web/middleware"
12) 12)
13 13
@@ -28,7 +28,7 @@ func UpdateDynamicDNS(c *gin.Context) {
28 return 28 return
29 } 29 }
30 30
31 inip := web.GetRequestIP(c) 31 inip := util.GetRequestIP(c)
32 if inip == nil { 32 if inip == nil {
33 log.Println("ddns: Unable to parse IP") 33 log.Println("ddns: Unable to parse IP")
34 c.AbortWithStatus(http.StatusInternalServerError) 34 c.AbortWithStatus(http.StatusInternalServerError)
diff --git a/web/controllers/reflect_ip.go b/web/controllers/reflect_ip.go
index d04b98c..199d736 100644
--- a/web/controllers/reflect_ip.go
+++ b/web/controllers/reflect_ip.go
@@ -5,11 +5,11 @@ import (
5 5
6 "github.com/gin-gonic/gin" 6 "github.com/gin-gonic/gin"
7 7
8 "code.crute.me/mcrute/go_ddns_manager/web" 8 "code.crute.me/mcrute/go_ddns_manager/util"
9) 9)
10 10
11func ReflectIP(c *gin.Context) { 11func ReflectIP(c *gin.Context) {
12 ip := web.GetRequestIP(c) 12 ip := util.GetRequestIP(c)
13 if ip == nil { 13 if ip == nil {
14 c.String(http.StatusInternalServerError, "") 14 c.String(http.StatusInternalServerError, "")
15 return 15 return