hscontrol: replace autocert with certmagic

Adds DNS-01 for headscale's own certificate through dns.challenge.provider,
with the same propagation check as node certificates. Storage format
changes: first start gets a new account and certificate.

Updates #2527
Updates #504
This commit is contained in:
Kristoffer Dalby committed 2026-10-18 20:53:18 +02:00
1 parent dcc01dc2b0
commit 5d15cc930d
13 files changed
+639 -134

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
package zlog
import (
"slices"
"github.com/rs/zerolog"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// Zap returns a [zap.Logger] that writes to logger, for libraries that
// only log through zap.
func Zap(logger zerolog.Logger) *zap.Logger {
return zap.New(zapCore{logger: logger})
}
type zapCore struct {
logger zerolog.Logger
fields []zapcore.Field
}
func (c zapCore) Enabled(level zapcore.Level) bool {
l := zerologLevel(level)
return l >= c.logger.GetLevel() && l >= zerolog.GlobalLevel()
}
func (c zapCore) With(fields []zapcore.Field) zapcore.Core {
return zapCore{logger: c.logger, fields: slices.Concat(c.fields, fields)}
}
func (c zapCore) Check(entry zapcore.Entry, checked *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if c.Enabled(entry.Level) {
return checked.AddCore(entry, c)
}
return checked
}
func (c zapCore) Write(entry zapcore.Entry, fields []zapcore.Field) error {
enc := zapcore.NewMapObjectEncoder()
for _, f := range slices.Concat(c.fields, fields) {
f.AddTo(enc)
}
c.logger.WithLevel(zerologLevel(entry.Level)).
Str("logger", entry.LoggerName).
Fields(enc.Fields).
Msg(entry.Message)
return nil
}
func (zapCore) Sync() error { return nil }
// zerologLevel maps zap levels to zerolog. Levels above error are logged
// as errors: zerolog's WithLevel never panics or exits.
func zerologLevel(level zapcore.Level) zerolog.Level {
switch {
case level <= zapcore.DebugLevel:
return zerolog.DebugLevel
case level == zapcore.InfoLevel:
return zerolog.InfoLevel
case level == zapcore.WarnLevel:
return zerolog.WarnLevel
default:
return zerolog.ErrorLevel
}
}
+33
View File
@@ -0,0 +1,33 @@
package zlog
import (
"bytes"
"encoding/json"
"testing"
"github.com/rs/zerolog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
func TestZap(t *testing.T) {
var buf bytes.Buffer
logger := Zap(zerolog.New(&buf).Level(zerolog.InfoLevel)).
Named("acme").
With(zap.String("issuer", "letsencrypt"))
logger.Debug("below the logger's level")
logger.Warn("renewing", zap.Int("attempt", 2))
var got map[string]any
require.NoError(t, json.Unmarshal(buf.Bytes(), &got), buf.String())
assert.Equal(t, map[string]any{
"level": "warn",
"logger": "acme",
"issuer": "letsencrypt",
"attempt": float64(2),
"message": "renewing",
}, got)
}