• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

joohoi / acme-dns / 21649894913

03 Feb 2026 10:13PM UTC coverage: 77.593% (+4.3%) from 73.276%
21649894913

Pull #325

github

web-flow
Merge c6826aad3 into b7a0a8a7b
Pull Request #325: Refactoring

578 of 754 new or added lines in 20 files covered. (76.66%)

3 existing lines in 1 file now uncovered.

793 of 1022 relevant lines covered (77.59%)

14.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

28.28
/pkg/api/api.go
1
package api
2

3
import (
4
        "context"
5
        "crypto/tls"
6
        "net/http"
7

8
        "github.com/joohoi/acme-dns/pkg/acmedns"
9

10
        "github.com/caddyserver/certmagic"
11
        "github.com/julienschmidt/httprouter"
12
        "github.com/rs/cors"
13
        "go.uber.org/zap"
14
)
15

16
type AcmednsAPI struct {
17
        Config  *acmedns.AcmeDnsConfig
18
        DB      acmedns.AcmednsDB
19
        Logger  *zap.SugaredLogger
20
        errChan chan error
21
}
22

23
func Init(config *acmedns.AcmeDnsConfig, db acmedns.AcmednsDB, logger *zap.SugaredLogger, errChan chan error) AcmednsAPI {
28✔
24
        a := AcmednsAPI{Config: config, DB: db, Logger: logger, errChan: errChan}
28✔
25
        return a
28✔
26
}
28✔
27

NEW
28
func (a *AcmednsAPI) Start(dnsservers []acmedns.AcmednsNS) {
×
NEW
29
        var err error
×
NEW
30
        //TODO: do we want to debug log the HTTP server?
×
NEW
31
        stderrorlog, err := zap.NewStdLogAt(a.Logger.Desugar(), zap.ErrorLevel)
×
NEW
32
        if err != nil {
×
NEW
33
                a.errChan <- err
×
NEW
34
                return
×
NEW
35
        }
×
NEW
36
        api := httprouter.New()
×
NEW
37
        c := cors.New(cors.Options{
×
NEW
38
                AllowedOrigins:     a.Config.API.CorsOrigins,
×
NEW
39
                AllowedMethods:     []string{"GET", "POST"},
×
NEW
40
                OptionsPassthrough: false,
×
NEW
41
                Debug:              a.Config.General.Debug,
×
NEW
42
        })
×
NEW
43
        if a.Config.General.Debug {
×
NEW
44
                // Logwriter for saner log output
×
NEW
45
                c.Log = stderrorlog
×
NEW
46
        }
×
NEW
47
        if !a.Config.API.DisableRegistration {
×
NEW
48
                api.POST("/register", a.webRegisterPost)
×
NEW
49
        }
×
NEW
50
        api.POST("/update", a.Auth(a.webUpdatePost))
×
NEW
51
        api.GET("/health", a.healthCheck)
×
NEW
52

×
NEW
53
        host := a.Config.API.IP + ":" + a.Config.API.Port
×
NEW
54

×
NEW
55
        // TLS specific general settings
×
NEW
56
        cfg := &tls.Config{
×
NEW
57
                MinVersion: tls.VersionTLS12,
×
NEW
58
        }
×
NEW
59

×
NEW
60
        switch a.Config.API.TLS {
×
NEW
61
        case acmedns.ApiTlsProviderLetsEncrypt, acmedns.ApiTlsProviderLetsEncryptStaging:
×
NEW
62
                magic := a.setupTLS(dnsservers)
×
NEW
63
                err = magic.ManageAsync(context.Background(), []string{a.Config.General.Domain})
×
NEW
64
                if err != nil {
×
NEW
65
                        a.errChan <- err
×
NEW
66
                        return
×
NEW
67
                }
×
NEW
68
                cfg.GetCertificate = magic.GetCertificate
×
NEW
69
                srv := &http.Server{
×
NEW
70
                        Addr:      host,
×
NEW
71
                        Handler:   c.Handler(api),
×
NEW
72
                        TLSConfig: cfg,
×
NEW
73
                        ErrorLog:  stderrorlog,
×
NEW
74
                }
×
NEW
75
                a.Logger.Infow("Listening HTTPS",
×
NEW
76
                        "host", host,
×
NEW
77
                        "domain", a.Config.General.Domain)
×
NEW
78
                err = srv.ListenAndServeTLS("", "")
×
NEW
79
        case acmedns.ApiTlsProviderCert:
×
NEW
80
                srv := &http.Server{
×
NEW
81
                        Addr:      host,
×
NEW
82
                        Handler:   c.Handler(api),
×
NEW
83
                        TLSConfig: cfg,
×
NEW
84
                        ErrorLog:  stderrorlog,
×
NEW
85
                }
×
NEW
86
                a.Logger.Infow("Listening HTTPS",
×
NEW
87
                        "host", host,
×
NEW
88
                        "domain", a.Config.General.Domain)
×
NEW
89
                err = srv.ListenAndServeTLS(a.Config.API.TLSCertFullchain, a.Config.API.TLSCertPrivkey)
×
NEW
90
        default:
×
NEW
91
                a.Logger.Infow("Listening HTTP",
×
NEW
92
                        "host", host)
×
NEW
93
                err = http.ListenAndServe(host, c.Handler(api))
×
94
        }
NEW
95
        if err != nil {
×
NEW
96
                a.errChan <- err
×
NEW
97
        }
×
98
}
99

100
func (a *AcmednsAPI) setupTLS(dnsservers []acmedns.AcmednsNS) *certmagic.Config {
4✔
101
        provider := NewChallengeProvider(dnsservers)
4✔
102
        certmagic.Default.Logger = a.Logger.Desugar()
4✔
103
        storage := certmagic.FileStorage{Path: a.Config.API.ACMECacheDir}
4✔
104

4✔
105
        // Set up certmagic for getting certificate for acme-dns api
4✔
106
        certmagic.DefaultACME.DNS01Solver = &provider
4✔
107
        certmagic.DefaultACME.Agreed = true
4✔
108
        certmagic.DefaultACME.Logger = a.Logger.Desugar()
4✔
109
        if a.Config.API.TLS == acmedns.ApiTlsProviderLetsEncrypt {
6✔
110
                certmagic.DefaultACME.CA = certmagic.LetsEncryptProductionCA
2✔
111
        } else {
4✔
112
                certmagic.DefaultACME.CA = certmagic.LetsEncryptStagingCA
2✔
113
        }
2✔
114
        certmagic.DefaultACME.Email = a.Config.API.NotificationEmail
4✔
115

4✔
116
        magicConf := certmagic.Default
4✔
117
        magicConf.Logger = a.Logger.Desugar()
4✔
118
        magicConf.Storage = &storage
4✔
119
        magicConf.DefaultServerName = a.Config.General.Domain
4✔
120
        magicCache := certmagic.NewCache(certmagic.CacheOptions{
4✔
121
                GetConfigForCert: func(cert certmagic.Certificate) (*certmagic.Config, error) {
4✔
NEW
122
                        return &magicConf, nil
×
NEW
123
                },
×
124
                Logger: a.Logger.Desugar(),
125
        })
126
        magic := certmagic.New(magicCache, magicConf)
4✔
127
        return magic
4✔
128
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc