Skip to content
Snippets Groups Projects
Commit 357d48dc authored by Leonidas Poulopoulos's avatar Leonidas Poulopoulos
Browse files

Added templates. Moved functionality out of models

parent 478173ac
No related branches found
No related tags found
No related merge requests found
from django.contrib import admin
from flowspy.flowspec.models import *
from utils import proxy as PR
class RouteAdmin(admin.ModelAdmin):
actions = ['deactivate']
def deactivate(self, request, queryset):
applier = PR.Applier(route_objects=queryset)
commit, response = applier.apply(configuration=applier.delete_routes())
if commit:
rows = queryset.update(is_online=False)
queryset.update(response="Successfully removed route from network")
self.message_user(request, "Successfully removed %s routes from network" % rows)
else:
self.message_user(request, "Could not remove routes from network")
deactivate.short_description = "Remove selected routes from network"
list_display = ('name', 'get_match', 'get_then', 'is_online', 'applier', 'response')
fields = ('name', 'match','then','applier', 'expires')
#def formfield_for_dbfield(self, db_field, **kwargs):
# if db_field.name == 'password':
# kwargs['widget'] = PasswordInput
# return db_field.formfield(**kwargs)
admin.site.register(MatchAddress)
admin.site.register(MatchPort)
......@@ -13,4 +37,8 @@ admin.site.register(MatchTcpFlag)
admin.site.register(ThenAction)
admin.site.register(ThenStatement)
admin.site.register(MatchStatement)
admin.site.register(Route)
admin.site.register(Route, RouteAdmin)
admin.site.disable_action('delete_selected')
......@@ -3,12 +3,15 @@
from django.db import models
from django.contrib.auth.models import User
import nxpy as np
from ncclient import manager
from ncclient.transport.errors import AuthenticationError, SSHError
from lxml import etree as ET
from utils import proxy as PR
from ipaddr import *
import logging
FORMAT = '%(asctime)s %(levelname)s: %(message)s'
logging.basicConfig(format=FORMAT)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
FRAGMENT_CODES = (
("dont-fragment", "Don't fragment"),
......@@ -38,7 +41,8 @@ class MatchAddress(models.Model):
def clean(self, *args, **kwargs):
from django.core.exceptions import ValidationError
try:
assert(IPNetwork(self.address))
address = IPNetwork(self.address)
self.address = address.exploded
except Exception:
raise ValidationError('Invalid network address format')
......@@ -108,7 +112,7 @@ class ThenAction(models.Model):
class ThenStatement(models.Model):
thenaction = models.ManyToManyField(ThenAction)
class Meta:
db_table = u'then'
db_table = u'then'
class MatchStatement(models.Model):
matchDestination = models.ForeignKey(MatchAddress, blank=True, null=True, related_name="matchDestination")
......@@ -123,7 +127,7 @@ class MatchStatement(models.Model):
matchSource = models.ForeignKey(MatchAddress, blank=True, null=True, related_name="matchSource")
matchSourcePort = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchSourcePort")
matchTcpFlag = models.ForeignKey(MatchTcpFlag, blank=True, null=True)
# def clean(self, *args, **kwargs):
# clean_error = True
# from django.core.exceptions import ValidationError
......@@ -164,7 +168,11 @@ class Route(models.Model):
then = models.ForeignKey(ThenStatement)
filed = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
is_online = models.BooleanField(default=False)
expires = models.DateTimeField()
response = models.CharField(max_length=512, blank=True, null=True)
def __unicode__(self):
return self.name
......@@ -172,45 +180,151 @@ class Route(models.Model):
db_table = u'route'
def save(self, *args, **kwargs):
# Begin translation to device xml configuration
device = np.Device()
flow = np.Flow()
route = np.Route()
flow.routes.append(route)
device.routing_options.append(flow)
route.name = self.name
applier = PR.Applier(route_object=self)
commit, response = applier.apply()
if commit:
self.is_online = True
self.response = response
else:
self.is_online = False
self.response = response
super(Route, self).save(*args, **kwargs)
def is_synced(self):
found = False
get_device = PR.Retriever()
device = get_device.fetch_device()
try:
routes = device.routing_options[0].routes
except Exception as e:
logger.error("No routing options on device. Exception: %s" %e)
return False
for route in routes:
if route.name == self.name:
found = True
logger.info('Found a matching route name')
devicematch = route.match
routematch = self.match
try:
assert(routematch.matchDestination.address)
assert(devicematch['destination'][0])
if routematch.matchDestination.address == devicematch['destination'][0]:
found = found and True
logger.info('Found a matching destination')
else:
found = False
logger.info('Destination fields do not match')
except:
pass
try:
assert(routematch.matchSource.address)
assert(devicematch['source'][0])
if routematch.matchSource.address == devicematch['source'][0]:
found = found and True
logger.info('Found a matching source')
else:
found = False
logger.info('Source fields do not match')
except:
pass
try:
assert(routematch.matchfragmenttype.fragmenttype)
assert(devicematch['fragment'][0])
if routematch.matchfragmenttype.fragmenttype == devicematch['fragment'][0]:
found = found and True
logger.info('Found a matching fragment type')
else:
found = False
logger.info('Fragment type fields do not match')
except:
pass
try:
assert(routematch.matchicmpcode.icmp_code)
assert(devicematch['icmp-code'][0])
if routematch.matchicmpcode.icmp_code == devicematch['icmp-code'][0]:
found = found and True
logger.info('Found a matching icmp code')
else:
found = False
logger.info('Icmp code fields do not match')
except:
pass
try:
assert(routematch.matchicmptype.icmp_type)
assert(devicematch['icmp-type'][0])
if routematch.matchicmpcode.icmp_type == devicematch['icmp-type'][0]:
found = found and True
logger.info('Found a matching icmp type')
else:
found = False
logger.info('Icmp type fields do not match')
except:
pass
try:
assert(routematch.matchprotocol.protocol)
assert(devicematch['protocol'][0])
if routematch.matchprotocol.protocol == devicematch['protocol'][0]:
found = found and True
logger.info('Found a matching protocol')
else:
found = False
logger.info('Protocol fields do not match')
except:
pass
if found and not self.is_online:
logger.error('Rule is applied on device but appears as offline')
found = False
return found
def get_then(self):
ret = ''
then_statements = self.then.thenaction.all()
for statement in then_statements:
if statement.action_value:
ret = "%s %s:<strong>%s</strong><br/>" %(ret, statement.action, statement.action_value)
else:
ret = "%s %s<br>" %(ret, statement.action)
return ret.rstrip(',')
get_then.short_description = 'Then statement'
get_then.allow_tags = True
def get_match(self):
ret = ''
match = self.match
if match.matchSource:
route.match['source'].append(match.matchSource.address)
if match.matchDestination:
route.match['destination'].append(match.matchDestination.address)
ret = ret = '%s Destination Address:<strong>%s</strong><br/>' %(ret, match.matchDestination)
if match.matchfragmenttype:
ret = ret = "%s Fragment Type:<strong>%s</strong><br/>" %(ret, match.matchfragmenttype)
if match.matchicmpcode:
ret = ret = "%s ICMP code:<strong>%s</strong><br/>" %(ret, match.matchicmpcode)
if match.matchicmptype:
ret = ret = "%s ICMP Type:<strong>%s</strong><br/>" %(ret, match.matchicmptype)
if match.matchpacketlength:
ret = ret = "%s Packet Length:<strong>%s</strong><br/>" %(ret, match.matchpacketlength)
if match.matchprotocol:
route.match['protocol'].append(match.matchprotocol.protocol)
ret = ret = "%s Protocol:<strong>%s</strong><br/>" %(ret, match.matchprotocol)
if match.matchSource:
ret = ret = "%s Source Address:<strong>%s</strong><br/>" %(ret, match.matchSource)
if match.matchTcpFlag:
ret = ret = "%s TCP flag:<strong>%s</strong><br/>" %(ret, match.matchTcpFlag)
if match.matchport:
for port in match.matchport.all():
route.match['port'].append(port.port)
ret = "%s Port:<strong>%s</strong><br/>" %(ret, port)
if match.matchDestinationPort:
for port in match.matchDestinationPort.all():
route.match['destination-port'].append(port.port)
ret = "%s Port:<strong>%s</strong><br/>" %(ret, port)
if match.matchSourcePort:
for port in match.matchSourcePort.all():
route.match['source-port'].append(port.port)
if match.matchicmpcode:
route.match['icmp-code'].append(match.matchicmpcode.icmp_code)
if match.matchicmptype:
route.match['icmp-type'].append(match.matchicmptype.icmp_type)
if match.matchTcpFlag:
route.match['tcp-flags'].append(match.matchTcpFlag.tcp_flags)
ret = "%s Port:<strong>%s</strong><br/>" %(ret, port)
if match.matchdscp:
for dscp in match.matchdscp.all():
route.match['dscp'].append(dscp.dscp)
if match.matchfragmenttype:
route.match['fragment'].append(match.matchfragmenttype.fragmenttype)
then = self.then
for thenaction in then.thenaction.all():
if thenaction.action_value:
route.then[thenaction.action] = thenaction.action_value
else:
route.then[thenaction.action] = True
print ET.tostring(device.export())
super(Route, self).save(*args, **kwargs)
\ No newline at end of file
ret = "%s Port:<strong>%s</strong><br/>" %(ret, dscp)
return ret.rstrip('<br/>')
get_match.short_description = 'Match statement'
get_match.allow_tags = True
# Create your views here.
import urllib2
import re
import socket
from django import forms
from django.core.cache import cache
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect, HttpResponseForbidden, HttpResponse
from django.shortcuts import get_object_or_404, render_to_response
from django.core.context_processors import request
from django.template.context import RequestContext
from django.template.loader import get_template
from django.utils import simplejson
from django.core.urlresolvers import reverse
from django.contrib import messages
from flowspy.flowspec.models import *
def user_routes(request):
if request.user.is_anonymous():
return HttpResponseRedirect(reverse('login'))
user_routes = Route.objects.filter(applier=request.user)
print user_routes
return render_to_response('user_routes.html', {'routes': user_routes},
context_instance=RequestContext(request))
from django.conf.urls.defaults import *
from django.conf import settings
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
......@@ -7,10 +7,20 @@ admin.autodiscover()
urlpatterns = patterns('',
# Example:
# (r'^flowspy/', include('flowspy.foo.urls')),
url(r'^/?$', 'flowspy.flowspec.views.user_routes', name="user-routes"),
url(r'^user/login/?', 'django.contrib.auth.views.login', {'template_name': 'login.html'}, name="login"),
url(r'^user/logout/?', 'django.contrib.auth.views.logout', {'next_page': '/'}, name="logout"),
(r'^setlang/?$', 'django.views.i18n.set_language'),
# Uncomment the admin/doc line below to enable admin documentation:
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
(r'^admin/', include(admin.site.urls)),
)
if settings.DEBUG:
urlpatterns += patterns('',
(r'^static/(?P<path>.*)', 'django.views.static.serve',\
{'document_root': settings.STATIC_URL}),
)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment