feat(system): report remote syslog, LuCI state and bridge STP
get_system_config() already parsed the whole system section but returned
only a slice of it, so netOrk had no IST side for three AP-profile fields
and could not compare them at all — the fields were editable, stored and
silently ineffective.
Adds:
* syslog_remote / syslog_ip / syslog_port / syslog_proto — read from the
system section that was already being parsed. log_remote gates the
others: OpenWrt ships nothing without it, so a leftover log_ip must
not read as an active target.
* luci_enabled — from the uhttpd init script rather than its listener
config, so the answer stays "is the web UI served" and re-enabling
restores whatever was configured before.
* bridge_stp — None when there is no br-ap at all, which is a different
statement from "bridge without STP" and has to stay distinguishable.
netOrk #164
This commit is contained in:
@@ -75,9 +75,17 @@ class OpenWrtSystemMixin:
|
||||
* dropbear_port (int) — SSH port
|
||||
* dropbear_password_auth (bool) — whether password login is allowed
|
||||
* dropbear_root_password_auth (bool)
|
||||
* syslog_remote (bool) — whether logs are shipped off the device
|
||||
* syslog_ip (str), syslog_port (int), syslog_proto (str)
|
||||
* luci_enabled (bool) — whether the uhttpd service serving LuCI is enabled
|
||||
* bridge_stp (bool | None) — STP on br-ap; None when there is no br-ap
|
||||
"""
|
||||
sys_out = self._send_command("uci show system 2>/dev/null || true")
|
||||
db_out = self._send_command("uci show dropbear 2>/dev/null || true")
|
||||
luci_out = self._send_command(
|
||||
"/etc/init.d/uhttpd enabled 2>/dev/null && echo 1 || echo 0"
|
||||
)
|
||||
net_out = self._send_command("uci show network 2>/dev/null || true")
|
||||
|
||||
sys_cfg: dict[str, str] = {}
|
||||
for line in sys_out.splitlines():
|
||||
@@ -109,6 +117,31 @@ class OpenWrtSystemMixin:
|
||||
def _bool_uci(val: str, default: bool = True) -> bool:
|
||||
return val.lower() not in ("0", "off", "false", "no") if val else default
|
||||
|
||||
# Remote syslog. OpenWrt only ships logs when log_remote is set, so a
|
||||
# leftover log_ip without it means nothing is being sent.
|
||||
syslog_remote = _bool_uci(sys_cfg.get("log_remote", ""), default=False)
|
||||
try:
|
||||
syslog_port = int(sys_cfg.get("log_port", "514") or "514")
|
||||
except (ValueError, TypeError):
|
||||
syslog_port = 514
|
||||
|
||||
# STP on the AP bridge. None when there is no br-ap device section at
|
||||
# all — "no bridge" is a different statement from "bridge without STP".
|
||||
bridge_stp: bool | None = None
|
||||
br_section: str | None = None
|
||||
for line in net_out.splitlines():
|
||||
m = re.match(r"network\.(\w+)\.name='br-ap'", line.strip())
|
||||
if m:
|
||||
br_section = m.group(1)
|
||||
break
|
||||
if br_section:
|
||||
bridge_stp = False
|
||||
for line in net_out.splitlines():
|
||||
m = re.match(rf"network\.{br_section}\.stp='([^']*)'", line.strip())
|
||||
if m:
|
||||
bridge_stp = _bool_uci(m.group(1), default=False)
|
||||
break
|
||||
|
||||
return {
|
||||
"hostname": sys_cfg.get("hostname", ""),
|
||||
"timezone": sys_cfg.get("timezone", ""),
|
||||
@@ -117,6 +150,12 @@ class OpenWrtSystemMixin:
|
||||
"dropbear_port": ssh_port,
|
||||
"dropbear_password_auth": _bool_uci(db_cfg.get("PasswordAuth", "on")),
|
||||
"dropbear_root_password_auth": _bool_uci(db_cfg.get("RootPasswordAuth", "on")),
|
||||
"syslog_remote": syslog_remote,
|
||||
"syslog_ip": sys_cfg.get("log_ip", "") if syslog_remote else "",
|
||||
"syslog_port": syslog_port,
|
||||
"syslog_proto": sys_cfg.get("log_proto", "udp"),
|
||||
"luci_enabled": luci_out.strip().endswith("1"),
|
||||
"bridge_stp": bridge_stp,
|
||||
}
|
||||
|
||||
def get_snmp_information(self) -> dict[str, Any]:
|
||||
|
||||
Reference in New Issue
Block a user