mirror of
https://github.com/home-assistant/core.git
synced 2026-07-03 04:36:04 +01:00
e02ea041b7
Co-authored-by: Norbert Rittel <norbert@rittel.de> Co-authored-by: Philippe Lafoucrière <12752+gravis@users.noreply.github.com> Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Ariel Ebersberger <ariel@ebersberger.io>
165 lines
5.5 KiB
Python
165 lines
5.5 KiB
Python
"""Support for OPNsense Routers."""
|
|
|
|
from aiopnsense import (
|
|
OPNsenseBelowMinFirmware,
|
|
OPNsenseClient,
|
|
OPNsenseConnectionError,
|
|
OPNsenseInvalidAuth,
|
|
OPNsenseInvalidURL,
|
|
OPNsensePrivilegeMissing,
|
|
OPNsenseSSLError,
|
|
OPNsenseTimeoutError,
|
|
OPNsenseUnknownFirmware,
|
|
)
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.config_entries import SOURCE_IMPORT
|
|
from homeassistant.const import CONF_API_KEY, CONF_URL, CONF_VERIFY_SSL, Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import ConfigEntryError, ConfigEntryNotReady
|
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
import homeassistant.helpers.config_validation as cv
|
|
from homeassistant.helpers.typing import ConfigType
|
|
|
|
from .const import CONF_API_SECRET, CONF_TRACKER_INTERFACES, DOMAIN
|
|
from .types import OPNsenseConfigEntry, OPNsenseRuntimeData
|
|
|
|
CONFIG_SCHEMA = vol.Schema(
|
|
{
|
|
DOMAIN: vol.Schema(
|
|
{
|
|
vol.Required(CONF_URL): cv.url,
|
|
vol.Required(CONF_API_KEY): cv.string,
|
|
vol.Required(CONF_API_SECRET): cv.string,
|
|
vol.Optional(CONF_VERIFY_SSL, default=False): cv.boolean,
|
|
vol.Optional(CONF_TRACKER_INTERFACES, default=[]): vol.All(
|
|
cv.ensure_list, [cv.string]
|
|
),
|
|
}
|
|
)
|
|
},
|
|
extra=vol.ALLOW_EXTRA,
|
|
)
|
|
|
|
PLATFORMS = [Platform.DEVICE_TRACKER]
|
|
|
|
|
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|
"""Set up the OPNsense component."""
|
|
if DOMAIN not in config:
|
|
return True
|
|
|
|
hass.async_create_task(_async_setup(hass, config))
|
|
|
|
return True
|
|
|
|
|
|
async def _async_setup(hass: HomeAssistant, config: ConfigType) -> None:
|
|
"""Set up the OPNsense component from YAML."""
|
|
await hass.config_entries.flow.async_init(
|
|
DOMAIN,
|
|
context={"source": SOURCE_IMPORT},
|
|
data=config[DOMAIN],
|
|
)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant, config_entry: OPNsenseConfigEntry
|
|
) -> bool:
|
|
"""Set up the OPNsense component from a config entry."""
|
|
url = config_entry.data[CONF_URL]
|
|
session = async_get_clientsession(
|
|
hass, verify_ssl=config_entry.data[CONF_VERIFY_SSL]
|
|
)
|
|
client = OPNsenseClient(
|
|
url,
|
|
config_entry.data[CONF_API_KEY],
|
|
config_entry.data[CONF_API_SECRET],
|
|
session,
|
|
opts={"verify_ssl": config_entry.data[CONF_VERIFY_SSL]},
|
|
)
|
|
tracker_interfaces = config_entry.data.get(CONF_TRACKER_INTERFACES, [])
|
|
try:
|
|
await client.validate()
|
|
if tracker_interfaces:
|
|
interfaces_resp = await client.get_interfaces()
|
|
except OPNsenseUnknownFirmware as err:
|
|
raise ConfigEntryError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="unknown_firmware",
|
|
translation_placeholders={"url": url},
|
|
) from err
|
|
except OPNsenseBelowMinFirmware as err:
|
|
raise ConfigEntryError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="firmware_too_old",
|
|
translation_placeholders={"url": url},
|
|
) from err
|
|
except OPNsenseInvalidURL as err:
|
|
raise ConfigEntryError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="invalid_url",
|
|
translation_placeholders={"url": url},
|
|
) from err
|
|
except OPNsenseTimeoutError as err:
|
|
raise ConfigEntryNotReady(
|
|
translation_domain=DOMAIN,
|
|
translation_key="timeout_connecting",
|
|
translation_placeholders={"url": url},
|
|
) from err
|
|
except OPNsenseSSLError as err:
|
|
raise ConfigEntryError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="ssl_error",
|
|
translation_placeholders={"url": url},
|
|
) from err
|
|
except OPNsenseInvalidAuth as err:
|
|
raise ConfigEntryError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="invalid_auth",
|
|
translation_placeholders={"url": url},
|
|
) from err
|
|
except OPNsensePrivilegeMissing as err:
|
|
raise ConfigEntryError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="privilege_missing",
|
|
translation_placeholders={"url": url},
|
|
) from err
|
|
except OPNsenseConnectionError as err:
|
|
raise ConfigEntryNotReady(
|
|
translation_domain=DOMAIN,
|
|
translation_key="cannot_connect",
|
|
translation_placeholders={"url": url},
|
|
) from err
|
|
|
|
if tracker_interfaces:
|
|
# Verify that specified tracker interfaces are valid
|
|
known_interfaces = [
|
|
name for ifinfo in interfaces_resp.values() if (name := ifinfo.get("name"))
|
|
]
|
|
for intf_description in tracker_interfaces:
|
|
if intf_description not in known_interfaces:
|
|
raise ConfigEntryError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="tracker_interface_not_found",
|
|
translation_placeholders={
|
|
"interface": intf_description,
|
|
"known": ", ".join(known_interfaces),
|
|
},
|
|
)
|
|
|
|
config_entry.runtime_data = OPNsenseRuntimeData(
|
|
client=client,
|
|
tracker_interfaces=tracker_interfaces,
|
|
)
|
|
|
|
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
|
return True
|
|
|
|
|
|
async def async_unload_entry(
|
|
hass: HomeAssistant, config_entry: OPNsenseConfigEntry
|
|
) -> bool:
|
|
"""Unload a config entry."""
|
|
return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
|