CI / changes (push) Successful in 9s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 26s
CI / web (push) Successful in 33s
CI / go (push) Successful in 2m11s
CI / bird2 (push) Successful in 16s
CI / release (push) Successful in 3m27s
Added PostgreSQL monitoring and maintenance capabilities to the API, including new endpoints for instance-level metrics, maintenance operations, and job scheduling. Updated the HTTP API to support PostgreSQL monitoring routes and integrated a background scheduler for metrics collection. Enhanced the CLI with database commands for maintenance tasks. Updated documentation to reflect these changes.
106 lines
2.5 KiB
Go
106 lines
2.5 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ed25519"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"evobgp/internal/jobs"
|
|
"evobgp/internal/pgmonitor"
|
|
"evobgp/internal/store"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// Server implements EvoBGP control-plane HTTP API.
|
|
type Server struct {
|
|
store store.Backend
|
|
pgPool *pgxpool.Pool
|
|
pgMonitor *pgmonitor.Service
|
|
jobs *jobs.Registry
|
|
bundlePriv ed25519.PrivateKey
|
|
keyResolver *apiKeyResolver
|
|
corsOrigins []string
|
|
cdnHTTP *http.Client
|
|
mux *http.ServeMux
|
|
}
|
|
|
|
// Options configures the API server.
|
|
type Options struct {
|
|
APIKeys string
|
|
// DatabaseURL enables PostgreSQL-backed store (migrations applied on connect).
|
|
DatabaseURL string
|
|
InsecureDev bool
|
|
SeedDemo bool
|
|
BundleSeedHex string
|
|
CORSAllowedOrigins string
|
|
}
|
|
|
|
// New constructs Server and wiring for async jobs.
|
|
func New(opts Options) (*Server, error) {
|
|
backend, reg, pool, err := BootstrapWorkers(context.Background(), opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var priv ed25519.PrivateKey
|
|
if strings.TrimSpace(opts.BundleSeedHex) != "" {
|
|
seed, err := hex.DecodeString(strings.TrimSpace(opts.BundleSeedHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(seed) != ed25519.SeedSize {
|
|
return nil, errors.New("httpapi: BundleSeedHex must decode to 32 bytes")
|
|
}
|
|
priv = ed25519.NewKeyFromSeed(seed)
|
|
} else {
|
|
_, priv, _ = ed25519.GenerateKey(rand.Reader)
|
|
}
|
|
|
|
resolver, err := newAPIKeyResolver(opts.APIKeys, backend)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var pgMon *pgmonitor.Service
|
|
if pool != nil {
|
|
pgMon = pgmonitor.NewService(pool)
|
|
}
|
|
s := &Server{
|
|
store: backend,
|
|
pgPool: pool,
|
|
pgMonitor: pgMon,
|
|
jobs: reg,
|
|
bundlePriv: priv,
|
|
keyResolver: resolver,
|
|
corsOrigins: parseCORSOrigins(opts.CORSAllowedOrigins),
|
|
cdnHTTP: NewCDNHTTPClient(),
|
|
}
|
|
s.mux = http.NewServeMux()
|
|
s.registerRoutes()
|
|
return s, nil
|
|
}
|
|
|
|
// Close releases database resources.
|
|
func (s *Server) Close() {
|
|
if s.pgPool != nil {
|
|
s.pgPool.Close()
|
|
}
|
|
}
|
|
|
|
// Store exposes the backing store (for operators / tests).
|
|
func (s *Server) Store() store.Backend { return s.store }
|
|
|
|
// Jobs exposes the in-process async job registry (for scheduler / evobgp-all).
|
|
func (s *Server) Jobs() *jobs.Registry { return s.jobs }
|
|
|
|
// StartBackground starts PostgreSQL monitoring scheduler until ctx is cancelled.
|
|
func (s *Server) StartBackground(ctx context.Context) {
|
|
if s != nil && s.pgPool != nil {
|
|
pgmonitor.StartScheduler(ctx, s.pgPool)
|
|
}
|
|
}
|