-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
329 additions
and
11 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from _socket import error as _socket_error | ||
import gevent.event | ||
import gevent.greenlet | ||
from gevent.server import StreamServer | ||
from io import BlockingIOError | ||
import json | ||
import logging | ||
from tendrl.commons.alert import AlertUtils | ||
from tendrl.node_agent.alerts.base_alert_handler import AlertHandlerManager | ||
from tendrl.node_agent.alerts.base_alert_handler import NoHandlerException | ||
import tendrl.node_agent.manager.utils as utils | ||
import uuid | ||
|
||
LOG = logging.getLogger(__name__) | ||
RECEIVE_DATA_SIZE = 4096 | ||
db_client = None | ||
|
||
|
||
class AlertsManager(gevent.greenlet.Greenlet): | ||
|
||
def read_socket(self, sock, address): | ||
try: | ||
data = sock.recv(RECEIVE_DATA_SIZE) | ||
alert_utils = AlertUtils(db_client) | ||
alert_json = json.loads(data) | ||
alert_json['alert_id'] = str(uuid.uuid4()) | ||
alert_json['significance'] = 'HIGH' | ||
alert_json['node_id'] = utils.get_local_node_context() | ||
alert_json['ackedby'] = '' | ||
alert_json['acked'] = False | ||
alert = alert_utils.to_obj(alert_json) | ||
AlertHandlerManager(db_client).handle(alert) | ||
except ( | ||
KeyError, | ||
TypeError, | ||
ValueError, | ||
NoHandlerException | ||
) as ex: | ||
LOG.error('Failed to handle data on alert socket.Error %s' % ex) | ||
|
||
def __init__(self, alerts_socket_addr, alerts_socket_port, etcd_client): | ||
super(AlertsManager, self).__init__() | ||
self.hostname = alerts_socket_addr | ||
self.port = alerts_socket_port | ||
global db_client | ||
db_client = etcd_client | ||
self.server = StreamServer( | ||
(self.hostname, int(self.port)), | ||
self.read_socket | ||
) | ||
|
||
def _run(self): | ||
try: | ||
self.server.serve_forever() | ||
except (TypeError, BlockingIOError, _socket_error, ValueError) as ex: | ||
LOG.error('Error trying to serve the alerting socket forever.\ | ||
Error %s' % ex) | ||
|
||
def stop(self): | ||
self.server.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import datetime | ||
import etcd | ||
import importlib | ||
import inspect | ||
import logging | ||
import os | ||
import six | ||
from tendrl.commons.alert import AlertUtils | ||
from tendrl.commons.singleton import to_singleton | ||
|
||
LOG = logging.getLogger(__name__) | ||
|
||
|
||
class NoHandlerException(Exception): | ||
pass | ||
|
||
|
||
class HandlerMount(type): | ||
|
||
def __init__(cls, name, bases, attrs): | ||
if not hasattr(cls, 'handlers'): | ||
cls.handlers = [] | ||
else: | ||
cls.register_handler(cls) | ||
|
||
def register_handler(cls, handler): | ||
instance = handler() | ||
cls.handlers.append(instance) | ||
|
||
|
||
@six.add_metaclass(HandlerMount) | ||
class AlertHandler(object): | ||
def __init__(self): | ||
self.time_stamp = datetime.datetime.now().isoformat() | ||
self.alert = None | ||
self.handles = '' | ||
|
||
def update_alert(self, etcd_client): | ||
# Fetch alerts in etcd | ||
try: | ||
alerts = AlertUtils(etcd_client).get_alerts() | ||
# Check if similar alert already exists | ||
for curr_alert in alerts: | ||
# If similar alert exists, update the similar alert to etcd | ||
if AlertUtils(etcd_client).is_same(self.alert, curr_alert): | ||
self.alert = AlertUtils( | ||
etcd_client | ||
).update( | ||
self.alert, | ||
curr_alert | ||
) | ||
if not AlertUtils( | ||
etcd_client | ||
).equals( | ||
self.alert, | ||
curr_alert | ||
): | ||
AlertUtils(etcd_client).store_alert(self.alert) | ||
return | ||
# else add this new alert to etcd | ||
AlertUtils(etcd_client).store_alert(self.alert) | ||
except etcd.EtcdKeyNotFound: | ||
AlertUtils(etcd_client).store_alert(self.alert) | ||
except etcd.EtcdConnectionFailed as ex: | ||
LOG.error( | ||
'Failed to fetch existing alerts.Error %s' % ex, | ||
exc_info=True | ||
) | ||
|
||
def handle(self, alert_obj, etcd_client): | ||
try: | ||
self.alert = alert_obj | ||
self.alert.significance = 'HIGH' | ||
self.update_alert(etcd_client) | ||
except Exception as ex: | ||
LOG.error( | ||
'Failed to handle the alert %s.Error %s' | ||
% (str(alert_obj.to_json_string()), str(ex)), | ||
exc_info=True | ||
) | ||
|
||
|
||
@to_singleton | ||
class AlertHandlerManager(object): | ||
def load_handlers(self): | ||
try: | ||
path = os.path.dirname(os.path.abspath(__file__)) + '/handlers' | ||
pkg = 'tendrl.node_agent.alerts.handlers' | ||
for py in [f[:-3] for f in os.listdir(path) | ||
if f.endswith('.py') and f != '__init__.py']: | ||
handler_name = '.'.join([pkg, py]) | ||
mod = importlib.import_module(handler_name) | ||
clsmembers = inspect.getmembers(mod, inspect.isclass) | ||
for name, cls in clsmembers: | ||
exec("from %s import %s" % (handler_name, name)) | ||
except (SyntaxError, ValueError, ImportError) as ex: | ||
LOG.error('Failed to load the alert handlers. Error %s' % | ||
ex, exc_info=True) | ||
raise ex | ||
|
||
def __init__(self, etcd_client): | ||
try: | ||
self.load_handlers() | ||
self.etcd_client = etcd_client | ||
alert_handlers = [] | ||
for handler in AlertHandler.handlers: | ||
alert_handlers.append(handler.handles) | ||
self.etcd_client.write( | ||
'/alerting/alert_types/node_agent', | ||
alert_handlers | ||
) | ||
except (SyntaxError, ValueError, ImportError) as ex: | ||
raise ex | ||
|
||
def handle(self, alert): | ||
for handler in AlertHandler.handlers: | ||
if handler.handles == alert.resource: | ||
handler.handle(alert, self.etcd_client) | ||
return | ||
raise NoHandlerException( | ||
'No alert handler defined for %s and hence cannot handle alert %s' | ||
% (alert['resource'], str(alert)) | ||
) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from tendrl.node_agent.alerts.base_alert_handler import AlertHandler | ||
|
||
|
||
class CpuHandler(AlertHandler): | ||
def __init__(self): | ||
AlertHandler.__init__(self) | ||
self.handles = 'cpu' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from tendrl.node_agent.alerts.base_alert_handler import AlertHandler | ||
|
||
|
||
class MemoryHandler(AlertHandler): | ||
def __init__(self): | ||
AlertHandler.__init__(self) | ||
self.handles = 'memory' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from tendrl.node_agent.alerts.base_alert_handler import AlertHandler | ||
|
||
|
||
class MountPointHandler(AlertHandler): | ||
def __init__(self): | ||
AlertHandler.__init__(self) | ||
self.handles = 'df' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from tendrl.node_agent.alerts.base_alert_handler import AlertHandler | ||
|
||
|
||
class SwapHandler(AlertHandler): | ||
def __init__(self): | ||
AlertHandler.__init__(self) | ||
self.handles = 'swap' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
Empty file.
12 changes: 12 additions & 0 deletions
12
tendrl/node_agent/objects/service/atoms/check_service_status.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import os | ||
|
||
|
||
class CheckServiceStatus(object): | ||
def run(self, parameters): | ||
service_name = parameters.get("Service.name") | ||
response = os.system("systemctl status %s" % service_name) | ||
# and then check the response... | ||
if response == 0: | ||
return True | ||
else: | ||
return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.