Merge Go frontend (apiserver + xcecli) into meson build

This commit is contained in:
Rongsong Shen 2026-04-14 11:20:17 +08:00
parent 43dc12a36c
commit c9dc8c4676
205 changed files with 30793 additions and 328 deletions

View file

@ -0,0 +1,117 @@
package main
import (
_ "apiserver/docs"
"apiserver/backend"
"apiserver/backend/auth"
"apiserver/middleware"
"apiserver/router"
"apiserver/store"
"apiserver/utils"
logger "apiserver/utils"
"flag"
"fmt"
"io"
"os"
"apiserver/controllers"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func main() {
gin.SetMode(gin.ReleaseMode)
gin.DefaultWriter = io.Discard
gin.DefaultErrorWriter = io.Discard
topDir := flag.String("d", "", "Top directory (default: current directory)")
flag.Usage = func() {
fmt.Fprintln(os.Stderr, `
Usage: apiserver -d <top_directory>
Top directory (default: current directory)
`)
}
flag.Parse()
utils.Global_TopDir = utils.PromptForTopDir(topDir)
if err := utils.InitLogger(); err != nil {
os.Exit(1)
}
logger.Info("********** Initialize Logger done!")
if err := utils.InitConf(); err != nil {
logger.Error("Failed to initialize configuration files", zap.Error(err))
os.Exit(1)
}
logger.Info("********** Initialize configuration files done!")
// Initialize in-memory stores
store.InitStores()
logger.Info("********** Initialize in-memory stores done!")
// Load builtin test data and RBAC from config
if err := store.LoadBuiltinData(); err != nil {
logger.Error("Failed to load builtin data", zap.Error(err))
os.Exit(1)
}
logger.Info("********** Load builtin data done!")
// Connect to the XCE controller backend for live data.
// StartNotificationListener must be called before RegisterToBackend so the
// handler is ready before any push events can arrive.
if utils.BackendYamlConfig != nil && utils.BackendYamlConfig.Address != "" {
handler := &backend.DefaultHandler{}
if err := backend.StartNotificationListener(handler); err != nil {
logger.Error("Failed to start notification listener", zap.Error(err))
os.Exit(1)
}
bcfg := &backend.BackendConfig{
Address: utils.BackendYamlConfig.Address,
Port: utils.BackendYamlConfig.Port,
From: utils.BackendYamlConfig.From,
Key: utils.BackendYamlConfig.Key,
}
if err := backend.RegisterToBackend(bcfg); err != nil {
logger.Error("Failed to connect to backend", zap.Error(err))
os.Exit(1)
}
logger.Info("********** Backend connection registered!")
} else {
logger.Info("********** Backend not configured — running in stub mode")
}
// Load RBAC config
rbacPath := utils.Global_TopDir + "/config/rbac.yaml"
if err := controllers.LoadRBACConfig(rbacPath); err != nil {
logger.Error("Failed to load RBAC config", zap.Error(err))
os.Exit(1)
}
logger.Info("********** Load RBAC config done!")
// Initialize auth provider
authConfigPath := utils.Global_TopDir + "/config/auth.yaml"
if err := auth.InitAuthProvider(authConfigPath); err != nil {
logger.Error("Failed to initialize auth provider", zap.Error(err))
os.Exit(1)
}
logger.Info("********** Initialize auth provider done! (" + auth.GlobalProvider.Name() + ")")
// Pre-populate user-role store from auth provider so permissions work
// immediately after restart without requiring users to re-login.
if seeder, ok := auth.GlobalProvider.(auth.UserRoleSeeder); ok {
for _, username := range seeder.AllUsers() {
for _, role := range auth.GlobalProvider.GetUserRoles(username) {
store.AddRoleForUser(username, role)
}
}
logger.Info("********** Pre-populated user-role store from auth provider done!")
}
r := router.Router()
if err := middleware.StartServer(r); err != nil {
logger.Error("Server failed to start:", zap.Error(err))
os.Exit(1)
}
}