Skip to content

Commit 6437e62

Browse files
committed
Check for dhcpv4/6 plugin before querying it
1 parent 14fc52a commit 6437e62

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Project structure expectations
2626

2727
Coding standards
2828
- Add typing annotations to all functions and classes (including return types).
29-
- Add or update docstrings (PEP 257) for functions and classes.
29+
- Add or update docstrings for all files, classes and methods, including private methods. Method docstrings much be in NumPy format.
3030
- Preserve existing comments and keep imports at the top of files.
3131
- Follow existing repository style; run `pre-commit` and `ruff` where available.
3232

custom_components/opnsense/pyopnsense/__init__.py

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,47 @@ async def _safe_list_post(
626626
result = await self._post(path=path, payload=payload)
627627
return result if isinstance(result, list) else []
628628

629+
async def _get_check(self, path: str) -> bool:
630+
"""Check if the given API path is accessible.
631+
632+
Parameters
633+
----------
634+
path : str
635+
The API path to check for accessibility.
636+
637+
Returns
638+
-------
639+
bool
640+
True if the path is accessible (HTTP 200 OK), False otherwise.
641+
642+
"""
643+
# /api/<module>/<controller>/<command>/[<param1>/[<param2>/...]]
644+
self._rest_api_query_count += 1
645+
url: str = f"{self._url}{path}"
646+
_LOGGER.debug("[get_check] url: %s", url)
647+
try:
648+
async with self._session.get(
649+
url,
650+
auth=aiohttp.BasicAuth(self._username, self._password),
651+
timeout=aiohttp.ClientTimeout(total=DEFAULT_TIMEOUT),
652+
ssl=self._verify_ssl,
653+
) as response:
654+
_LOGGER.debug("[get_check] Response %s: %s", response.status, response.reason)
655+
if response.ok:
656+
return True
657+
if response.status == 403:
658+
_LOGGER.error(
659+
"Permission Error in get_check. Path: %s. Ensure the OPNsense user connected to HA has appropriate access. Recommend full admin access",
660+
url,
661+
)
662+
return False
663+
except aiohttp.ClientError as e:
664+
_LOGGER.error("Client error. %s: %s", type(e).__name__, e)
665+
if self._initial:
666+
raise
667+
668+
return False
669+
629670
@_log_errors
630671
async def _filter_configure(self) -> None:
631672
script: str = r"""
@@ -1140,7 +1181,17 @@ async def _get_dnsmasq_leases(self) -> list:
11401181
return leases
11411182

11421183
async def _get_isc_dhcpv4_leases(self) -> list:
1143-
"""Return IPv4 DHCP Leases by ISC."""
1184+
"""Return IPv4 DHCP Leases by ISC.
1185+
1186+
Returns
1187+
-------
1188+
list
1189+
A list of dictionaries representing IPv4 DHCP leases.
1190+
1191+
"""
1192+
if not self._get_check("/api/dhcpv4/service/status"):
1193+
_LOGGER.debug("ISC DHCPv4 service is not running, skipping lease retrieval")
1194+
return []
11441195
if self._use_snake_case:
11451196
response = await self._safe_dict_get("/api/dhcpv4/leases/search_lease")
11461197
else:
@@ -1184,7 +1235,17 @@ async def _get_isc_dhcpv4_leases(self) -> list:
11841235
return leases
11851236

11861237
async def _get_isc_dhcpv6_leases(self) -> list:
1187-
"""Return IPv6 DHCP Leases by ISC."""
1238+
"""Return IPv6 DHCP Leases by ISC.
1239+
1240+
Returns
1241+
-------
1242+
list
1243+
A list of dictionaries representing IPv6 DHCP leases.
1244+
1245+
"""
1246+
if not self._get_check("/api/dhcpv6/service/status"):
1247+
_LOGGER.debug("ISC DHCPv6 service is not running, skipping lease retrieval")
1248+
return []
11881249
if self._use_snake_case:
11891250
response = await self._safe_dict_get("/api/dhcpv6/leases/search_lease")
11901251
else:

0 commit comments

Comments
 (0)