diff options
author | Michael Elkins <melkins@tislabs.com> | 2012-11-25 04:21:51 +0000 |
---|---|---|
committer | Michael Elkins <melkins@tislabs.com> | 2012-11-25 04:21:51 +0000 |
commit | 6b24f45e97061a7bafa9af1a7efd21311892bcc4 (patch) | |
tree | 58dc94da6e4168b4a2ea32659c05fa75993144d6 | |
parent | 1b84c1e1febeeb5e0141eb8196b8d7c968d2c514 (diff) |
do not display part of the vcard that are disallowed by RFC
add new roa detail view, displaying covered routes
use {% url %} to get the url instead of hardcoding it in templates
add some missing title params to buttons
remove edit button from generic object detail
modify labels for validation statuses to use the label- suffix required by bootstrap 2.2.x
don't use object_detail for the repository_detail view
remove stub get_absolute_url() methods where they were previously used as placeholders
svn path=/branches/tk329/; revision=4900
-rw-r--r-- | rpkid/portal-gui/settings.py.in | 3 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/forms.py | 18 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/models.py | 8 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/child_detail.html | 3 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/client_detail.html | 24 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/dashboard.html | 11 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/ghostbusterrequest_detail.html | 7 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/object_confirm_delete.html | 4 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/object_detail.html | 3 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/parent_detail.html | 2 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/roa_detail.html | 25 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/user_list.html | 10 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/urls.py | 3 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/views.py | 61 |
14 files changed, 92 insertions, 90 deletions
diff --git a/rpkid/portal-gui/settings.py.in b/rpkid/portal-gui/settings.py.in index 2b87629f..0c939c28 100644 --- a/rpkid/portal-gui/settings.py.in +++ b/rpkid/portal-gui/settings.py.in @@ -107,6 +107,3 @@ TEMPLATE_CONTEXT_PROCESSORS = ( ) STATIC_URL = '/static/' - -# whether or not to force rpkid to run its cron job immediately after a change -RPKID_RUN = False diff --git a/rpkid/rpki/gui/app/forms.py b/rpkid/rpki/gui/app/forms.py index 74874d49..1057ee01 100644 --- a/rpkid/rpki/gui/app/forms.py +++ b/rpkid/rpki/gui/app/forms.py @@ -58,11 +58,6 @@ class GhostbusterRequestForm(forms.ModelForm): parent = forms.ModelChoiceField(queryset=None, required=False, help_text='Specify specific parent, or none for all parents') - # override full_name. it is required in the db schema, but we allow the - # user to skip it and default from family+given name - full_name = forms.CharField(max_length=40, required=False, - help_text='automatically generated from family and given names if left blank') - #override issuer = forms.ModelChoiceField(queryset=None, widget=forms.HiddenInput) @@ -77,14 +72,10 @@ class GhostbusterRequestForm(forms.ModelForm): class Meta: model = models.GhostbusterRequest - exclude = ('vcard') + exclude = ('vcard', 'given_name', 'family_name', 'additional_name', + 'honorific_prefix', 'honorific_suffix') def clean(self): - family_name = self.cleaned_data.get('family_name') - given_name = self.cleaned_data.get('given_name') - if not all([family_name, given_name]): - raise forms.ValidationError('Family and Given names must be specified') - email = self.cleaned_data.get('email_address') postal = self.cleaned_data.get('postal_address') telephone = self.cleaned_data.get('telephone') @@ -92,11 +83,6 @@ class GhostbusterRequestForm(forms.ModelForm): raise forms.ValidationError( 'One of telephone, email or postal address must be specified') - # if the full name is not specified, default to given+family - fn = self.cleaned_data.get('full_name') - if not fn: - self.cleaned_data['full_name'] = '%s %s' % (given_name, family_name) - return self.cleaned_data diff --git a/rpkid/rpki/gui/app/models.py b/rpkid/rpki/gui/app/models.py index 0ed01aa8..2975aa0a 100644 --- a/rpkid/rpki/gui/app/models.py +++ b/rpkid/rpki/gui/app/models.py @@ -119,10 +119,6 @@ class Conf(rpki.irdb.models.ResourceHolderCA): def roas(self): return ROARequest.objects.filter(issuer=self) - @models.permalink - def get_absolute_url(self): - return ('rpki.gui.app.views.user_detail', [str(self.pk)]) - class Meta: proxy = True @@ -184,11 +180,9 @@ class ROARequest(rpki.irdb.models.ROARequest): class ROARequestPrefix(rpki.irdb.models.ROARequestPrefix): class Meta: proxy = True - verbose_name = 'ROA' def __unicode__(self): - return u'ROA request prefix %s for asn %d' % (str(self.as_roa_prefix()), - self.roa_request.asn) + return u'ROA Request Prefix %s' % str(self.as_roa_prefix()) class GhostbusterRequest(rpki.irdb.models.GhostbusterRequest): diff --git a/rpkid/rpki/gui/app/templates/app/child_detail.html b/rpkid/rpki/gui/app/templates/app/child_detail.html index 8d62a278..0c6a4922 100644 --- a/rpkid/rpki/gui/app/templates/app/child_detail.html +++ b/rpkid/rpki/gui/app/templates/app/child_detail.html @@ -47,8 +47,9 @@ {% endblock object_display %} {% block action %} -{{ block.super }} +<a class='btn' href="{% url rpki.gui.app.views.child_edit object.pk %}" title='Edit this child'><i class="icon-edit"></i> Edit</a> <a class='btn' href="{% url rpki.gui.app.views.child_add_asn object.pk %}" title='Delegate an ASN to this child'><i class="icon-plus-sign"></i> AS</a> <a class='btn' href="{% url rpki.gui.app.views.child_add_prefix object.pk %}" title='Delegate a prefix to this child'><i class="icon-plus-sign"></i> Prefix</a> <a class='btn' href="{% url rpki.gui.app.views.child_response object.pk %}" title='Download XML file to send to child'><i class="icon-download"></i> Export</a> +{{ block.super }} {% endblock action %} diff --git a/rpkid/rpki/gui/app/templates/app/client_detail.html b/rpkid/rpki/gui/app/templates/app/client_detail.html index 0638e05b..bb9ea212 100644 --- a/rpkid/rpki/gui/app/templates/app/client_detail.html +++ b/rpkid/rpki/gui/app/templates/app/client_detail.html @@ -2,19 +2,17 @@ {% block object_display %} <div class='row'> - <div class='span2'> - <p><strong>Name</strong> - </div> - <div class='span6'> - <p>{{ object.handle }} - </div> -</div> -<div class='row'> - <div class='span2'> - <p><strong>SIA</strong> - </div> - <div class='span6'> - <p>{{ object.sia_base }} + <div class='span3'> + <table class="table"> + <tr> + <td>Name</td> + <td>{{ object.handle }} </td> + </tr> + <tr> + <td>SIA</td> + <td>{{ object.sia_base }}</td> + </tr> + </table> </div> </div> {% endblock object_display %} diff --git a/rpkid/rpki/gui/app/templates/app/dashboard.html b/rpkid/rpki/gui/app/templates/app/dashboard.html index 71398115..d7a660c4 100644 --- a/rpkid/rpki/gui/app/templates/app/dashboard.html +++ b/rpkid/rpki/gui/app/templates/app/dashboard.html @@ -105,6 +105,7 @@ <td>{{ roa.prefixes.all.0.max_prefixlen }}</td> <td>{{ roa.asn }}</td> <td> + <a class="btn btn-mini" href="{% url rpki.gui.app.views.roa_detail roa.pk %}" title="Detail"><i class="icon-info-sign"></i></a> <a class="btn btn-mini" href="{% url rpki.gui.app.views.roa_delete roa.pk %}" title="Delete"><i class="icon-trash"></i></a> </td> </tr> @@ -126,6 +127,7 @@ <td>{{ gbr.email_address }}</td> <td>{{ gbr.telephone }}</td> <td> + <a class="btn btn-mini" href="{% url gbr-detail gbr.pk %}" title="View"><i class="icon-info-sign"></i></a> <a class="btn btn-mini" href="{% url gbr-edit gbr.pk %}" title="Edit"><i class="icon-edit"></i></a> <a class="btn btn-mini" href="{% url gbr-delete gbr.pk %}" title="Delete"><i class="icon-trash"></i></a> </td> @@ -142,11 +144,12 @@ <h1>Children</h1> </div> <table class="table table-condensed table-striped"> + <tr><th>Handle</th><th></th> {% for child in conf.children %} <tr> <td><a href="{{ child.get_absolute_url }}">{{ child.handle }}</a></td> <td> - <a class="btn btn-mini" href="{% url rpki.gui.app.views.child_delete child.pk %}"><i class="icon-trash"></i></a> + <a class="btn btn-mini" href="{% url rpki.gui.app.views.child_delete child.pk %}" title="Delete"><i class="icon-trash"></i></a> </td> </tr> {% endfor %} @@ -163,7 +166,7 @@ <tr> <td><a href="{{ parent.get_absolute_url }}">{{ parent.handle }}</a></td> <td> - <a class="btn btn-mini" href="{% url rpki.gui.app.views.parent_delete parent.pk %}"><i class="icon-trash"></i></a> + <a class="btn btn-mini" href="{% url rpki.gui.app.views.parent_delete parent.pk %}" title="Delete"><i class="icon-trash"></i></a> </td> </tr> {% endfor %} @@ -183,7 +186,7 @@ <tr> <td><a href="{{ repo.get_absolute_url }}">{{ repo.handle }}</a></td> <td> - <a class="btn btn-mini" href="{% url rpki.gui.app.views.repository_delete repo.pk %}"><i class="icon-trash"></i></a> + <a class="btn btn-mini" href="{% url rpki.gui.app.views.repository_delete repo.pk %}" title="Delete"><i class="icon-trash"></i></a> </td> </tr> {% endfor %} @@ -201,7 +204,7 @@ <tr> <td><a href="{% url rpki.gui.app.views.client_detail client.pk %}">{{ client.handle }}</a></td> <td> - <a class="btn btn-mini" href="{% url rpki.gui.app.views.client_delete client.pk %}"><i class="icon-trash"></i></a> + <a class="btn btn-mini" href="{% url rpki.gui.app.views.client_delete client.pk %}" title="Delete"><i class="icon-trash"></i></a> </td> </tr> {% endfor %} diff --git a/rpkid/rpki/gui/app/templates/app/ghostbusterrequest_detail.html b/rpkid/rpki/gui/app/templates/app/ghostbusterrequest_detail.html index f4cb3c0f..abaa7560 100644 --- a/rpkid/rpki/gui/app/templates/app/ghostbusterrequest_detail.html +++ b/rpkid/rpki/gui/app/templates/app/ghostbusterrequest_detail.html @@ -2,7 +2,7 @@ {% block object_display %} <table class='table table-striped table-condensed'> - <tr><td >Full Name</td><td>{{ object.full_name }}</td></tr> + <tr><td>Full Name</td><td>{{ object.full_name }}</td></tr> {% if object.honorific_prefix %} <tr><td >Honorific Prefix</td><td>{{ object.honorific_prefix }}</td></tr> @@ -50,3 +50,8 @@ </table> {% endblock object_display %} + +{% block action %} +{{ block.super }} +<a class="btn" href="{% url gbr-edit object.pk %}"><i class="icon-edit"></i> Edit</a> +{% endblock %} diff --git a/rpkid/rpki/gui/app/templates/app/object_confirm_delete.html b/rpkid/rpki/gui/app/templates/app/object_confirm_delete.html index da60409e..821b70b5 100644 --- a/rpkid/rpki/gui/app/templates/app/object_confirm_delete.html +++ b/rpkid/rpki/gui/app/templates/app/object_confirm_delete.html @@ -16,7 +16,7 @@ string specifying the concrete template to inherit from. <form action='' method='POST'> {% csrf_token %} - <input class='btn btn-danger' type='submit' value='Confirm'> - <a class='btn' href="{{ object.get_absolute_url }}">Cancel</a> + <input class='btn btn-danger' type='submit' value='Delete'> + <a class='btn' href="{% url rpki.gui.app.views.dashboard %}">Cancel</a> </form> {% endblock %} diff --git a/rpkid/rpki/gui/app/templates/app/object_detail.html b/rpkid/rpki/gui/app/templates/app/object_detail.html index 131e24cc..81fdbdf0 100644 --- a/rpkid/rpki/gui/app/templates/app/object_detail.html +++ b/rpkid/rpki/gui/app/templates/app/object_detail.html @@ -12,8 +12,7 @@ {% endblock object_display %} {% block action %} -<a class="btn" href="{{ object.get_absolute_url }}edit"><i class="icon-edit"></i> Edit</a> -<a class="btn btn-danger" href="{{ object.get_absolute_url }}delete"><i class="icon-trash icon-white"></i> Delete</a> +<a class="btn" href="{{ object.get_absolute_url }}delete" title="Delete this object"><i class="icon-trash"></i> Delete</a> {% endblock action %} {% endblock content %} diff --git a/rpkid/rpki/gui/app/templates/app/parent_detail.html b/rpkid/rpki/gui/app/templates/app/parent_detail.html index 591de843..c50d37e5 100644 --- a/rpkid/rpki/gui/app/templates/app/parent_detail.html +++ b/rpkid/rpki/gui/app/templates/app/parent_detail.html @@ -59,5 +59,5 @@ {% block action %} {{ block.super }} -<a class='btn' href='{{ object.get_absolute_url }}export' title='Download XML to send to repository operator'>Export</a> +<a class='btn' href='{{ object.get_absolute_url }}export' title='Download XML to send to repository operator'><i class="icon-download"></i> Export</a> {% endblock action %} diff --git a/rpkid/rpki/gui/app/templates/app/roa_detail.html b/rpkid/rpki/gui/app/templates/app/roa_detail.html new file mode 100644 index 00000000..5500941f --- /dev/null +++ b/rpkid/rpki/gui/app/templates/app/roa_detail.html @@ -0,0 +1,25 @@ +{% extends "app/object_detail.html" %} + +{% block object_display %} +<div class="row"> + <div class="span3 well"> + <table class="table"> + <tr><th>Prefix</th><th>Max Length</th><th>AS</th></tr> + <tr> + <td>{{ object.prefixes.all.0.as_roa_prefix }}</td> + <td>{{ object.prefixes.all.0.max_prefixlen }}</td> + <td>{{ object.asn }}</td> + </tr> + </table> + </div> + <div class="span2"> + <h3>Covered Routes</h3> + <table class="table"> + <tr><th>Prefix</th><th>AS</th></tr> + {% for r in routes %} + <tr><td>{{ r.as_resource_range }}</td><td>{{ r.asn }}</td></tr> + {% endfor %} + </table> + </div> +</div> +{% endblock %} diff --git a/rpkid/rpki/gui/app/templates/app/user_list.html b/rpkid/rpki/gui/app/templates/app/user_list.html index 607e5a9c..fed943f0 100644 --- a/rpkid/rpki/gui/app/templates/app/user_list.html +++ b/rpkid/rpki/gui/app/templates/app/user_list.html @@ -9,21 +9,19 @@ <tr> <th>Username</th> <th>Email</th> - <th>Action</th> + <th></th> </tr> {% for u in users %} <tr> <td>{{ u.0.handle }}</td> <td>{{ u.1.email }}</td> <td> - <a class='btn small' href='{{ u.0.get_absolute_url }}/edit'>Edit</a> - <a class='btn small danger' href='{{ u.0.get_absolute_url }}/delete'>Delete</a> + <a class='btn btn-small' href='{% url rpki.gui.app.views.user_edit u.0.pk %}' title="Edit"><i class="icon-edit"></i></a> + <a class='btn btn-small' href='{% url rpki.gui.app.views.user_delete u.0.pk %}' title="Delete"><i class="icon-trash"></i></a> </td> </tr> {% endfor %} </table> -<div class='actions'> - <a class='btn' href="{% url rpki.gui.app.views.user_create %}" title="create a new locally hosted resource handle">Create</a> -</div> +<a class='btn' href="{% url rpki.gui.app.views.user_create %}" title="create a new locally hosted resource handle">Create</a> {% endblock content %} diff --git a/rpkid/rpki/gui/app/urls.py b/rpkid/rpki/gui/app/urls.py index 99e0c7dc..c8dfaf1f 100644 --- a/rpkid/rpki/gui/app/urls.py +++ b/rpkid/rpki/gui/app/urls.py @@ -49,15 +49,14 @@ urlpatterns = patterns( (r'^repo/import$', views.repository_import), (r'^repo/(?P<pk>\d+)/$', views.repository_detail), (r'^repo/(?P<pk>\d+)/delete$', views.repository_delete), + (r'^roa/(?P<pk>\d+)/$', views.roa_detail), (r'^roa/create$', views.roa_create), (r'^roa/confirm$', views.roa_create_confirm), (r'^roa/(?P<pk>\d+)/delete$', views.roa_delete), (r'^route/$', views.route_view), - (r'^route/(?P<pk>\d+)/$', views.route_detail), (r'^route/(?P<pk>\d+)/roa/$', views.route_roa_list), (r'^user/$', views.user_list), (r'^user/create$', views.user_create), - (r'^user/(?P<pk>\d+)/$', views.user_detail), (r'^user/(?P<pk>\d+)/delete$', views.user_delete), (r'^user/(?P<pk>\d+)/edit$', views.user_edit), ) diff --git a/rpkid/rpki/gui/app/views.py b/rpkid/rpki/gui/app/views.py index 05d6380b..1a8be108 100644 --- a/rpkid/rpki/gui/app/views.py +++ b/rpkid/rpki/gui/app/views.py @@ -29,11 +29,9 @@ from django.contrib.auth.decorators import login_required from django.shortcuts import get_object_or_404, render from django.utils.http import urlquote from django import http -from django.views.generic.list_detail import object_detail from django.core.urlresolvers import reverse, reverse_lazy from django.contrib.auth.models import User from django.views.generic import DetailView, CreateView, UpdateView, DeleteView -from django.conf import settings from rpki.irdb import Zookeeper, ChildASN, ChildNet from rpki.gui.app import models, forms, glue, range_list @@ -41,7 +39,8 @@ from rpki.resource_set import (resource_range_as, resource_range_ipv4, resource_range_ipv6, roa_prefix_ipv4) from rpki import sundial -from rpki.gui.cacheview.models import ROAPrefixV4, ROAPrefixV6, ROA +from rpki.gui.cacheview.models import ROAPrefixV4, ROA +from rpki.gui.routeview.models import RouteOrigin def superuser_required(f): @@ -321,9 +320,7 @@ def child_add_prefix(request, pk): version = 'IPv4' child.address_ranges.create(start_ip=str(r.min), end_ip=str(r.max), version=version) - z = Zookeeper(handle=conf.handle, logstream=logstream) - if settings.RPKID_RUN: - z.run_rpkid_now() + Zookeeper(handle=conf.handle, logstream=logstream).run_rpkid_now() return http.HttpResponseRedirect(child.get_absolute_url()) else: form = forms.AddNetForm(child=child) @@ -342,9 +339,7 @@ def child_add_asn(request, pk): asns = form.cleaned_data.get('asns') r = resource_range_as.parse_str(asns) child.asns.create(start_as=r.min, end_as=r.max) - if settings.RPKID_RUN: - z = Zookeeper(handle=conf.handle, logstream=logstream) - z.run_rpkid_now() + Zookeeper(handle=conf.handle, logstream=logstream).run_rpkid_now() return http.HttpResponseRedirect(child.get_absolute_url()) else: form = forms.AddASNForm(child=child) @@ -373,8 +368,7 @@ def child_edit(request, pk): # remove AS & prefixes that are not selected in the form models.ChildASN.objects.filter(child=child).exclude(pk__in=form.cleaned_data.get('as_ranges')).delete() models.ChildNet.objects.filter(child=child).exclude(pk__in=form.cleaned_data.get('address_ranges')).delete() - if settings.RPKID_RUN: - Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() + Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() return http.HttpResponseRedirect(child.get_absolute_url()) else: form = form_class(initial={ @@ -425,6 +419,19 @@ def child_delete(request, pk): @handle_required +def roa_detail(request, pk): + conf = request.session['handle'] + obj = get_object_or_404(conf.roas, pk=pk) + pfx = obj.prefixes.all()[0].as_resource_range() + routes = RouteOrigin.objects.filter(prefix_min__gte=pfx.min, + prefix_max__lte=pfx.max) + return render(request, 'app/roa_detail.html', { + 'object': obj, + 'routes': routes, + }) + + +@handle_required def roa_create(request): """Present the user with a form to create a ROA. @@ -507,8 +514,7 @@ def roa_create_confirm(request): roa.prefixes.create(version=v, prefix=str(rng.min), prefixlen=rng.prefixlen(), max_prefixlen=max_prefixlen) - if settings.RPKID_RUN: - Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() + Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() return http.HttpResponseRedirect(reverse(dashboard)) # What should happen when the submission form isn't valid? For now # just fall through and redirect back to the ROA creation form @@ -528,8 +534,7 @@ def roa_delete(request, pk): roa = get_object_or_404(conf.roas, pk=pk) if request.method == 'POST': roa.delete() - if settings.RPKID_RUN: - Zookeeper(handle=conf.handle).run_rpkid_now() + Zookeeper(handle=conf.handle).run_rpkid_now() return http.HttpResponseRedirect(reverse(dashboard)) ### Process GET ### @@ -620,7 +625,9 @@ def roa_match(rng): pfx = 'prefixes' rv = [] - for obj in route_manager.filter(prefix_min__gte=rng.min, prefix_max__lte=rng.max): + # return a max of 50 routes + for obj in route_manager.filter(prefix_min__gte=rng.min, + prefix_max__lte=rng.max)[:50]: # This is a bit of a gross hack, since the foreign keys for v4 and v6 # prefixes have different names. args = {'%s__prefix_min__lte' % pfx: obj.prefix_min, @@ -646,17 +653,17 @@ def validate_route(route, roas): # 2. if the candidate ROA set is empty, end with unknown if not roas.exists(): route.status = 'unknown' - route.status_label = 'warning' + route.status_label = 'label-warning' # 3. if any candidate roa matches the origin AS and max_length, end with # valid # # AS0 is always invalid. elif route.asn != 0 and roas.filter(**args).exists(): - route.status_label = 'success' + route.status_label = 'label-success' route.status = 'valid' # 4. otherwise the route is invalid else: - route.status_label = 'important' + route.status_label = 'label-important' route.status = 'invalid' return route @@ -687,10 +694,6 @@ def route_view(request): {'routes': routes, 'timestamp': ts}) -def route_detail(request, pk): - pass - - def route_roa_list(request, pk): """Show a list of ROAs that match a given route.""" object = get_object_or_404(models.RouteOrigin, pk=pk) @@ -703,9 +706,9 @@ def route_roa_list(request, pk): @handle_required def repository_detail(request, pk): conf = request.session['handle'] - qs = models.Repository.objects.filter(issuer=conf) - return object_detail(request, queryset=qs, object_id=pk, - template_name='app/repository_detail.html') + return render(request, + 'app/repository_detail.html', + {'object': get_object_or_404(conf.repositories, pk=pk)}) @handle_required @@ -798,12 +801,6 @@ def user_list(request): @superuser_required -def user_detail(request): - """Placeholder for Conf.get_absolute_url().""" - pass - - -@superuser_required def user_delete(request, pk): conf = models.Conf.objects.get(pk=pk) log = request.META['wsgi.errors'] |