diff options
Diffstat (limited to 'rpkid/rpki/gui/cacheview')
-rw-r--r-- | rpkid/rpki/gui/cacheview/admin.py | 14 | ||||
-rw-r--r-- | rpkid/rpki/gui/cacheview/models.py | 51 | ||||
-rw-r--r-- | rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html | 23 | ||||
-rw-r--r-- | rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html | 19 |
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 %} |