Changeset - 421171af6c75
[Not reviewed]
default
0 11 0
Branko Majic (branko) - 8 years ago 2017-12-22 10:33:56
branko@majic.rs
CONNT-25: Updating application and project to use Django 1.11.x:

- Bumped Django version in both the development requirements and setup
script to 1.11.x.
- Bumped Django Crispy Forms to version 1.7.0 in both development
requirements and setup script.
- Updated import of URL-related modules to use the new path (previous
one is deprecated).
- Added explicit on_delete = models.CASCADE option to all foreign key
fields (old implicit behaviour will be deprecated in Django 2.0).
- Fixed the custom change_list.html template used in Django Admin to
render without errors.
11 files changed with 22 insertions and 23 deletions:
0 comments (0 inline, 0 general)
conntrackt/admin.py
Show inline comments
 
@@ -29,33 +29,33 @@
 
# under the terms of the GNU General Public License as published by the Free
 
# Software Foundation, either version 3 of the License, or (at your option) any
 
# later version.
 
#
 
# Django Conntrackt is distributed in the hope that it will be useful, but
 
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
# details.
 
#
 
# You should have received a copy of the GNU General Public License along with
 
# Django Conntrackt.  If not, see <http://www.gnu.org/licenses/>.
 
#
 

	
 

	
 
# Django imports.
 
from django.contrib import admin
 
from django.core.urlresolvers import resolve
 
from django.urls import resolve
 

	
 
# Application imports.
 
from .models import Project, Location, Entity, Interface, Communication
 

	
 

	
 
class InterfaceInline(admin.StackedInline):
 
    """
 
    This class implements the inline admin view of the Interface instances. This
 
    is used when adding the entities (since it's easier to specify interface for
 
    an entity right away).
 

	
 
    Properties:
 

	
 
      - model - Model that this admin class refers to.
 
      - extra - Number of interfaces that should be show inline for
 
        adding/editing.
conntrackt/models.py
Show inline comments
 
@@ -9,33 +9,33 @@
 
# Software Foundation, either version 3 of the License, or (at your option) any
 
# later version.
 
#
 
# Django Conntrackt is distributed in the hope that it will be useful, but
 
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
# details.
 
#
 
# You should have received a copy of the GNU General Public License along with
 
# Django Conntrackt.  If not, see <http://www.gnu.org/licenses/>.
 
#
 

	
 

	
 
# Django imports.
 
from django.contrib.admin.utils import NestedObjects
 
from django.core.exceptions import ValidationError
 
from django.core.urlresolvers import reverse
 
from django.urls import reverse
 
from django.db import models
 
from django.db.models.query_utils import Q
 

	
 
# Application imports.
 
from .utils import list_formatter_callback, get_distinct_colors
 

	
 

	
 
class SearchManager(models.Manager):
 
    """
 
    Custom model manager that implements search for model instances that contain
 
    a specific string (search term) in fields "name" or "description".
 
    """
 

	
 
    def search(self, search_term):
 
        """
 
        Performs a search for model instances that contain the provided search
 
@@ -235,34 +235,34 @@ class Entity(RelatedCollectorMixin, mode
 
    the communication restrictions need to be applied across a subnet.
 

	
 
    Entities are tied to specific projects and locations.
 

	
 
    Fields:
 

	
 
      name - String denoting the entity name.
 
      description - Free-form description of an entity.
 
      project - Foreign key pointing to the project to which the entity
 
      belongs.
 
      location - Foreign key pointing to the location at which the entity is
 
      located.
 
    """
 

	
 
    name = models.CharField(max_length=100)
 
    description = models.TextField(blank=True)
 
    project = models.ForeignKey(Project)
 
    location = models.ForeignKey(Location)
 
    project = models.ForeignKey(Project, on_delete = models.CASCADE)
 
    location = models.ForeignKey(Location, on_delete = models.CASCADE)
 
    objects = SearchManager()
 

	
 
    class Meta:
 
        # Fix the plural form used by Django.
 
        verbose_name_plural = 'entities'
 
        # Enforce uniqueness of entity name in a project.
 
        unique_together = ("name", "project")
 

	
 
    def __unicode__(self):
 
        """
 
        Returns:
 
          String representation of an entity. This identifier contains name of
 
          entity, its project name, and location name.
 
        """
 

	
 
        return "%s (%s - %s)" % (self.name, self.project, self.location)
 
@@ -332,33 +332,33 @@ class Interface(RelatedCollectorMixin, m
 

	
 
    Fields:
 
      name - String denoting the interface name. For example 'eth0', 'eth1'
 
      etc.
 
      description - Free-form description of an interface.
 
      entity - Foreign key pointing to the entity to which the interface
 
      belongs.
 
      address - IP address of an interface. It's possible to store network
 
      address in it as well.
 
      netmask - Netmask of the interface. By default this is /32
 
      (255.255.255.255), but in case of subnet entities this can be used for
 
      denoting the network netmask.
 
    """
 

	
 
    name = models.CharField(max_length=100, default='eth0')
 
    description = models.TextField(blank=True, default='Main network interface.')
 
    entity = models.ForeignKey(Entity)
 
    entity = models.ForeignKey(Entity, on_delete = models.CASCADE)
 
    address = models.GenericIPAddressField()
 
    netmask = models.GenericIPAddressField(default='255.255.255.255')
 

	
 
    class Meta:
 
        # Enforce uniqueness of interface name in an entity. Enforce uniqueness
 
        # of IP address in a subnet for an entity.
 
        unique_together = (("name", "entity"),
 
                           ("entity", "address", "netmask"),)
 

	
 
    def __unicode__(self):
 
        """
 
        Returns:
 
          String representation of an interface. In case of single IP this will
 
          simply be the interface name and IP address. In case of subnet it will
 
          include the netmask as well.
 
        """
 
@@ -394,34 +394,34 @@ class Communication(RelatedCollectorMixi
 
      (i.e. entity's servers are listening on those).
 
      protocol - Textual field denoting the protocol that is used for
 
      communication. This can be 'TCP', 'UDP', or 'ICMP'.
 
      port - Port number used by the protocol. In case of ICMP, this is an ICMP
 
      type (in numeric form).
 
      description - Free-form text that can be used to describe the
 
      communication. This is also used when generating the iptables rules for
 
      documenting the rules.
 
    """
 

	
 
    PROTOCOL_CHOICES = (
 
        ('TCP', 'TCP'),
 
        ('UDP', 'UDP'),
 
        ('ICMP', 'ICMP'),
 
        )
 

	
 
    source = models.ForeignKey(Interface, related_name='source_set')
 
    destination = models.ForeignKey(Interface, related_name='destination_set')
 
    source = models.ForeignKey(Interface, related_name='source_set', on_delete = models.CASCADE)
 
    destination = models.ForeignKey(Interface, related_name='destination_set', on_delete = models.CASCADE)
 
    protocol = models.CharField(max_length=10, choices=PROTOCOL_CHOICES)
 
    port = models.IntegerField(default=0)
 
    description = models.TextField(blank=True)
 

	
 
    class Meta:
 
        # Enforce uniqueness of communication.
 
        unique_together = ("source", "destination", "protocol", "port")
 

	
 
    def __unicode__(self):
 
        """
 
        Returns:
 
          String representation of an interface. This involves showing the
 
          source and destination _entity_ name, protocol, and port.
 
        """
 

	
 
        return "%s -> %s (%s:%s)" % (self.source.entity.name, self.destination.entity.name, self.protocol, self.port)
conntrackt/templates/admin/conntrackt/communication/change_list.html
Show inline comments
 
{% extends "admin/change_list.html" %}
 
{% load i18n admin_static admin_list %}
 
{% load url from future %}
 
{% load admin_urls %}
 

	
 
{% block object-tools-items %}
 
            <li>
 
              {# Add the GET parameters from the admin's filter to 'Add entity' button #}
 
              {# so we can perform some filtering on source/destination interfaces. #}
 
              <a href="{% url cl.opts|admin_urlname:'add' %}?{% if is_popup %}_popup=1{% endif %}{% if 'location' in cl.params %}&amp;location={{ cl.params.location }}{% endif %}{% if 'project' in cl.params %}&amp;project={{ cl.params.project }}{% endif %}" class="addlink">
 
                {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
 
              </a>
 
            </li>
 
{% endblock %}
 

	
conntrackt/templatetags/conntrackt_tags.py
Show inline comments
 
@@ -8,33 +8,33 @@
 
# under the terms of the GNU General Public License as published by the Free
 
# Software Foundation, either version 3 of the License, or (at your option) any
 
# later version.
 
#
 
# Django Conntrackt is distributed in the hope that it will be useful, but
 
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
# details.
 
#
 
# You should have received a copy of the GNU General Public License along with
 
# Django Conntrackt.  If not, see <http://www.gnu.org/licenses/>.
 
#
 

	
 

	
 
# Django imports.
 
from django import template
 
from django.core import urlresolvers
 
from django import urls
 
from django.utils.html import format_html
 

	
 

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

	
 

	
 
@register.simple_tag(takes_context=False)
 
def html_link(text, view, *args, **kwargs):
 
    """
 
    A small wrapper for showing HTML links.
 

	
 
    Positional arguments:
 

	
 
        text - Text that should be used as a link.
 

	
 
@@ -49,33 +49,33 @@ def html_link(text, view, *args, **kwarg
 

	
 
        class - Class(es) for the <a> HTML element.
 

	
 
        title - Title for the HTML <a> element.
 

	
 
        get - Additional GET parameter that should be appended to the URL.
 

	
 
    """
 

	
 
    # Verify the passed-in keyword arguments first.
 
    for key in kwargs.keys():
 
        if key not in ("get", "class", "title", "id"):
 
            raise template.TemplateSyntaxError("Unknown argument for 'html_link' tag: %r" % key)
 

	
 
    # Generate the URL by using the supplied view name and arguments that should
 
    # be passed to the view.
 
    url = urlresolvers.reverse(view, args=args)
 
    url = urls.reverse(view, args=args)
 

	
 
    # Set-up the base pattern (url, parameters, text).
 
    if 'get' in kwargs:
 
        pattern = '<a href="{url}?{get}"'
 
    else:
 
        pattern = '<a href="{url}"'
 

	
 
    if 'class' in kwargs:
 
        pattern += ' class="{class}"'
 

	
 
    if 'title' in kwargs:
 
        pattern += ' title="{title}"'
 

	
 
    if 'id' in kwargs:
 
        pattern += ' id="{id}"'
 

	
 
@@ -108,32 +108,32 @@ def current_url_equals(context, url_name
 
    """
 
    Helper function for checking if the specified URL corresponds to the current
 
    request path in the context.
 

	
 
    Arguments:
 

	
 
      - context - Context of the view being rendered.
 

	
 
      - url_name - Name of the URL against which the context request path is
 
      being checked.
 
    """
 

	
 
    # Assume that we have not been able to resolve the request path to an URL.
 
    resolved = False
 
    try:
 
        # Use the request path, and resolve it to a URL name.
 
        resolved = urlresolvers.resolve(context.get('request').path)
 
    except urlresolvers.Resolver404:
 
        resolved = urls.resolve(context.get('request').path)
 
    except urls.Resolver404:
 
        # This means we haven't been able to resolve the path from request.
 
        pass
 

	
 
    # If the request was resolved and URL names match, verify that the kwargs
 
    # match as well.
 
    matches = resolved and resolved.url_name == url_name
 
    if matches and kwargs:
 
        for key in kwargs:
 
            kwarg = kwargs.get(key)
 
            resolved_kwarg = resolved.kwargs.get(key)
 
            if not resolved_kwarg or kwarg != resolved_kwarg:
 
                return False
 

	
 
    return matches
conntrackt/tests/test_tags.py
Show inline comments
 
@@ -22,33 +22,33 @@
 
# Standard library imports.
 
import json
 
from StringIO import StringIO
 
from zipfile import ZipFile, ZIP_DEFLATED
 

	
 
# Python third-party library imports.
 
import mock
 

	
 
# Django imports.
 
from django.template import Context, Template, TemplateSyntaxError
 
from django.test import TestCase
 

	
 
# Application imports
 
from conntrackt.templatetags.conntrackt_tags import html_link, active_link, current_url_equals
 

	
 

	
 
@mock.patch('conntrackt.templatetags.conntrackt_tags.urlresolvers.reverse')
 
@mock.patch('conntrackt.templatetags.conntrackt_tags.urls.reverse')
 
class HtmlLinkTest(TestCase):
 

	
 
    def test_url_reverse_called_with_passed_in_args(self, mock_reverse):
 
        """
 
        Tests if URL reversing is performed using the correct set of
 
        passed-in arguments.
 
        """
 

	
 
        html_link("My link", "my_view", 'arg1', 'arg2', 'arg3')
 

	
 
        mock_reverse.assert_called_once_with("my_view", args=('arg1', 'arg2', 'arg3'))
 

	
 
    def test_url_reverse_called_without_args_if_they_are_not_passed_in(self, mock_reverse):
 
        """
 
        Tests if URL reverse is performed without using any positional
 
        arguments if they are not specified.
conntrackt/tests/test_views.py
Show inline comments
 
@@ -16,33 +16,33 @@
 
#
 
# You should have received a copy of the GNU General Public License along with
 
# Django Conntrackt.  If not, see <http://www.gnu.org/licenses/>.
 
#
 

	
 

	
 
# Standard library imports.
 
import json
 
from StringIO import StringIO
 
from zipfile import ZipFile, ZIP_DEFLATED
 

	
 
# Python third-party library imports.
 
import mock
 

	
 
# Django imports.
 
from django.core.exceptions import ValidationError
 
from django.core.urlresolvers import reverse
 
from django.urls import reverse
 
from django.http import Http404
 
from django.test import RequestFactory
 
from django.test import TestCase
 
from django.utils.http import urlquote
 

	
 
# Application imports
 
from conntrackt.models import Project, Location, Entity, Interface, Communication
 

	
 
from conntrackt.views import IndexView, SearchView, APISearchView
 
from conntrackt.views import entity_iptables, project_iptables, project_diagram
 

	
 
from conntrackt.views import ProjectView, ProjectCreateView, ProjectUpdateView, ProjectDeleteView
 
from conntrackt.views import LocationCreateView, LocationUpdateView, LocationDeleteView
 
from conntrackt.views import EntityView, EntityCreateView, EntityUpdateView, EntityDeleteView
 
from conntrackt.views import InterfaceCreateView, InterfaceUpdateView, InterfaceDeleteView
 
from conntrackt.views import CommunicationCreateView, CommunicationUpdateView, CommunicationDeleteView
conntrackt/views.py
Show inline comments
 
@@ -15,37 +15,37 @@
 
# details.
 
#
 
# You should have received a copy of the GNU General Public License along with
 
# Django Conntrackt.  If not, see <http://www.gnu.org/licenses/>.
 
#
 

	
 

	
 
# Standard library imports.
 
from StringIO import StringIO
 
from zipfile import ZipFile, ZIP_DEFLATED
 
import json
 

	
 
# Django imports.
 
from django.contrib.auth.decorators import permission_required
 
from django.contrib import messages
 
from django.core.exceptions import ValidationError
 
from django.core.urlresolvers import reverse, reverse_lazy
 
from django.db.models import Q
 
from django.db.models.deletion import Collector
 
from django.http import HttpResponse
 
from django.shortcuts import render_to_response, get_object_or_404
 
from django.urls import reverse, reverse_lazy
 
from django.views.generic import TemplateView, DetailView, CreateView, UpdateView, DeleteView, View
 

	
 
# Third-party application imports.
 
from braces.views import MultiplePermissionsRequiredMixin, SetHeadlineMixin
 

	
 
# Application imports.
 
from .forms import ProjectForm, LocationForm, EntityForm, InterfaceForm, CommunicationForm
 
from .models import Project, Entity, Location, Interface, Communication
 
from .utils import generate_entity_iptables, generate_project_diagram
 

	
 

	
 
class RedirectToNextMixin(object):
 
    """
 
    View mixin that can be used for redirecting the user to URL defined through
 
    a GET parameter. The mixin is usable with Create/Update/Delete views that
 
    utilise the get_success_url() call.
requirements/base.in
Show inline comments
 
@@ -8,27 +8,27 @@
 
# Software Foundation, either version 3 of the License, or (at your option) any
 
# later version.
 
#
 
# Django Conntrackt is distributed in the hope that it will be useful, but
 
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
# details.
 
#
 
# You should have received a copy of the GNU General Public License along with
 
# Django Conntrackt.  If not, see <http://www.gnu.org/licenses/>.
 
#
 

	
 
# Convenience mixins for Django (for authentication etc).
 
django-braces~=1.12.0
 

	
 
# Convenience tools for controlling rendering of forms while embracing DRY.
 
django-crispy-forms~=1.6.0
 
django-crispy-forms~=1.7.0
 

	
 
# Web framework used by application.
 
django~=1.10.0
 
django~=1.11.0
 

	
 
# Library for programatic calculation of colours (contrasts,
 
# inversions etc).
 
palette~=0.2.0
 

	
 
# Interaface towards Graphviz for chart generation.
 
pydot~=1.2.0
requirements/development.txt
Show inline comments
 
#
 
# This file is autogenerated by pip-compile
 
# To update, run:
 
#
 
#    pip-compile --output-file requirements/development.txt requirements/development.in
 
#
 
alabaster==0.7.10         # via sphinx
 
babel==2.5.1              # via sphinx
 
certifi==2017.11.5        # via requests
 
chardet==3.0.4            # via requests
 
coverage==4.4.2
 
django-braces==1.12.0
 
django-crispy-forms==1.6.1
 
django==1.10.8
 
django-crispy-forms==1.7.0
 
django==1.11.8
 
docutils==0.14            # via sphinx
 
factory-boy==2.1.2
 
funcsigs==1.0.2           # via mock
 
idna==2.6                 # via requests
 
imagesize==0.7.1          # via sphinx
 
jinja2==2.10              # via sphinx
 
markupsafe==1.0           # via jinja2
 
mock==1.3.0
 
palette==0.2
 
pbr==3.1.1                # via mock
 
pydot==1.2.3
 
pygments==2.2.0           # via sphinx
 
pyparsing==2.2.0          # via pydot
 
pytz==2017.3
 
requests==2.18.4          # via sphinx
 
six==1.11.0               # via mock, sphinx
requirements/test.txt
Show inline comments
 
#
 
# This file is autogenerated by pip-compile
 
# To update, run:
 
#
 
#    pip-compile --output-file requirements/test.txt requirements/test.in
 
#
 
alabaster==0.7.10         # via sphinx
 
babel==2.5.1              # via sphinx
 
certifi==2017.11.5        # via requests
 
chardet==3.0.4            # via requests
 
coverage==4.4.2
 
django-braces==1.12.0
 
django-crispy-forms==1.6.1
 
django==1.10.8
 
django-crispy-forms==1.7.0
 
django==1.11.8
 
docutils==0.14            # via sphinx
 
factory-boy==2.1.2
 
funcsigs==1.0.2           # via mock
 
idna==2.6                 # via requests
 
imagesize==0.7.1          # via sphinx
 
jinja2==2.10              # via sphinx
 
markupsafe==1.0           # via jinja2
 
mock==1.3.0
 
palette==0.2
 
pbr==3.1.1                # via mock
 
pydot==1.2.3
 
pygments==2.2.0           # via sphinx
 
pyparsing==2.2.0          # via pydot
 
pytz==2017.3
 
requests==2.18.4          # via sphinx
 
six==1.11.0               # via mock, sphinx
setup.py
Show inline comments
 
@@ -12,34 +12,34 @@
 
# Django Conntrackt is distributed in the hope that it will be useful, but
 
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
# details.
 
#
 
# You should have received a copy of the GNU General Public License along with
 
# Django Conntrackt.  If not, see <http://www.gnu.org/licenses/>.
 
#
 

	
 

	
 
import os
 
from setuptools import setup, find_packages
 

	
 
README = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
 
INSTALL_REQUIREMENTS = [
 
    "django-braces~=1.12.0",
 
    "django-crispy-forms~=1.6.0",
 
    "django~=1.10.0",
 
    "django-crispy-forms~=1.7.0",
 
    "django~=1.11.0",
 
    "palette~=0.2.0",
 
    "pydot~=1.2.0",
 
]
 

	
 
# allow setup.py to be run from any path
 
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
 

	
 
setup(
 
    name='django-conntrackt',
 
    version='dev',
 
    packages=find_packages(exclude=["testproject", "testproject.*"]),
 
    include_package_data=True,
 
    license='GPLv3+',
 
    description='A simple application for tracking connection requirements between different entities in a network.',
 
    long_description=README,
 
    url='http://projects.majic.rs/conntrackt',
0 comments (0 inline, 0 general)