diff options
author | Mike Crute <mike@crute.us> | 2020-01-04 06:39:30 +0000 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2020-08-11 02:56:10 +0000 |
commit | a810417e580890028cf725f6a71d43dbc5c02235 (patch) | |
tree | 863ea8743a94c816664ebbecc9e9a68387e2ed7a | |
parent | 8ed9671c0b4f78711858448cf3b4ee9af0eba51e (diff) | |
download | go_ddns_manager-a810417e580890028cf725f6a71d43dbc5c02235.tar.bz2 go_ddns_manager-a810417e580890028cf725f6a71d43dbc5c02235.tar.xz go_ddns_manager-a810417e580890028cf725f6a71d43dbc5c02235.zip |
Refator using le utils
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 10 | ||||
-rw-r--r-- | main.go | 52 | ||||
-rw-r--r-- | util/file.go | 19 | ||||
-rw-r--r-- | util/gin.go (renamed from web/utils.go) | 61 | ||||
-rw-r--r-- | util/http.go | 26 | ||||
-rw-r--r-- | util/ip.go | 24 | ||||
-rw-r--r-- | util/viper.go | 36 | ||||
-rw-r--r-- | web/controllers/acme.go | 4 | ||||
-rw-r--r-- | web/controllers/ddns.go | 4 | ||||
-rw-r--r-- | web/controllers/reflect_ip.go | 4 |
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 @@ | |||
1 | GO_FILES := $(shell find . -name '*.go') | ||
2 | |||
3 | dns-service: main.go $(GO_FILES) | ||
4 | go build -o $@ $< | ||
@@ -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 | ) |
@@ -7,6 +7,7 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc | |||
7 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | 7 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
8 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | 8 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= |
9 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | 9 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
10 | github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= | ||
10 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | 11 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= |
11 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= | 12 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= |
12 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= | 13 | github.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 | |||
19 | github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= | 20 | github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= |
20 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | 21 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= |
21 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | 22 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= |
23 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= | ||
22 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | 24 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= |
23 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | 25 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= |
24 | github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= | 26 | github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= |
25 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | 27 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= |
26 | github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= | 28 | github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= |
27 | github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= | 29 | github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= |
30 | github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= | ||
28 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= | 31 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= |
29 | github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= | 32 | github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= |
30 | github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= | 33 | github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= |
31 | github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= | 34 | github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= |
32 | github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= | 35 | github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= |
33 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | 36 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= |
37 | github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= | ||
34 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | 38 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= |
35 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= | 39 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= |
36 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | 40 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
37 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= | 41 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= |
38 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | 42 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= |
43 | github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= | ||
39 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= | 44 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= |
40 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | 45 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
41 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | 46 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
42 | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= | 47 | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= |
48 | github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= | ||
43 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= | 49 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= |
50 | github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= | ||
44 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | 51 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= |
45 | github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= | 52 | github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= |
46 | github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= | 53 | github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= |
54 | github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= | ||
47 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= | 55 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= |
48 | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | 56 | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= |
49 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | 57 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= |
58 | github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= | ||
50 | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= | 59 | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= |
51 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | 60 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
52 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | 61 | github.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 | |||
76 | golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M= | 85 | golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M= |
77 | golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | 86 | golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
78 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | 87 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
88 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= | ||
79 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | 89 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= |
80 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | 90 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |
81 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | 91 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
@@ -1,44 +1,19 @@ | |||
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
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 | ||
18 | func 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 | ||
28 | func 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 | |||
42 | func makeServer(cfg *web.ServerConfig) *gin.Engine { | 17 | func 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 @@ | |||
1 | package util | ||
2 | |||
3 | import ( | ||
4 | "io" | ||
5 | "io/ioutil" | ||
6 | ) | ||
7 | |||
8 | func 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 @@ | |||
1 | package web | 1 | package util |
2 | 2 | ||
3 | import ( | 3 | import ( |
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. | ||
20 | var 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 | ||
23 | func 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 | ||
37 | func 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 | ||
45 | func 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 |
66 | func resolveAddress(addr []string) string { | 15 | func 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 |
84 | func GinRun(e *gin.Engine, debug bool, a ...string) { | 32 | func 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 | |||
67 | func 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 @@ | |||
1 | package util | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "net/http" | ||
6 | "net/url" | ||
7 | ) | ||
8 | |||
9 | func 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 @@ | |||
1 | package util | ||
2 | |||
3 | import ( | ||
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. | ||
11 | var ipRegexp = regexp.MustCompile(`(?:\[([0-9a-f:]+)\]|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))(?::\d+)?`) | ||
12 | |||
13 | func 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 @@ | |||
1 | package util | ||
2 | |||
3 | import ( | ||
4 | "strings" | ||
5 | |||
6 | "github.com/spf13/cobra" | ||
7 | "github.com/spf13/viper" | ||
8 | ) | ||
9 | |||
10 | type ViperWrap struct { | ||
11 | cmd *cobra.Command | ||
12 | } | ||
13 | |||
14 | func WrapViper(cmd *cobra.Command, prefix string) *ViperWrap { | ||
15 | viper.SetEnvPrefix(prefix) | ||
16 | viper.AutomaticEnv() | ||
17 | return &ViperWrap{cmd} | ||
18 | } | ||
19 | |||
20 | func (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 | |||
26 | func (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 | |||
32 | func (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 | ||
11 | func ReflectIP(c *gin.Context) { | 11 | func 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 |