rmm2/agent/collector/caddy.go

90 lines
1.8 KiB
Go

package collector
import (
"os"
"os/exec"
"strings"
)
type CaddySite struct {
Domain string `json:"domain"`
Upstream string `json:"upstream"`
TLS bool `json:"tls"`
}
type CaddyData struct {
Version string `json:"version"`
Sites []CaddySite `json:"sites"`
}
const caddyFile = "/usr/local/etc/caddy/Caddyfile"
func CollectCaddy() *CaddyData {
if _, err := os.Stat(caddyFile); err != nil {
return nil
}
data := &CaddyData{}
// Version
if out, err := exec.Command("/usr/local/bin/caddy", "version").Output(); err == nil {
fields := strings.Fields(strings.TrimSpace(string(out)))
if len(fields) > 0 {
data.Version = fields[0]
}
}
// Parse Caddyfile
content, err := os.ReadFile(caddyFile)
if err != nil {
return data
}
lines := strings.Split(string(content), "\n")
var currentDomain string
var currentTLS bool
depth := 0
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if trimmed == "" || strings.HasPrefix(trimmed, "#") {
continue
}
// Check for domain block start: "domain.com {" or "http://domain.com {"
if depth == 0 && strings.Contains(trimmed, "{") {
parts := strings.Fields(trimmed)
if len(parts) >= 2 && parts[len(parts)-1] == "{" {
currentDomain = parts[0]
currentTLS = !strings.HasPrefix(currentDomain, "http://")
depth = 1
continue
}
}
if depth > 0 {
// Track nested braces
depth += strings.Count(trimmed, "{") - strings.Count(trimmed, "}")
if strings.HasPrefix(trimmed, "reverse_proxy") {
parts := strings.Fields(trimmed)
if len(parts) >= 2 {
upstream := parts[1]
data.Sites = append(data.Sites, CaddySite{
Domain: currentDomain,
Upstream: upstream,
TLS: currentTLS,
})
}
}
if depth <= 0 {
currentDomain = ""
depth = 0
}
}
}
return data
}