aboutsummaryrefslogtreecommitdiff
path: root/rpki/gui/cacheview
diff options
context:
space:
mode:
Diffstat (limited to 'rpki/gui/cacheview')
-rw-r--r--rpki/gui/cacheview/__init__.py0
-rw-r--r--rpki/gui/cacheview/forms.py51
-rw-r--r--rpki/gui/cacheview/misc.py31
-rw-r--r--rpki/gui/cacheview/models.py245
-rw-r--r--rpki/gui/cacheview/templates/cacheview/addressrange_detail.html18
-rw-r--r--rpki/gui/cacheview/templates/cacheview/cacheview_base.html10
-rw-r--r--rpki/gui/cacheview/templates/cacheview/cert_detail.html105
-rw-r--r--rpki/gui/cacheview/templates/cacheview/ghostbuster_detail.html13
-rw-r--r--rpki/gui/cacheview/templates/cacheview/global_summary.html26
-rw-r--r--rpki/gui/cacheview/templates/cacheview/query_result.html21
-rw-r--r--rpki/gui/cacheview/templates/cacheview/roa_detail.html18
-rw-r--r--rpki/gui/cacheview/templates/cacheview/search_form.html17
-rw-r--r--rpki/gui/cacheview/templates/cacheview/search_result.html42
-rw-r--r--rpki/gui/cacheview/templates/cacheview/signedobject_detail.html58
-rw-r--r--rpki/gui/cacheview/tests.py23
-rw-r--r--rpki/gui/cacheview/urls.py32
-rw-r--r--rpki/gui/cacheview/util.py435
-rw-r--r--rpki/gui/cacheview/views.py173
18 files changed, 0 insertions, 1318 deletions
diff --git a/rpki/gui/cacheview/__init__.py b/rpki/gui/cacheview/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/rpki/gui/cacheview/__init__.py
+++ /dev/null
diff --git a/rpki/gui/cacheview/forms.py b/rpki/gui/cacheview/forms.py
deleted file mode 100644
index 7ae3601f..00000000
--- a/rpki/gui/cacheview/forms.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2011 SPARTA, Inc. dba Cobham Analytic Solutions
-# Copyright (C) 2013 SPARTA, Inc. a Parsons Company
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-__version__ = '$Id$'
-
-from django import forms
-
-from rpki.gui.cacheview.misc import parse_ipaddr
-from rpki.exceptions import BadIPResource
-from rpki.resource_set import resource_range_as
-
-
-class SearchForm(forms.Form):
- asn = forms.CharField(required=False, help_text='AS or range', label='AS')
- addr = forms.CharField(required=False, max_length=40, help_text='range/CIDR', label='IP Address')
-
- def clean(self):
- asn = self.cleaned_data.get('asn')
- addr = self.cleaned_data.get('addr')
- if (asn and addr) or ((not asn) and (not addr)):
- raise forms.ValidationError('Please specify either an AS or IP range, not both')
-
- if asn:
- try:
- resource_range_as.parse_str(asn)
- except ValueError:
- raise forms.ValidationError('invalid AS range')
-
- if addr:
- #try:
- parse_ipaddr(addr)
- #except BadIPResource:
- # raise forms.ValidationError('invalid IP address range/prefix')
-
- return self.cleaned_data
-
-
-class SearchForm2(forms.Form):
- resource = forms.CharField(required=True)
diff --git a/rpki/gui/cacheview/misc.py b/rpki/gui/cacheview/misc.py
deleted file mode 100644
index 54431224..00000000
--- a/rpki/gui/cacheview/misc.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2011 SPARTA, Inc. dba Cobham Analytic Solutions
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-from rpki.resource_set import resource_range_ipv4, resource_range_ipv6
-from rpki.exceptions import BadIPResource
-
-def parse_ipaddr(s):
- # resource_set functions only accept str
- if isinstance(s, unicode):
- s = s.encode()
- s = s.strip()
- r = resource_range_ipv4.parse_str(s)
- try:
- r = resource_range_ipv4.parse_str(s)
- return 4, r
- except BadIPResource:
- r = resource_range_ipv6.parse_str(s)
- return 6, r
-
-# vim:sw=4 ts=8 expandtab
diff --git a/rpki/gui/cacheview/models.py b/rpki/gui/cacheview/models.py
deleted file mode 100644
index 08acfa2d..00000000
--- a/rpki/gui/cacheview/models.py
+++ /dev/null
@@ -1,245 +0,0 @@
-# Copyright (C) 2011 SPARTA, Inc. dba Cobham Analytic Solutions
-# Copyright (C) 2012 SPARTA, Inc. a Parsons Company
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-__version__ = '$Id$'
-
-from datetime import datetime
-import time
-
-from django.db import models
-from django.core.urlresolvers import reverse
-
-import rpki.resource_set
-import rpki.gui.models
-
-
-class TelephoneField(models.CharField):
- def __init__(self, *args, **kwargs):
- kwargs['max_length'] = 255
- models.CharField.__init__(self, *args, **kwargs)
-
-
-class AddressRange(rpki.gui.models.PrefixV4):
- @models.permalink
- def get_absolute_url(self):
- return ('rpki.gui.cacheview.views.addressrange_detail', [str(self.pk)])
-
-
-class AddressRangeV6(rpki.gui.models.PrefixV6):
- @models.permalink
- def get_absolute_url(self):
- return ('rpki.gui.cacheview.views.addressrange_detail_v6',
- [str(self.pk)])
-
-
-class ASRange(rpki.gui.models.ASN):
- @models.permalink
- def get_absolute_url(self):
- return ('rpki.gui.cacheview.views.asrange_detail', [str(self.pk)])
-
-kinds = list(enumerate(('good', 'warn', 'bad')))
-kinds_dict = dict((v, k) for k, v in kinds)
-
-
-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)
-
- def __unicode__(self):
- return self.label
-
-
-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')))
-generations_dict = dict((val, key) for (key, val) in generations)
-
-
-class ValidationStatus(models.Model):
- timestamp = models.DateTimeField()
- generation = models.PositiveSmallIntegerField(choices=generations, null=True)
- status = models.ForeignKey(ValidationLabel)
- repo = models.ForeignKey(RepositoryObject, related_name='statuses')
-
-
-class SignedObject(models.Model):
- """
- Abstract class to hold common metadata for all signed objects.
- 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
- mtime = models.PositiveIntegerField(default=0)
-
- # SubjectName
- name = models.CharField(max_length=255)
-
- # value from the SKI extension
- keyid = models.CharField(max_length=60, db_index=True)
-
- # validity period from EE cert which signed object
- not_before = models.DateTimeField()
- not_after = models.DateTimeField()
-
- def mtime_as_datetime(self):
- """
- convert the local timestamp to UTC and convert to a datetime object
- """
-
- return datetime.utcfromtimestamp(self.mtime + time.timezone)
-
- def status_id(self):
- """
- Returns a HTML class selector for the current object based on its validation status.
- 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]
- return None # should not happen
-
- def __unicode__(self):
- return u'%s' % self.name
-
-
-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')
- issuer = models.ForeignKey('self', related_name='children', null=True)
- sia = models.CharField(max_length=255)
-
- def get_absolute_url(self):
- return reverse('cert-detail', args=[str(self.pk)])
-
- def get_cert_chain(self):
- """Return a list containing the complete certificate chain for this
- certificate."""
-
- cert = self
- x = [cert]
- while cert != cert.issuer:
- cert = cert.issuer
- x.append(cert)
- x.reverse()
- return x
- cert_chain = property(get_cert_chain)
-
-
-class ROAPrefix(models.Model):
- "Abstract base class for ROA mixin."
-
- max_length = models.PositiveSmallIntegerField()
-
- class Meta:
- abstract = True
-
- def as_roa_prefix(self):
- "Return value as a rpki.resource_set.roa_prefix_ip object."
- rng = self.as_resource_range()
- return self.roa_cls(rng.min, rng.prefixlen(), self.max_length)
-
- def __unicode__(self):
- p = self.as_resource_range()
- if p.prefixlen() == self.max_length:
- return str(p)
- return '%s-%s' % (str(p), self.max_length)
-
-
-# ROAPrefix is declared first, so subclass picks up __unicode__ from it.
-class ROAPrefixV4(ROAPrefix, rpki.gui.models.PrefixV4):
- "One v4 prefix in a ROA."
-
- roa_cls = rpki.resource_set.roa_prefix_ipv4
-
- @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)
-
- class Meta:
- ordering = ('prefix_min',)
-
-
-# ROAPrefix is declared first, so subclass picks up __unicode__ from it.
-class ROAPrefixV6(ROAPrefix, rpki.gui.models.PrefixV6):
- "One v6 prefix in a ROA."
-
- roa_cls = rpki.resource_set.roa_prefix_ipv6
-
- class Meta:
- ordering = ('prefix_min',)
-
-
-class ROA(SignedObject):
- asid = models.PositiveIntegerField()
- prefixes = models.ManyToManyField(ROAPrefixV4, related_name='roas')
- prefixes_v6 = models.ManyToManyField(ROAPrefixV6, related_name='roas')
- issuer = models.ForeignKey('Cert', related_name='roas')
-
- def get_absolute_url(self):
- return reverse('roa-detail', args=[str(self.pk)])
-
- class Meta:
- ordering = ('asid',)
-
- def __unicode__(self):
- return u'ROA for AS%d' % self.asid
-
-
-class Ghostbuster(SignedObject):
- full_name = models.CharField(max_length=40)
- email_address = models.EmailField(blank=True, null=True)
- organization = models.CharField(blank=True, null=True, max_length=255)
- telephone = TelephoneField(blank=True, null=True)
- issuer = models.ForeignKey('Cert', related_name='ghostbusters')
-
- def get_absolute_url(self):
- # note that ghostbuster-detail is different from gbr-detail! sigh
- return reverse('ghostbuster-detail', args=[str(self.pk)])
-
- def __unicode__(self):
- if self.full_name:
- return self.full_name
- if self.organization:
- return self.organization
- if self.email_address:
- return self.email_address
- return self.telephone
-
-
-from rpki.gui.routeview.models import RouteOrigin
diff --git a/rpki/gui/cacheview/templates/cacheview/addressrange_detail.html b/rpki/gui/cacheview/templates/cacheview/addressrange_detail.html
deleted file mode 100644
index 76edc1ba..00000000
--- a/rpki/gui/cacheview/templates/cacheview/addressrange_detail.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% extends "cacheview/cacheview_base.html" %}
-
-{% block content %}
-<h1>{% block title %}IP Range Detail{% endblock %}</h1>
-
-<p>
-IP Range: {{ object }}
-</p>
-
-<p>Covered by the following resource certs:</p>
-
-<ul>
-{% for cert in object.certs.all %}
-<li><a href="{{ cert.get_absolute_url }}">{{ cert }}</a></li>
-{% endfor %}
-</ul>
-
-{% endblock %}
diff --git a/rpki/gui/cacheview/templates/cacheview/cacheview_base.html b/rpki/gui/cacheview/templates/cacheview/cacheview_base.html
deleted file mode 100644
index ec71d740..00000000
--- a/rpki/gui/cacheview/templates/cacheview/cacheview_base.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "base.html" %}
-{% load url from future %}
-
-{% block sidebar %}
-<form method='post' action='{% url 'res-search' %}'>
- {% csrf_token %}
- <input type='text' id='id_resource' name='resource' placeholder='prefix or AS'>
- <button type='submit'>Search</button>
-</form>
-{% endblock %}
diff --git a/rpki/gui/cacheview/templates/cacheview/cert_detail.html b/rpki/gui/cacheview/templates/cacheview/cert_detail.html
deleted file mode 100644
index 256e7780..00000000
--- a/rpki/gui/cacheview/templates/cacheview/cert_detail.html
+++ /dev/null
@@ -1,105 +0,0 @@
-{% extends "cacheview/signedobject_detail.html" %}
-
-{% block title %}
-Resource Certificate Detail
-{% endblock %}
-
-{% block detail %}
-
-<h2>RFC3779 Resources</h2>
-
-<table class='table table-striped'>
- <thead>
- <tr><th>AS Ranges</th><th>IP Ranges</th></tr>
- </thead>
- <tbody>
- <tr>
- <td style='text-align:left;vertical-align:top'>
- <ul class='compact'>
- {% for asn in object.asns.all %}
- <li><a href="{{ asn.get_absolute_url }}">{{ asn }}</a></li>
- {% endfor %}
- </ul>
- </td>
- <td style='text-align:left;vertical-align:top'>
- <ul class='compact'>
- {% for rng in object.addresses.all %}
- <li><a href="{{ rng.get_absolute_url }}">{{ rng }}</a></li>
- {% endfor %}
- </ul>
- </td>
- </tr>
- </tbody>
-</table>
-
-<div class='section'>
-<h2>Issued Objects</h2>
-<ul>
-
-{% if object.ghostbusters.all %}
- <li>
-<h3>Ghostbusters</h3>
-
-<table class='table table-striped'>
- <thead>
- <tr><th>Name</th><th>Expires</th></tr>
- </thead>
- <tbody>
-
-{% for g in object.ghostbusters.all %}
- <tr class='{{ g.status_id }}'>
- <td><a href="{{ g.get_absolute_url }}">{{ g }}</a></td>
- <td>{{ g.not_after }}</td>
- </tr>
- </tbody>
-{% endfor %}
-
-</table>
-{% endif %}
-
-{% if object.roas.all %}
- <li>
-<h3>ROAs</h3>
-<table class='table table-striped'>
- <thead>
- <tr><th>#</th><th>Prefix</th><th>AS</th><th>Expires</th></tr>
- </thead>
- <tbody>
- {% for roa in object.roas.all %}
- {% for pfx in roa.prefixes.all %}
- <tr class='{{ roa.status_id }}'>
- <td><a href="{{ roa.get_absolute_url }}">#</a></td>
- <td>{{ pfx }}</td>
- <td>{{ roa.asid }}</td>
- <td>{{ roa.not_after }}</td>
- </tr>
- {% endfor %}
- {% endfor %}
- </tbody>
-</table>
-{% endif %}
-
-{% if object.children.all %}
-<li>
-<h3>Children</h3>
-<table class='table table-striped'>
- <thead>
- <tr><th>Name</th><th>Expires</th></tr>
- </thead>
- <tbody>
-
- {% for child in object.children.all %}
- <tr class='{{ child.status_id }}'>
- <td><a href="{{ child.get_absolute_url }}">{{ child.name }}</a></td>
- <td>{{ child.not_after }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% endif %}
-
-</ul>
-
-</div><!--issued objects-->
-
-{% endblock %}
diff --git a/rpki/gui/cacheview/templates/cacheview/ghostbuster_detail.html b/rpki/gui/cacheview/templates/cacheview/ghostbuster_detail.html
deleted file mode 100644
index 4215f757..00000000
--- a/rpki/gui/cacheview/templates/cacheview/ghostbuster_detail.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "cacheview/signedobject_detail.html" %}
-
-{% block title %}Ghostbuster Detail{% endblock %}
-
-{% block detail %}
-<p>
-<table class='table'>
- <tr><td>Full Name</td><td>{{ object.full_name }}</td></tr>
- <tr><td>Organization</td><td>{{ object.organization }}</td></tr>
- <tr><td>Email</td><td>{{ object.email_address }}</td></tr>
- <tr><td>Telephone</td><td>{{ object.telephone }}</td></tr>
-</table>
-{% endblock %}
diff --git a/rpki/gui/cacheview/templates/cacheview/global_summary.html b/rpki/gui/cacheview/templates/cacheview/global_summary.html
deleted file mode 100644
index 0dbd0ffc..00000000
--- a/rpki/gui/cacheview/templates/cacheview/global_summary.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "cacheview/cacheview_base.html" %}
-
-{% block content %}
-<div class='page-header'>
- <h1>Browse Global RPKI</h1>
-</div>
-
-<table class="table table-striped">
- <thead>
- <tr>
- <th>Name</th>
- <th>Expires</th>
- <th>URI</th>
- </tr>
- </thead>
- <tbody>
- {% for r in roots %}
- <tr>
- <td><a href="{{ r.get_absolute_url }}">{{ r.name }}</a></td>
- <td>{{ r.not_after }}</td>
- <td>{{ r.repo.uri }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% endblock content %}
diff --git a/rpki/gui/cacheview/templates/cacheview/query_result.html b/rpki/gui/cacheview/templates/cacheview/query_result.html
deleted file mode 100644
index 0694c531..00000000
--- a/rpki/gui/cacheview/templates/cacheview/query_result.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "cacheview/cacheview_base.html" %}
-
-{% block content %}
-
-<h1>{% block title %}Query Results{% endblock %}</h1>
-
-<table>
- <tr><th>Prefix</th><th>AS</th><th>Valid</th><th>Until</th></tr>
- {% for object in object_list %}
- <tr class='{{ object.1.status.kind_as_str }}'>
- <td>{{ object.0 }}</td>
- <td>{{ object.1.asid }}</td>
- <td><a href="{{ object.1.get_absolute_url }}">{{ object.1.ok }}</a></td>
- <td>{{ object.1.not_after }}</td>
- </tr>
- {% endfor %}
-</table>
-
-<p><a href="{% url rpki.gui.cacheview.views.query_view %}">new query</a></p>
-
-{% endblock %}
diff --git a/rpki/gui/cacheview/templates/cacheview/roa_detail.html b/rpki/gui/cacheview/templates/cacheview/roa_detail.html
deleted file mode 100644
index 39cc547b..00000000
--- a/rpki/gui/cacheview/templates/cacheview/roa_detail.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% extends "cacheview/signedobject_detail.html" %}
-
-{% block title %}ROA Detail{% endblock %}
-
-{% block detail %}
-<p>
-<table>
- <tr><td>AS</td><td>{{ object.asid }}</td></tr>
-</table>
-
-<h2>Prefixes</h2>
-
-<ul>
-{% for pfx in object.prefixes.all %}
-<li>{{ pfx }}
-{% endfor %}
-</ul>
-{% endblock %}
diff --git a/rpki/gui/cacheview/templates/cacheview/search_form.html b/rpki/gui/cacheview/templates/cacheview/search_form.html
deleted file mode 100644
index 1141615d..00000000
--- a/rpki/gui/cacheview/templates/cacheview/search_form.html
+++ /dev/null
@@ -1,17 +0,0 @@
-{% extends "cacheview/cacheview_base.html" %}
-
-{% block title %}
-{{ search_type }} Search
-{% endblock %}
-
-{% block content %}
-
-<h1>{{search_type}} Search</h1>
-
-<form method='post' action='{{ request.url }}'>
- {% csrf_token %}
- {{ form.as_p }}
- <input type='submit' name='Search'>
-</form>
-
-{% endblock %}
diff --git a/rpki/gui/cacheview/templates/cacheview/search_result.html b/rpki/gui/cacheview/templates/cacheview/search_result.html
deleted file mode 100644
index 7cbf852e..00000000
--- a/rpki/gui/cacheview/templates/cacheview/search_result.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% extends "cacheview/cacheview_base.html" %}
-
-{% block content %}
-
-<div class='page-header'>
- <h1>Search Results <small>{{ resource }}</small></h1>
-</div>
-
-<h2>Matching Resource Certificates</h2>
-{% if certs %}
-<ul>
-{% for cert in certs %}
-<li><a href="{{ cert.get_absolute_url }}">{{ cert }}</a>
-{% endfor %}
-</ul>
-{% else %}
-<p>none</p>
-{% endif %}
-
-<h2>Matching ROAs</h2>
-{% if roas %}
-<table class='table table-striped'>
- <thead>
- <tr>
- <th>#</th><th>Prefix</th><th>AS</th>
- </tr>
- </thead>
- <tbody>
-{% for roa in roas %}
-<tr>
- <td><a href="{{ roa.get_absolute_url }}">#</a></td>
- <td>{{ roa.prefixes.all.0 }}</td>
- <td>{{ roa.asid }}</td>
-</tr>
-{% endfor %}
-</tbody>
-</table>
-{% else %}
-<p>none</p>
-{% endif %}
-
-{% endblock %}
diff --git a/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html b/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html
deleted file mode 100644
index 22ae3d27..00000000
--- a/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html
+++ /dev/null
@@ -1,58 +0,0 @@
-{% extends "cacheview/cacheview_base.html" %}
-
-{% block content %}
-<div class='page-header'>
-<h1>{% block title %}Signed Object Detail{% endblock %}</h1>
-</div>
-
-<h2>Cert Info</h2>
-<table class='table table-striped'>
- <tr><td>Subject Name</td><td>{{ object.name }}</td></tr>
- <tr><td>SKI</td><td>{{ object.keyid }}</td></tr>
- {% if object.sia %}
- <tr><td>SIA</td><td>{{ object.sia }}</td></tr>
- {% endif %}
- <tr><td>Not Before</td><td>{{ object.not_before }}</td></tr>
- <tr><td>Not After</td><td>{{ object.not_after }}</td></tr>
-</table>
-
-<h2>Metadata</h2>
-
-<table class='table table-striped'>
- <tr><td>URI</td><td>{{ object.repo.uri }}</td></tr>
- <tr><td>Last Modified</td><td>{{ object.mtime_as_datetime|date:"DATETIME_FORMAT" }}</td></tr>
-</table>
-
-<h2>Validation Status</h2>
-<table class='table table-striped'>
- <thead>
- <tr><th>Timestamp</th><th>Generation</th><th>Status</th></tr>
- </thead>
- <tbody>
- {% for status in object.repo.statuses.all %}
- <tr class="{{ status.status.get_kind_display }}"><td>{{ status.timestamp }}</td><td>{{ status.get_generation_display }}</td><td>{{ status.status.status }}</td></tr>
- {% endfor %}
- </tbody>
-</table>
-
-<h2>X.509 Certificate Chain</h2>
-
-<table class='table table-striped'>
- <thead>
- <tr><th>Depth</th><th>Name</th></tr>
- </thead>
- <tbody>
-
-{% for cert in chain %}
-<tr class='{{ cert.1.status_id }}'>
- <td>{{ cert.0 }}</td>
- <td><a href="{{ cert.1.get_absolute_url }}">{{ cert.1.name }}</a></td>
-</tr>
-{% endfor %}
-</tbody>
-
-</table>
-
-{% block detail %}{% endblock %}
-
-{% endblock %}
diff --git a/rpki/gui/cacheview/tests.py b/rpki/gui/cacheview/tests.py
deleted file mode 100644
index c2958c72..00000000
--- a/rpki/gui/cacheview/tests.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""
-This file demonstrates two different styles of tests (one doctest and one
-unittest). These will both pass when you run "manage.py test".
-
-Replace these with more appropriate tests for your application.
-"""
-
-from django.test import TestCase
-
-class SimpleTest(TestCase):
- def test_basic_addition(self):
- """
- Tests that 1 + 1 always equals 2.
- """
-
- self.failUnlessEqual(1 + 1, 2)
-
-__test__ = {"doctest": """
-Another way to test that 1 + 1 is equal to 2.
-
->>> 1 + 1 == 2
-True
-"""}
diff --git a/rpki/gui/cacheview/urls.py b/rpki/gui/cacheview/urls.py
deleted file mode 100644
index cc03a587..00000000
--- a/rpki/gui/cacheview/urls.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2011 SPARTA, Inc. dba Cobham Analytic Solutions
-# Copyright (C) 2013 SPARTA, Inc. a Parsons Company
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-__version__ = '$Id$'
-
-from django.conf.urls import patterns, url
-from rpki.gui.cacheview.views import (CertDetailView, RoaDetailView,
- GhostbusterDetailView)
-
-urlpatterns = patterns('',
- url(r'^search$', 'rpki.gui.cacheview.views.search_view',
- name='res-search'),
- url(r'^cert/(?P<pk>[^/]+)$', CertDetailView.as_view(), name='cert-detail'),
- url(r'^gbr/(?P<pk>[^/]+)$', GhostbusterDetailView.as_view(),
- name='ghostbuster-detail'),
- url(r'^roa/(?P<pk>[^/]+)$', RoaDetailView.as_view(), name='roa-detail'),
- (r'^$', 'rpki.gui.cacheview.views.global_summary'),
-)
-
-# vim:sw=4 ts=8 expandtab
diff --git a/rpki/gui/cacheview/util.py b/rpki/gui/cacheview/util.py
deleted file mode 100644
index 00298b2c..00000000
--- a/rpki/gui/cacheview/util.py
+++ /dev/null
@@ -1,435 +0,0 @@
-# Copyright (C) 2011 SPARTA, Inc. dba Cobham
-# Copyright (C) 2012, 2013 SPARTA, Inc. a Parsons Company
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-__version__ = '$Id$'
-__all__ = ('import_rcynic_xml')
-
-default_logfile = '/var/rcynic/data/rcynic.xml'
-default_root = '/var/rcynic/data'
-object_accepted = None # set by import_rcynic_xml()
-
-import time
-import vobject
-import logging
-import os
-import stat
-from socket import getfqdn
-from cStringIO import StringIO
-
-from django.db import transaction
-import django.db.models
-
-import rpki
-import rpki.left_right
-import rpki.gui.app.timestamp
-from rpki.gui.app.models import Conf, Alert
-from rpki.gui.cacheview import models
-from rpki.rcynic import rcynic_xml_iterator, label_iterator
-from rpki.sundial import datetime
-from rpki.irdb.zookeeper import Zookeeper
-
-from lxml.etree import Element, SubElement
-
-logger = logging.getLogger(__name__)
-
-
-def rcynic_cert(cert, obj):
- obj.sia = cert.sia_directory_uri
-
- # object must be saved for the related manager methods below to work
- obj.save()
-
- # for the root cert, we can't set inst.issuer = inst until
- # after inst.save() has been called.
- if obj.issuer is None:
- obj.issuer = obj
- obj.save()
-
- # resources can change when a cert is updated
- obj.asns.clear()
- obj.addresses.clear()
-
- if cert.resources.asn.inherit:
- # FIXME: what happens when the parent's resources change and the child
- # cert is not reissued?
- obj.asns.add(*obj.issuer.asns.all())
- else:
- for asr in cert.resources.asn:
- logger.debug('processing %s', asr)
-
- attrs = {'min': asr.min, 'max': asr.max}
- q = models.ASRange.objects.filter(**attrs)
- if not q:
- obj.asns.create(**attrs)
- else:
- obj.asns.add(q[0])
-
- # obj.issuer is None the first time we process the root cert in the
- # hierarchy, so we need to guard against dereference
- for cls, addr_obj, addrset, parentset in (
- models.AddressRange, obj.addresses, cert.resources.v4,
- obj.issuer.addresses.all() if obj.issuer else []
- ), (
- models.AddressRangeV6, obj.addresses_v6, cert.resources.v6,
- obj.issuer.addresses_v6.all() if obj.issuer else []
- ):
- if addrset.inherit:
- addr_obj.add(*parentset)
- else:
- for rng in addrset:
- logger.debug('processing %s', rng)
-
- attrs = {'prefix_min': rng.min, 'prefix_max': rng.max}
- q = cls.objects.filter(**attrs)
- if not q:
- addr_obj.create(**attrs)
- else:
- addr_obj.add(q[0])
-
-
-def rcynic_roa(roa, obj):
- obj.asid = roa.asID
- # object must be saved for the related manager methods below to work
- obj.save()
- obj.prefixes.clear()
- obj.prefixes_v6.clear()
- for pfxset in roa.prefix_sets:
- if pfxset.__class__.__name__ == 'roa_prefix_set_ipv6':
- roa_cls = models.ROAPrefixV6
- prefix_obj = obj.prefixes_v6
- else:
- roa_cls = models.ROAPrefixV4
- prefix_obj = obj.prefixes
-
- for pfx in pfxset:
- attrs = {'prefix_min': pfx.min(),
- 'prefix_max': pfx.max(),
- 'max_length': pfx.max_prefixlen}
- q = roa_cls.objects.filter(**attrs)
- if not q:
- prefix_obj.create(**attrs)
- else:
- prefix_obj.add(q[0])
-
-
-def rcynic_gbr(gbr, obj):
- vcard = vobject.readOne(gbr.vcard)
- obj.full_name = vcard.fn.value if hasattr(vcard, 'fn') else None
- obj.email_address = vcard.email.value if hasattr(vcard, 'email') else None
- obj.telephone = vcard.tel.value if hasattr(vcard, 'tel') else None
- obj.organization = vcard.org.value[0] if hasattr(vcard, 'org') else None
- obj.save()
-
-LABEL_CACHE = {}
-
-# dict keeping mapping of uri to (handle, old status, new status) for objects
-# published by the local rpkid
-uris = {}
-
-dispatch = {
- 'rcynic_certificate': rcynic_cert,
- 'rcynic_roa': rcynic_roa,
- 'rcynic_ghostbuster': rcynic_gbr
-}
-
-model_class = {
- 'rcynic_certificate': models.Cert,
- 'rcynic_roa': models.ROA,
- 'rcynic_ghostbuster': models.Ghostbuster
-}
-
-
-def save_status(repo, vs):
- timestamp = datetime.fromXMLtime(vs.timestamp).to_sql()
- status = LABEL_CACHE[vs.status]
- g = models.generations_dict.get(vs.generation)
- repo.statuses.create(generation=g, timestamp=timestamp, status=status)
-
- # if this object is in our interest set, update with the current validation
- # status
- if repo.uri in uris:
- x, y, z, q = uris[repo.uri]
- valid = z or (status is object_accepted) # don't clobber previous True value
- uris[repo.uri] = x, y, valid, repo
-
- if status is not object_accepted:
- return
-
- cls = model_class[vs.file_class.__name__]
- # find the instance of the signedobject subclass that is associated with
- # this repo instance (may be empty when not accepted)
- inst_qs = cls.objects.filter(repo=repo)
-
- logger.debug('processing %s', vs.filename)
-
- if not inst_qs:
- inst = cls(repo=repo)
- logger.debug('object not found in db, creating new object cls=%s id=%s',
- cls, id(inst))
- else:
- inst = inst_qs[0]
-
- try:
- # determine if the object is changed/new
- mtime = os.stat(vs.filename)[stat.ST_MTIME]
- except OSError as e:
- logger.error('unable to stat %s: %s %s',
- vs.filename, type(e), e)
- # treat as if missing from rcynic.xml
- # use inst_qs rather than deleting inst so that we don't raise an
- # exception for newly created objects (inst_qs will be empty)
- inst_qs.delete()
- return
-
- if mtime != inst.mtime:
- inst.mtime = mtime
- try:
- obj = vs.obj # causes object to be lazily loaded
- except Exception, e:
- logger.warning('Caught %s while processing %s: %s',
- type(e), vs.filename, e)
- return
-
- inst.not_before = obj.notBefore.to_sql()
- inst.not_after = obj.notAfter.to_sql()
- inst.name = obj.subject
- inst.keyid = obj.ski
-
- # look up signing cert
- if obj.issuer == obj.subject:
- # self-signed cert (TA)
- assert isinstance(inst, models.Cert)
- inst.issuer = None
- else:
- # if an object has moved in the repository, the entry for
- # the old location will still be in the database, but
- # without any object_accepted in its validtion status
- qs = models.Cert.objects.filter(
- keyid=obj.aki,
- name=obj.issuer,
- repo__statuses__status=object_accepted
- )
- ncerts = len(qs)
- if ncerts == 0:
- logger.warning('unable to find signing cert with ski=%s (%s)', obj.aki, obj.issuer)
- return
- else:
- if ncerts > 1:
- # multiple matching certs, all of which are valid
- logger.warning('Found multiple certs matching ski=%s sn=%s', obj.aki, obj.issuer)
- for c in qs:
- logger.warning(c.repo.uri)
- # just use the first match
- inst.issuer = qs[0]
-
- try:
- # do object-specific tasks
- dispatch[vs.file_class.__name__](obj, inst)
- except:
- logger.error('caught exception while processing rcynic_object:\n'
- 'vs=' + repr(vs) + '\nobj=' + repr(obj))
- # .show() writes to stdout
- obj.show()
- raise
-
- logger.debug('object saved id=%s', id(inst))
- else:
- logger.debug('object is unchanged')
-
-
-@transaction.atomic
-def process_cache(root, xml_file):
-
- last_uri = None
- repo = None
-
- logger.info('clearing validation statuses')
- models.ValidationStatus.objects.all().delete()
-
- logger.info('updating validation status')
- for vs in rcynic_xml_iterator(root, xml_file):
- if vs.uri != last_uri:
- repo, created = models.RepositoryObject.objects.get_or_create(uri=vs.uri)
- last_uri = vs.uri
- save_status(repo, vs)
-
- # garbage collection
- # remove all objects which have no ValidationStatus references, which
- # means they did not appear in the last XML output
- logger.info('performing garbage collection')
-
- # Delete all objects that have zero validation status elements.
- models.RepositoryObject.objects.annotate(num_statuses=django.db.models.Count('statuses')).filter(num_statuses=0).delete()
-
- # Delete all SignedObject instances that were not accepted. There may
- # exist rows for objects that were previously accepted.
- # See https://trac.rpki.net/ticket/588#comment:30
- #
- # We have to do this here rather than in save_status() because the
- # <validation_status/> elements are not guaranteed to be consecutive for a
- # given URI. see https://trac.rpki.net/ticket/625#comment:5
- models.SignedObject.objects.exclude(repo__statuses__status=object_accepted).delete()
-
- # ROAPrefixV* objects are M2M so they are not automatically deleted when
- # their ROA object disappears
- models.ROAPrefixV4.objects.annotate(num_roas=django.db.models.Count('roas')).filter(num_roas=0).delete()
- models.ROAPrefixV6.objects.annotate(num_roas=django.db.models.Count('roas')).filter(num_roas=0).delete()
- logger.info('done with garbage collection')
-
-
-@transaction.atomic
-def process_labels(xml_file):
- logger.info('updating labels...')
-
- for label, kind, desc in label_iterator(xml_file):
- logger.debug('label=%s kind=%s desc=%s', label, kind, desc)
- if kind:
- q = models.ValidationLabel.objects.filter(label=label)
- if not q:
- obj = models.ValidationLabel(label=label)
- else:
- obj = q[0]
-
- obj.kind = models.kinds_dict[kind]
- obj.status = desc
- obj.save()
-
- LABEL_CACHE[label] = obj
-
-
-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()]
- q_msg = Element(rpki.left_right.tag_msg, nsmap = rpki.left_right.nsmap,
- type = "query", version = rpki.left_right.version)
- for h in handles:
- SubElement(q_msg, rpki.left_right.tag_list_published_objects, action="list", tenant_handle=h, tag=h)
- z = Zookeeper()
- r_msg = z.call_rpkid(q_msg)
- for r_pdu in r_msg:
- if r_pdu.tag == rpki.left_right.tag_list_published_objects:
- # Look up the object in the rcynic cache
- qs = models.RepositoryObject.objects.filter(uri=r_pdu.get("uri"))
- if qs:
- # get the current validity state
- valid = qs[0].statuses.filter(status=object_accepted).exists()
- uris[r_pdu.get("uri")] = (r_pdu.get("tenant_handle"), valid, False, None)
- logger.debug('adding %s', r_pdu.get("uri"))
- else:
- # this object is not in the cache. it was either published
- # recently, or disappared previously. if it disappeared
- # previously, it has already been alerted. in either case, we
- # omit the uri from the list since we are interested only in
- # objects which were valid and are no longer valid
- pass
- elif r_pdu.tag == rpki.left_right.tag_report_error:
- logging.error('rpkid reported an error: %s', r_pdu.get("error_code"))
-
-
-class Handle(object):
- def __init__(self):
- self.invalid = []
- self.missing = []
-
- def add_invalid(self, v):
- self.invalid.append(v)
-
- def add_missing(self, v):
- self.missing.append(v)
-
-
-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')
-
- # group invalid objects by user
- notify = {}
- for uri, v in uris.iteritems():
- handle, old_status, new_status, obj = v
-
- if obj is None:
- # object went missing
- n = notify.get(handle, Handle())
- n.add_missing(uri)
- # only select valid->invalid
- elif old_status and not new_status:
- n = notify.get(handle, Handle())
- n.add_invalid(obj)
-
- for handle, v in notify.iteritems():
- conf = Conf.objects.get(handle)
-
- msg = StringIO()
- msg.write('This is an alert about problems with objects published by '
- 'the resource handle %s.\n\n' % handle)
-
- if v.invalid:
- msg.write('The following objects were previously valid, but are '
- 'now invalid:\n')
-
- for o in v.invalid:
- msg.write('\n')
- msg.write(o.repo.uri)
- msg.write('\n')
- for s in o.statuses.all():
- msg.write('\t')
- msg.write(s.status.label)
- msg.write(': ')
- msg.write(s.status.status)
- msg.write('\n')
-
- if v.missing:
- msg.write('The following objects were previously valid but are no '
- 'longer in the cache:\n')
-
- for o in v.missing:
- msg.write(o)
- msg.write('\n')
-
- msg.write("""--
-You are receiving this email because your address is published in a Ghostbuster
-record, or is the default email address for this resource holder account on
-%s.""" % getfqdn())
-
- from_email = 'root@' + getfqdn()
- subj = 'invalid RPKI object alert for resource handle %s' % conf.handle
- conf.send_alert(subj, msg.getvalue(), from_email, severity=Alert.ERROR)
-
-
-def import_rcynic_xml(root=default_root, logfile=default_logfile):
- """Load the contents of rcynic.xml into the rpki.gui.cacheview database."""
-
- global object_accepted
-
- start = time.time()
- process_labels(logfile)
- object_accepted = LABEL_CACHE['OBJECT_ACCEPTED']
- fetch_published_objects()
- process_cache(root, logfile)
- notify_invalid()
-
- rpki.gui.app.timestamp.update('rcynic_import')
-
- stop = time.time()
- logger.info('elapsed time %d seconds.', (stop - start))
diff --git a/rpki/gui/cacheview/views.py b/rpki/gui/cacheview/views.py
deleted file mode 100644
index 451c0d1e..00000000
--- a/rpki/gui/cacheview/views.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright (C) 2011 SPARTA, Inc. dba Cobham Analytic Solutions
-# Copyright (C) 2013 SPARTA, Inc. a Parsons Company
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-__version__ = '$Id$'
-
-from django.views.generic import DetailView
-from django.shortcuts import render
-from django.db.models import F
-
-from rpki.gui.cacheview import models, forms, misc
-from rpki.resource_set import resource_range_as, resource_range_ip
-from rpki.POW import IPAddress
-from rpki.exceptions import BadIPResource
-
-
-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
- chain.append(obj)
- return zip(range(len(chain)), reversed(chain))
-
-
-class SignedObjectDetailView(DetailView):
- def get_context_data(self, **kwargs):
- context = super(SignedObjectDetailView,
- self).get_context_data(**kwargs)
- context['chain'] = cert_chain(self.object)
- return context
-
-
-class RoaDetailView(SignedObjectDetailView):
- model = models.ROA
-
-
-class CertDetailView(SignedObjectDetailView):
- model = models.Cert
-
-
-class GhostbusterDetailView(SignedObjectDetailView):
- model = models.Ghostbuster
-
-
-def search_view(request):
- certs = None
- roas = None
-
- if request.method == 'POST':
- form = forms.SearchForm2(request.POST, request.FILES)
- if form.is_valid():
- resource = form.cleaned_data.get('resource')
- # try to determine the type of input given
- try:
- r = resource_range_as.parse_str(resource)
- certs = models.Cert.objects.filter(asns__min__gte=r.min,
- asns__max__lte=r.max)
- roas = models.ROA.objects.filter(asid__gte=r.min,
- asid__lte=r.max)
- except:
- try:
- r = resource_range_ip.parse_str(resource)
- if r.version == 4:
- certs = models.Cert.objects.filter(
- addresses__prefix_min__lte=r.min,
- addresses__prefix_max__gte=r.max)
- roas = models.ROA.objects.filter(
- prefixes__prefix_min__lte=r.min,
- prefixes__prefix_max__gte=r.max)
- else:
- certs = models.Cert.objects.filter(
- addresses_v6__prefix_min__lte=r.min,
- addresses_v6__prefix_max__gte=r.max)
- roas = models.ROA.objects.filter(
- prefixes_v6__prefix_min__lte=r.min,
- prefixes_v6__prefix_max__gte=r.max)
- except BadIPResource:
- pass
-
- return render(request, 'cacheview/search_result.html',
- {'resource': resource, 'certs': certs, 'roas': roas})
-
-
-def cmp_prefix(x, y):
- r = cmp(x[0].family, y[0].family)
- if r == 0:
- r = cmp(x[2], y[2]) # integer address
- if r == 0:
- r = cmp(x[0].bits, y[0].bits)
- if r == 0:
- r = cmp(x[0].max_length, y[0].max_length)
- if r == 0:
- r = cmp(x[1].asid, y[1].asid)
- return r
-
-
-#def cmp_prefix(x,y):
-# for attr in ('family', 'prefix', 'bits', 'max_length'):
-# r = cmp(getattr(x[0], attr), getattr(y[0], attr))
-# if r:
-# return r
-# return cmp(x[1].asid, y[1].asid)
-
-
-def query_view(request):
- """
- Allow the user to search for an AS or prefix, and show all published ROA
- information.
- """
-
- if request.method == 'POST':
- form = forms.SearchForm(request.POST, request.FILES)
- if form.is_valid():
- certs = None
- roas = None
-
- addr = form.cleaned_data.get('addr')
- asn = form.cleaned_data.get('asn')
-
- if addr:
- family, r = misc.parse_ipaddr(addr)
- prefixes = models.ROAPrefix.objects.filter(family=family, prefix=str(r.min))
-
- prefix_list = []
- for pfx in prefixes:
- for roa in pfx.roas.all():
- prefix_list.append((pfx, roa))
- elif asn:
- r = resource_range_as.parse_str(asn)
- roas = models.ROA.objects.filter(asid__gte=r.min, asid__lte=r.max)
-
- # display the results sorted by prefix
- prefix_list = []
- for roa in roas:
- for pfx in roa.prefixes.all():
- addr = IPAddress(pfx.prefix.encode())
- prefix_list.append((pfx, roa, addr))
- prefix_list.sort(cmp=cmp_prefix)
-
- return render('cacheview/query_result.html',
- {'object_list': prefix_list}, request)
- else:
- form = forms.SearchForm()
-
- return render('cacheview/search_form.html', {
- 'form': form, 'search_type': 'ROA '}, request)
-
-
-def global_summary(request):
- """Display a table summarizing the state of the global RPKI."""
-
- roots = models.Cert.objects.filter(issuer=F('pk')) # self-signed
-
- return render(request, 'cacheview/global_summary.html', {
- 'roots': roots
- })
-
-# vim:sw=4 ts=8 expandtab