- 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
98 lines
2.2 KiB
Go
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
|
|
}
|