2019-12-29 23:57:39 -07:00
|
|
|
"""Custom exceptions for hyperglass."""
|
|
|
|
|
2019-12-30 09:47:31 -07:00
|
|
|
# Standard Library Imports
|
2019-12-29 23:57:39 -07:00
|
|
|
import json as _json
|
2019-12-30 09:47:31 -07:00
|
|
|
|
|
|
|
# Project Imports
|
2019-12-29 23:57:39 -07:00
|
|
|
from hyperglass.util import log
|
2019-07-07 02:49:54 -07:00
|
|
|
|
|
|
|
|
|
|
|
class HyperglassError(Exception):
|
2019-12-29 23:57:39 -07:00
|
|
|
"""hyperglass base exception."""
|
|
|
|
|
|
|
|
def __init__(self, message="", alert="warning", keywords=None):
|
|
|
|
"""Initialize the hyperglass base exception class.
|
2019-07-07 02:49:54 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
Keyword Arguments:
|
|
|
|
message {str} -- Error message (default: {""})
|
|
|
|
alert {str} -- Error severity (default: {"warning"})
|
|
|
|
keywords {list} -- 'Important' keywords (default: {None})
|
|
|
|
"""
|
2019-12-30 01:44:19 -07:00
|
|
|
self._message = message
|
|
|
|
self._alert = alert
|
|
|
|
self._keywords = keywords or []
|
|
|
|
if self._alert == "warning":
|
2019-12-29 23:57:39 -07:00
|
|
|
log.error(repr(self))
|
2019-12-30 01:44:19 -07:00
|
|
|
elif self._alert == "danger":
|
2019-12-29 23:57:39 -07:00
|
|
|
log.critical(repr(self))
|
|
|
|
else:
|
|
|
|
log.info(repr(self))
|
2019-08-31 23:50:02 -07:00
|
|
|
|
2019-09-03 00:42:45 -07:00
|
|
|
def __str__(self):
|
2019-12-29 23:57:39 -07:00
|
|
|
"""Return the instance's error message.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
{str} -- Error Message
|
|
|
|
"""
|
2019-12-30 01:44:19 -07:00
|
|
|
return self._message
|
2019-09-03 00:42:45 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
def __repr__(self):
|
|
|
|
"""Return the instance's severity & error message in a string.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
{str} -- Error message with code
|
|
|
|
"""
|
2019-12-30 01:44:19 -07:00
|
|
|
return f"[{self.alert.upper()}] {self._message}"
|
2019-12-29 23:57:39 -07:00
|
|
|
|
2020-01-20 00:32:42 -07:00
|
|
|
def dict(self):
|
2019-12-29 23:57:39 -07:00
|
|
|
"""Return the instance's attributes as a dictionary.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
{dict} -- Exception attributes in dict
|
|
|
|
"""
|
2019-12-30 01:44:19 -07:00
|
|
|
return {
|
|
|
|
"message": self._message,
|
|
|
|
"alert": self._alert,
|
|
|
|
"keywords": self._keywords,
|
|
|
|
}
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
def json(self):
|
|
|
|
"""Return the instance's attributes as a JSON object.
|
2019-07-07 02:49:54 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
Returns:
|
|
|
|
{str} -- Exception attributes as JSON
|
|
|
|
"""
|
|
|
|
return _json.dumps(self.__dict__())
|
2019-07-07 02:49:54 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
@property
|
|
|
|
def message(self):
|
|
|
|
"""Return the instance's `message` attribute.
|
2019-08-29 23:05:54 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
Returns:
|
|
|
|
{str} -- Error Message
|
|
|
|
"""
|
2019-12-30 01:44:19 -07:00
|
|
|
return self._message
|
2019-07-07 02:49:54 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
@property
|
|
|
|
def alert(self):
|
|
|
|
"""Return the instance's `alert` attribute.
|
2019-07-07 02:49:54 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
Returns:
|
|
|
|
{str} -- Alert name
|
|
|
|
"""
|
2019-12-30 01:44:19 -07:00
|
|
|
return self._alert
|
2019-08-29 23:05:54 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
@property
|
|
|
|
def keywords(self):
|
|
|
|
"""Return the instance's `keywords` attribute.
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
Returns:
|
|
|
|
{list} -- Keywords List
|
|
|
|
"""
|
2019-12-30 01:44:19 -07:00
|
|
|
return self._keywords
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2019-08-29 23:05:54 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
class _UnformattedHyperglassError(HyperglassError):
|
|
|
|
"""Base exception class for freeform error messages."""
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2020-01-05 00:34:44 -07:00
|
|
|
_alert = "warning"
|
|
|
|
|
|
|
|
def __init__(self, unformatted_msg="", alert=None, **kwargs):
|
2019-12-29 23:57:39 -07:00
|
|
|
"""Format error message with keyword arguments.
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
Keyword Arguments:
|
|
|
|
message {str} -- Error message (default: {""})
|
|
|
|
alert {str} -- Error severity (default: {"warning"})
|
|
|
|
keywords {list} -- 'Important' keywords (default: {None})
|
|
|
|
"""
|
2019-12-30 01:44:19 -07:00
|
|
|
self._message = unformatted_msg.format(**kwargs)
|
2020-01-05 00:34:44 -07:00
|
|
|
self._alert = alert or self._alert
|
2019-12-30 01:44:19 -07:00
|
|
|
self._keywords = list(kwargs.values())
|
|
|
|
super().__init__(
|
|
|
|
message=self._message, alert=self._alert, keywords=self._keywords
|
|
|
|
)
|
2019-08-29 23:05:54 -07:00
|
|
|
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2020-01-05 00:34:44 -07:00
|
|
|
class _PredefinedHyperglassError(HyperglassError):
|
|
|
|
_message = "undefined"
|
|
|
|
_alert = "warning"
|
|
|
|
|
|
|
|
def __init__(self, alert=None, **kwargs):
|
|
|
|
self._fmt_msg = self._message.format(**kwargs)
|
|
|
|
self._alert = alert or self._alert
|
|
|
|
self._keywords = list(kwargs.values())
|
|
|
|
super().__init__(
|
|
|
|
message=self._fmt_msg, alert=self._alert, keywords=self._keywords
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
class ConfigError(_UnformattedHyperglassError):
|
|
|
|
"""Raised for generic user-config issues."""
|
2019-08-29 23:05:54 -07:00
|
|
|
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2020-01-05 00:34:44 -07:00
|
|
|
class ConfigInvalid(_PredefinedHyperglassError):
|
2019-12-29 23:57:39 -07:00
|
|
|
"""Raised when a config item fails type or option validation."""
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2019-12-30 01:44:19 -07:00
|
|
|
_message = 'The value field "{field}" is invalid: {error_msg}'
|
2019-08-29 23:05:54 -07:00
|
|
|
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2020-01-05 00:34:44 -07:00
|
|
|
class ConfigMissing(_PredefinedHyperglassError):
|
2019-12-29 23:57:39 -07:00
|
|
|
"""Raised when a required config file or item is missing or undefined."""
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2019-12-30 01:44:19 -07:00
|
|
|
_message = (
|
2019-12-29 23:57:39 -07:00
|
|
|
"{missing_item} is missing or undefined and is required to start "
|
|
|
|
"hyperglass. Please consult the installation documentation."
|
|
|
|
)
|
2019-08-29 07:10:40 -07:00
|
|
|
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
class ScrapeError(_UnformattedHyperglassError):
|
|
|
|
"""Raised when a scrape/netmiko error occurs."""
|
2019-08-25 23:22:20 -07:00
|
|
|
|
2019-12-30 01:44:19 -07:00
|
|
|
_alert = "danger"
|
2019-07-15 02:30:42 -07:00
|
|
|
|
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
class AuthError(_UnformattedHyperglassError):
|
|
|
|
"""Raised when authentication to a device fails."""
|
2019-10-09 03:10:52 -07:00
|
|
|
|
2019-12-30 01:44:19 -07:00
|
|
|
_alert = "danger"
|
2019-10-09 03:10:52 -07:00
|
|
|
|
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
class RestError(_UnformattedHyperglassError):
|
|
|
|
"""Raised upon a rest API client error."""
|
2019-07-07 02:49:54 -07:00
|
|
|
|
2019-12-30 01:44:19 -07:00
|
|
|
_alert = "danger"
|
2019-07-07 02:49:54 -07:00
|
|
|
|
2019-09-03 00:42:45 -07:00
|
|
|
|
2019-12-29 23:57:39 -07:00
|
|
|
class DeviceTimeout(_UnformattedHyperglassError):
|
2019-09-03 00:42:45 -07:00
|
|
|
"""Raised when the connection to a device times out."""
|
|
|
|
|
2019-12-30 01:44:19 -07:00
|
|
|
_alert = "danger"
|
2019-12-29 23:57:39 -07:00
|
|
|
|
|
|
|
|
|
|
|
class InputInvalid(_UnformattedHyperglassError):
|
|
|
|
"""Raised when input validation fails."""
|
|
|
|
|
|
|
|
|
|
|
|
class InputNotAllowed(_UnformattedHyperglassError):
|
|
|
|
"""Raised when input validation fails due to a configured check."""
|
|
|
|
|
|
|
|
|
|
|
|
class ResponseEmpty(_UnformattedHyperglassError):
|
|
|
|
"""Raised when hyperglass can connect to the device but the response is empty."""
|
|
|
|
|
|
|
|
|
|
|
|
class UnsupportedDevice(_UnformattedHyperglassError):
|
|
|
|
"""Raised when an input NOS is not in the supported NOS list."""
|