Browse Source

Cleanup, redeploy, deal with expired certs

master
Chris Smith 5 years ago
parent
commit
ce833310ac
2 changed files with 73 additions and 26 deletions
  1. 49
    24
      dotege.go
  2. 24
    2
      lego.go

+ 49
- 24
dotege.go View File

@@ -31,7 +31,7 @@ func monitorSignals() <-chan bool {
31 31
 	return done
32 32
 }
33 33
 
34
-func main() {
34
+func createLogger() *zap.SugaredLogger {
35 35
 	zapConfig := zap.NewDevelopmentConfig()
36 36
 	zapConfig.DisableCaller = true
37 37
 	zapConfig.DisableStacktrace = true
@@ -39,12 +39,17 @@ func main() {
39 39
 	zapConfig.OutputPaths = []string{"stdout"}
40 40
 	zapConfig.ErrorOutputPaths = []string{"stdout"}
41 41
 	logger, _ := zapConfig.Build()
42
-	sugar := logger.Sugar()
43
-	sugar.Info("Dotege is starting")
44
-
45
-	doneChan := monitorSignals()
42
+	return logger.Sugar()
43
+}
46 44
 
47
-	config := model.Config{
45
+func createConfig() *model.Config {
46
+	return &model.Config{
47
+		Templates: []model.TemplateConfig{
48
+			{
49
+				Source:      "./templates/haproxy.cfg.tpl",
50
+				Destination: "haproxy.cfg",
51
+			},
52
+		},
48 53
 		Labels: model.LabelConfig{
49 54
 			Hostnames:   "com.chameth.vhost",
50 55
 			RequireAuth: "com.chameth.auth",
@@ -52,54 +57,74 @@ func main() {
52 57
 		DefaultCertActions:     model.COMBINE | model.FLATTEN,
53 58
 		DefaultCertDestination: "/data/certs/",
54 59
 	}
60
+}
55 61
 
56
-	dockerStopChan := make(chan struct{})
57
-	dockerClient, err := client.NewEnvClient()
62
+func createTemplateGenerator(logger *zap.SugaredLogger, config *model.Config) *TemplateGenerator {
63
+	templateGenerator := NewTemplateGenerator(logger)
64
+	for _, template := range config.Templates {
65
+		templateGenerator.AddTemplate(template)
66
+	}
67
+	return templateGenerator
68
+}
69
+
70
+func createCertificateManager(logger *zap.SugaredLogger) *CertificateManager {
71
+	certificateManager := NewCertificateManager(logger, lego.LEDirectoryStaging, certcrypto.EC256, env.GetOrDefaultString("DOTEGE_DNS_PROVIDER", ""), "/config/certs.json")
72
+	err := certificateManager.Init(env.GetOrDefaultString("DOTEGE_ACME_EMAIL", ""))
58 73
 	if err != nil {
59 74
 		panic(err)
60 75
 	}
76
+	return certificateManager
77
+}
61 78
 
62
-	templateGenerator := NewTemplateGenerator(sugar)
63
-	templateGenerator.AddTemplate(model.TemplateConfig{
64
-		Source:      "./templates/haproxy.cfg.tpl",
65
-		Destination: "haproxy.cfg",
66
-	})
79
+func main() {
80
+	logger := createLogger()
81
+	logger.Info("Dotege is starting")
82
+
83
+	doneChan := monitorSignals()
84
+	config := createConfig()
67 85
 
68
-	certificateManager := NewCertificateManager(sugar, lego.LEDirectoryStaging, certcrypto.EC256, env.GetOrDefaultString("DOTEGE_DNS_PROVIDER", ""), "/config/certs.json")
69
-	err = certificateManager.Init(env.GetOrDefaultString("DOTEGE_ACME_EMAIL", ""))
86
+	dockerStopChan := make(chan struct{})
87
+	dockerClient, err := client.NewEnvClient()
70 88
 	if err != nil {
71 89
 		panic(err)
72 90
 	}
73 91
 
74
-	timer := time.NewTimer(time.Hour)
75
-	timer.Stop()
92
+	templateGenerator := createTemplateGenerator(logger, config)
93
+	certificateManager := createCertificateManager(logger)
94
+
95
+	jitterTimer := time.NewTimer(time.Minute)
96
+	redeployTimer := time.NewTicker(time.Hour * 24)
76 97
 	containers := make(map[string]model.Container)
77 98
 
78 99
 	go func() {
79 100
 		err := monitorContainers(dockerClient, dockerStopChan, func(container model.Container) {
80 101
 			containers[container.Name] = container
81
-			timer.Reset(100 * time.Millisecond)
82
-			err, _ = certificateManager.GetCertificate(getHostnamesForContainer(container, config))
102
+			jitterTimer.Reset(100 * time.Millisecond)
103
+			err, _ = certificateManager.GetCertificate(getHostnamesForContainer(container, *config))
83 104
 		}, func(name string) {
84 105
 			delete(containers, name)
85
-			timer.Reset(100 * time.Millisecond)
106
+			jitterTimer.Reset(100 * time.Millisecond)
86 107
 		})
87 108
 
88 109
 		if err != nil {
89
-			sugar.Fatal("Error monitoring containers: ", err.Error())
110
+			logger.Fatal("Error monitoring containers: ", err.Error())
90 111
 		}
91 112
 	}()
92 113
 
93 114
 	go func() {
94 115
 		for {
95 116
 			select {
96
-			case <-timer.C:
97
-				hostnames := getHostnames(containers, config)
117
+			case <-jitterTimer.C:
118
+				hostnames := getHostnames(containers, *config)
98 119
 				templateGenerator.Generate(Context{
99 120
 					Containers: containers,
100 121
 					Hostnames:  hostnames,
101 122
 				})
102
-				//certDeployer.UpdateHostnames(hostnames)
123
+			case <-redeployTimer.C:
124
+				logger.Info("Performing periodic certificate refresh")
125
+				for _, container := range containers {
126
+					err, _ = certificateManager.GetCertificate(getHostnamesForContainer(container, *config))
127
+				}
103 128
 			}
104 129
 		}
105 130
 	}()

+ 24
- 2
lego.go View File

@@ -184,8 +184,12 @@ func (c *CertificateManager) register() error {
184 184
 func (c *CertificateManager) GetCertificate(domains []string) (error, *SavedCertificate) {
185 185
 	existing := c.loadCert(domains)
186 186
 	if existing != nil {
187
-		c.logger.Debugf("Returning existing certificate for request %s", domains)
188
-		return nil, existing
187
+		if existing.NotAfter.Before(time.Now().Add(time.Hour * 24 * 31)) {
188
+			c.logger.Debugf("Found existing certificate for %s, but it expires soon; renewing", domains)
189
+		} else {
190
+			c.logger.Debugf("Returning existing certificate for request %s", domains)
191
+			return nil, existing
192
+		}
189 193
 	}
190 194
 
191 195
 	request := certificate.ObtainRequest{
@@ -226,7 +230,25 @@ func domainsMatch(domains1, domains2 []string) bool {
226 230
 	return true
227 231
 }
228 232
 
233
+func (c *CertificateManager) removeCerts(domains []string) {
234
+	var newCerts []*SavedCertificate
235
+	for _, cert := range c.data.Certs {
236
+		if !domainsMatch(cert.Domains, domains) {
237
+			newCerts = append(newCerts, cert)
238
+		}
239
+	}
240
+
241
+	diff := len(c.data.Certs) - len(newCerts)
242
+
243
+	if diff > 0 {
244
+		c.logger.Debugf("Removed %d certificates matching %s", diff, domains)
245
+		c.data.Certs = newCerts
246
+	}
247
+}
248
+
229 249
 func (c *CertificateManager) saveCert(domains []string, cert *certificate.Resource) (error, *SavedCertificate) {
250
+	c.removeCerts(domains)
251
+
230 252
 	savedCert := &SavedCertificate{
231 253
 		Domains:           domains,
232 254
 		Certificate:       cert.Certificate,

Loading…
Cancel
Save