$available detected binaries (apt-get, dnf, ufw, firewall-cmd, systemctl, …) */ public function __construct( public readonly string $family, // debian|rhel|suse|arch|alpine|unknown public readonly string $id, // raw /etc/os-release ID public readonly string $prettyName, // PRETTY_NAME for display public readonly string $packageManager, // apt|dnf|zypper|pacman|apk|none public readonly string $firewallTool, // ufw|firewalld|none public readonly string $serviceManager, // systemd|openrc|none public readonly array $available = [], ) {} public function has(string $binary): bool { return in_array($binary, $this->available, true); } public function isSystemd(): bool { return $this->serviceManager === 'systemd'; } /** True when Clusev can drive package install/update on this host. */ public function managesPackages(): bool { return in_array($this->packageManager, self::SUPPORTED_MANAGERS, true); } /** German family label for the UI. */ public function familyLabel(): string { return match ($this->family) { 'debian' => __('backend.family_debian'), 'rhel' => __('backend.family_rhel'), 'suse' => __('backend.family_suse'), 'arch' => __('backend.family_arch'), 'alpine' => __('backend.family_alpine'), default => __('backend.family_unknown'), }; } /** German label for the host firewall in the hardening checklist. */ public function firewallLabel(): string { return match ($this->firewallTool) { 'ufw' => __('backend.firewall_label_ufw'), 'firewalld' => __('backend.firewall_label_firewalld'), default => __('backend.firewall_label_generic'), }; } /** * Whether a feature is supported on this host. Returns NULL when supported, or * a German reason to show the operator when not — so unsupported combinations * degrade with an explanation instead of failing opaquely. */ public function supports(string $feature): ?string { return match ($feature) { 'ssh' => $this->isSystemd() ? null : __('backend.support_ssh', ['family' => $this->familyLabel()]), 'services' => $this->isSystemd() ? null : __('backend.support_services'), 'updates' => $this->managesPackages() ? null : __('backend.support_updates', ['family' => $this->familyLabel()]), 'fail2ban' => ($this->managesPackages() && $this->isSystemd()) ? null : __('backend.support_fail2ban', ['family' => $this->familyLabel()]), 'firewall' => ($this->firewallTool !== 'none' && $this->isSystemd() && ($this->firewallTool === 'firewalld' || $this->managesPackages() || $this->has('ufw'))) ? null : __('backend.support_firewall', ['family' => $this->familyLabel()]), // apt -> unattended-upgrades; dnf -> dnf-automatic. A yum-ONLY host (e.g. // CentOS 7) maps to the dnf manager for upgrades but has no dnf-automatic // (it uses yum-cron), so require a real `dnf` binary for this feature. 'auto_updates' => (($this->packageManager === 'apt' || ($this->packageManager === 'dnf' && $this->has('dnf'))) && $this->isSystemd()) ? null : __('backend.support_auto_updates', ['family' => $this->familyLabel()]), default => null, }; } }