rmm2/agent/collector/services.go
cynfo3000 6120d0cffa Initial commit: RMM Agent + Backend
- Go Agent (FreeBSD/amd64) fuer OPNsense
- Go Backend (Linux/amd64) mit REST API + SQLite
- Collector: Hardware, CPU, Memory, Disks, Network, Services,
  WireGuard, DHCP (KEA/ISC/dnsmasq), Routes, Gateways,
  Certificates, Plugins, Updates
- Persistente Agent-ID
- TLS + API-Key Auth
- WebSocket-Infrastruktur (WIP): bidirektionaler Command-Kanal,
  TCP-Tunnel fuer Remote-Zugriff auf Firewall-WebUI
- Lastenheft und README
2026-02-28 07:38:14 +01:00

98 lines
2.2 KiB
Go

package collector
import (
"os/exec"
"path/filepath"
"strings"
)
type ServiceInfo struct {
Name string `json:"name"`
Description string `json:"description"`
Status string `json:"status"`
}
func CollectServices() []ServiceInfo {
// Versuche zuerst pluginctl -s (OPNsense-spezifisch)
services := tryPluginctl()
if len(services) > 0 {
return services
}
// Fallback: service -e listet aktivierte Services
return tryServiceList()
}
func tryPluginctl() []ServiceInfo {
out, err := exec.Command("pluginctl", "-s").Output()
if err != nil {
return nil
}
var services []ServiceInfo
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
name := strings.TrimSpace(line)
if name == "" {
continue
}
// pluginctl -s gibt nur Service-Namen, Status einzeln pruefen
status := "stopped"
statusOut, err := exec.Command("service", name, "status").CombinedOutput()
if err == nil && strings.Contains(string(statusOut), "is running") {
status = "running"
}
// Beschreibung aus rc.d Script extrahieren (# PROVIDE: name)
desc := ""
descOut, _ := exec.Command("grep", "-h", "PROVIDE:", "/etc/rc.d/"+name, "/usr/local/etc/rc.d/"+name).Output()
if len(descOut) > 0 {
parts := strings.SplitN(string(descOut), "PROVIDE:", 2)
if len(parts) == 2 {
desc = strings.TrimSpace(parts[1])
}
}
services = append(services, ServiceInfo{
Name: name,
Description: desc,
Status: status,
})
}
return services
}
func tryServiceList() []ServiceInfo {
out, err := exec.Command("service", "-e").Output()
if err != nil {
return nil
}
var services []ServiceInfo
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
if line == "" {
continue
}
// service -e gibt volle Pfade: /etc/rc.d/sshd, /usr/local/etc/rc.d/openvpn
name := filepath.Base(strings.TrimSpace(line))
// Status pruefen
status := "running" // service -e listet nur laufende Services
statusOut, err := exec.Command("service", name, "status").Output()
if err != nil {
status = "stopped"
} else if strings.Contains(string(statusOut), "not running") {
status = "stopped"
}
services = append(services, ServiceInfo{
Name: name,
Status: status,
})
}
return services
}