aboutsummaryrefslogtreecommitdiff
path: root/rpkid/rpki/gui/cacheview
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid/rpki/gui/cacheview')
-rw-r--r--rpkid/rpki/gui/cacheview/admin.py14
-rw-r--r--rpkid/rpki/gui/cacheview/models.py51
-rw-r--r--rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html23
-rw-r--r--rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html19
4 files changed, 81 insertions, 26 deletions
diff --git a/rpkid/rpki/gui/cacheview/admin.py b/rpkid/rpki/gui/cacheview/admin.py
index 2b88c1f3..05bab881 100644
--- a/rpkid/rpki/gui/cacheview/admin.py
+++ b/rpkid/rpki/gui/cacheview/admin.py
@@ -37,8 +37,13 @@ class ROAAdmin(admin.ModelAdmin):
class GhostbusterAdmin(admin.ModelAdmin):
pass
-class ValidationStatusAdmin(admin.ModelAdmin):
- pass
+class ValidationLabelAdmin(admin.ModelAdmin): pass
+
+class ValidationStatus_CertAdmin(admin.ModelAdmin): pass
+
+class ValidationStatus_ROAAdmin(admin.ModelAdmin): pass
+
+class ValidationStatus_GhostbusterAdmin(admin.ModelAdmin): pass
admin.site.register(models.AddressRange, AddressRangeAdmin)
admin.site.register(models.ASRange, AddressRangeAdmin)
@@ -46,6 +51,9 @@ admin.site.register(models.Cert, CertAdmin)
admin.site.register(models.Ghostbuster, GhostbusterAdmin)
admin.site.register(models.ROA, ROAAdmin)
admin.site.register(models.ROAPrefix, ROAPrefixAdmin)
-admin.site.register(models.ValidationStatus, ValidationStatusAdmin)
+admin.site.register(models.ValidationLabel, ValidationLabelAdmin)
+admin.site.register(models.ValidationStatus_Cert, ValidationStatus_CertAdmin)
+admin.site.register(models.ValidationStatus_ROA, ValidationStatus_ROAAdmin)
+admin.site.register(models.ValidationStatus_Ghostbuster, ValidationStatus_GhostbusterAdmin)
# vim:sw=4 ts=8
diff --git a/rpkid/rpki/gui/cacheview/models.py b/rpkid/rpki/gui/cacheview/models.py
index d68601fc..077a28ff 100644
--- a/rpkid/rpki/gui/cacheview/models.py
+++ b/rpkid/rpki/gui/cacheview/models.py
@@ -73,9 +73,10 @@ class ASRange(models.Model):
def get_absolute_url(self):
return ('rpki.gui.cacheview.views.asrange_detail', [str(self.pk)])
-kinds = ( (0, 'good'), (1, 'warn'), (2, 'bad') )
+kinds = list(enumerate(('good', 'warn', 'bad')))
+kinds_dict = dict((v,k) for k,v in kinds)
-class ValidationStatus(models.Model):
+class ValidationLabel(models.Model):
"""
Represents a specific error condition defined in the rcynic XML
output file.
@@ -87,11 +88,19 @@ class ValidationStatus(models.Model):
def __unicode__(self):
return self.label
- def kind_as_str(self):
- return kinds[self.kind][1]
+ class Meta:
+ verbose_name_plural = 'ValidationLabels'
+
+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')
class Meta:
- verbose_name_plural = 'ValidationStatuses'
+ abstract = True
class SignedObject(models.Model):
"""
@@ -101,10 +110,8 @@ class SignedObject(models.Model):
"""
# attributes from rcynic's output XML file
uri = models.URLField(unique=True, db_index=True)
- timestamp = models.DateTimeField()
- ok = models.BooleanField()
- status = models.ForeignKey('ValidationStatus')
+ # on-disk file modification time
mtime = models.PositiveIntegerField(default=0)
# SubjectName
@@ -126,6 +133,24 @@ class SignedObject(models.Model):
"""
return datetime.utcfromtimestamp(self.mtime + time.timezone)
+ def is_valid(self):
+ """
+ Returns a boolean value indicating whether this object has passed
+ validation checks.
+ """
+ return bool(self.statuses.filter(status=ValidationLabel.objects.get(label="object_accepted")))
+
+ 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.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
@@ -136,11 +161,15 @@ class Cert(SignedObject):
addresses = models.ManyToManyField(AddressRange, related_name='certs')
asns = models.ManyToManyField(ASRange, related_name='certs')
issuer = models.ForeignKey('Cert', related_name='children', null=True, blank=True)
+ sia = models.CharField(max_length=255)
@models.permalink
def get_absolute_url(self):
return ('rpki.gui.cacheview.views.cert_detail', [str(self.pk)])
+class ValidationStatus_Cert(ValidationStatus):
+ cert = models.ForeignKey('Cert', related_name='statuses')
+
class ROAPrefix(models.Model):
family = models.PositiveIntegerField()
prefix = models.IPAddressField()
@@ -175,6 +204,9 @@ class ROA(SignedObject):
def get_absolute_url(self):
return ('rpki.gui.cacheview.views.roa_detail', [str(self.pk)])
+class ValidationStatus_ROA(ValidationStatus):
+ roa = models.ForeignKey('ROA', related_name='statuses')
+
class Ghostbuster(SignedObject):
full_name = models.CharField(max_length=40)
email_address = models.EmailField(blank=True, null=True)
@@ -195,4 +227,7 @@ class Ghostbuster(SignedObject):
return self.email_address
return self.telephone
+class ValidationStatus_Ghostbuster(ValidationStatus):
+ gbr = models.ForeignKey('Ghostbuster', related_name='statuses')
+
# vim:sw=4 ts=8 expandtab
diff --git a/rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html b/rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html
index a0291d7b..9ff304a2 100644
--- a/rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html
+++ b/rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html
@@ -32,6 +32,7 @@ Resource Certificate Detail
<h2>Issued Objects</h2>
<ul>
+{% if object.ghostbusters.all %}
<li>
<h3>Ghostbusters</h3>
@@ -39,26 +40,27 @@ Resource Certificate Detail
<tr><th>Name</th><th>Valid</th><th>Until</th></tr>
{% for g in object.ghostbusters.all %}
- <tr class='{{ g.status.kind_as_str }}'>
+ <tr class='{{ g.status_id }}'>
<td><a href="{{ g.get_absolute_url }}">{{ g }}</a></td>
- <td>{{ g.ok }}</td>
+ <td>{{ g.is_valid }}</td>
<td>{{ g.not_after }}</td>
</tr>
{% endfor %}
</table>
+{% endif %}
+{% if object.roas.all %}
<li>
<h3>ROAs</h3>
-{% if object.roas.all %}
<table>
<tr><th>Prefix</th><th>AS</th><th>Valid</th><th>Until</th></tr>
{% for roa in object.roas.all %}
{% for pfx in roa.prefixes.all %}
- <tr class='{{ roa.status.kind_as_str }}'>
+ <tr class='{{ roa.status_id }}'>
<td>{{ pfx }}</td>
<td>{{ roa.asid }}</td>
- <td><a href="{{ roa.get_absolute_url }}">{{ roa.ok }}</a></td>
+ <td><a href="{{ roa.get_absolute_url }}">{{ roa.is_valid }}</a></td>
<td>{{ roa.not_after }}</td>
</tr>
{% endfor %}
@@ -66,21 +68,24 @@ Resource Certificate Detail
</table>
{% endif %}
+{% if object.children.all %}
<li>
-
<h3>Children</h3>
<table>
- <tr><th>Name</th><th>Valid</th><th>Until</th></tr>
+ <tr><th>Name</th><th>SIA</th><th>Valid</th><th>Until</th><th>Ghostbuster</th></tr>
{% for child in object.children.all %}
- <tr class='{{ child.status.kind_as_str }}'>
+ <tr class='{{ child.status_id }}'>
<td><a href="{{ child.get_absolute_url }}">{{ child.name }}</a></td>
- <td>{{ child.ok }}</td>
+ <td>{{ child.sia }}</td>
+ <td>{{ child.is_valid }}</td>
<td>{{ child.not_after }}</td>
+ <td><a href="{{ child.ghostbusters.all.0.get_absolute_url }}">{{ child.ghostbusters.all.0 }}</a></td>
</tr>
{% endfor %}
</table>
+{% endif %}
</ul>
diff --git a/rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html b/rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html
index 45dff81b..b5f629d8 100644
--- a/rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html
+++ b/rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html
@@ -8,22 +8,29 @@
<table>
<tr><td>URI</td><td>{{ object.uri }}</td></tr>
<tr><td>Last Modified</td><td>{{ object.mtime_as_datetime|date:"DATETIME_FORMAT" }}</td></tr>
- <tr><td>Timestamp</td><td>{{ object.timestamp }}</td></tr>
- <tr><td>Valid</td><td>{{ object.ok }}</td></tr>
- <tr><td>Status</td><td class='{{ object.status.kind_as_str }}'>{{ object.status.status }}</td></tr>
+</table>
+
+<h3>Validation Status</h3>
+<table>
+ <tr><th>Timestamp</th><th>Generation</th><th>Status</th></tr>
+ {% for status in object.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 %}
</table>
<h2>X.509 Certificate Chain</h2>
<table>
- <tr><th>Depth</th><th>Name</th><th>Valid</th><th>Until</th></tr>
+ <tr><th>Depth</th><th>Name</th><th>SIA</th><th>Valid</th><th>Until</th><th>Ghostbuster</th></tr>
{% for cert in chain %}
-<tr class='{{ cert.1.status.kind_as_str }}'>
+<tr class='{{ cert.1.status_id }}'>
<td>{{ cert.0 }}</td>
<td><a href="{{ cert.1.get_absolute_url }}">{{ cert.1.name }}</a></td>
- <td>{{ cert.1.ok }}</td>
+ <td>{{ cert.1.sia }}</td>
+ <td>{{ cert.1.is_valid }}</td>
<td>{{ cert.1.not_after }}</td>
+ <td><a href="{{ cert.1.ghostbusters.all.0.get_absolute_url }}">{{ cert.1.ghostbusters.all.0 }}</a></td>
</tr>
{% endfor %}