Files
EvoBGP/internal/httpapi/server.go
T
Denozordec 032fa9945c
CI / changes (push) Successful in 5s
CI / go (push) Successful in 22s
CI / openapi (push) Has been skipped
CI / bird2 (push) Successful in 15s
refactor: adjust BootstrapWorkers function call in server.go to change the order of returned values, improving clarity in dependency management for backend, registry, and pool.
2026-04-05 17:45:13 +07:00

88 lines
2.0 KiB
Go

package httpapi
import (
"context"
"crypto/ed25519"
"crypto/rand"
"encoding/hex"
"errors"
"net/http"
"strings"
"evobgp/internal/jobs"
"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
jobs *jobs.Registry
bundlePriv ed25519.PrivateKey
apiKeys []apiKeyRecord
insecureDev bool
corsOrigins []string
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)
}
s := &Server{
store: backend,
pgPool: pool,
jobs: reg,
bundlePriv: priv,
apiKeys: parseAPIKeysSpec(opts.APIKeys),
insecureDev: opts.InsecureDev && opts.SeedDemo,
corsOrigins: parseCORSOrigins(opts.CORSAllowedOrigins),
}
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 }