summaryrefslogtreecommitdiff
path: root/main.go
blob: 1998942a8cc572865686d1566a8f2dedac9065cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main

import (
	"encoding/json"
	"io/ioutil"
	"time"

	"github.com/gin-gonic/gin"

	"code.crute.me/mcrute/frame"
	"code.crute.me/mcrute/go_ddns_manager/bind"
	"code.crute.me/mcrute/go_ddns_manager/dns"
	"code.crute.me/mcrute/go_ddns_manager/web"
	"code.crute.me/mcrute/go_ddns_manager/web/controllers"
	"code.crute.me/mcrute/go_ddns_manager/web/middleware"
)

func loadConfig(app *frame.WebApp, args []string) (interface{}, error) {
	zonesFile := app.GetStringArgument("zones_config")
	secretsFile := app.GetStringArgument("auth_config")
	server := args[0]
	view := app.GetStringArgument("view_name")

	scfg := &web.ServerConfig{
		DNSClient: &dns.DNSClient{
			Server: server,
			RecursiveResolvers: []string{
				"google-public-dns-a.google.com:53",
				"google-public-dns-b.google.com:53",
			},
			PollTimeout: 3 * time.Second,
		},
		AcmeView:       view,
		DynamicDnsView: view,
	}

	cfg, err := bind.ParseBINDConfig(zonesFile)
	if err != nil {
		return nil, err
	}
	scfg.BindConfig = cfg

	fd, err := ioutil.ReadFile(secretsFile)
	if err != nil {
		return nil, err
	}

	if err = json.Unmarshal(fd, scfg); err != nil {
		return nil, err
	}

	return scfg, nil
}

func prepareServer(c interface{}, router *gin.Engine) error {
	cfg := c.(*web.ServerConfig)

	router.Use(middleware.ConfigContextMiddleware(cfg))

	router.GET("/reflect-ip", controllers.ReflectIP)

	ddns := router.Group("/dynamic-dns")
	ddns.Use(middleware.DDNSAuthMiddleware)
	{
		ddns.POST("", controllers.UpdateDynamicDNS)
	}

	acme := router.Group("/acme")
	acme.Use(middleware.AcmeAuthMiddleware)
	{
		acme.POST("", controllers.CreateAcmeChallenge)
		acme.DELETE("/:id", controllers.DeleteAcmeChallenge)
	}

	acme2 := router.Group("/acmev2")
	acme2.Use(middleware.AcmeAuthMiddleware)
	{
		acme2.POST("", controllers.CreateAcmeChallengeV2)
		acme2.DELETE("", controllers.DeleteAcmeChallengeV2)
	}

	manage := router.Group("/manage")
	manage.Use(middleware.ApiAuthMiddleware)
	{
		manage.GET("", controllers.ManageRoot)

		views := manage.Group("/views")
		{
			views.GET("", controllers.ListViews)
			views.GET("/:view", controllers.ListView)
			views.GET("/:view/:zone", controllers.ListZone)
		}
	}

	return nil
}

func main() {
	app := &frame.WebApp{
		Name:        "dns-manage-service",
		Usage:       "dns-manage-service [flags] dns-server-ip-port",
		Help:        "DNS manager service",
		MinArgCount: 1,
		Arguments: []frame.Argument{
			&frame.StringArgument{"zones-config", "z", "cfg/zones.conf", "Bind key and zones config file"},
			&frame.StringArgument{"auth-config", "a", "cfg/server_auth.json", "Server auth configuration file"},
			&frame.StringArgument{"view-name", "n", "external", "Name of view to update for ACME and DDNS"},
		},
		LoadConfig:    loadConfig,
		PrepareServer: prepareServer,
	}

	if err := app.RunForever(); err != nil {
		panic(err)
	}
}