Files
EvoBGP/cmd/evobgp-api/main.go
T
Denozordec 6329a4df27
CI / changes (push) Successful in 7s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 25s
CI / web (push) Successful in 28s
CI / go (push) Failing after 24s
CI / bird2 (push) Has been skipped
CI / release (push) Has been skipped
feat(api): implement API key management and authentication enhancements
- Added endpoints for managing API keys, including creation, retrieval, updating, and revocation.
- Introduced a new Auth session endpoint to retrieve current tenant and role information.
- Updated the authentication middleware to support API key-based authentication and track last used timestamps.
- Enhanced documentation to reflect new API key functionalities and usage guidelines.
- Improved logging for demo authentication scenarios.
2026-05-21 11:26:17 +07:00

95 lines
2.9 KiB
Go

package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"
"evobgp/internal/birdfmt"
"evobgp/internal/config"
"evobgp/internal/httpapi"
"evobgp/internal/observability"
"evobgp/internal/platform"
"evobgp/internal/version"
)
func main() {
cfg := config.Load()
seedDemo := os.Getenv("EVOBGP_SEED_DEMO") != "0"
opts := httpapi.Options{
APIKeys: os.Getenv("EVOBGP_API_KEYS"),
DatabaseURL: cfg.DatabaseURL,
InsecureDev: os.Getenv("EVOBGP_DEV_INSECURE") == "1",
SeedDemo: seedDemo,
BundleSeedHex: strings.TrimSpace(os.Getenv("EVOBGP_BUNDLE_SEED_HEX")),
CORSAllowedOrigins: strings.TrimSpace(os.Getenv("EVOBGP_CORS_ORIGINS")),
}
srv, err := httpapi.New(opts)
if err != nil {
log.Fatal(err)
}
defer srv.Close()
observability.SetBuildInfo(version.Version, version.GitSHA)
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
startBirdMetricsPoller(ctx)
httpSrv := &http.Server{
Addr: cfg.HTTPAddr,
Handler: srv.Handler(),
ReadHeaderTimeout: 10 * time.Second,
ReadTimeout: 60 * time.Second,
WriteTimeout: 120 * time.Second,
IdleTimeout: 120 * time.Second,
}
go func() {
svc := platform.ServiceName("evobgp-api")
log.Printf("%s listening on %s", svc, cfg.HTTPAddr)
log.Printf("bundle signing public key (base64, set on evobgp-node): %s", srv.BundlePublicKeyBase64())
if opts.SeedDemo {
tid, mCDN, mIP, rev, sp := srv.Store().DemoIDs()
log.Printf("demo tenant=%s module_cdn=%s module_ip_ranges=%s revision=%s speaker=%s", tid, mCDN, mIP, rev, sp)
log.Printf("example: EVOBGP_API_KEYS=op|%s|operator,node|%s|node", tid, tid)
log.Printf("demo auth: Authorization: Bearer dev (operator, demo tenant only)")
}
if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := httpSrv.Shutdown(shutdownCtx); err != nil {
log.Printf("HTTP shutdown: %v", err)
}
log.Printf("%s stopped", platform.ServiceName("evobgp-api"))
}
func startBirdMetricsPoller(ctx context.Context) {
sock := strings.TrimSpace(os.Getenv("EVOBGP_BIRDC_SOCKET"))
if sock == "" {
return
}
interval := 30 * time.Second
if d, err := time.ParseDuration(strings.TrimSpace(os.Getenv("EVOBGP_BIRDC_INTERVAL"))); err == nil && d > 0 {
interval = d
}
bin := strings.TrimSpace(os.Getenv("EVOBGP_BIRDC_BIN"))
observability.StartBirdProtocolsPoller(ctx, sock, bin, interval,
func(ctx context.Context, socket, birdcBin string) (string, error) {
return birdfmt.ShowProtocols(ctx, socket, birdcBin)
},
birdfmt.CountEstablishedBGPSessions,
birdfmt.ParseBGPProtocolStates,
)
log.Printf("birdc protocols poller enabled (socket=%s interval=%s)", sock, interval)
}