aboutsummaryrefslogtreecommitdiff
path: root/rpki/gui
diff options
context:
space:
mode:
Diffstat (limited to 'rpki/gui')
-rw-r--r--rpki/gui/app/check_expired.py6
-rw-r--r--rpki/gui/app/forms.py17
-rw-r--r--rpki/gui/app/glue.py3
-rw-r--r--rpki/gui/app/models.py14
-rwxr-xr-xrpki/gui/app/range_list.py2
-rw-r--r--rpki/gui/app/views.py41
-rw-r--r--rpki/gui/cacheview/models.py8
-rw-r--r--rpki/gui/cacheview/tests.py1
-rw-r--r--rpki/gui/cacheview/util.py3
-rw-r--r--rpki/gui/cacheview/views.py1
-rw-r--r--rpki/gui/decorators.py2
-rw-r--r--rpki/gui/default_settings.py1
-rw-r--r--rpki/gui/models.py4
-rw-r--r--rpki/gui/routeview/api.py2
-rw-r--r--rpki/gui/routeview/util.py2
-rw-r--r--rpki/gui/script_util.py1
16 files changed, 69 insertions, 39 deletions
diff --git a/rpki/gui/app/check_expired.py b/rpki/gui/app/check_expired.py
index a084af79..2907f071 100644
--- a/rpki/gui/app/check_expired.py
+++ b/rpki/gui/app/check_expired.py
@@ -41,8 +41,8 @@ def check_cert(handle, p, errs):
The displayed object name defaults to the class name, but can be overridden
using the `object_name` argument.
-
"""
+
t = p.certificate.getNotAfter()
if t <= expire_time:
e = 'expired' if t <= now else 'will expire'
@@ -102,8 +102,8 @@ def check_expire(conf, errs):
def check_child_certs(conf, errs):
"""Fetch the list of published objects from rpkid, and inspect the issued
resource certs (uri ending in .cer).
-
"""
+
z = Zookeeper(handle=conf.handle)
req = list_published_objects_elt.make_pdu(action="list",
tag="list_published_objects",
@@ -139,8 +139,8 @@ def notify_expired(expire_days=14, from_email=None):
expire_days: the number of days ahead of today to warn
from_email: set the From: address for the email
-
"""
+
global expire_time # so i don't have to pass it around
global now
diff --git a/rpki/gui/app/forms.py b/rpki/gui/app/forms.py
index 5394a804..02561303 100644
--- a/rpki/gui/app/forms.py
+++ b/rpki/gui/app/forms.py
@@ -52,6 +52,7 @@ class GhostbusterRequestForm(forms.ModelForm):
Generate a ModelForm with the subset of parents for the current
resource handle.
"""
+
# override default form field
parent = forms.ModelChoiceField(queryset=None, required=False,
help_text='Specify specific parent, or none for all parents')
@@ -86,6 +87,7 @@ class GhostbusterRequestForm(forms.ModelForm):
class ImportForm(forms.Form):
"""Form used for uploading parent/child identity xml files."""
+
handle = forms.CharField(required=False,
widget=forms.TextInput(attrs={'class': 'xlarge'}),
help_text='Optional. Your name for this entity, or blank to accept name in XML')
@@ -101,6 +103,7 @@ class ImportRepositoryForm(forms.Form):
class ImportClientForm(forms.Form):
"""Form used for importing publication client requests."""
+
xml = forms.FileField(label='XML file')
@@ -137,6 +140,7 @@ class UserCreateForm(forms.Form):
class UserEditForm(forms.Form):
"""Form for editing a user."""
+
email = forms.CharField()
pw = forms.CharField(widget=forms.PasswordInput, label='Password',
required=False)
@@ -185,8 +189,8 @@ class ROARequest(forms.Form):
"""Takes an optional `conf` keyword argument specifying the user that
is creating the ROAs. It is used for validating that the prefix the
user entered is currently allocated to that user.
-
"""
+
conf = kwargs.pop('conf', None)
kwargs['auto_id'] = False
super(ROARequest, self).__init__(*args, **kwargs)
@@ -199,8 +203,8 @@ class ROARequest(forms.Form):
rpki.resource_set.resource_range_ip object.
If there is no mask provided, assume the closest classful mask.
-
"""
+
prefix = self.cleaned_data.get('prefix')
if '/' not in prefix:
p = IPAddress(prefix)
@@ -296,7 +300,6 @@ class AddASNForm(forms.Form):
Returns a forms.Form subclass which verifies that the entered ASN range
does not overlap with a previous allocation to the specified child, and
that the ASN range is within the range allocated to the parent.
-
"""
asns = forms.CharField(
@@ -335,8 +338,8 @@ class AddNetForm(forms.Form):
Returns a forms.Form subclass which validates that the entered address
range is within the resources allocated to the parent, and does not overlap
with what is already allocated to the specified child.
-
"""
+
address_range = forms.CharField(
help_text='CIDR or range',
widget=forms.TextInput(attrs={'autofocus': 'true'})
@@ -383,7 +386,6 @@ def ChildForm(instance):
This is roughly based on the equivalent ModelForm, but uses Form as a base
class so that selection boxes for the AS and Prefixes can be edited in a
single form.
-
"""
class _wrapped(forms.Form):
@@ -401,11 +403,13 @@ def ChildForm(instance):
class Empty(forms.Form):
"""Stub form for views requiring confirmation."""
+
pass
class ResourceHolderForm(forms.Form):
"""form for editing ACL on Conf objects."""
+
users = forms.ModelMultipleChoiceField(
queryset=User.objects.all(),
help_text='users allowed to mange this resource holder'
@@ -413,7 +417,8 @@ class ResourceHolderForm(forms.Form):
class ResourceHolderCreateForm(forms.Form):
- """form for creating new resource holdres."""
+ """form for creating new resource holders."""
+
handle = forms.CharField(max_length=30)
parent = forms.ModelChoiceField(
required=False,
diff --git a/rpki/gui/app/glue.py b/rpki/gui/app/glue.py
index 0bf5f942..f17ba5ac 100644
--- a/rpki/gui/app/glue.py
+++ b/rpki/gui/app/glue.py
@@ -16,7 +16,6 @@
"""
This file contains code that interfaces between the django views implementing
the portal gui and the rpki.* modules.
-
"""
from __future__ import with_statement
@@ -39,6 +38,7 @@ from django.db.transaction import commit_on_success
def ghostbuster_to_vcard(gbr):
"""Convert a GhostbusterRequest object into a vCard object."""
+
import vobject
vcard = vobject.vCard()
@@ -86,7 +86,6 @@ def list_received_resources(log, conf):
The semantics are to clear the entire table and populate with the list of
certs received. Other models should not reference the table directly with
foreign keys.
-
"""
z = Zookeeper(handle=conf.handle)
diff --git a/rpki/gui/app/models.py b/rpki/gui/app/models.py
index 32a897c7..d6332796 100644
--- a/rpki/gui/app/models.py
+++ b/rpki/gui/app/models.py
@@ -120,16 +120,16 @@ class Conf(rpki.irdb.models.ResourceHolderCA):
def parents(self):
"""Simulates irdb.models.Parent.objects, but returns app.models.Parent
proxy objects.
-
"""
+
return Parent.objects.filter(issuer=self)
@property
def children(self):
"""Simulates irdb.models.Child.objects, but returns app.models.Child
proxy objects.
-
"""
+
return Child.objects.filter(issuer=self)
@property
@@ -148,8 +148,8 @@ class Conf(rpki.irdb.models.ResourceHolderCA):
def routes(self):
"""Return all IPv4 routes covered by RPKI certs issued to this resource
holder.
-
"""
+
# build a Q filter to select all RouteOrigin objects covered by
# prefixes in the resource holder's certificates
q = models.Q()
@@ -162,8 +162,8 @@ class Conf(rpki.irdb.models.ResourceHolderCA):
def routes_v6(self):
"""Return all IPv6 routes covered by RPKI certs issued to this resource
holder.
-
"""
+
# build a Q filter to select all RouteOrigin objects covered by
# prefixes in the resource holder's certificates
q = models.Q()
@@ -174,6 +174,7 @@ class Conf(rpki.irdb.models.ResourceHolderCA):
def send_alert(self, subject, message, from_email, severity=Alert.INFO):
"""Store an alert for this resource holder."""
+
self.alerts.create(subject=subject, text=message, severity=severity)
send_mail(
@@ -189,8 +190,8 @@ class Conf(rpki.irdb.models.ResourceHolderCA):
Contact emails are extract from any ghostbuster requests, and any
linked user accounts.
-
"""
+
notify_emails = [gbr.email_address for gbr in self.ghostbusters if gbr.email_address]
notify_emails.extend(
[acl.user.email for acl in ConfACL.objects.filter(conf=self) if acl.user.email]
@@ -209,7 +210,6 @@ class ResourceCert(models.Model):
"""Represents a resource certificate.
This model is used to cache the output of <list_received_resources/>.
-
"""
# Handle to which this cert was issued
@@ -237,6 +237,7 @@ class ResourceCert(models.Model):
def get_cert_chain(self):
"""Return a list containing the complete certificate chain for this
certificate."""
+
cert = self
x = [cert]
while cert.issuer:
@@ -410,7 +411,6 @@ class RouteOriginV6(rpki.gui.routeview.models.RouteOriginV6):
class ConfACL(models.Model):
"""Stores access control for which users are allowed to manage a given
resource handle.
-
"""
conf = models.ForeignKey(Conf)
diff --git a/rpki/gui/app/range_list.py b/rpki/gui/app/range_list.py
index 21fd1f29..5cb4f5e4 100755
--- a/rpki/gui/app/range_list.py
+++ b/rpki/gui/app/range_list.py
@@ -70,6 +70,7 @@ class RangeList(list):
def difference(self, other):
"""Return a RangeList object which contains ranges in this object which
are not in "other"."""
+
it = iter(other)
try:
@@ -85,6 +86,7 @@ class RangeList(list):
def V(v):
"""convert the integer value to the appropriate type for this
range"""
+
return x.__class__.datum_type(v)
try:
diff --git a/rpki/gui/app/views.py b/rpki/gui/app/views.py
index 9a1c4cfe..228d5c6c 100644
--- a/rpki/gui/app/views.py
+++ b/rpki/gui/app/views.py
@@ -71,6 +71,7 @@ def superuser_required(f):
def get_conf(user, handle):
"""return the Conf object for 'handle'.
user is a request.user object to use enforce ACLs."""
+
if user.is_superuser:
qs = models.Conf.objects.all()
else:
@@ -81,8 +82,8 @@ def get_conf(user, handle):
def handle_required(f):
"""Decorator for view functions which require the user to be logged in and
a resource handle selected for the session.
-
"""
+
@login_required
@tls_required
def wrapped_fn(request, *args, **kwargs):
@@ -126,8 +127,8 @@ def generic_import(request, queryset, configure, form_class=None,
if None (default), the user will be redirected to the detail page for
the imported object. Otherwise, the user will be redirected to the
specified URL.
-
"""
+
conf = get_conf(request.user, request.session['handle'])
if form_class is None:
form_class = forms.ImportForm
@@ -251,6 +252,7 @@ def dashboard(request):
@login_required
def conf_list(request, **kwargs):
"""Allow the user to select a handle."""
+
log = request.META['wsgi.errors']
next_url = request.GET.get('next', reverse(dashboard))
if request.user.is_superuser:
@@ -266,6 +268,7 @@ def conf_list(request, **kwargs):
@login_required
def conf_select(request):
"""Change the handle for the current session."""
+
if not 'handle' in request.GET:
return redirect(conf_list)
handle = request.GET['handle']
@@ -288,8 +291,8 @@ def serve_xml(content, basename, ext='xml'):
`basename` is the prefix to specify for the XML filename.
`csv` is the type (default: xml)
-
"""
+
resp = http.HttpResponse(content, mimetype='application/%s' % ext)
resp['Content-Disposition'] = 'attachment; filename=%s.%s' % (basename, ext)
return resp
@@ -298,6 +301,7 @@ def serve_xml(content, basename, ext='xml'):
@handle_required
def conf_export(request):
"""Return the identity.xml for the current handle."""
+
conf = get_conf(request.user, request.session['handle'])
z = Zookeeper(handle=conf.handle)
xml = z.generate_identity()
@@ -307,6 +311,7 @@ def conf_export(request):
@handle_required
def export_asns(request):
"""Export CSV file containing ASN allocations to children."""
+
conf = get_conf(request.user, request.session['handle'])
s = cStringIO.StringIO()
csv_writer = csv.writer(s, delimiter=' ')
@@ -342,6 +347,7 @@ def import_asns(request):
@handle_required
def export_prefixes(request):
"""Export CSV file containing ASN allocations to children."""
+
conf = get_conf(request.user, request.session['handle'])
s = cStringIO.StringIO()
csv_writer = csv.writer(s, delimiter=' ')
@@ -411,6 +417,7 @@ def parent_delete(request, pk):
@handle_required
def parent_export(request, pk):
"""Export XML repository request for a given parent."""
+
conf = get_conf(request.user, request.session['handle'])
parent = get_object_or_404(conf.parents, pk=pk)
z = Zookeeper(handle=conf.handle)
@@ -474,6 +481,7 @@ def child_detail(request, pk):
@handle_required
def child_edit(request, pk):
"""Edit the end validity date for a resource handle's child."""
+
log = request.META['wsgi.errors']
conf = get_conf(request.user, request.session['handle'])
child = get_object_or_404(conf.children.all(), pk=pk)
@@ -505,8 +513,8 @@ def child_response(request, pk):
"""
Export the XML file containing the output of the configure_child
to send back to the client.
-
"""
+
conf = get_conf(request.user, request.session['handle'])
child = get_object_or_404(models.Child, issuer=conf, pk=pk)
z = Zookeeper(handle=conf.handle)
@@ -551,7 +559,6 @@ def get_covered_routes(rng, max_prefixlen, asn):
A "newstatus" attribute is monkey-patched on the RouteOrigin objects which
can be used in the template. "status" remains the current validation
status of the object.
-
"""
# find all routes that match or are completed covered by the proposed new roa
@@ -591,7 +598,6 @@ def roa_create(request):
Doesn't use the generic create_object() form because we need to
create both the ROARequest and ROARequestPrefix objects.
-
"""
conf = get_conf(request.user, request.session['handle'])
@@ -628,7 +634,6 @@ def roa_create(request):
class ROARequestFormSet(BaseFormSet):
"""There is no way to pass arbitrary keyword arguments to the form
constructor, so we have to override BaseFormSet to allow it.
-
"""
def __init__(self, *args, **kwargs):
self.conf = kwargs.pop('conf')
@@ -666,7 +671,6 @@ def roa_create_multi(request):
?roa=1.1.1.1-2.2.2.2,42
The ASN may optionally be omitted.
-
"""
conf = get_conf(request.user, request.session['handle'])
@@ -717,8 +721,8 @@ def roa_create_multi(request):
def roa_create_confirm(request):
"""This function is called when the user confirms the creation of a ROA
request. It is responsible for updating the IRDB.
-
"""
+
conf = get_conf(request.user, request.session['handle'])
log = request.META['wsgi.errors']
if request.method == 'POST':
@@ -746,8 +750,8 @@ def roa_create_confirm(request):
def roa_create_multi_confirm(request):
"""This function is called when the user confirms the creation of a ROA
request. It is responsible for updating the IRDB.
-
"""
+
conf = get_conf(request.user, request.session['handle'])
log = request.META['wsgi.errors']
if request.method == 'POST':
@@ -778,7 +782,6 @@ def roa_delete(request, pk):
Uses a form for double confirmation, displaying how the route
validation status may change as a result.
-
"""
conf = get_conf(request.user, request.session['handle'])
@@ -835,6 +838,7 @@ def roa_clone(request, pk):
@handle_required
def roa_import(request):
"""Import CSV containing ROA declarations."""
+
if request.method == 'POST':
form = forms.ImportCSVForm(request.POST, request.FILES)
if form.is_valid():
@@ -860,6 +864,7 @@ def roa_import(request):
@handle_required
def roa_export(request):
"""Export CSV containing ROA declarations."""
+
# FIXME: remove when Zookeeper can do this
f = cStringIO.StringIO()
csv_writer = csv.writer(f, delimiter=' ')
@@ -941,8 +946,8 @@ def ghostbuster_edit(request, pk):
def refresh(request):
"""
Query rpkid, update the db, and redirect back to the dashboard.
-
"""
+
conf = get_conf(request.user, request.session['handle'])
glue.list_received_resources(request.META['wsgi.errors'], conf)
return http.HttpResponseRedirect(reverse(dashboard))
@@ -953,8 +958,8 @@ def route_view(request):
"""
Display a list of global routing table entries which match resources
listed in received certificates.
-
"""
+
conf = get_conf(request.user, request.session['handle'])
count = request.GET.get('count', 25)
page = request.GET.get('page', 1)
@@ -972,6 +977,7 @@ def route_view(request):
def route_detail(request, pk):
"""Show a list of ROAs that match a given IPv4 route."""
+
route = get_object_or_404(models.RouteOrigin, pk=pk)
# when running rootd, viewing the 0.0.0.0/0 route will cause a fetch of all
# roas, so we paginate here, even though in the general case the number of
@@ -989,8 +995,8 @@ def route_suggest(request):
"""Handles POSTs from the route view and redirects to the ROA creation
page based on selected route objects. The form should contain elements of
the form "pk-NUM" where NUM is the RouteOrigin object id.
-
"""
+
if request.method == 'POST':
routes = []
for pk in request.POST.iterkeys():
@@ -1040,6 +1046,7 @@ def repository_delete(request, pk):
@handle_required
def repository_import(request):
"""Import XML response file from repository operator."""
+
return generic_import(request,
models.Repository.objects,
Zookeeper.configure_repository,
@@ -1094,8 +1101,8 @@ def client_import(request):
def client_export(request, pk):
"""Return the XML file resulting from a configure_publication_client
request.
-
"""
+
client = get_object_or_404(models.Client, pk=pk)
z = Zookeeper()
xml = z.generate_repository_response(client)
@@ -1107,6 +1114,7 @@ def client_export(request, pk):
@superuser_required
def resource_holder_list(request):
"""Display a list of all the RPKI handles managed by this server."""
+
return render(request, 'app/resource_holder_list.html', {
'object_list': models.Conf.objects.all()
})
@@ -1115,6 +1123,7 @@ def resource_holder_list(request):
@superuser_required
def resource_holder_edit(request, pk):
"""Display a list of all the RPKI handles managed by this server."""
+
conf = get_object_or_404(models.Conf, pk=pk)
if request.method == 'POST':
form = forms.ResourceHolderForm(request.POST, request.FILES)
@@ -1221,6 +1230,7 @@ def user_create(request):
@superuser_required
def user_list(request):
"""Display a list of all the RPKI handles managed by this server."""
+
return render(request, 'app/user_list.html', {
'object_list': User.objects.all()
})
@@ -1316,6 +1326,7 @@ class AlertDeleteView(DeleteView):
@handle_required
def alert_clear_all(request):
"""Clear all alerts associated with the current resource holder."""
+
if request.method == 'POST':
form = forms.Empty(request.POST, request.FILES)
if form.is_valid():
diff --git a/rpki/gui/cacheview/models.py b/rpki/gui/cacheview/models.py
index c3ee8421..08acfa2d 100644
--- a/rpki/gui/cacheview/models.py
+++ b/rpki/gui/cacheview/models.py
@@ -58,6 +58,7 @@ class ValidationLabel(models.Model):
Represents a specific error condition defined in the rcynic XML
output file.
"""
+
label = models.CharField(max_length=79, db_index=True, unique=True)
status = models.CharField(max_length=255)
kind = models.PositiveSmallIntegerField(choices=kinds)
@@ -70,6 +71,7 @@ class RepositoryObject(models.Model):
"""
Represents a globally unique RPKI repository object, specified by its URI.
"""
+
uri = models.URLField(unique=True, db_index=True)
generations = list(enumerate(('current', 'backup')))
@@ -89,6 +91,7 @@ class SignedObject(models.Model):
The signing certificate is ommitted here in order to give a proper
value for the 'related_name' attribute.
"""
+
repo = models.ForeignKey(RepositoryObject, related_name='cert', unique=True)
# on-disk file modification time
@@ -108,6 +111,7 @@ class SignedObject(models.Model):
"""
convert the local timestamp to UTC and convert to a datetime object
"""
+
return datetime.utcfromtimestamp(self.mtime + time.timezone)
def status_id(self):
@@ -116,6 +120,7 @@ class SignedObject(models.Model):
The selector is chosen based on the current generation only. If there is any bad status,
return bad, else if there are any warn status, return warn, else return good.
"""
+
for x in reversed(kinds):
if self.repo.statuses.filter(generation=generations_dict['current'], status__kind=x[0]):
return x[1]
@@ -129,6 +134,7 @@ class Cert(SignedObject):
"""
Object representing a resource certificate.
"""
+
addresses = models.ManyToManyField(AddressRange, related_name='certs')
addresses_v6 = models.ManyToManyField(AddressRangeV6, related_name='certs')
asns = models.ManyToManyField(ASRange, related_name='certs')
@@ -141,6 +147,7 @@ class Cert(SignedObject):
def get_cert_chain(self):
"""Return a list containing the complete certificate chain for this
certificate."""
+
cert = self
x = [cert]
while cert != cert.issuer:
@@ -180,6 +187,7 @@ class ROAPrefixV4(ROAPrefix, rpki.gui.models.PrefixV4):
@property
def routes(self):
"""return all routes covered by this roa prefix"""
+
return RouteOrigin.objects.filter(prefix_min__gte=self.prefix_min,
prefix_max__lte=self.prefix_max)
diff --git a/rpki/gui/cacheview/tests.py b/rpki/gui/cacheview/tests.py
index 2247054b..daca07bf 100644
--- a/rpki/gui/cacheview/tests.py
+++ b/rpki/gui/cacheview/tests.py
@@ -12,6 +12,7 @@ class SimpleTest(TestCase):
"""
Tests that 1 + 1 always equals 2.
"""
+
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
diff --git a/rpki/gui/cacheview/util.py b/rpki/gui/cacheview/util.py
index 9e8748bf..31ad8b8b 100644
--- a/rpki/gui/cacheview/util.py
+++ b/rpki/gui/cacheview/util.py
@@ -310,8 +310,8 @@ def fetch_published_objects():
"""Query rpkid for all objects published by local users, and look up the
current validation status of each object. The validation status is used
later to send alerts for objects which have transitioned to invalid.
-
"""
+
logger.info('querying for published objects')
handles = [conf.handle for conf in Conf.objects.all()]
@@ -353,7 +353,6 @@ class Handle(object):
def notify_invalid():
"""Send email alerts to the addresses registered in ghostbuster records for
any invalid objects that were published by users of this system.
-
"""
logger.info('sending notifications for invalid objects')
diff --git a/rpki/gui/cacheview/views.py b/rpki/gui/cacheview/views.py
index 94870eb2..451c0d1e 100644
--- a/rpki/gui/cacheview/views.py
+++ b/rpki/gui/cacheview/views.py
@@ -29,6 +29,7 @@ def cert_chain(obj):
"""
returns an iterator covering all certs from the root cert down to the EE.
"""
+
chain = [obj]
while obj != obj.issuer:
obj = obj.issuer
diff --git a/rpki/gui/decorators.py b/rpki/gui/decorators.py
index 69d20c46..ed10f3d9 100644
--- a/rpki/gui/decorators.py
+++ b/rpki/gui/decorators.py
@@ -20,8 +20,8 @@ from django import http
def tls_required(f):
"""Decorator which returns a 500 error if the connection is not secured
with TLS (https).
-
"""
+
def _tls_required(request, *args, **kwargs):
if not request.is_secure():
return http.HttpResponseServerError(
diff --git a/rpki/gui/default_settings.py b/rpki/gui/default_settings.py
index 3859247c..e0626965 100644
--- a/rpki/gui/default_settings.py
+++ b/rpki/gui/default_settings.py
@@ -93,6 +93,7 @@ TIME_ZONE = select_tz()
def get_secret_key():
"""Retrieve the secret-key value from rpki.conf or generate a random value
if it is not present."""
+
d = string.letters + string.digits
val = ''.join([random.choice(d) for _ in range(50)])
return rpki_config.get('secret-key', val)
diff --git a/rpki/gui/models.py b/rpki/gui/models.py
index 184383c0..62400d2a 100644
--- a/rpki/gui/models.py
+++ b/rpki/gui/models.py
@@ -42,8 +42,8 @@ class IPv6AddressField(models.Field):
"""
Note that we add a custom conversion to encode long values as hex
strings in SQL statements. See settings.get_conv() for details.
-
"""
+
return value.toBytes()
@@ -82,6 +82,7 @@ class Prefix(models.Model):
"""
Returns the prefix as a rpki.resource_set.resource_range_ip object.
"""
+
return self.range_cls(self.prefix_min, self.prefix_max)
@property
@@ -96,6 +97,7 @@ class Prefix(models.Model):
def __unicode__(self):
"""This method may be overridden by subclasses. The default
implementation calls get_prefix_display(). """
+
return self.get_prefix_display()
class Meta:
diff --git a/rpki/gui/routeview/api.py b/rpki/gui/routeview/api.py
index cf699c9a..b4ff297a 100644
--- a/rpki/gui/routeview/api.py
+++ b/rpki/gui/routeview/api.py
@@ -29,8 +29,8 @@ def route_list(request):
By default, only returns up to 10 matching routes, but the client may
request a different limit with the 'count=' query string parameter.
-
"""
+
hard_limit = 100
if request.method == 'GET' and 'prefix__in' in request.GET:
diff --git a/rpki/gui/routeview/util.py b/rpki/gui/routeview/util.py
index 54d50f24..a2b515c8 100644
--- a/rpki/gui/routeview/util.py
+++ b/rpki/gui/routeview/util.py
@@ -179,8 +179,8 @@ def import_routeviews_dump(filename=DEFAULT_URL, filetype='auto'):
filename [optional]: the full path to the downloaded file to parse
filetype [optional]: 'text' or 'mrt'
-
"""
+
start_time = time.time()
if filename.startswith('http://'):
diff --git a/rpki/gui/script_util.py b/rpki/gui/script_util.py
index c3a864fd..46545d83 100644
--- a/rpki/gui/script_util.py
+++ b/rpki/gui/script_util.py
@@ -28,6 +28,7 @@ def setup():
"""
Configure Django enough to use the ORM.
"""
+
cfg = config.parser(section='web_portal')
# INSTALLED_APPS doesn't seem necessary so long as you are only accessing
# existing tables.