feat: Updates-Tab, Aufgaben-Tab ProxmoxPanel, security_only Tasks, 3x Netzwerk-Charts, Updates-Spalte Übersicht, dist-upgrade, DeleteAgent cascades metrics
This commit is contained in:
@@ -62,7 +62,7 @@ func (s *TaskScheduler) executeTask(task models.Task) {
|
||||
case "backup":
|
||||
result, taskErr = s.executeBackup(task.AgentID)
|
||||
case "update":
|
||||
result, taskErr = s.executeUpdateWithHealthCheck(task.AgentID, task.Reboot, task.HealthCheck, task.HealthCheckTimeout)
|
||||
result, taskErr = s.executeUpdateWithHealthCheck(task.AgentID, task.Reboot, task.HealthCheck, task.HealthCheckTimeout, task.SecurityOnly)
|
||||
default:
|
||||
taskErr = fmt.Errorf("unbekannte Aktion: %s", task.Action)
|
||||
}
|
||||
@@ -174,10 +174,10 @@ func (s *TaskScheduler) executeBackup(agentID string) (interface{}, error) {
|
||||
}
|
||||
|
||||
func (s *TaskScheduler) executeUpdate(agentID string, reboot bool) (interface{}, error) {
|
||||
return s.executeUpdateWithHealthCheck(agentID, reboot, false, 600)
|
||||
return s.executeUpdateWithHealthCheck(agentID, reboot, false, 600, false)
|
||||
}
|
||||
|
||||
func (s *TaskScheduler) executeUpdateWithHealthCheck(agentID string, reboot bool, healthCheck bool, healthCheckTimeout int) (interface{}, error) {
|
||||
func (s *TaskScheduler) executeUpdateWithHealthCheck(agentID string, reboot bool, healthCheck bool, healthCheckTimeout int, securityOnly bool) (interface{}, error) {
|
||||
if !s.hub.IsAgentConnected(agentID) {
|
||||
return nil, fmt.Errorf("Agent nicht verbunden")
|
||||
}
|
||||
@@ -212,7 +212,7 @@ func (s *TaskScheduler) executeUpdateWithHealthCheck(agentID string, reboot bool
|
||||
"type": "command",
|
||||
"id": updateCmdID,
|
||||
"command": "update",
|
||||
"params": map[string]interface{}{"reboot": reboot},
|
||||
"params": map[string]interface{}{"reboot": reboot, "security_only": securityOnly},
|
||||
}
|
||||
|
||||
updateCh := s.hub.RegisterResponseWaiter(updateCmdID)
|
||||
|
||||
@@ -79,6 +79,7 @@ func (h *Handler) createTask(hub *ws.Hub) http.HandlerFunc {
|
||||
Reboot bool `json:"reboot"`
|
||||
HealthCheck bool `json:"health_check"`
|
||||
HealthCheckTimeout int `json:"health_check_timeout"`
|
||||
SecurityOnly bool `json:"security_only"`
|
||||
WebhookURL string `json:"webhook_url"`
|
||||
Active *bool `json:"active"`
|
||||
}
|
||||
@@ -117,7 +118,7 @@ func (h *Handler) createTask(hub *ws.Hub) http.HandlerFunc {
|
||||
req.AgentID, req.Action, req.ScheduledAt, req.WebhookURL, createdBy,
|
||||
req.Name, req.ScheduleType, req.ScheduleTime,
|
||||
req.ScheduleWeekday, req.ScheduleMonthday,
|
||||
req.Reboot, req.HealthCheck, req.HealthCheckTimeout, active,
|
||||
req.Reboot, req.HealthCheck, req.HealthCheckTimeout, req.SecurityOnly, active,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Task erstellen fehlgeschlagen: %v", err)
|
||||
|
||||
@@ -261,6 +261,7 @@ func (d *Database) migrate() error {
|
||||
d.db.Exec(`ALTER TABLE tasks ADD COLUMN IF NOT EXISTS reboot BOOLEAN DEFAULT FALSE`)
|
||||
d.db.Exec(`ALTER TABLE tasks ADD COLUMN IF NOT EXISTS health_check BOOLEAN DEFAULT FALSE`)
|
||||
d.db.Exec(`ALTER TABLE tasks ADD COLUMN IF NOT EXISTS health_check_timeout INT DEFAULT 600`)
|
||||
d.db.Exec(`ALTER TABLE tasks ADD COLUMN IF NOT EXISTS security_only BOOLEAN DEFAULT FALSE`)
|
||||
d.db.Exec(`ALTER TABLE tasks ADD COLUMN IF NOT EXISTS active BOOLEAN DEFAULT TRUE`)
|
||||
d.db.Exec(`ALTER TABLE tasks ADD COLUMN IF NOT EXISTS last_run TIMESTAMPTZ`)
|
||||
d.db.Exec(`ALTER TABLE tasks ADD COLUMN IF NOT EXISTS next_run TIMESTAMPTZ`)
|
||||
@@ -759,6 +760,9 @@ func (d *Database) GetAllInstallerInfo() ([]map[string]interface{}, error) {
|
||||
}
|
||||
|
||||
func (d *Database) DeleteAgent(id string) (bool, error) {
|
||||
// metrics hat keinen FK-Cascade → manuell löschen
|
||||
d.db.Exec("DELETE FROM metrics WHERE agent_id = $1", id)
|
||||
// agents löschen → CASCADE löscht system_data, tasks, config_backups, agent_events
|
||||
res, err := d.db.Exec("DELETE FROM agents WHERE id = $1", id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
+8
-7
@@ -62,7 +62,7 @@ func CalculateNextRun(scheduleType, scheduleTime string, weekday, monthday *int,
|
||||
|
||||
func (d *Database) CreateTask(agentID, action, scheduledAt, webhookURL, createdBy string,
|
||||
name, scheduleType, scheduleTime string, weekday, monthday *int,
|
||||
reboot, healthCheck bool, healthCheckTimeout int, active bool) (*models.Task, error) {
|
||||
reboot, healthCheck bool, healthCheckTimeout int, securityOnly bool, active bool) (*models.Task, error) {
|
||||
|
||||
validActions := map[string]bool{"backup": true, "update": true}
|
||||
if !validActions[action] {
|
||||
@@ -107,12 +107,12 @@ func (d *Database) CreateTask(agentID, action, scheduledAt, webhookURL, createdB
|
||||
err := d.db.QueryRow(`
|
||||
INSERT INTO tasks (agent_id, name, action, scheduled_at, webhook_url, created_by,
|
||||
schedule_type, schedule_time, schedule_weekday, schedule_monthday,
|
||||
reboot, health_check, health_check_timeout, active, next_run)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
||||
reboot, health_check, health_check_timeout, security_only, active, next_run)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
RETURNING id
|
||||
`, agentID, name, action, schedTime, webhookURL, createdBy,
|
||||
scheduleType, scheduleTime, weekday, monthday,
|
||||
reboot, healthCheck, healthCheckTimeout, active, nextRun).Scan(&taskID)
|
||||
reboot, healthCheck, healthCheckTimeout, securityOnly, active, nextRun).Scan(&taskID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Task erstellen: %w", err)
|
||||
}
|
||||
@@ -129,7 +129,7 @@ func scanTask(scan func(dest ...interface{}) error) (*models.Task, error) {
|
||||
var agentName, customerName, customerNumber sql.NullString
|
||||
var name, scheduleType, scheduleTime sql.NullString
|
||||
var scheduleWeekday, scheduleMonthday sql.NullInt32
|
||||
var reboot, healthCheck, active sql.NullBool
|
||||
var reboot, healthCheck, securityOnly, active sql.NullBool
|
||||
var healthCheckTimeout, runCount sql.NullInt32
|
||||
|
||||
err := scan(
|
||||
@@ -138,7 +138,7 @@ func scanTask(scan func(dest ...interface{}) error) (*models.Task, error) {
|
||||
&resultJSON, &webhookURL, &t.WebhookSent, &webhookResponse,
|
||||
&createdBy, &createdAt,
|
||||
&scheduleType, &scheduleTime, &scheduleWeekday, &scheduleMonthday,
|
||||
&reboot, &healthCheck, &healthCheckTimeout, &active, &lastRun, &nextRun, &runCount,
|
||||
&reboot, &healthCheck, &healthCheckTimeout, &securityOnly, &active, &lastRun, &nextRun, &runCount,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -170,6 +170,7 @@ func scanTask(scan func(dest ...interface{}) error) (*models.Task, error) {
|
||||
if healthCheckTimeout.Valid {
|
||||
t.HealthCheckTimeout = int(healthCheckTimeout.Int32)
|
||||
}
|
||||
t.SecurityOnly = securityOnly.Valid && securityOnly.Bool
|
||||
t.Active = !active.Valid || active.Bool
|
||||
t.RunCount = int(runCount.Int32)
|
||||
|
||||
@@ -214,7 +215,7 @@ const taskSelectCols = `t.id, t.agent_id, COALESCE(a.name, ''), COALESCE(c.name,
|
||||
t.result, t.webhook_url, t.webhook_sent, t.webhook_response,
|
||||
t.created_by, t.created_at,
|
||||
t.schedule_type, t.schedule_time, t.schedule_weekday, t.schedule_monthday,
|
||||
t.reboot, t.health_check, t.health_check_timeout, t.active, t.last_run, t.next_run, t.run_count`
|
||||
t.reboot, t.health_check, t.health_check_timeout, COALESCE(t.security_only, FALSE), t.active, t.last_run, t.next_run, t.run_count`
|
||||
|
||||
const taskFromJoin = `FROM tasks t
|
||||
LEFT JOIN agents a ON a.id = t.agent_id
|
||||
|
||||
@@ -157,16 +157,27 @@ type PluginInfo struct {
|
||||
}
|
||||
|
||||
type UpdateInfo struct {
|
||||
UpdateAvailable bool `json:"update_available"`
|
||||
PendingCount int `json:"pending_count"`
|
||||
UpdateAvailable bool `json:"update_available"`
|
||||
PendingCount int `json:"pending_count"`
|
||||
SecurityCount int `json:"security_count,omitempty"`
|
||||
Updates []PendingUpdateInfo `json:"updates"`
|
||||
OPNsenseUpdate string `json:"opnsense_update,omitempty"`
|
||||
OPNsenseUpdate string `json:"opnsense_update,omitempty"`
|
||||
}
|
||||
|
||||
type PendingUpdateInfo struct {
|
||||
Package string `json:"package"`
|
||||
Arch string `json:"arch,omitempty"`
|
||||
CurrentVer string `json:"current_version"`
|
||||
NewVer string `json:"new_version"`
|
||||
Repository string `json:"repository,omitempty"`
|
||||
Security bool `json:"security,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateInfoFull struct {
|
||||
UpdateAvailable bool `json:"update_available"`
|
||||
PendingCount int `json:"pending_count"`
|
||||
SecurityCount int `json:"security_count,omitempty"`
|
||||
Updates []PendingUpdateInfo `json:"updates"`
|
||||
}
|
||||
|
||||
type CronJob struct {
|
||||
|
||||
@@ -20,6 +20,7 @@ type Task struct {
|
||||
Reboot bool `json:"reboot"`
|
||||
HealthCheck bool `json:"health_check"`
|
||||
HealthCheckTimeout int `json:"health_check_timeout"`
|
||||
SecurityOnly bool `json:"security_only,omitempty"`
|
||||
WebhookURL string `json:"webhook_url,omitempty"`
|
||||
WebhookSent bool `json:"webhook_sent"`
|
||||
WebhookResponse string `json:"webhook_response,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user