mirror of
https://github.com/MizuchiLabs/mantrae.git
synced 2025-12-16 20:05:17 -06:00
129 lines
3.0 KiB
Go
129 lines
3.0 KiB
Go
// package tasks provides functionality for running periodic tasks.
|
|
package tasks
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"github.com/mizuchilabs/mantrae/server/internal/config"
|
|
"github.com/mizuchilabs/mantrae/server/internal/dns"
|
|
"github.com/mizuchilabs/mantrae/server/internal/settings"
|
|
"github.com/mizuchilabs/mantrae/server/internal/store/db"
|
|
)
|
|
|
|
type Scheduler struct {
|
|
ctx context.Context
|
|
cfg *config.App
|
|
}
|
|
|
|
func NewScheduler(ctx context.Context, cfg *config.App) *Scheduler {
|
|
return &Scheduler{ctx: ctx, cfg: cfg}
|
|
}
|
|
|
|
func (s *Scheduler) Start() {
|
|
go s.syncDNS()
|
|
go s.cleanupAgents()
|
|
}
|
|
|
|
// syncDNS periodically syncs the DNS records
|
|
func (s *Scheduler) syncDNS() {
|
|
duration, ok := s.cfg.SM.Get(s.ctx, settings.KeyDNSSyncInterval)
|
|
if !ok {
|
|
slog.Error("Failed to get DNS sync interval setting")
|
|
return
|
|
}
|
|
|
|
ticker := time.NewTicker(settings.AsDuration(duration))
|
|
defer ticker.Stop()
|
|
|
|
manager := dns.NewManager(s.cfg.Conn, s.cfg.Secret)
|
|
if err := manager.UpdateDNS(); err != nil {
|
|
slog.Error("Failed to update DNS", "error", err)
|
|
}
|
|
for {
|
|
select {
|
|
case <-s.ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
if err := manager.UpdateDNS(); err != nil {
|
|
slog.Error("Failed to update DNS", "error", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *Scheduler) cleanupAgents() {
|
|
duration, ok := s.cfg.SM.Get(s.ctx, settings.KeyAgentCleanupInterval)
|
|
if !ok {
|
|
slog.Error("failed to get agent cleanup interval setting")
|
|
return
|
|
}
|
|
|
|
ticker := time.NewTicker(settings.AsDuration(duration))
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-s.ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
enabled, ok := s.cfg.SM.Get(s.ctx, settings.KeyAgentCleanupEnabled)
|
|
if !ok {
|
|
slog.Error("failed to get agent cleanup enabled setting")
|
|
return
|
|
}
|
|
if enabled != "true" {
|
|
slog.Info("agent cleanup is disabled, skipping")
|
|
return
|
|
}
|
|
|
|
// Timeout to delete old agents
|
|
timeout, ok := s.cfg.SM.Get(s.ctx, settings.KeyAgentCleanupInterval)
|
|
if !ok {
|
|
slog.Error("failed to get agent cleanup interval setting")
|
|
return
|
|
}
|
|
|
|
// List profiles
|
|
profiles, err := s.cfg.Conn.GetQuery().ListProfiles(s.ctx, &db.ListProfilesParams{})
|
|
if err != nil {
|
|
slog.Error("failed to list profiles", "error", err)
|
|
continue
|
|
}
|
|
|
|
var agents []*db.Agent
|
|
for _, profile := range profiles {
|
|
a, err := s.cfg.Conn.GetQuery().
|
|
ListAgents(s.ctx, &db.ListAgentsParams{ProfileID: profile.ID})
|
|
if err != nil {
|
|
slog.Error("failed to list agents", "error", err)
|
|
continue
|
|
}
|
|
agents = append(agents, a...)
|
|
}
|
|
|
|
for _, agent := range agents {
|
|
if agent.UpdatedAt == nil || agent.Hostname == nil {
|
|
continue
|
|
}
|
|
|
|
if time.Since(*agent.UpdatedAt) > settings.AsDuration(timeout) {
|
|
if err := s.cfg.Conn.GetQuery().DeleteAgent(s.ctx, agent.ID); err != nil {
|
|
slog.Error(
|
|
"failed to delete disconnected agent",
|
|
"id",
|
|
agent.ID,
|
|
"error",
|
|
err,
|
|
)
|
|
continue
|
|
} else {
|
|
slog.Info("Deleted disconnected agent", "id", agent.ID)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|