2020-03-11 23:34:26 +01:00
|
|
|
"""Mikrotik API for Mikrotik Router."""
|
|
|
|
|
2020-03-21 19:02:28 +03:00
|
|
|
import importlib
|
2020-03-11 23:34:26 +01:00
|
|
|
import logging
|
2020-03-21 19:02:28 +03:00
|
|
|
import os
|
|
|
|
import ssl
|
|
|
|
import sys
|
2020-03-11 23:34:26 +01:00
|
|
|
import time
|
|
|
|
from threading import Lock
|
2020-03-21 18:46:54 +03:00
|
|
|
|
|
|
|
from voluptuous import Optional
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
from .const import (
|
|
|
|
DEFAULT_LOGIN_METHOD,
|
|
|
|
DEFAULT_ENCODING,
|
|
|
|
)
|
2020-03-21 19:02:28 +03:00
|
|
|
from .exceptions import ApiEntryNotFound
|
2020-03-11 23:34:26 +01:00
|
|
|
|
2020-03-21 19:02:28 +03:00
|
|
|
MODULE_PATH = os.path.join(os.path.dirname(__file__), "librouteros_custom",
|
|
|
|
"__init__.py")
|
2020-03-18 09:33:36 +01:00
|
|
|
MODULE_NAME = "librouteros_custom"
|
|
|
|
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
|
|
|
|
librouteros_custom = importlib.util.module_from_spec(spec)
|
|
|
|
sys.modules[spec.name] = librouteros_custom
|
|
|
|
spec.loader.exec_module(librouteros_custom)
|
2020-03-11 23:34:26 +01:00
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# MikrotikAPI
|
|
|
|
# ---------------------------
|
|
|
|
class MikrotikAPI:
|
|
|
|
"""Handle all communication with the Mikrotik API."""
|
|
|
|
|
2020-03-16 18:35:51 +01:00
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
host,
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
port=0,
|
|
|
|
use_ssl=True,
|
|
|
|
login_method=DEFAULT_LOGIN_METHOD,
|
|
|
|
encoding=DEFAULT_ENCODING,
|
|
|
|
):
|
2020-03-11 23:34:26 +01:00
|
|
|
"""Initialize the Mikrotik Client."""
|
|
|
|
self._host = host
|
|
|
|
self._use_ssl = use_ssl
|
|
|
|
self._port = port
|
|
|
|
self._username = username
|
|
|
|
self._password = password
|
|
|
|
self._login_method = login_method
|
|
|
|
self._encoding = encoding
|
|
|
|
self._ssl_wrapper = None
|
|
|
|
self.lock = Lock()
|
|
|
|
|
|
|
|
self._connection = None
|
|
|
|
self._connected = False
|
|
|
|
self._connection_epoch = 0
|
|
|
|
self._connection_retry_sec = 58
|
|
|
|
self.error = None
|
2020-03-17 00:40:08 +01:00
|
|
|
self.connection_error_reported = False
|
2020-03-11 23:34:26 +01:00
|
|
|
|
|
|
|
# Default ports
|
|
|
|
if not self._port:
|
|
|
|
self._port = 8729 if self._use_ssl else 8728
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# disconnect
|
|
|
|
# ---------------------------
|
2020-03-21 18:46:54 +03:00
|
|
|
def disconnect(self):
|
2020-03-11 23:34:26 +01:00
|
|
|
"""Disconnect from Mikrotik device."""
|
|
|
|
self._connected = False
|
|
|
|
self._connection = None
|
|
|
|
self._connection_epoch = 0
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# connect
|
|
|
|
# ---------------------------
|
|
|
|
def connect(self) -> bool:
|
|
|
|
"""Connect to Mikrotik device."""
|
|
|
|
self.error = ""
|
|
|
|
self._connected = None
|
|
|
|
self._connection_epoch = time.time()
|
|
|
|
|
|
|
|
kwargs = {
|
|
|
|
"encoding": self._encoding,
|
|
|
|
"login_methods": self._login_method,
|
|
|
|
"port": self._port,
|
|
|
|
}
|
|
|
|
|
|
|
|
if self._use_ssl:
|
|
|
|
if self._ssl_wrapper is None:
|
|
|
|
ssl_context = ssl.create_default_context()
|
|
|
|
ssl_context.check_hostname = False
|
|
|
|
ssl_context.verify_mode = ssl.CERT_NONE
|
|
|
|
self._ssl_wrapper = ssl_context.wrap_socket
|
|
|
|
kwargs["ssl_wrapper"] = self._ssl_wrapper
|
|
|
|
self.lock.acquire()
|
|
|
|
try:
|
2020-03-18 09:33:36 +01:00
|
|
|
self._connection = librouteros_custom.connect(
|
2020-03-16 18:35:51 +01:00
|
|
|
self._host, self._username, self._password, **kwargs
|
|
|
|
)
|
2020-03-11 23:34:26 +01:00
|
|
|
except (
|
2020-03-18 09:33:36 +01:00
|
|
|
librouteros_custom.exceptions.TrapError,
|
|
|
|
librouteros_custom.exceptions.MultiTrapError,
|
|
|
|
librouteros_custom.exceptions.ConnectionClosed,
|
|
|
|
librouteros_custom.exceptions.ProtocolError,
|
|
|
|
librouteros_custom.exceptions.FatalError,
|
2020-03-16 18:35:51 +01:00
|
|
|
ssl.SSLError,
|
|
|
|
BrokenPipeError,
|
|
|
|
OSError,
|
2020-03-11 23:34:26 +01:00
|
|
|
) as api_error:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while connecting: %s", self._host,
|
|
|
|
api_error
|
2020-03-17 00:40:08 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.error_to_strings("%s" % api_error)
|
|
|
|
self._connection = None
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return False
|
|
|
|
except:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while connecting: %s", self._host,
|
|
|
|
"Unknown"
|
2020-03-17 00:40:08 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self._connection = None
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return False
|
|
|
|
else:
|
2020-03-17 00:40:08 +01:00
|
|
|
if self.connection_error_reported:
|
|
|
|
_LOGGER.warning("Mikrotik Reconnected to %s", self._host)
|
|
|
|
self.connection_error_reported = False
|
|
|
|
else:
|
|
|
|
_LOGGER.debug("Mikrotik Connected to %s", self._host)
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self._connected = True
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
|
|
|
|
return self._connected
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# error_to_strings
|
|
|
|
# ---------------------------
|
|
|
|
def error_to_strings(self, error):
|
|
|
|
"""Translate error output to error string."""
|
|
|
|
self.error = "cannot_connect"
|
|
|
|
if error == "invalid user name or password (6)":
|
|
|
|
self.error = "wrong_login"
|
|
|
|
|
|
|
|
if "ALERT_HANDSHAKE_FAILURE" in error:
|
|
|
|
self.error = "ssl_handshake_failure"
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# connected
|
|
|
|
# ---------------------------
|
|
|
|
def connected(self) -> bool:
|
|
|
|
"""Return connected boolean."""
|
|
|
|
return self._connected
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# path
|
|
|
|
# ---------------------------
|
2020-04-04 17:51:35 +02:00
|
|
|
def path(self, path, return_list=False) -> Optional(list):
|
2020-03-11 23:34:26 +01:00
|
|
|
"""Retrieve data from Mikrotik API."""
|
2020-04-04 17:51:35 +02:00
|
|
|
"""Returns generator object, unless return_list passed as True"""
|
2020-03-11 23:34:26 +01:00
|
|
|
if not self._connected or not self._connection:
|
|
|
|
if self._connection_epoch > time.time() - self._connection_retry_sec:
|
|
|
|
return None
|
|
|
|
|
|
|
|
if not self.connect():
|
|
|
|
return None
|
|
|
|
|
|
|
|
self.lock.acquire()
|
|
|
|
try:
|
|
|
|
response = self._connection.path(path)
|
2020-03-11 23:35:28 +01:00
|
|
|
_LOGGER.debug("API response (%s): %s", path, response)
|
2020-03-18 09:33:36 +01:00
|
|
|
except librouteros_custom.exceptions.ConnectionClosed:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error("Mikrotik %s connection closed", self._host)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-13 02:27:21 +01:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return None
|
|
|
|
except (
|
2020-04-04 17:51:35 +02:00
|
|
|
librouteros_custom.exceptions.TrapError,
|
|
|
|
librouteros_custom.exceptions.MultiTrapError,
|
|
|
|
librouteros_custom.exceptions.ProtocolError,
|
|
|
|
librouteros_custom.exceptions.FatalError,
|
|
|
|
ssl.SSLError,
|
|
|
|
BrokenPipeError,
|
|
|
|
OSError,
|
|
|
|
ValueError,
|
2020-03-11 23:34:26 +01:00
|
|
|
) as api_error:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
2020-04-04 17:51:35 +02:00
|
|
|
_LOGGER.error("Mikrotik %s error while path %s", self._host, api_error)
|
2020-03-17 00:40:08 +01:00
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.disconnect()
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return None
|
|
|
|
except:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
2020-04-04 17:51:35 +02:00
|
|
|
_LOGGER.error("Mikrotik %s error while path %s", self._host, "unknown")
|
2020-03-17 00:40:08 +01:00
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.disconnect()
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return None
|
|
|
|
|
2020-04-04 17:51:35 +02:00
|
|
|
if return_list:
|
|
|
|
try:
|
|
|
|
response = list(response)
|
|
|
|
except librouteros_custom.exceptions.ConnectionClosed as api_error:
|
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error("Mikrotik %s error while building list for path %s", self._host, api_error)
|
|
|
|
self.connection_error_reported = True
|
2020-03-17 00:40:08 +01:00
|
|
|
|
2020-04-04 17:51:35 +02:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
|
|
|
return None
|
|
|
|
except:
|
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error("Mikrotik %s error while building list for path %s", self._host, "unknown")
|
|
|
|
self.connection_error_reported = True
|
2020-03-17 00:40:08 +01:00
|
|
|
|
2020-04-04 17:51:35 +02:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
|
|
|
return None
|
2020-03-13 02:39:35 +01:00
|
|
|
|
2020-03-11 23:35:28 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return response if response else None
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# update
|
|
|
|
# ---------------------------
|
|
|
|
def update(self, path, param, value, mod_param, mod_value) -> bool:
|
|
|
|
"""Modify a parameter"""
|
|
|
|
entry_found = False
|
|
|
|
if not self._connected or not self._connection:
|
|
|
|
if self._connection_epoch > time.time() - self._connection_retry_sec:
|
2020-03-21 18:46:54 +03:00
|
|
|
return False
|
2020-03-11 23:34:26 +01:00
|
|
|
|
|
|
|
if not self.connect():
|
|
|
|
return False
|
|
|
|
|
|
|
|
response = self.path(path)
|
|
|
|
if response is None:
|
|
|
|
return False
|
|
|
|
|
|
|
|
for tmp in response:
|
|
|
|
if param not in tmp:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if tmp[param] != value:
|
|
|
|
continue
|
|
|
|
|
|
|
|
entry_found = True
|
2020-03-16 18:35:51 +01:00
|
|
|
params = {".id": tmp[".id"], mod_param: mod_value}
|
2020-03-11 23:34:26 +01:00
|
|
|
|
|
|
|
self.lock.acquire()
|
|
|
|
try:
|
|
|
|
response.update(**params)
|
2020-03-18 09:33:36 +01:00
|
|
|
except librouteros_custom.exceptions.ConnectionClosed:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error("Mikrotik %s connection closed", self._host)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-13 02:27:21 +01:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return False
|
|
|
|
except (
|
2020-03-18 09:33:36 +01:00
|
|
|
librouteros_custom.exceptions.TrapError,
|
|
|
|
librouteros_custom.exceptions.MultiTrapError,
|
|
|
|
librouteros_custom.exceptions.ProtocolError,
|
|
|
|
librouteros_custom.exceptions.FatalError,
|
2020-03-16 18:35:51 +01:00
|
|
|
ssl.SSLError,
|
|
|
|
BrokenPipeError,
|
|
|
|
OSError,
|
|
|
|
ValueError,
|
2020-03-11 23:34:26 +01:00
|
|
|
) as api_error:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while update %s", self._host,
|
|
|
|
api_error
|
2020-03-17 00:40:08 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.disconnect()
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return False
|
|
|
|
except:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while update %s", self._host,
|
|
|
|
"unknown"
|
2020-03-17 00:40:08 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
2020-03-13 02:27:21 +01:00
|
|
|
return False
|
2020-03-11 23:34:26 +01:00
|
|
|
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
if not entry_found:
|
2020-03-16 19:02:54 +01:00
|
|
|
error = f'Parameter "{param}" with value "{value}" not found'
|
2020-03-11 23:34:26 +01:00
|
|
|
raise ApiEntryNotFound(error)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# run_script
|
|
|
|
# ---------------------------
|
|
|
|
def run_script(self, name) -> bool:
|
|
|
|
"""Run script"""
|
|
|
|
entry_found = False
|
|
|
|
if not self._connected or not self._connection:
|
|
|
|
if self._connection_epoch > time.time() - self._connection_retry_sec:
|
2020-03-21 18:46:54 +03:00
|
|
|
return False
|
2020-03-11 23:34:26 +01:00
|
|
|
|
|
|
|
if not self.connect():
|
|
|
|
return False
|
|
|
|
|
2020-03-16 18:35:51 +01:00
|
|
|
response = self.path("/system/script")
|
2020-03-11 23:34:26 +01:00
|
|
|
if response is None:
|
|
|
|
return False
|
|
|
|
|
|
|
|
for tmp in response:
|
2020-03-16 18:35:51 +01:00
|
|
|
if "name" not in tmp:
|
2020-03-11 23:34:26 +01:00
|
|
|
continue
|
|
|
|
|
2020-03-16 18:35:51 +01:00
|
|
|
if tmp["name"] != name:
|
2020-03-11 23:34:26 +01:00
|
|
|
continue
|
|
|
|
|
|
|
|
entry_found = True
|
|
|
|
self.lock.acquire()
|
|
|
|
try:
|
2020-03-16 18:35:51 +01:00
|
|
|
run = response("run", **{".id": tmp[".id"]})
|
2020-03-11 23:34:26 +01:00
|
|
|
tuple(run)
|
2020-03-18 09:33:36 +01:00
|
|
|
except librouteros_custom.exceptions.ConnectionClosed:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error("Mikrotik %s connection closed", self._host)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-13 02:27:21 +01:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return False
|
|
|
|
except (
|
2020-03-18 09:33:36 +01:00
|
|
|
librouteros_custom.exceptions.TrapError,
|
|
|
|
librouteros_custom.exceptions.MultiTrapError,
|
|
|
|
librouteros_custom.exceptions.ProtocolError,
|
|
|
|
librouteros_custom.exceptions.FatalError,
|
2020-03-16 18:35:51 +01:00
|
|
|
ssl.SSLError,
|
|
|
|
BrokenPipeError,
|
|
|
|
OSError,
|
|
|
|
ValueError,
|
2020-03-11 23:34:26 +01:00
|
|
|
) as api_error:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while run_script %s", self._host,
|
|
|
|
api_error
|
2020-03-17 00:40:08 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.disconnect()
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return False
|
|
|
|
except:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while run_script %s", self._host,
|
|
|
|
"unknown"
|
2020-03-17 00:40:08 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
2020-03-13 02:27:21 +01:00
|
|
|
return False
|
2020-03-11 23:34:26 +01:00
|
|
|
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
if not entry_found:
|
2020-03-16 19:02:54 +01:00
|
|
|
error = f'Script "{name}" not found'
|
2020-03-11 23:34:26 +01:00
|
|
|
raise ApiEntryNotFound(error)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
# get_traffic
|
|
|
|
# ---------------------------
|
2020-03-21 18:46:54 +03:00
|
|
|
def get_traffic(self, interfaces) -> Optional(list):
|
2020-03-11 23:34:26 +01:00
|
|
|
"""Get traffic stats"""
|
|
|
|
traffic = None
|
|
|
|
if not self._connected or not self._connection:
|
|
|
|
if self._connection_epoch > time.time() - self._connection_retry_sec:
|
|
|
|
return None
|
|
|
|
|
|
|
|
if not self.connect():
|
|
|
|
return None
|
|
|
|
|
2020-03-16 18:35:51 +01:00
|
|
|
response = self.path("/interface")
|
2020-03-11 23:34:26 +01:00
|
|
|
if response is None:
|
|
|
|
return None
|
|
|
|
|
2020-03-16 18:35:51 +01:00
|
|
|
args = {"interface": interfaces, "once": True}
|
2020-03-11 23:34:26 +01:00
|
|
|
self.lock.acquire()
|
|
|
|
try:
|
2020-03-16 18:35:51 +01:00
|
|
|
traffic = response("monitor-traffic", **args)
|
|
|
|
_LOGGER.debug(
|
|
|
|
"API response (%s): %s", "/interface/monitor-traffic", traffic
|
|
|
|
)
|
2020-03-18 09:33:36 +01:00
|
|
|
except librouteros_custom.exceptions.ConnectionClosed:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error("Mikrotik %s connection closed", self._host)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-13 02:27:21 +01:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return None
|
|
|
|
except (
|
2020-03-18 09:33:36 +01:00
|
|
|
librouteros_custom.exceptions.TrapError,
|
|
|
|
librouteros_custom.exceptions.MultiTrapError,
|
|
|
|
librouteros_custom.exceptions.ProtocolError,
|
|
|
|
librouteros_custom.exceptions.FatalError,
|
2020-03-16 18:35:51 +01:00
|
|
|
ssl.SSLError,
|
|
|
|
BrokenPipeError,
|
|
|
|
OSError,
|
|
|
|
ValueError,
|
2020-03-11 23:34:26 +01:00
|
|
|
) as api_error:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while get_traffic %s", self._host,
|
|
|
|
api_error
|
2020-03-17 00:40:08 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.disconnect()
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return None
|
|
|
|
except:
|
2020-03-17 00:40:08 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while get_traffic %s", self._host,
|
|
|
|
"unknown"
|
2020-03-17 00:40:08 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
2020-03-11 23:34:26 +01:00
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
2020-03-13 02:27:21 +01:00
|
|
|
return None
|
2020-03-11 23:34:26 +01:00
|
|
|
|
2020-03-17 00:42:44 +01:00
|
|
|
try:
|
|
|
|
tuple(response)
|
2020-03-18 09:33:36 +01:00
|
|
|
except librouteros_custom.exceptions.ConnectionClosed as api_error:
|
2020-03-17 00:42:44 +01:00
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while get_traffic %s", self._host,
|
|
|
|
api_error
|
2020-03-17 00:42:44 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
|
|
|
return None
|
|
|
|
except:
|
|
|
|
if not self.connection_error_reported:
|
|
|
|
_LOGGER.error(
|
2020-03-21 19:02:28 +03:00
|
|
|
"Mikrotik %s error while get_traffic %s", self._host,
|
|
|
|
"unknown"
|
2020-03-17 00:42:44 +01:00
|
|
|
)
|
|
|
|
self.connection_error_reported = True
|
|
|
|
|
|
|
|
self.disconnect()
|
|
|
|
self.lock.release()
|
|
|
|
return None
|
|
|
|
|
2020-03-13 02:27:21 +01:00
|
|
|
self.lock.release()
|
2020-03-11 23:34:26 +01:00
|
|
|
return traffic if traffic else None
|