diff --git a/cterasdk/edge/mail.py b/cterasdk/edge/mail.py index 783d717c..89ccf161 100644 --- a/cterasdk/edge/mail.py +++ b/cterasdk/edge/mail.py @@ -1,5 +1,6 @@ import logging +from .types import AlertSettings from ..common import Object from .base_command import BaseCommand @@ -8,9 +9,18 @@ class Mail(BaseCommand): - """ Edge Filer Mail Server configuration APIs """ + """ + Edge Filer Mail Server configuration APIs - def enable(self, smtp_server, port=25, username=None, password=None, use_tls=True): + :ivar cterasdk.edge.mail.alerts alerts: Object holding the Edge Filer e-mail alert APIs + """ + + def __init__(self, edge): + super().__init__(edge) + self.alerts = Alerts(self._edge) + + def enable(self, smtp_server, port=25, username=None, password=None, use_tls=True, + sender=None, recipients=None, min_severity=None): """ Enable e-mail delivery using a custom SMTP server @@ -19,6 +29,9 @@ def enable(self, smtp_server, port=25, username=None, password=None, use_tls=Tru :param str,optional username: The user name of the SMTP Server, defaults to None :param str,optional password: The password of the SMTP Server, defaults to None :param bool,optional use_tls: Use TLS when connecting to the SMTP Server, defaults to True + :param str,optional sender: Sender e-mail address + :param list[str],optional recipients: List of e-mail recipients + :param cterasdk.edge.enum.Severity severity: Minimum severity level to trigger email alerts """ settings = self._edge.api.get('/config/logging/alert') settings.useCustomServer = True @@ -30,12 +43,22 @@ def enable(self, smtp_server, port=25, username=None, password=None, use_tls=Tru if username is not None and password is not None: settings.useAuth = True settings.auth = Object() + settings.auth._classname = 'AuthSettings' # pylint: disable=protected-access settings.auth.username = username settings.auth.password = password if settings.useTLS != use_tls: settings.useTLS = use_tls + if sender is not None: + setattr(settings, 'from', sender) + + if recipients is not None: + settings.emails = recipients + + if min_severity is not None: + settings.minSeverity = min_severity + logger.info('Enabling mail server.') self._edge.api.put('/config/logging/alert', settings) @@ -50,3 +73,23 @@ def disable(self): logger.info('Disabling mail server.') self._edge.api.put('/config/logging/alert/useCustomServer', False) logger.info('Mail server disabled.') + + +class Alerts(BaseCommand): + + def get(self): + """ + Get Alert Settings + + :returns: Alert settings + :rtype: cterasdk.edge.types.AlertSettings + """ + return AlertSettings.from_server_object(self._edge.api.get('/config/logging/alert/specificAlerts')) + + def modify(self, alerts): + """ + Modify Alert Settings + + :param cterasdk.edge.types.AlertSettings alerts: Alert Settings + """ + return AlertSettings.from_server_object(self._edge.api.put('/config/logging/alert/specificAlerts', alerts.to_server_object())) diff --git a/cterasdk/edge/types.py b/cterasdk/edge/types.py index e212184b..3b19f768 100644 --- a/cterasdk/edge/types.py +++ b/cterasdk/edge/types.py @@ -351,3 +351,72 @@ def monthly(day, hour, minute): :param int minute: Minute """ return AntivirusUpdateSchedule(mode='monthly', monthly=Object(day=day, hour=hour, minute=minute)) + + +class AlertSettings(Object): # pylint: disable=too-many-instance-attributes + """ + Alert Settings + + :ivar bool firmware_upgrade: Enables alerting when a firmware upgrade occurs. + :ivar bool device_startup: Enables alerting on Edge Filer shutdowns and startups. + :ivar bool backup_success: Enables alerting upon successful backup completion. + :ivar bool storage_volume_usage: Enables alerting for high storage volume utilization. + :ivar int storage_volume_usage_percent: Volume usage percentage threshold that triggers an alert. + :ivar bool overdue_backup: Enables alerting when a Cloud Backup is overdue. + :ivar int overdue_backup_days: Number of days since last Cloud Backup after which an alert is triggered. + :ivar bool delayed_synchronization: Enables alerting when synchronization is delayed. + :ivar int delayed_synchronization_hours: Number of hours of synchronization delay to trigger an alert. + :ivar bool disconnected: Enables alerting when the Edge Filer disconnects from the CTERA Portal. + :ivar int disconnected_hours: Number of hours of disconnection duration to trigger an alert. + """ + # pylint: disable=too-many-arguments, too-many-locals + def __init__(self, firmware_upgrade, device_startup, backup_success, + storage_volume_usage, storage_volume_usage_percent, + overdue_backup, overdue_backup_days, + delayed_synchronization, delayed_synchronization_hours, + disconnected, disconnected_hours): + super().__init__() + self.firmware_upgrade = firmware_upgrade + self.device_startup = device_startup + self.backup_success = backup_success + self.storage_volume_usage = storage_volume_usage + self.storage_volume_usage_percent = storage_volume_usage_percent + self.overdue_backup = overdue_backup + self.overdue_backup_days = overdue_backup_days + self.delayed_synchronization = delayed_synchronization + self.delayed_synchronization_hours = delayed_synchronization_hours + self.disconnected = disconnected + self.disconnected_hours = disconnected_hours + + def to_server_object(self): + param = Object() + param._classname = 'SpecificAlerts' # pylint: disable=protected-access + param.NotifyFirmwareUpgrade = self.firmware_upgrade + param.NotifyDeviceStarted = self.device_startup + param.NotifyBackupSuccess = self.backup_success + param.VolumeFullAlert = self.storage_volume_usage + param.VolumeFullPercent = self.storage_volume_usage_percent + param.BackupFailAlert = self.overdue_backup + param.BackupFailDays = self.overdue_backup_days + param.CloudSyncFailAlert = self.delayed_synchronization + param.CloudSyncFailHours = self.delayed_synchronization_hours + param.CloudConnectFailAlert = self.disconnected + param.CloudConnectFailHours = self.disconnected_hours + return param + + @staticmethod + def from_server_object(server_object): + params = { + 'firmware_upgrade': server_object.NotifyFirmwareUpgrade, + 'device_startup': server_object.NotifyDeviceStarted, + 'backup_success': server_object.NotifyBackupSuccess, + 'storage_volume_usage': server_object.VolumeFullAlert, + 'storage_volume_usage_percent': server_object.VolumeFullPercent, + 'overdue_backup': server_object.BackupFailAlert, + 'overdue_backup_days': server_object.BackupFailDays, + 'delayed_synchronization': server_object.CloudSyncFailAlert, + 'delayed_synchronization_hours': server_object.CloudSyncFailHours, + 'disconnected': server_object.CloudConnectFailAlert, + 'disconnected_hours': server_object.CloudConnectFailHours, + } + return AlertSettings(**params) diff --git a/docs/source/UserGuides/Edge/Configuration.rst b/docs/source/UserGuides/Edge/Configuration.rst index a5e2ba30..15779c84 100644 --- a/docs/source/UserGuides/Edge/Configuration.rst +++ b/docs/source/UserGuides/Edge/Configuration.rst @@ -1118,7 +1118,13 @@ Mail Server """Use default port number, use authentication and require TLS""" - edge.mail.enable('smtp.ctera.com', username = 'user', password = 'secret', useTLS = True) + edge.mail.enable('smtp.ctera.com', username='user', password='secret', useTLS=True) + + """Configure e-mail sender, recipients and minimum severity""" + edge.mail.enable('smtp.ctera.com', username='user', password='secret', useTLS=True, sender='alert-no-reply@ctera.com', recipients=[ + 'recipient_one@acme.com', + 'recipient_two@acme.com', + ], min_severity=edge_enum.Severity.ERROR) .. automethod:: cterasdk.edge.mail.Mail.disable :noindex: @@ -1127,6 +1133,33 @@ Mail Server edge.mail.disable() + +Email Alerts +------------ + +.. automethod:: cterasdk.edge.mail.Alerts.get + :noindex: + +.. automethod:: cterasdk.edge.mail.Alerts.modify + :noindex: + +.. code-block:: python + + alerts = edge.mail.alerts.get() + alerts.firmware_upgrade = True + alerts.device_startup = True + alerts.backup_success = False + alerts.storage_volume_usage = True + alerts.storage_volume_usage_percent = 85 + alerts.overdue_backup = False + alerts.delayed_synchronization = True + alerts.delayed_synchronization_hours = 1 + alerts.disconnected = True + alerts.disconnected_hours = 1 + edge.mail.alerts.modify(alerts) + +.. note:: See :py:class:`cterasdk.edge.types.AlertSettings` for alert description + Logging ======= diff --git a/docs/source/UserGuides/Miscellaneous/Changelog.rst b/docs/source/UserGuides/Miscellaneous/Changelog.rst index 2e8b8076..d45ca2c1 100644 --- a/docs/source/UserGuides/Miscellaneous/Changelog.rst +++ b/docs/source/UserGuides/Miscellaneous/Changelog.rst @@ -1,6 +1,21 @@ Changelog ========= +2.20.18 +------- + +Improvements +^^^^^^^^^^^^ + +* Added support for managing email alerts on Edge Filers. + +Bug Fixes +^^^^^^^^^ + +* Fixed an issue where email server credentials were not stored correctly due to a missing class name in the object. + +Related issues and pull requests on GitHub: `#314 `_ + 2.20.17 ------- diff --git a/tests/ut/edge/test_mail.py b/tests/ut/edge/test_mail.py index 87512e71..45699faf 100644 --- a/tests/ut/edge/test_mail.py +++ b/tests/ut/edge/test_mail.py @@ -80,6 +80,7 @@ def _get_mail_server_config(self, port=25, username=None, password=None, use_tls if username is not None and password is not None: mail_param.useAuth = True mail_param.auth = Object() + mail_param.auth._classname = 'AuthSettings' # pylint: disable=protected-access mail_param.auth.username = username mail_param.auth.password = password