mirror of
https://github.com/fankes/beszel.git
synced 2025-10-20 02:09:28 +08:00
@@ -15,6 +15,7 @@ require (
|
|||||||
github.com/spf13/cast v1.7.0
|
github.com/spf13/cast v1.7.0
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
golang.org/x/crypto v0.28.0
|
golang.org/x/crypto v0.28.0
|
||||||
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
@@ -398,6 +398,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
135
beszel/internal/hub/config.go
Normal file
135
beszel/internal/hub/config.go
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package hub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"beszel/internal/entities/system"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Systems []SystemConfig `yaml:"systems"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemConfig struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port string `yaml:"port"`
|
||||||
|
Users []string `yaml:"users"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syncs systems with the config.yml file
|
||||||
|
func (h *Hub) syncSystemsWithConfig() error {
|
||||||
|
configPath := filepath.Join(h.app.DataDir(), "config.yml")
|
||||||
|
configData, err := os.ReadFile(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var config Config
|
||||||
|
err = yaml.Unmarshal(configData, &config)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse config.yml: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(config.Systems) == 0 {
|
||||||
|
log.Println("No systems defined in config.yml.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstUser *models.Record
|
||||||
|
|
||||||
|
// Create a map of email to user ID
|
||||||
|
userEmailToID := make(map[string]string)
|
||||||
|
users, err := h.app.Dao().FindRecordsByFilter("users", "id != ''", "created", -1, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(users) > 0 {
|
||||||
|
firstUser = users[0]
|
||||||
|
for _, user := range users {
|
||||||
|
userEmailToID[user.GetString("email")] = user.Id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add default settings for systems if not defined in config
|
||||||
|
for i := range config.Systems {
|
||||||
|
system := &config.Systems[i]
|
||||||
|
if system.Port == "" {
|
||||||
|
system.Port = "45876"
|
||||||
|
}
|
||||||
|
if len(users) > 0 && len(system.Users) == 0 {
|
||||||
|
// default to first user if none are defined
|
||||||
|
system.Users = []string{firstUser.Id}
|
||||||
|
} else {
|
||||||
|
// Convert email addresses to user IDs
|
||||||
|
userIDs := make([]string, 0, len(system.Users))
|
||||||
|
for _, email := range system.Users {
|
||||||
|
if id, ok := userEmailToID[email]; ok {
|
||||||
|
userIDs = append(userIDs, id)
|
||||||
|
} else {
|
||||||
|
log.Printf("User %s not found", email)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
system.Users = userIDs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get existing systems
|
||||||
|
existingSystems, err := h.app.Dao().FindRecordsByFilter("systems", "id != ''", "", -1, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a map of existing systems for easy lookup
|
||||||
|
existingSystemsMap := make(map[string]*models.Record)
|
||||||
|
for _, system := range existingSystems {
|
||||||
|
key := system.GetString("host") + ":" + system.GetString("port")
|
||||||
|
existingSystemsMap[key] = system
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process systems from config
|
||||||
|
for _, sysConfig := range config.Systems {
|
||||||
|
key := sysConfig.Host + ":" + sysConfig.Port
|
||||||
|
if existingSystem, ok := existingSystemsMap[key]; ok {
|
||||||
|
// Update existing system
|
||||||
|
existingSystem.Set("name", sysConfig.Name)
|
||||||
|
existingSystem.Set("users", sysConfig.Users)
|
||||||
|
existingSystem.Set("port", sysConfig.Port)
|
||||||
|
if err := h.app.Dao().SaveRecord(existingSystem); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
delete(existingSystemsMap, key)
|
||||||
|
} else {
|
||||||
|
// Create new system
|
||||||
|
systemsCollection, err := h.app.Dao().FindCollectionByNameOrId("systems")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to find systems collection: %v", err)
|
||||||
|
}
|
||||||
|
newSystem := models.NewRecord(systemsCollection)
|
||||||
|
newSystem.Set("name", sysConfig.Name)
|
||||||
|
newSystem.Set("host", sysConfig.Host)
|
||||||
|
newSystem.Set("port", sysConfig.Port)
|
||||||
|
newSystem.Set("users", sysConfig.Users)
|
||||||
|
newSystem.Set("info", system.Info{})
|
||||||
|
newSystem.Set("status", "pending")
|
||||||
|
if err := h.app.Dao().SaveRecord(newSystem); err != nil {
|
||||||
|
return fmt.Errorf("failed to create new system: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete systems not in config
|
||||||
|
for _, system := range existingSystemsMap {
|
||||||
|
if err := h.app.Dao().DeleteRecord(system); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Systems synced with config.yml")
|
||||||
|
return nil
|
||||||
|
}
|
@@ -56,14 +56,10 @@ func NewHub(app *pocketbase.PocketBase) *Hub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Hub) Run() {
|
func (h *Hub) Run() {
|
||||||
// rm := records.NewRecordManager(h.app)
|
|
||||||
// am := alerts.NewAlertManager(h.app)
|
|
||||||
// um := users.NewUserManager(h.app)
|
|
||||||
|
|
||||||
// loosely check if it was executed using "go run"
|
// loosely check if it was executed using "go run"
|
||||||
isGoRun := strings.HasPrefix(os.Args[0], os.TempDir())
|
isGoRun := strings.HasPrefix(os.Args[0], os.TempDir())
|
||||||
|
|
||||||
// // enable auto creation of migration files when making collection changes in the Admin UI
|
// enable auto creation of migration files when making collection changes in the Admin UI
|
||||||
migratecmd.MustRegister(h.app, h.app.RootCmd, migratecmd.Config{
|
migratecmd.MustRegister(h.app, h.app.RootCmd, migratecmd.Config{
|
||||||
// (the isGoRun check is to enable it only during development)
|
// (the isGoRun check is to enable it only during development)
|
||||||
Automigrate: isGoRun,
|
Automigrate: isGoRun,
|
||||||
@@ -93,7 +89,8 @@ func (h *Hub) Run() {
|
|||||||
if err := h.app.Dao().SaveCollection(usersCollection); err != nil {
|
if err := h.app.Dao().SaveCollection(usersCollection); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
// sync systems with config
|
||||||
|
return h.syncSystemsWithConfig()
|
||||||
})
|
})
|
||||||
|
|
||||||
// serve web ui
|
// serve web ui
|
||||||
|
@@ -112,14 +112,6 @@ func (rm *RecordManager) CreateLongerRecords() {
|
|||||||
// get shorter records from the past x minutes
|
// get shorter records from the past x minutes
|
||||||
var stats RecordStats
|
var stats RecordStats
|
||||||
|
|
||||||
// allShorterRecords, err := txDao.FindRecordsByExpr(
|
|
||||||
// collection,
|
|
||||||
// dbx.NewExp(
|
|
||||||
// "type = {:type} AND system = {:system} AND created > {:created}",
|
|
||||||
// dbx.Params{"type": recordData.shorterType, "system": system.Id, "created": shorterRecordPeriod},
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
|
|
||||||
err := txDao.DB().
|
err := txDao.DB().
|
||||||
Select("stats").
|
Select("stats").
|
||||||
From(collection.Name).
|
From(collection.Name).
|
||||||
|
Reference in New Issue
Block a user