package collector import ( "encoding/json" "os" "os/exec" "strconv" "strings" "time" ) func CollectOPNsenseVersion() string { out, err := exec.Command("/usr/local/sbin/opnsense-version").Output() if err != nil { return "" } // Format: "OPNsense 24.1.1_1" - alles nach erstem Leerzeichen s := strings.TrimSpace(string(out)) return s } func CollectFreeBSDVersion() string { out, err := exec.Command("/bin/freebsd-version").Output() if err != nil { return sysctlGet("kern.osrelease") } return strings.TrimSpace(string(out)) } func CollectHostname() string { return sysctlGet("kern.hostname") } func CollectUptime() int64 { // kern.boottime: { sec = 1706000000, usec = 0 } ... oder "sec = 1706000000" out := sysctlGet("kern.boottime") if out == "" { return 0 } // Parse "{ sec = TIMESTAMP, usec = ... }" idx := strings.Index(out, "sec = ") if idx == -1 { return 0 } numStr := out[idx+6:] if commaIdx := strings.IndexAny(numStr, ", }"); commaIdx != -1 { numStr = numStr[:commaIdx] } numStr = strings.TrimSpace(numStr) bootTime, err := strconv.ParseInt(numStr, 10, 64) if err != nil { return 0 } uptime := time.Now().Unix() - bootTime if uptime < 0 { return 0 } return uptime } // LicenseInfo fuer OPNsense Business Edition type LicenseInfo struct { IsBusinessEdition bool `json:"is_business_edition"` ProductName string `json:"product_name,omitempty"` Subscription string `json:"subscription,omitempty"` ValidTo string `json:"valid_to,omitempty"` DaysRemaining int `json:"days_remaining,omitempty"` } func CollectLicense() *LicenseInfo { // core version file lesen coreData, err := os.ReadFile("/usr/local/opnsense/version/core") if err != nil { return nil } var core map[string]interface{} if err := json.Unmarshal(coreData, &core); err != nil { return nil } productID, _ := core["product_id"].(string) coreName, _ := core["CORE_NAME"].(string) isBusiness := productID == "opnsense-business" || coreName == "opnsense-business" if !isBusiness { return &LicenseInfo{IsBusinessEdition: false, ProductName: "OPNsense Community"} } info := &LicenseInfo{ IsBusinessEdition: true, ProductName: "OPNsense Business Edition", } // Lizenz-Ablauf lesen licData, err := os.ReadFile("/usr/local/opnsense/version/core.license") if err == nil { var lic map[string]string if json.Unmarshal(licData, &lic) == nil { if validTo, ok := lic["valid_to"]; ok { info.ValidTo = validTo if t, err := time.Parse("2006-01-02", validTo); err == nil { days := int(time.Until(t).Hours() / 24) info.DaysRemaining = days } } } } // Subscription-Code aus config.xml lesen out, err := exec.Command("/usr/local/bin/php", "-r", ` $c = simplexml_load_file("/conf/config.xml"); if (isset($c->system->firmware->subscription)) { echo (string)$c->system->firmware->subscription; } `).Output() if err == nil { sub := strings.TrimSpace(string(out)) if sub != "" { info.Subscription = sub } } return info }