mirror of
https://github.com/zrepl/zrepl.git
synced 2025-04-11 13:08:46 +02:00
Add a TLSConfig struct/library to configure a simple TLS/HTTPS server with most basic toggles that most users would want. This is based on the structure that the prometheus/exporter-toolkit web-config uses. Notably this does not make use of either of the two existing TLS configuration structures that exist as both are specific in their usage and neither are suitable for generally configuring a TLS server. Signed-off-by: Joe Groocock <me@frebib.net>
131 lines
3.0 KiB
Go
131 lines
3.0 KiB
Go
package daemon
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"net"
|
|
"net/http"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/prometheus/exporter-toolkit/web"
|
|
|
|
"github.com/zrepl/zrepl/internal/config"
|
|
"github.com/zrepl/zrepl/internal/daemon/job"
|
|
"github.com/zrepl/zrepl/internal/daemon/logging"
|
|
"github.com/zrepl/zrepl/internal/endpoint"
|
|
"github.com/zrepl/zrepl/internal/logger"
|
|
"github.com/zrepl/zrepl/internal/rpc/dataconn/frameconn"
|
|
"github.com/zrepl/zrepl/internal/util/tcpsock"
|
|
"github.com/zrepl/zrepl/internal/zfs"
|
|
)
|
|
|
|
type prometheusJob struct {
|
|
listen string
|
|
freeBind bool
|
|
tls *tls.Config
|
|
}
|
|
|
|
func newPrometheusJobFromConfig(in *config.PrometheusMonitoring) (*prometheusJob, error) {
|
|
_, _, err := net.SplitHostPort(in.Listen)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var tlsConfig *tls.Config
|
|
if in.TLS != nil {
|
|
tlsConfig, err = web.ConfigToTLSConfig(in.TLS)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return &prometheusJob{
|
|
listen: in.Listen,
|
|
freeBind: in.ListenFreeBind,
|
|
tls: tlsConfig,
|
|
}, nil
|
|
}
|
|
|
|
var prom struct {
|
|
taskLogEntries *prometheus.CounterVec
|
|
}
|
|
|
|
func init() {
|
|
prom.taskLogEntries = prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
Namespace: "zrepl",
|
|
Subsystem: "daemon",
|
|
Name: "log_entries",
|
|
Help: "number of log entries per job task and level",
|
|
}, []string{"zrepl_job", "level"})
|
|
prometheus.MustRegister(prom.taskLogEntries)
|
|
}
|
|
|
|
func (j *prometheusJob) Name() string { return jobNamePrometheus }
|
|
|
|
func (j *prometheusJob) Status() *job.Status { return &job.Status{Type: job.TypeInternal} }
|
|
|
|
func (j *prometheusJob) OwnedDatasetSubtreeRoot() (p *zfs.DatasetPath, ok bool) { return nil, false }
|
|
|
|
func (j *prometheusJob) SenderConfig() *endpoint.SenderConfig { return nil }
|
|
|
|
func (j *prometheusJob) RegisterMetrics(registerer prometheus.Registerer) {}
|
|
|
|
func (j *prometheusJob) Run(ctx context.Context) {
|
|
|
|
if err := zfs.PrometheusRegister(prometheus.DefaultRegisterer); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if err := frameconn.PrometheusRegister(prometheus.DefaultRegisterer); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
log := job.GetLogger(ctx)
|
|
|
|
l, err := tcpsock.Listen(j.listen, j.freeBind)
|
|
if err != nil {
|
|
log.WithError(err).Error("cannot listen")
|
|
return
|
|
}
|
|
go func() {
|
|
<-ctx.Done()
|
|
l.Close()
|
|
}()
|
|
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/metrics", promhttp.Handler())
|
|
|
|
server := &http.Server{
|
|
Handler: mux,
|
|
TLSConfig: j.tls,
|
|
}
|
|
|
|
if j.tls != nil {
|
|
err = server.ServeTLS(l, "", "")
|
|
} else {
|
|
err = server.Serve(l)
|
|
}
|
|
if err != nil && ctx.Err() == nil {
|
|
log.WithError(err).Error("error while serving")
|
|
}
|
|
|
|
}
|
|
|
|
type prometheusJobOutlet struct {
|
|
}
|
|
|
|
var _ logger.Outlet = prometheusJobOutlet{}
|
|
|
|
func newPrometheusLogOutlet() prometheusJobOutlet {
|
|
return prometheusJobOutlet{}
|
|
}
|
|
|
|
func (o prometheusJobOutlet) WriteEntry(entry logger.Entry) error {
|
|
jobFieldVal, ok := entry.Fields[logging.JobField].(string)
|
|
if !ok {
|
|
jobFieldVal = "_nojobid"
|
|
}
|
|
prom.taskLogEntries.WithLabelValues(jobFieldVal, entry.Level.String()).Inc()
|
|
return nil
|
|
}
|