feat: enhance evobgp with new command-line tools for bundle management, including pull, verify, and apply functionalities. Update go.mod to include necessary dependencies and complete todos in architecture plan for improved observability and deployment practices.
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"evobgp/internal/jobs"
|
||||
"evobgp/internal/observability"
|
||||
"evobgp/internal/store"
|
||||
)
|
||||
|
||||
// Server implements EvoBGP control-plane HTTP API (subset focused on jobs, deploy, node bundle).
|
||||
type Server struct {
|
||||
store *store.Memory
|
||||
jobs *jobs.Registry
|
||||
bundlePriv ed25519.PrivateKey
|
||||
apiKeys []apiKeyRecord
|
||||
insecureDev bool
|
||||
corsOrigins []string
|
||||
mux *http.ServeMux
|
||||
}
|
||||
|
||||
// Options configures the API server.
|
||||
type Options struct {
|
||||
// APIKeys is comma-separated "token|tenantUUID|role" (role: viewer, editor, operator, node).
|
||||
APIKeys string
|
||||
// InsecureDev with SeedDemo allows Bearer "dev" as operator for the demo tenant (local only).
|
||||
InsecureDev bool
|
||||
SeedDemo bool
|
||||
// BundleSeedHex is 64 hex chars (32 bytes) for deterministic Ed25519 bundle signing; if empty, random.
|
||||
BundleSeedHex string
|
||||
// CORSAllowedOrigins is comma-separated list of allowed browser Origins (e.g. http://localhost:4173).
|
||||
CORSAllowedOrigins string
|
||||
}
|
||||
|
||||
// New constructs Server and wiring for async jobs.
|
||||
func New(opts Options) (*Server, error) {
|
||||
mem := store.NewMemory()
|
||||
if opts.SeedDemo {
|
||||
mem.SeedDemo()
|
||||
}
|
||||
wk := &jobs.Worker{Store: mem}
|
||||
reg := jobs.NewRegistry(wk.Process)
|
||||
|
||||
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: mem,
|
||||
jobs: reg,
|
||||
bundlePriv: priv,
|
||||
apiKeys: parseAPIKeysSpec(opts.APIKeys),
|
||||
insecureDev: opts.InsecureDev && opts.SeedDemo,
|
||||
corsOrigins: parseCORSOrigins(opts.CORSAllowedOrigins),
|
||||
}
|
||||
observability.RegisterStoreMetrics(mem)
|
||||
s.mux = http.NewServeMux()
|
||||
s.registerRoutes()
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Store exposes the in-memory store (for operators / tests).
|
||||
func (s *Server) Store() *store.Memory { return s.store }
|
||||
Reference in New Issue
Block a user