Skip to content

Commit

Permalink
Merge pull request #49 from CitoEngine/gevent
Browse files Browse the repository at this point in the history
Gevent + Suppression
  • Loading branch information
extremeunix committed Nov 3, 2014
2 parents 449585c + da8c49e commit e9d29cf
Show file tree
Hide file tree
Showing 46 changed files with 1,805 additions and 202 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ install:
before_script:
- mysql -e 'create database cito;'
- python manage.py syncdb --noinput
- python manage.py migrate
# command to run tests
script:
- coverage run --source='.' --omit=tests*,fabfile*,*admin*,*urls*,*manage*,*/settings/*,*wsgi* manage.py test
- coverage run --source='.' --omit=tests*,fabfile*,*admin*,*urls*,*manage*,*/settings/*,*wsgi*,*/migrations/* manage.py test
after_success:
- coveralls
notifications:
Expand Down
1 change: 1 addition & 0 deletions api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__author__ = 'cyrus.dasadia'
58 changes: 58 additions & 0 deletions api/incident_listener.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
__author__ = 'cyrus.dasadia'

import json
import gevent
import logging
from django.conf import settings
from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from queue_manager.sqs import sqs_writer
from queue_manager.rabbitmq import rabbitmq_writer
from .json_responses import json_error, json_ok

logger = logging.getLogger('listener_logger')


class IncidentListenerAPI(View):
"""
API for accepting incidents in JSON format
"""
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(IncidentListenerAPI, self).dispatch(*args, **kwargs)

def post(self, request):
"""
Accepts JSON
{
"event":
{
"eventid": <int>,
"element": <string>,
"message": <string>,
},
"timestamp": <int>
}
:return JSON response:
"""

try:
parsed_json = json.loads(request.body)
except Exception as e:
return json_error('Invalid JSON' % e)

for k in settings.INCIDENT_PARAMS:
if k not in parsed_json:
return json_error('Missing JSON key:%s' % k)

if settings.QUEUE_TYPE in ['SQS', 'sqs']:
queue_writer = sqs_writer.send_to_sqs
elif settings.QUEUE_TYPE in ['RABBITMQ', 'rabbitmq']:
queue_writer = rabbitmq_writer.send_to_rabbitmq
else:
raise ValueError('Incorrect value "%s" for QUEUE_TYPE in %s' %
(settings.QUEUE_TYPE, settings.SETTINGS_MODULE))

gevent.spawn(queue_writer, request.body)
return json_ok('accepted')
21 changes: 21 additions & 0 deletions api/json_responses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import json
from django.http import HttpResponseBadRequest, HttpResponse


def json_error(msg):
return HttpResponseBadRequest('{"status": "error", "reason": "%s"}' % msg,
content_type="application/json")


def json_ok(msg):
return HttpResponse('{"status": "ok", "reason": "%s"}' % msg,
content_type="application/json")


def json_warning(msg):
return HttpResponse('{"status": "warning", "reason": "%s"}' % msg,
content_type="application/json")


def json_response(msg_dict):
return HttpResponse(json.dumps(msg_dict), content_type="application/json")
70 changes: 70 additions & 0 deletions appauth/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'Perms'
db.create_table(u'appauth_perms', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True)),
('access_level', self.gf('django.db.models.fields.SmallIntegerField')(default=5, max_length=1)),
))
db.send_create_signal(u'appauth', ['Perms'])


def backwards(self, orm):
# Deleting model 'Perms'
db.delete_table(u'appauth_perms')


models = {
u'appauth.perms': {
'Meta': {'object_name': 'Perms'},
'access_level': ('django.db.models.fields.SmallIntegerField', [], {'default': '5', 'max_length': '1'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'})
},
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}

complete_apps = ['appauth']
Empty file added appauth/migrations/__init__.py
Empty file.
1 change: 1 addition & 0 deletions audit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__author__ = 'cyrus.dasadia'
9 changes: 9 additions & 0 deletions event_listener/__init__.py → audit/auditlog.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,12 @@
See the License for the specific language governing permissions and
limitations under the License.
"""

from .models import IncidentAuditLog


def incidentauditlog(incident, message, level='info'):
try:
IncidentAuditLog.objects.create(incident=incident, level=level, message=message)
except Exception:
pass
24 changes: 16 additions & 8 deletions cito_engine/api.py → audit/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,22 @@
limitations under the License.
"""


from tastypie.resources import ModelResource
from tastypie.serializers import Serializer
from django.db import models
from cito_engine.models import Incident

class IncidentResource(ModelResource):
class Meta:
queryset = Incident.objects.all()
resource_name = 'incident'
serializer = Serializer(formats=['json'])

class AuditLog(models.Model):
LOG_TYPE_CHOICES = (('info', 'info'),
('warn', 'warn'),
('error', 'error'),
)
date_added = models.DateTimeField(auto_now_add=True)
message = models.TextField()
level = models.CharField(choices=LOG_TYPE_CHOICES, default='info', max_length=5)


class IncidentAuditLog(AuditLog):
incident = models.ForeignKey(Incident, db_index=True)

def __unicode__(self):
return '%s:%s:%s' % (self.date_added, self.level, self.message[:10])
7 changes: 6 additions & 1 deletion cito/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,20 @@
'django.contrib.admin',
'gunicorn',
'south',
'tastypie',
'cito_engine',
'appauth',
'reports',
'comments',
'rules_engine',
'audit',
)

STATIC_FILES = PROJECT_ROOT.ancestor(1).child('staticfiles')

INCIDENT_PARAMS = ['event', 'timestamp']

LOGIN_URL = '/login/'

try:
from .secret_key import *
except ImportError:
Expand Down
153 changes: 153 additions & 0 deletions cito/templates/suppressor_view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
{% include "header.html" %}
{% include 'top_nav_bar.html' %}
{% include 'noscript.html' %}

<div class="container-fluid">

<div class="box span12">
<div class="box-header well">
<h2><i class="icon-wrench"></i>{{ page_title }}</h2>
</div>
<div class="box-content">
<form class="form-horizontal" method="POST" accept-charset="."> {% csrf_token %}
{% for field in form.visible_fields %}
{{ field.label }}
{{ field }}
{% endfor %}
<button type="submit" class="btn btn-primary btn-small">Search</button>
</form>
</div>
</div>

{% if search_content %}
<form method="post" id="suppression_remove" action="/suppression/remove/" accept-charset="."> {% csrf_token %}
<input type="hidden" name="record_id" value="">
<input type="hidden" name="record_type" value="">
</form>

<div class="box span12">
<div class="box-header well">
<h2><i class="icon-wrench"></i>Events suppressed</h2>
</div>
<div class="box-content">
<table class="table table-bordered table-striped table-condensed table-fixed-header table-hover">
<thead>
<tr>
<th>Event ID</th>
<th>Suppressed By</th>
<th>Date Added</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for record in event_sup %}
<tr>
<td width="20%">
<div class="btn-group"><a class="btn btn-info btn-mini" href="/events/view/{{ record.event.id }}"><i class="icon-list"></i>View #{{ record.event.id }}</a></div>
</td>
<td>
{{ record.suppressed_by.username }}
</td>
<td>
{{ record.date_added|date:"M d, Y, H:i" }}
</td>
<td>
<input type="button" class="btn btn-info btn-small" value="Remove" onclick="javascript:suppression_remove({{ record.id }}, 'Event');">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="box span12">
<div class="box-header well">
<h2><i class="icon-wrench"></i>Elements suppressed</h2>
</div>
<div class="box-content">
<table class="table table-bordered table-striped table-condensed table-fixed-header table-hover">
<thead>
<tr>
<th>Element</th>
<th>Suppressed By</th>
<th>Date Added</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for record in element_sup %}
<tr>
<td width="20%">
{{ record.element }}
</td>
<td>
{{ record.suppressed_by.username }}
</td>
<td>
{{ record.date_added|date:"M d, Y, H:i" }}
</td>
<td>
<input type="button" class="btn btn-info btn-small" value="Remove" onclick="javascript:suppression_remove({{ record.id }}, 'Element');">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="box span12">
<div class="box-header well">
<h2><i class="icon-wrench"></i>Events suppressed on specific elements</h2>
</div>
<div class="box-content">
<table class="table table-bordered table-striped table-condensed table-fixed-header table-hover">
<thead>
<tr>
<th>Event ID</th>
<th>Element</th>
<th>Suppressed By</th>
<th>Date Added</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for record in event_and_element_sup %}
<tr>
<td width="20%">
<div class="btn-group"><a class="btn btn-info btn-mini" href="/events/view/{{ record.event.id }}"><i class="icon-list"></i>View #{{ record.event.id }}</a></div>
</td>
<td width="20%">
{{ record.element }}
</td>
<td>
{{ record.suppressed_by.username }}
</td>
<td>
{{ record.date_added|date:"M d, Y, H:i" }}
</td>
<td>
<input type="button" class="btn btn-info btn-small" value="Remove" onclick="javascript:suppression_remove({{ record.id }}, 'EventAndElementSuppressor');">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}

<div class=" span12">
<div class="btn-group"><a class="btn btn-info" href="/suppression/add/"><i class="icon-plus"></i>Add a suppression rule</a></div>
</div>

</div> <!-- container -->

<script type="text/javascript">
function suppression_remove(record_id, record_type){
$('[name=record_id]').val(record_id);
$('[name=record_type]').val(record_type);
$('#suppression_remove').submit()

};
</script>
{% include 'footer.html' %}
Loading

0 comments on commit e9d29cf

Please sign in to comment.