feat: report Kea's HA peers and the firewall's config sync
CI / test (3.10) (push) Successful in 32s
CI / test (3.11) (push) Successful in 33s
CI / test (3.12) (push) Successful in 34s
CI / test (3.10) (pull_request) Successful in 38s
CI / test (3.11) (pull_request) Successful in 37s
CI / test (3.12) (pull_request) Successful in 38s

get_dhcp_ha reads kea/dhcpv4/get (the ha section) and
kea/dhcpv4/searchPeer: whether Kea's HA hook is on, this firewall's peer
name -- the % twin when left at its default -- and each peer's name,
role and HA URL. get_config_sync reads core/hasync/get: the address this
firewall pushes its configuration to and the ticked sync items, mapped to
the service names get_services reports; items that are no service stay
under `unmapped`. Both raise when the request fails.

Configuration, not state: Kea's control agent, which knows whether the
pair is in hot standby right now, listens on localhost only.

Needs napalm-device-types 4.11.0 (ConfigSyncMixin). NetOrk/netork#1125.
This commit is contained in:
Christian Manivong committed 2026-10-16 15:18:45 +02:00
1 parent 5a1aa66db4
commit e334dc0058
5 files changed
+694 -4

No files matched your search

+27 -3
View File
@@ -52,17 +52,23 @@ _REFRESH_INTERVAL = 3
import requests
from requests.exceptions import RequestException
from napalm_device_types import FingerprintRule, FirewallDriver
from napalm_device_types.models import ListeningSocketsDict, VirtualIpsDict
from napalm_device_types import ConfigSyncMixin, FingerprintRule, FirewallDriver
from napalm_device_types.models import (
ConfigSyncDict,
DhcpHaDict,
ListeningSocketsDict,
VirtualIpsDict,
)
from napalm.base.exceptions import ConnectionException, ConnectionClosedException, MergeConfigException
from napalm_opnsense.ha import config_sync, dhcp_ha
from napalm_opnsense.listening import parse_socket_statistics, wireguard_listen_ports
from napalm_opnsense.ping_mixin import OPNsensePingMixin
from napalm_opnsense.port_forwards import alias_index, port_forwards, wan_interfaces
from napalm_opnsense.virtual_ips import carp_addresses
class OPNsenseDriver(OPNsensePingMixin, FirewallDriver):
class OPNsenseDriver(OPNsensePingMixin, ConfigSyncMixin, FirewallDriver):
"""NAPALM driver for OPNsense (read-only, REST API)."""
VENDOR = "OPNsense"
@@ -1841,6 +1847,24 @@ class OPNsenseDriver(OPNsensePingMixin, FirewallDriver):
"carp": carp_addresses(self._get("/api/interfaces/overview/export")),
}
def get_dhcp_ha(self) -> DhcpHaDict:
"""Kea's HA configuration: on or off, this firewall's peer name, every peer.
Configuration, not state (:mod:`napalm_opnsense.ha`).
:raises: whatever either request raises -- an unread answer is not "off".
"""
return dhcp_ha(
self._get("/api/kea/dhcpv4/get"), self._get("/api/kea/dhcpv4/searchPeer")
)
def get_config_sync(self) -> ConfigSyncDict:
"""Where this firewall pushes its configuration (HA sync), and for which services.
:raises: whatever the request raises -- an unread answer is not "no sync".
"""
return config_sync(self._get("/api/core/hasync/get"))
def manage_service(self, name: str, action: str) -> dict[str, Any]:
"""Execute a lifecycle action on an OPNsense service.