Changeset - 90fac7c6abb9
[Not reviewed]
default
1 10 2
Branko Majic (branko) - 11 years ago 2013-03-24 19:42:40
branko@majic.rs
Renamed the tags library. Removed the line stripper middleware, and replaced it with some custom code that will remove all blank lines. The iptables rule rendering has been rewritten to accomodate this change (a utility function has been added for generating them). Fixed some code styling.
12 files changed with 109 insertions and 56 deletions:
0 comments (0 inline, 0 general)
conntrackt/templates/conntrackt/entity_detail.html
Show inline comments
 
{% extends "conntrackt/template.html" %}
 

	
 
{# For html_link. #}
 
{% load conntrackt %}
 
{% load conntrackt_tags %}
 

	
 
{% block content %}
 
{# Use a bit shorter variable names. #}
 
@@ -20,7 +20,7 @@
 
  {% for communication in interface.source_set.all %}
 
      <li>{{communication.destination}} - {{communication.protocol}}: {{communication.port}}</li>
 
{% endfor %}{% endfor %}</ul></dd>
 
      <dt>iptables rules</dt><dd><pre>{% include "conntrackt/entity_iptables.html" with entity=entity %}</pre>{% html_link 'Download' 'entity_iptables' entity.id class="btn btn-primary" %}</dd>
 
      <dt>iptables rules</dt><dd><pre>{{ entity_iptables }}</pre>{% html_link 'Download' 'entity_iptables' entity.id class="btn btn-primary" %}</dd>
 
</dl>
 
{% endif %}
 
{% endwith %}
conntrackt/templates/conntrackt/entity_iptables.html
Show inline comments
 
{% load conntrackt %}
 
{% load conntrackt_tags %}
 
# iptables rules generated by conntrackt for {{entity}}
 
*filter
 
:INPUT ACCEPT [0:0]
conntrackt/templates/conntrackt/index.html
Show inline comments
 
{% extends "conntrackt/template.html" %}
 

	
 
{# For html_link #}
 
{% load conntrackt %}
 
{% load conntrackt_tags %}
 

	
 
{% block content %}
 
<h1>Welcome to Conntrackt</h1>
conntrackt/templates/conntrackt/location_widget.html
Show inline comments
 
{% load conntrackt %}
 
{% load conntrackt_tags %}
 
  <table class="table table-striped">
 
    <tr><td><strong>{{location.name}}</strong></td><td>{% html_link '<i class="icon-book"></i>' 'project_location_iptables' project.id location.id class="btn btn-link" %}</td></tr>
 
{% for entity in entities %}
conntrackt/templates/conntrackt/login.html
Show inline comments
 
{% extends "conntrackt/template.html" %}
 

	
 
{# For html_link #}
 
{% load conntrackt %}
 
{% load conntrackt_tags %}
 

	
 
{% block content %}
 

	
conntrackt/templates/conntrackt/project_detail.html
Show inline comments
 
{% extends "conntrackt/template.html" %}
 

	
 
{% load conntrackt %}
 
{% load conntrackt_tags %}
 

	
 
{% block content %}
 
<h1>{{project.name}}</h1>
conntrackt/templates/conntrackt/project_widget.html
Show inline comments
 
{% load conntrackt %}
 
{% load conntrackt_tags %}
 
  <table class="table table-striped">
 
    <tr><td><strong>{% html_link project.name 'project' project.id title=project.description %}</strong></td><td>{% html_link '<i class="icon-book"></i>' 'project_iptables' project.id class="btn btn-link pull-right" %}</td></tr>
 
{% for entity in project.entity_set.all %}
conntrackt/templates/conntrackt/template.html
Show inline comments
 
{% load conntrackt %}
 
{% load conntrackt_tags %}
 

	
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
conntrackt/templatetags/conntrackt_tags.py
Show inline comments
 
file renamed from conntrackt/templatetags/conntrackt.py to conntrackt/templatetags/conntrackt_tags.py
 
# Import Django's template library.
 
from django import template
 

	
 
# Import for determining the active URL.
 
from django.core import urlresolvers
 

	
 
# Get an instance of Django's template library.
 
register = template.Library()
 

	
 

	
 
@register.inclusion_tag('conntrackt/html_link.html')
 
def html_link(text, view, *args, **kwargs):
 
    """
 
@@ -51,6 +51,7 @@ def html_link(text, view, *args, **kwarg
 

	
 
    return context
 

	
 

	
 
@register.simple_tag
 
def iptables(communication):
 
    """
 
@@ -70,6 +71,7 @@ def iptables(communication):
 

	
 
    return rule_template % values
 

	
 

	
 
@register.simple_tag(takes_context = True)
 
def active_link(context, url_name, return_value='active', **kwargs):
 
    """
conntrackt/urls.py
Show inline comments
 
@@ -9,7 +9,7 @@ from conntrackt.models import Entity
 
from django.views.generic import DetailView
 

	
 
# Import some app-specific views.
 
from conntrackt.views import IndexView, IptablesView, ProjectView, get_project_iptables
 
from conntrackt.views import IndexView, ProjectView, EntityView, entity_iptables, project_iptables
 

	
 
urlpatterns = patterns(
 
    'conntrackt.views',
 
@@ -19,14 +19,14 @@ urlpatterns = patterns(
 
    url(r'^project/(?P<pk>\d+)/$', ProjectView.as_view(),
 
        name = 'project'),
 
    # View for showing information about an entity.
 
    url(r'^entity/(?P<pk>\d+)/$', DetailView.as_view(model = Entity),
 
    url(r'^entity/(?P<pk>\d+)/$', EntityView.as_view(),
 
        name = 'entity'),
 
    # View for rendering iptables rules for a specific entity.
 
    url(r'^entity/(?P<pk>\d+)/iptables/$', IptablesView.as_view(), name="entity_iptables"),
 
    url(r'^entity/(?P<pk>\d+)/iptables/$', entity_iptables, name="entity_iptables"),
 
    # View for rendering zip file with iptables rules for all entities in a project.
 
    url(r'^project/(?P<project_id>\d+)/iptables/$', get_project_iptables, name="project_iptables"),
 
    url(r'^project/(?P<project_id>\d+)/iptables/$', project_iptables, name="project_iptables"),
 
    # View for rendering zip file with iptables rules for all entities in a project for a specific location.
 
    url(r'^project/(?P<project_id>\d+)/location/(?P<location_id>\d+)/iptables/$', get_project_iptables, name="project_location_iptables"),
 
    url(r'^project/(?P<project_id>\d+)/location/(?P<location_id>\d+)/iptables/$', project_iptables, name="project_location_iptables"),
 
    # Views for logging-in/out the users.
 
    url(r'^login/$', login, {'template_name': 'conntrackt/login.html'}, name = "login"),
 
    url(r'^logout/$', logout, name = "logout"),
conntrackt/utils.py
Show inline comments
 
new file 100644
 
# Standard library imports.
 
import re
 

	
 
# Django-specific imports.
 
from django.template import Context, loader
 

	
 

	
 
def generate_entity_iptables(entity):
 
    """
 
    Generates full iptables rules for the supplied entity. The generated rules
 
    can be fed directly to the iptables-restore utility.
 

	
 
    Arguments:
 

	
 
        entity - An Entity instance for which the iptables rules should be
 
        generated.
 

	
 
    Returns:
 

	
 
        String containing the iptables rules for entity.
 
    """
 

	
 
    # Render the iptables template.
 
    template = loader.get_template('conntrackt/entity_iptables.html')
 
    context = Context({'entity': entity})
 
    content = template.render(context)
 

	
 
    # Remove the blank lines.
 
    content = re.sub('^\s*\n', '', content)
 
    content = re.sub('\n\s*\n', '\n', content)
 

	
 
    return content
 

	
conntrackt/views.py
Show inline comments
 
# For generating ZIP files.
 
from StringIO import StringIO
 
from zipfile import ZipFile, ZIP_DEFLATED
 
import re
 

	
 
# Django-specific imports.
 
from django.http import HttpResponse
 
@@ -9,8 +8,10 @@ from django.shortcuts import render_to_r
 
from django.views.generic import TemplateView, DetailView
 

	
 
# Application-specific imports.
 
from conntrackt.models import Project, Entity, Location
 
from conntrackt.stripper import StripperMiddleware
 
from .models import Project, Entity, Location
 
from .stripper import StripperMiddleware
 
from .utils import generate_entity_iptables
 

	
 

	
 
class IndexView(TemplateView):
 
    """
 
@@ -35,6 +36,7 @@ class IndexView(TemplateView):
 

	
 
        return context
 

	
 

	
 
class ProjectView(DetailView):
 
    """
 
    Custom view for presenting the project information.
 
@@ -71,44 +73,64 @@ class ProjectView(DetailView):
 
        # Finally return the context.
 
        return context
 

	
 
class IptablesView(DetailView):
 

	
 
class EntityView(DetailView):
 
    """
 
    Custom view for presenting entity information.
 
    """
 
    Custom view for rendering iptables rules for a specific entity, and starting
 
    automatic download by browser.
 
    model = Entity
 

	
 
    def get_context_data(self, **kwargs):
 
        """
 
        Returns the context data that should be used for rendering of the
 
        template.
 

	
 
        Adds the 'entity_iptables' context object that contains full iptables
 
        rules generated for the entity.
 
        """
 

	
 
        # Call the parent class method.
 
        context = super(DetailView, self).get_context_data(**kwargs)
 

	
 
        # Add the rendered iptables rules to the context.
 
        context['entity_iptables'] = generate_entity_iptables(self.object)
 

	
 
        return context
 

	
 

	
 
def entity_iptables(request, pk):
 
    """
 
    Custom view that returns response containing iptables rules generated for an
 
    entity.
 

	
 
    Makes sure to set the Content-Disposition of a response in order to
 
    signal the browser it should start download of this view's response
 
    immediately. Also sets the suggested filename for it.
 

	
 
    Arguments:
 

	
 
        pk - Primary key of the Entity object for which the rules should be
 
        generated.
 

	
 
    Returns:
 

	
 
        Response object that contains the iptables rules for specified entity.
 
    """
 

	
 
    model = Entity
 
    template_name = 'conntrackt/entity_iptables.html'
 

	
 
    def render_to_response(self, context, **kwargs):
 
        """
 
        Renders the template with the given context to response. The response
 
        will be an iptables configuration file that can be used with
 
        iptables-restore.
 

	
 
        Makes sure to set the Content-Disposition of a response in order to
 
        signal the browser it should start download of this view's response
 
        immediately. Also sets the suggested filename for it.
 
        """
 
    # Fetch the entity, and construct the response with iptables rules as
 
    # content.
 
    entity = get_object_or_404(Entity, pk = pk)
 
    content = generate_entity_iptables(entity)
 
    response = HttpResponse(content, mimetype='text/plain')
 
    
 
    # Add the Content-Disposition information for the browser, telling the
 
    # browser to download the file with suggested filename.
 
    response['Content-Disposition']="attachment; filename=%s-iptables.conf" % entity.name.lower().replace(" ", "_")
 

	
 
        # Call the parent class method first. This will render the template. Set
 
        # the content type to text/plain.
 
        response = super(IptablesView, self).render_to_response(context,
 
                                                                content_type='text/plain', **kwargs)
 

	
 
        # Add the Content-Disposition information for the browser, telling the
 
        # browser to download the file with suggested filename.
 
        response['Content-Disposition']="attachment; filename=%s-iptables.conf" % self.object.name.lower().replace(" ", "_")
 
    return response
 

	
 
        # Render the response, and remove the blank lines from the template.
 
        response.render()
 
        response.content = re.sub('^\s*\n', '', response.content)
 
        response.content = re.sub('\n\s*\n', '\n', response.content)
 

	
 
        # Return the modified response.
 
        return response
 

	
 
def get_project_iptables(request, project_id, location_id = None):
 
def project_iptables(request, project_id, location_id = None):
 
    """
 
    Custom view for obtaining iptables for all entities of a project or project
 
    location in a single ZIP file.
 
@@ -143,10 +165,6 @@ def get_project_iptables(request, projec
 
    # to open the file with program as well.
 
    response = HttpResponse(mimetype='application/zip')
 

	
 
    # Stripper middleware has to be used in order to remove the excess blank
 
    # lines from rendering (this has to be done manually).
 
    stripper_middleware = StripperMiddleware()
 

	
 
    # If specific location was specified, get the entities that are part of that
 
    # project location only, otherwise fetch all of the project's entities. Also
 
    # set-up the filename that will be suggested to the browser.
 
@@ -163,8 +181,8 @@ def get_project_iptables(request, projec
 

	
 
    # Render iptables rules for each entity, placing them in the ZIP archive.
 
    for entity in entities:
 
        entity_iptables = stripper_middleware.process_response(request,render_to_response('conntrackt/entity_iptables.html', {'entity': entity}, mimetype="text/plain"))
 
        zipped_iptables.writestr("%s-iptables.conf" % entity.name.lower().replace(" ", "_"), entity_iptables.content)
 
        entity_iptables = generate_entity_iptables(entity)
 
        zipped_iptables.writestr("%s-iptables.conf" % entity.name.lower().replace(" ", "_"), entity_iptables)
 

	
 
    # Close the archive, and flush the buffer.
 
    zipped_iptables.close()
0 comments (0 inline, 0 general)