mirror of
https://github.com/crocofied/CoreControl.git
synced 2025-12-17 15:36:50 +00:00
199 lines
5.6 KiB
Go
199 lines
5.6 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/corecontrol/agent/internal/models"
|
|
|
|
_ "github.com/jackc/pgx/v4/stdlib"
|
|
"github.com/joho/godotenv"
|
|
)
|
|
|
|
// InitDB initializes the database connection
|
|
func InitDB() (*sql.DB, error) {
|
|
// Load environment variables
|
|
if err := godotenv.Load(); err != nil {
|
|
fmt.Println("No env vars found")
|
|
}
|
|
|
|
dbURL := os.Getenv("DATABASE_URL")
|
|
if dbURL == "" {
|
|
return nil, fmt.Errorf("DATABASE_URL not set")
|
|
}
|
|
|
|
db, err := sql.Open("pgx", dbURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("database connection failed: %v", err)
|
|
}
|
|
|
|
return db, nil
|
|
}
|
|
|
|
// GetApplications fetches all applications with public URLs
|
|
func GetApplications(db *sql.DB) ([]models.Application, error) {
|
|
rows, err := db.Query(
|
|
`SELECT id, name, "publicURL", online, "uptimecheckURL" FROM application WHERE "publicURL" IS NOT NULL`,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error fetching applications: %v", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var apps []models.Application
|
|
for rows.Next() {
|
|
var app models.Application
|
|
if err := rows.Scan(&app.ID, &app.Name, &app.PublicURL, &app.Online, &app.UptimeCheckURL); err != nil {
|
|
fmt.Printf("Error scanning row: %v\n", err)
|
|
continue
|
|
}
|
|
apps = append(apps, app)
|
|
}
|
|
return apps, nil
|
|
}
|
|
|
|
// GetServers fetches all servers with monitoring enabled
|
|
func GetServers(db *sql.DB) ([]models.Server, error) {
|
|
rows, err := db.Query(
|
|
`SELECT id, name, monitoring, "monitoringURL", online, "cpuUsage", "ramUsage", "diskUsage"
|
|
FROM server WHERE monitoring = true`,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error fetching servers: %v", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var servers []models.Server
|
|
for rows.Next() {
|
|
var server models.Server
|
|
if err := rows.Scan(
|
|
&server.ID, &server.Name, &server.Monitoring, &server.MonitoringURL,
|
|
&server.Online, &server.CpuUsage, &server.RamUsage, &server.DiskUsage,
|
|
); err != nil {
|
|
fmt.Printf("Error scanning server row: %v\n", err)
|
|
continue
|
|
}
|
|
servers = append(servers, server)
|
|
}
|
|
return servers, nil
|
|
}
|
|
|
|
// LoadNotifications loads all enabled notifications
|
|
func LoadNotifications(db *sql.DB) ([]models.Notification, error) {
|
|
rows, err := db.Query(
|
|
`SELECT id, enabled, type, "smtpHost", "smtpPort", "smtpFrom", "smtpUser", "smtpPass", "smtpSecure", "smtpTo",
|
|
"telegramChatId", "telegramToken", "discordWebhook", "gotifyUrl", "gotifyToken", "ntfyUrl", "ntfyToken",
|
|
"pushoverUrl", "pushoverToken", "pushoverUser"
|
|
FROM notification
|
|
WHERE enabled = true`,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var configs []models.Notification
|
|
for rows.Next() {
|
|
var n models.Notification
|
|
if err := rows.Scan(
|
|
&n.ID, &n.Enabled, &n.Type,
|
|
&n.SMTPHost, &n.SMTPPort, &n.SMTPFrom, &n.SMTPUser, &n.SMTPPass, &n.SMTPSecure, &n.SMTPTo,
|
|
&n.TelegramChatID, &n.TelegramToken, &n.DiscordWebhook,
|
|
&n.GotifyUrl, &n.GotifyToken, &n.NtfyUrl, &n.NtfyToken,
|
|
&n.PushoverUrl, &n.PushoverToken, &n.PushoverUser,
|
|
); err != nil {
|
|
fmt.Printf("Error scanning notification: %v\n", err)
|
|
continue
|
|
}
|
|
configs = append(configs, n)
|
|
}
|
|
return configs, nil
|
|
}
|
|
|
|
// DeleteOldEntries removes entries older than 30 days
|
|
func DeleteOldEntries(db *sql.DB) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
// Delete old uptime history entries
|
|
res, err := db.ExecContext(ctx,
|
|
`DELETE FROM uptime_history WHERE "createdAt" < now() - interval '30 days'`,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
affected, _ := res.RowsAffected()
|
|
fmt.Printf("Deleted %d old entries from uptime_history\n", affected)
|
|
|
|
// Delete old server history entries
|
|
res, err = db.ExecContext(ctx,
|
|
`DELETE FROM server_history WHERE "createdAt" < now() - interval '30 days'`,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
affected, _ = res.RowsAffected()
|
|
fmt.Printf("Deleted %d old entries from server_history\n", affected)
|
|
|
|
return nil
|
|
}
|
|
|
|
// UpdateServerStatus updates a server's status and metrics
|
|
func UpdateServerStatus(db *sql.DB, serverID int, online bool, cpuUsage, ramUsage, diskUsage float64, uptime string) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
_, err := db.ExecContext(ctx,
|
|
`UPDATE server SET online = $1, "cpuUsage" = $2::float8, "ramUsage" = $3::float8, "diskUsage" = $4::float8, "uptime" = $5
|
|
WHERE id = $6`,
|
|
online, cpuUsage, ramUsage, diskUsage, uptime, serverID,
|
|
)
|
|
return err
|
|
}
|
|
|
|
// CheckAndSendTestNotifications checks for and processes test notifications
|
|
func CheckAndSendTestNotifications(db *sql.DB, notifications []models.Notification, sendFunc func(models.Notification, string)) {
|
|
// Query for test notifications
|
|
rows, err := db.Query(`SELECT tn.id, tn."notificationId" FROM test_notification tn`)
|
|
if err != nil {
|
|
fmt.Printf("Error fetching test notifications: %v\n", err)
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
|
|
// Process each test notification
|
|
var testIds []int
|
|
for rows.Next() {
|
|
var id, notificationId int
|
|
if err := rows.Scan(&id, ¬ificationId); err != nil {
|
|
fmt.Printf("Error scanning test notification: %v\n", err)
|
|
continue
|
|
}
|
|
|
|
// Add to list of IDs to delete
|
|
testIds = append(testIds, id)
|
|
|
|
// Find the notification configuration
|
|
for _, n := range notifications {
|
|
if n.ID == notificationId {
|
|
// Send test notification
|
|
fmt.Printf("Sending test notification to notification ID %d\n", notificationId)
|
|
sendFunc(n, "Test notification from CoreControl")
|
|
}
|
|
}
|
|
}
|
|
|
|
// Delete processed test notifications
|
|
if len(testIds) > 0 {
|
|
for _, id := range testIds {
|
|
_, err := db.Exec(`DELETE FROM test_notification WHERE id = $1`, id)
|
|
if err != nil {
|
|
fmt.Printf("Error deleting test notification (ID: %d): %v\n", id, err)
|
|
}
|
|
}
|
|
}
|
|
}
|