Switch to official Zabbix Python API (#131674)

This commit is contained in:
Kenny Root 2024-12-20 01:59:30 -08:00 committed by GitHub
parent 7e6392f062
commit b391dfe647
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 21 additions and 20 deletions

View File

@ -1742,6 +1742,7 @@ build.json @home-assistant/supervisor
/tests/components/youless/ @gjong /tests/components/youless/ @gjong
/homeassistant/components/youtube/ @joostlek /homeassistant/components/youtube/ @joostlek
/tests/components/youtube/ @joostlek /tests/components/youtube/ @joostlek
/homeassistant/components/zabbix/ @kruton
/homeassistant/components/zamg/ @killer0071234 /homeassistant/components/zamg/ @killer0071234
/tests/components/zamg/ @killer0071234 /tests/components/zamg/ @killer0071234
/homeassistant/components/zengge/ @emontnemery /homeassistant/components/zengge/ @emontnemery

View File

@ -11,8 +11,9 @@ import time
from urllib.error import HTTPError from urllib.error import HTTPError
from urllib.parse import urljoin from urllib.parse import urljoin
from pyzabbix import ZabbixAPI, ZabbixAPIException, ZabbixMetric, ZabbixSender
import voluptuous as vol import voluptuous as vol
from zabbix_utils import ItemValue, Sender, ZabbixAPI
from zabbix_utils.exceptions import APIRequestError
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_HOST,
@ -42,6 +43,7 @@ CONF_PUBLISH_STATES_HOST = "publish_states_host"
DEFAULT_SSL = False DEFAULT_SSL = False
DEFAULT_PATH = "zabbix" DEFAULT_PATH = "zabbix"
DEFAULT_SENDER_PORT = 10051
TIMEOUT = 5 TIMEOUT = 5
RETRY_DELAY = 20 RETRY_DELAY = 20
@ -86,7 +88,7 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool:
try: try:
zapi = ZabbixAPI(url=url, user=username, password=password) zapi = ZabbixAPI(url=url, user=username, password=password)
_LOGGER.debug("Connected to Zabbix API Version %s", zapi.api_version()) _LOGGER.debug("Connected to Zabbix API Version %s", zapi.api_version())
except ZabbixAPIException as login_exception: except APIRequestError as login_exception:
_LOGGER.error("Unable to login to the Zabbix API: %s", login_exception) _LOGGER.error("Unable to login to the Zabbix API: %s", login_exception)
return False return False
except HTTPError as http_error: except HTTPError as http_error:
@ -104,7 +106,7 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool:
def event_to_metrics( def event_to_metrics(
event: Event, float_keys: set[str], string_keys: set[str] event: Event, float_keys: set[str], string_keys: set[str]
) -> list[ZabbixMetric] | None: ) -> list[ItemValue] | None:
"""Add an event to the outgoing Zabbix list.""" """Add an event to the outgoing Zabbix list."""
state = event.data.get("new_state") state = event.data.get("new_state")
if state is None or state.state in (STATE_UNKNOWN, "", STATE_UNAVAILABLE): if state is None or state.state in (STATE_UNKNOWN, "", STATE_UNAVAILABLE):
@ -145,14 +147,14 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool:
float_keys.update(floats) float_keys.update(floats)
if len(float_keys) != float_keys_count: if len(float_keys) != float_keys_count:
floats_discovery = [{"{#KEY}": float_key} for float_key in float_keys] floats_discovery = [{"{#KEY}": float_key} for float_key in float_keys]
metric = ZabbixMetric( metric = ItemValue(
publish_states_host, publish_states_host,
"homeassistant.floats_discovery", "homeassistant.floats_discovery",
json.dumps(floats_discovery), json.dumps(floats_discovery),
) )
metrics.append(metric) metrics.append(metric)
for key, value in floats.items(): for key, value in floats.items():
metric = ZabbixMetric( metric = ItemValue(
publish_states_host, f"homeassistant.float[{key}]", value publish_states_host, f"homeassistant.float[{key}]", value
) )
metrics.append(metric) metrics.append(metric)
@ -161,7 +163,7 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool:
return metrics return metrics
if publish_states_host: if publish_states_host:
zabbix_sender = ZabbixSender(zabbix_server=conf[CONF_HOST]) zabbix_sender = Sender(server=conf[CONF_HOST], port=DEFAULT_SENDER_PORT)
instance = ZabbixThread(zabbix_sender, event_to_metrics) instance = ZabbixThread(zabbix_sender, event_to_metrics)
instance.setup(hass) instance.setup(hass)
@ -175,10 +177,8 @@ class ZabbixThread(threading.Thread):
def __init__( def __init__(
self, self,
zabbix_sender: ZabbixSender, zabbix_sender: Sender,
event_to_metrics: Callable[ event_to_metrics: Callable[[Event, set[str], set[str]], list[ItemValue] | None],
[Event, set[str], set[str]], list[ZabbixMetric] | None
],
) -> None: ) -> None:
"""Initialize the listener.""" """Initialize the listener."""
threading.Thread.__init__(self, name="Zabbix") threading.Thread.__init__(self, name="Zabbix")
@ -208,12 +208,12 @@ class ZabbixThread(threading.Thread):
item = (time.monotonic(), event) item = (time.monotonic(), event)
self.queue.put(item) self.queue.put(item)
def get_metrics(self) -> tuple[int, list[ZabbixMetric]]: def get_metrics(self) -> tuple[int, list[ItemValue]]:
"""Return a batch of events formatted for writing.""" """Return a batch of events formatted for writing."""
queue_seconds = QUEUE_BACKLOG_SECONDS + self.MAX_TRIES * RETRY_DELAY queue_seconds = QUEUE_BACKLOG_SECONDS + self.MAX_TRIES * RETRY_DELAY
count = 0 count = 0
metrics: list[ZabbixMetric] = [] metrics: list[ItemValue] = []
dropped = 0 dropped = 0
@ -243,7 +243,7 @@ class ZabbixThread(threading.Thread):
return count, metrics return count, metrics
def write_to_zabbix(self, metrics: list[ZabbixMetric]) -> None: def write_to_zabbix(self, metrics: list[ItemValue]) -> None:
"""Write preprocessed events to zabbix, with retry.""" """Write preprocessed events to zabbix, with retry."""
for retry in range(self.MAX_TRIES + 1): for retry in range(self.MAX_TRIES + 1):

View File

@ -1,10 +1,10 @@
{ {
"domain": "zabbix", "domain": "zabbix",
"name": "Zabbix", "name": "Zabbix",
"codeowners": [], "codeowners": ["@kruton"],
"documentation": "https://www.home-assistant.io/integrations/zabbix", "documentation": "https://www.home-assistant.io/integrations/zabbix",
"iot_class": "local_polling", "iot_class": "local_polling",
"loggers": ["pyzabbix"], "loggers": ["zabbix_utils"],
"quality_scale": "legacy", "quality_scale": "legacy",
"requirements": ["py-zabbix==1.1.7"] "requirements": ["zabbix-utils==2.0.1"]
} }

View File

@ -6,8 +6,8 @@ from collections.abc import Mapping
import logging import logging
from typing import Any from typing import Any
from pyzabbix import ZabbixAPI
import voluptuous as vol import voluptuous as vol
from zabbix_utils import ZabbixAPI
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA, PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,

View File

@ -1723,9 +1723,6 @@ py-sucks==0.9.10
# homeassistant.components.synology_dsm # homeassistant.components.synology_dsm
py-synologydsm-api==2.5.3 py-synologydsm-api==2.5.3
# homeassistant.components.zabbix
py-zabbix==1.1.7
# homeassistant.components.atome # homeassistant.components.atome
pyAtome==0.1.1 pyAtome==0.1.1
@ -3084,6 +3081,9 @@ youtubeaio==1.1.5
# homeassistant.components.media_extractor # homeassistant.components.media_extractor
yt-dlp[default]==2024.12.13 yt-dlp[default]==2024.12.13
# homeassistant.components.zabbix
zabbix-utils==2.0.1
# homeassistant.components.zamg # homeassistant.components.zamg
zamg==0.3.6 zamg==0.3.6