summaryrefslogtreecommitdiff
path: root/sublab_project/sublab_monitor
diff options
context:
space:
mode:
Diffstat (limited to 'sublab_project/sublab_monitor')
-rw-r--r--sublab_project/sublab_monitor/__init__.py1
-rw-r--r--sublab_project/sublab_monitor/models.py3
-rw-r--r--sublab_project/sublab_monitor/storage.py63
-rw-r--r--sublab_project/sublab_monitor/tasks.py46
-rw-r--r--sublab_project/sublab_monitor/templates/sublab_monitor/host_status.html6
-rw-r--r--sublab_project/sublab_monitor/templatetags/__init__.py0
-rw-r--r--sublab_project/sublab_monitor/templatetags/host_status.py46
-rw-r--r--sublab_project/sublab_monitor/tests.py24
-rw-r--r--sublab_project/sublab_monitor/views.py1
9 files changed, 190 insertions, 0 deletions
diff --git a/sublab_project/sublab_monitor/__init__.py b/sublab_project/sublab_monitor/__init__.py
new file mode 100644
index 0000000..1b8cfc0
--- /dev/null
+++ b/sublab_project/sublab_monitor/__init__.py
@@ -0,0 +1 @@
+from sublab_monitor.storage import Storage, StorageError
diff --git a/sublab_project/sublab_monitor/models.py b/sublab_project/sublab_monitor/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/sublab_project/sublab_monitor/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/sublab_project/sublab_monitor/storage.py b/sublab_project/sublab_monitor/storage.py
new file mode 100644
index 0000000..8b3e385
--- /dev/null
+++ b/sublab_project/sublab_monitor/storage.py
@@ -0,0 +1,63 @@
+import redis
+import pickle
+import sys
+
+# load some django settings here some day
+
+
+class StorageError(Exception):
+ pass
+
+
+def storage_error(typ):
+ return type('Storage%sError' % typ.__name__, (typ, StorageError), {})
+
+
+def raise_storage_error():
+ typ, value, trace = sys.exc_info()
+
+ raise storage_error(typ), value, trace
+
+
+class Storage:
+ key_prefix = 'sublab_monitor.'
+
+ def __init__(self, app_prefix):
+ self.key_prefix += '%s.' % app_prefix
+
+ try:
+ self.redis = redis.StrictRedis()
+ except redis.RedisError:
+ raise_storage_error()
+
+ def key(self, key):
+ return '%s%s' % (self.key_prefix, key)
+
+ def get(self, key):
+ lookup_key = self.key(key)
+
+ try:
+ entry = self.redis.get(lookup_key)
+ except redis.RedisError:
+ raise_storage_error()
+
+ if entry is None:
+ return None
+
+ try:
+ return pickle.loads(entry)
+ except pickle.PickleError:
+ raise_storage_error()
+
+ def set(self, key, value):
+ lookup_key = self.key(key)
+
+ try:
+ entry = pickle.dumps(value)
+ except pickle.PickleError:
+ raise_storage_error()
+
+ try:
+ self.redis.set(lookup_key, entry)
+ except redis.RedisError:
+ raise_storage_error()
diff --git a/sublab_project/sublab_monitor/tasks.py b/sublab_project/sublab_monitor/tasks.py
new file mode 100644
index 0000000..33dcad6
--- /dev/null
+++ b/sublab_project/sublab_monitor/tasks.py
@@ -0,0 +1,46 @@
+"""Celery tasks.
+"""
+from datetime import timedelta
+from celery.task import PeriodicTask
+import subprocess
+
+import sublab_monitor
+
+class NetworkStatus(PeriodicTask):
+ """Periodic task for getting sublab network status
+ """
+ hosts = {
+ 'taifun': '172.22.83.5',
+ 'trieste': '172.22.80.4',
+ 'nautilus': '172.22.80.7',
+ }
+ run_every = timedelta(minutes=4)
+ ignore_result = True
+
+ def __init__(self, *args, **kwargs):
+ PeriodicTask.__init__(self, *args, **kwargs)
+
+
+ @staticmethod
+ def host_alive(host):
+ rc = subprocess.call(['ping', '-c', '2', '-W', '1', host])
+
+ if rc == 0:
+ return True
+ else:
+ return False
+
+ def run(self, **kwargs):
+ """Ping all the hosts.
+ """
+ self.logger = self.get_logger(**kwargs)
+
+ results = {}
+ for host, target in self.hosts.items():
+ results[host] = self.host_alive(target)
+
+ storage = sublab_monitor.Storage('network_status')
+ for host, status in results.items():
+ storage.set(host, status)
+
+ return repr(results)
diff --git a/sublab_project/sublab_monitor/templates/sublab_monitor/host_status.html b/sublab_project/sublab_monitor/templates/sublab_monitor/host_status.html
new file mode 100644
index 0000000..5d26dd9
--- /dev/null
+++ b/sublab_project/sublab_monitor/templates/sublab_monitor/host_status.html
@@ -0,0 +1,6 @@
+<td class="status"> {{ hostname|capfirst }}: </td>
+<td class="status">
+ <span class="{{ status|yesno:"green,grey" }}">Online</span>
+ &nbsp;
+ <span class="{{ status|yesno:"grey,red,grey" }}">Offline</span>
+</td>
diff --git a/sublab_project/sublab_monitor/templatetags/__init__.py b/sublab_project/sublab_monitor/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sublab_project/sublab_monitor/templatetags/__init__.py
diff --git a/sublab_project/sublab_monitor/templatetags/host_status.py b/sublab_project/sublab_monitor/templatetags/host_status.py
new file mode 100644
index 0000000..e119f60
--- /dev/null
+++ b/sublab_project/sublab_monitor/templatetags/host_status.py
@@ -0,0 +1,46 @@
+from django import template
+import sublab_monitor
+
+register = template.Library()
+
+class HostStatusNode(template.Node):
+ def __init__(self, host):
+ self.host = host
+
+ def host_status(self, context):
+ if self not in context.render_context:
+ try:
+ context.render_context[self] = sublab_monitor.Storage('network_status')
+ except sublab_monitor.StorageError:
+ return None
+
+ storage = context.render_context[self]
+ try:
+ return storage.get(self.host)
+ except sublab_monitor.StorageError:
+ return None
+
+ def host_context(self, context):
+ context_data = {
+ 'hostname': self.host,
+ 'status': self.host_status(context)
+ }
+
+ return template.context.Context(context_data, autoescape=context.autoescape)
+
+ def render(self, context):
+ t = template.loader.get_template('sublab_monitor/host_status.html')
+ c = self.host_context(context)
+ return t.render(c)
+
+@register.tag
+def host_status(parser, token):
+ try:
+ tag_name, host = token.split_contents()
+ except ValueError:
+ raise template.TemplateSyntaxError(
+ "%r tag requires a single argument" % token.contents.split()[0])
+ if not host[0] == host[-1] and host[0] in ('"', "'"):
+ raise template.TemplateSyntaxError(
+ "%r tag's argument should be in quotes" % token.contents.split()[0])
+ return HostStatusNode(host[1:-1])
diff --git a/sublab_project/sublab_monitor/tests.py b/sublab_project/sublab_monitor/tests.py
new file mode 100644
index 0000000..c80bb61
--- /dev/null
+++ b/sublab_project/sublab_monitor/tests.py
@@ -0,0 +1,24 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+from sublab_monitor.tasks import NetworkStatus
+
+class SimpleTest(TestCase):
+ def test_reachable(self):
+ """
+ Tests that for reachable hosts host_alive() returns True
+ """
+ self.assertEqual(NetworkStatus.host_alive('127.0.0.1'), True)
+
+ def test_unreachable(self):
+ """
+ Tests that for unreachable hosts host_alive() returns False
+ """
+ # Hopefully, this DoD? IP will never be reachable on the
+ # Internet :)
+ self.assertEqual(NetworkStatus.host_alive('8.5.4.3'), False)
diff --git a/sublab_project/sublab_monitor/views.py b/sublab_project/sublab_monitor/views.py
new file mode 100644
index 0000000..60f00ef
--- /dev/null
+++ b/sublab_project/sublab_monitor/views.py
@@ -0,0 +1 @@
+# Create your views here.