Skip to content

Commit f94affb

Browse files
authored
acmeserver: support additional database types beside bbolt
1 parent c78ebb3 commit f94affb

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

modules/caddypki/acmeserver/acmeserver.go

+39-7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
weakrand "math/rand"
2121
"net"
2222
"net/http"
23+
"net/url"
2324
"os"
2425
"path/filepath"
2526
"regexp"
@@ -52,6 +53,10 @@ type Handler struct {
5253
// the default ID is "local".
5354
CA string `json:"ca,omitempty"`
5455

56+
// The connection string of the database used for
57+
// the account data of the ACME clients
58+
Database string `json:"database,omitempty"`
59+
5560
// The lifetime for issued certificates
5661
Lifetime caddy.Duration `json:"lifetime,omitempty"`
5762

@@ -153,6 +158,12 @@ func (ash *Handler) Provision(ctx caddy.Context) error {
153158
return fmt.Errorf("certificate lifetime (%s) should be less than intermediate certificate lifetime (%s)", time.Duration(ash.Lifetime), time.Duration(ca.IntermediateLifetime))
154159
}
155160

161+
repl, ok := ctx.Context.Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
162+
if !ok {
163+
repl = caddy.NewReplacer()
164+
ctx.Context = context.WithValue(ctx.Context, caddy.ReplacerCtxKey, repl)
165+
}
166+
ash.Database = repl.ReplaceKnown(ash.Database, "")
156167
database, err := ash.openDatabase()
157168
if err != nil {
158169
return err
@@ -248,17 +259,38 @@ func (ash Handler) Cleanup() error {
248259
func (ash Handler) openDatabase() (*db.AuthDB, error) {
249260
key := ash.getDatabaseKey()
250261
database, loaded, err := databasePool.LoadOrNew(key, func() (caddy.Destructor, error) {
251-
dbFolder := filepath.Join(caddy.AppDataDir(), "acme_server", key)
252-
dbPath := filepath.Join(dbFolder, "db")
253-
254-
err := os.MkdirAll(dbFolder, 0o755)
262+
var dsn string
263+
dburl, err := url.Parse(ash.Database)
255264
if err != nil {
256-
return nil, fmt.Errorf("making folder for CA database: %v", err)
265+
return nil, err
266+
}
267+
if dburl.Scheme == "" {
268+
dburl.Scheme = "bbolt"
269+
}
270+
var dbtype string
271+
switch dburl.Scheme {
272+
case "postgresql", "postgres", "psql":
273+
dbtype = nosql.PostgreSQLDriver // normalize the postgres identifier
274+
dsn = ash.Database
275+
case "mysql":
276+
dbtype = nosql.MySQLDriver
277+
dsn = ash.Database
278+
case "bbolt":
279+
dbtype = nosql.BBoltDriver
280+
dbFolder := filepath.Join(caddy.AppDataDir(), "acme_server", key)
281+
dsn = filepath.Join(dbFolder, "db")
282+
if err := os.MkdirAll(dbFolder, 0o755); err != nil {
283+
return nil, fmt.Errorf("making folder for CA database: %v", err)
284+
}
285+
default:
286+
// Although smallstep/nosql rejects unrecognized database, we
287+
// reject them here to avoid surprises. We also reject 'badger'.
288+
return nil, fmt.Errorf("unsupported database type: %s", dburl.Scheme)
257289
}
258290

259291
dbConfig := &db.Config{
260-
Type: "bbolt",
261-
DataSource: dbPath,
292+
Type: dbtype,
293+
DataSource: dsn,
262294
}
263295
database, err := db.New(dbConfig)
264296
return databaseCloser{&database}, err

0 commit comments

Comments
 (0)