diff options
-rw-r--r-- | rpkid/Makefile.in | 5 | ||||
-rw-r--r-- | rpkid/portal-gui/settings.py.in | 3 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/forms.py | 4 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/glue.py | 2 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/models.py | 12 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/app_base.html | 2 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/app_form.html | 2 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/child_detail.html | 6 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/client_detail.html | 4 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/dashboard.html | 70 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/object_detail.html | 2 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html | 53 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/roarequest_confirm_form.html | 2 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/urls.py | 4 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/views.py | 141 |
15 files changed, 170 insertions, 142 deletions
diff --git a/rpkid/Makefile.in b/rpkid/Makefile.in index 0141a3fd..e12ec350 100644 --- a/rpkid/Makefile.in +++ b/rpkid/Makefile.in @@ -56,7 +56,7 @@ BUILD_SCRIPTS = portal-gui/scripts/rpkigui-reset-demo AUX_SCRIPTS = -SETTINGS = portal-gui/settings.py rpki/gui/app/settings.py portal-gui/rpki.wsgi +SETTINGS = portal-gui/settings.py portal-gui/rpki.wsgi all:: ${POW_SO} rpki/relaxng.py myrpki.rng rpki/sql_schemas.py ${SCRIPTS} ${AUX_SCRIPTS} ${SETTINGS} ${BUILD_SCRIPTS} @@ -254,9 +254,6 @@ portal-gui/rpki.wsgi: ${srcdir}/portal-gui/rpki.wsgi.in portal-gui/settings.py: ${srcdir}/portal-gui/settings.py.in ${COMPILE_SETTINGS} -rpki/gui/app/settings.py: ${srcdir}/rpki/gui/app/settings.py.in - ${COMPILE_SETTINGS} - portal-gui/scripts/rpki-manage: ${srcdir}/portal-gui/scripts/rpki-manage.in sed -e "s|@DJANGO""_ADMIN@|${DJANGO_ADMIN}|" \ -e "s|@PYTHON""PATH@|${sysconfdir}/rpki|" \ diff --git a/rpkid/portal-gui/settings.py.in b/rpkid/portal-gui/settings.py.in index 0c939c28..2b87629f 100644 --- a/rpkid/portal-gui/settings.py.in +++ b/rpkid/portal-gui/settings.py.in @@ -107,3 +107,6 @@ 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 810279c2..74874d49 100644 --- a/rpkid/rpki/gui/app/forms.py +++ b/rpkid/rpki/gui/app/forms.py @@ -398,6 +398,6 @@ def ChildForm(instance): return _wrapped -class UserDeleteForm(forms.Form): - """Stub form for deleting users.""" +class Empty(forms.Form): + """Stub form for views requiring confirmation.""" pass diff --git a/rpkid/rpki/gui/app/glue.py b/rpkid/rpki/gui/app/glue.py index b50bc557..cad48147 100644 --- a/rpkid/rpki/gui/app/glue.py +++ b/rpkid/rpki/gui/app/glue.py @@ -109,6 +109,7 @@ def list_received_resources(log, conf): else: print >>log, "error: unexpected pdu from rpkid type=%s" % type(pdu) + def str_to_resource_range(prefix): try: r = resource_range_ipv4.parse_str(prefix) @@ -116,6 +117,7 @@ def str_to_resource_range(prefix): r = resource_range_ipv6.parse_str(prefix) return r + def get_email_list(conf): """Return a list of the contact emails for this user. diff --git a/rpkid/rpki/gui/app/models.py b/rpkid/rpki/gui/app/models.py index 27ed9f15..0ed01aa8 100644 --- a/rpkid/rpki/gui/app/models.py +++ b/rpkid/rpki/gui/app/models.py @@ -115,6 +115,10 @@ class Conf(rpki.irdb.models.ResourceHolderCA): def repositories(self): return Repository.objects.filter(issuer=self) + @property + 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)]) @@ -172,6 +176,10 @@ class ROARequest(rpki.irdb.models.ROARequest): def __unicode__(self): return u"%s's ROA request for AS%d" % (self.issuer.handle, self.asn) + @models.permalink + def get_absolute_url(self): + return ('rpki.gui.app.views.roa_detail', [str(self.pk)]) + class ROARequestPrefix(rpki.irdb.models.ROARequestPrefix): class Meta: @@ -182,10 +190,6 @@ class ROARequestPrefix(rpki.irdb.models.ROARequestPrefix): return u'ROA request prefix %s for asn %d' % (str(self.as_roa_prefix()), self.roa_request.asn) - @models.permalink - def get_absolute_url(self): - return ('rpki.gui.app.views.roa_detail', [str(self.pk)]) - class GhostbusterRequest(rpki.irdb.models.GhostbusterRequest): """ diff --git a/rpkid/rpki/gui/app/templates/app/app_base.html b/rpkid/rpki/gui/app/templates/app/app_base.html index 93a1d988..d01130d5 100644 --- a/rpkid/rpki/gui/app/templates/app/app_base.html +++ b/rpkid/rpki/gui/app/templates/app/app_base.html @@ -4,7 +4,7 @@ {% block sidebar %} -<h2><i class="icon-user"></i> {{ request.session.handle }}</h2> +<h2>{{ request.session.handle }}</h2> {# common navigation #} diff --git a/rpkid/rpki/gui/app/templates/app/app_form.html b/rpkid/rpki/gui/app/templates/app/app_form.html index b23183e0..6b4b26b9 100644 --- a/rpkid/rpki/gui/app/templates/app/app_form.html +++ b/rpkid/rpki/gui/app/templates/app/app_form.html @@ -11,7 +11,7 @@ {{ form|crispy }} <div class='form-actions'> <input class='btn btn-primary' type='submit' value='Save'> - <a class='btn' href="{% if cancel_url %}{{ cancel_url }}{% else %}{% url rpki.gui.app.views.dashboard %}{% endif %}">Cancel</a> + <a class='btn' href="{% url rpki.gui.app.views.dashboard %}">Cancel</a> </div> </form> {% endblock %} diff --git a/rpkid/rpki/gui/app/templates/app/child_detail.html b/rpkid/rpki/gui/app/templates/app/child_detail.html index 9776c30b..8d62a278 100644 --- a/rpkid/rpki/gui/app/templates/app/child_detail.html +++ b/rpkid/rpki/gui/app/templates/app/child_detail.html @@ -48,7 +48,7 @@ {% block action %} {{ block.super }} -<a class='btn' href="{{ object.get_absolute_url }}add_asn" title='Delegate an ASN to this child'>+AS</a> -<a class='btn' href="{{ object.get_absolute_url }}add_address" title='Delegate a prefix to this child'>+Prefix</a> -<a class='btn' href="{{ object.get_absolute_url }}export" title='Download XML file to send to child'><i class="icon-download"></i> Export</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> {% 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 4755fbca..0638e05b 100644 --- a/rpkid/rpki/gui/app/templates/app/client_detail.html +++ b/rpkid/rpki/gui/app/templates/app/client_detail.html @@ -1,6 +1,6 @@ {% extends "app/object_detail.html" %} -{% block object_detail %} +{% block object_display %} <div class='row'> <div class='span2'> <p><strong>Name</strong> @@ -17,4 +17,4 @@ <p>{{ object.sia_base }} </div> </div> -{% endblock object_detail %} +{% endblock object_display %} diff --git a/rpkid/rpki/gui/app/templates/app/dashboard.html b/rpkid/rpki/gui/app/templates/app/dashboard.html index 0662e75b..71398115 100644 --- a/rpkid/rpki/gui/app/templates/app/dashboard.html +++ b/rpkid/rpki/gui/app/templates/app/dashboard.html @@ -4,10 +4,6 @@ <ul class='unstyled'> <li><a href="{% url rpki.gui.app.views.conf_export %}" title="download XML identity to send to parent"><i class="icon-download"></i> export identity</a></li> </ul> - -<ul class='unstyled'> - <li> -</ul> {% endblock sidebar_extra %} {% block content %} @@ -101,12 +97,16 @@ <h1>ROA Requests</h1> </div> <table class="table table-condensed table-striped"> - <tr><th>Prefix</th><th>Max Length</th><th>AS</th></tr> + <tr><th>Prefix</th><th>Max Length</th><th>AS</th><th></th></tr> {% for roa in conf.roas %} <tr> - <td>{{ roa.prefixes.0.prefix }}/{{ roa.prefixes.0.prefixlen }}</td> - <td>{{ roa.prefixes.0.max_prefixlen }}</td> + <!-- each roa request has a single roa request prefix object associated --> + <td>{{ roa.prefixes.all.0.as_roa_prefix }}</td> + <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_delete roa.pk %}" title="Delete"><i class="icon-trash"></i></a> + </td> </tr> {% endfor %} </table> @@ -118,14 +118,17 @@ <h1>Ghostbuster Requests</h1> </div> <table class="table table-condensed table-striped"> - <tr><th>Full Name</th><th>Organization</th><th>Email</th><th>Telephone</th></tr> + <tr><th>Full Name</th><th>Organization</th><th>Email</th><th>Telephone</th><th></th></tr> {% for gbr in conf.ghostbusters %} <tr> <td>{{ gbr.full_name }}</td> <td>{{ gbr.organization }}</td> <td>{{ gbr.email_address }}</td> <td>{{ gbr.telephone }}</td> - <td><a href="{{ gbr.get_absolute_url }}"><i class="icon-edit"></i> edit</a></td> + <td> + <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> </tr> {% endfor %} </table> @@ -138,22 +141,33 @@ <div class="page-header"> <h1>Children</h1> </div> - <ul> +<table class="table table-condensed table-striped"> {% for child in conf.children %} - <li><a href="{{ child.get_absolute_url }}">{{ child.handle }}</a></li> + <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> + </td> + </tr> {% endfor %} - </ul> + </table> <a class="btn" href="{% url rpki.gui.app.views.child_import %}"><i class="icon-upload"></i> Import</a> </div><!-- /span --> <div class="span5"> <div class="page-header"> <h1>Parents</h1> </div> - <ul> +<table class="table table-condensed table-striped"> + <tr><th>Handle</th><th></th></tr> {% for parent in conf.parents %} - <li><a href="{{ parent.get_absolute_url }}">{{ parent.handle }}</a></li> + <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> + </td> + </tr> {% endfor %} - </ul> + </table> <a class="btn" href="{% url rpki.gui.app.views.parent_import %}"><i class="icon-upload"></i> Import</a> </div><!-- /span --> </div><!-- /row --> @@ -163,11 +177,17 @@ <div class="page-header"> <h1>Repositories</h1> </div> - <ul> +<table class="table table-condensed table-striped"> + <tr><th>Handle</th><th></th></tr> {% for repo in conf.repositories %} - <li><a href="{{ repo.get_absolute_url }}">{{ repo.handle }}</a></li> + <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> + </td> + </tr> {% endfor %} - </ul> + </table> <a class="btn" href="{% url rpki.gui.app.views.repository_import %}"><i class="icon-upload"></i> Import</a> </div><!-- /span --> {% if request.user.is_superuser %} @@ -175,9 +195,17 @@ <div class="page-header"> <h1>Repository Clients</h1> </div> - <ul> - <li>TODO</li> - </ul> +<table class="table table-condensed table-striped"> + <tr><th>Handle</th><th></th></tr> + {% for client in clients %} + <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> + </td> + </tr> + {% endfor %} + </table> <a class="btn" href="{% url rpki.gui.app.views.client_import %}"><i class="icon-upload"></i> Import</a> </div><!-- /span --> {% endif %} diff --git a/rpkid/rpki/gui/app/templates/app/object_detail.html b/rpkid/rpki/gui/app/templates/app/object_detail.html index 2b91ff87..131e24cc 100644 --- a/rpkid/rpki/gui/app/templates/app/object_detail.html +++ b/rpkid/rpki/gui/app/templates/app/object_detail.html @@ -13,7 +13,7 @@ {% 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-remove icon-white"></i> Delete</a> +<a class="btn btn-danger" href="{{ object.get_absolute_url }}delete"><i class="icon-trash icon-white"></i> Delete</a> {% endblock action %} {% endblock content %} diff --git a/rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html b/rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html index 522ad97c..4a4bce71 100644 --- a/rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html +++ b/rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html @@ -2,40 +2,43 @@ {% block content %} <div class='page-header'> -<h1>Delete ROA Prefix</h1> + <h1>Delete ROA Request</h1> </div> <div class='row'> - <div class='span8'> - <div class='alert-message block-message warning'> - <p><strong>Please confirm</strong> that you would like to delete the following ROA Request. The table to the right indicates how validation status for matching routes may change. + <div class='span5'> + <div class='alert alert-block alert-warning'> + <p><strong>Please confirm</strong> that you would like to delete the + following ROA Request. The table to the right indicates how validation + status for matching routes may change. + </div> - <table style='table table-striped table-condensed'> - <tr> - <th>Prefix</th> - <th>Max Length</th> - <th>AS</th> - <tr> - <td>{{ object.prefix }}/{{ object.prefixlen }}</td> - <td>{{ object.max_prefixlen }}</td> - <td>{{ object.roa_request.asn }}</td> - </tr> - </table> + <table class='table'> + <tr> + <th>Prefix</th> + <td>{{ object.prefixes.all.0.as_roa_prefix }}</td> + </tr> + <tr> + <th>Max Length</th> + <td>{{ object.prefixes.all.0.max_prefixlen }}</td> + </tr> + <tr> + <th>AS</th> + <td>{{ object.asn }}</td> + </tr> + </table> - <form method='POST' action='{{ request.get_full_path }}'> - {% csrf_token %} - <div class='alert-actions'> - <input class='btn danger' type='submit' value='Delete'/> - <a class='btn' href="{% url rpki.gui.app.views.roa_list %}">Cancel</a> - </div> - </form> - </div> + <form method='POST' action='{{ request.get_full_path }}'> + {% csrf_token %} + <input class='btn btn-danger' type='submit' value='Delete'/> + <a class='btn' href="{% url rpki.gui.app.views.dashboard %}">Cancel</a> + </form> </div> - <div class='span8'> + <div class='span5'> <h2>Matching Routes</h2> - <table style='table table-striped table-condensed'> + <table class='table table-striped table-condensed'> <tr> <th>Prefix</th> <th>Origin AS</th> diff --git a/rpkid/rpki/gui/app/templates/app/roarequest_confirm_form.html b/rpkid/rpki/gui/app/templates/app/roarequest_confirm_form.html index d8f05f92..18b4ce30 100644 --- a/rpkid/rpki/gui/app/templates/app/roarequest_confirm_form.html +++ b/rpkid/rpki/gui/app/templates/app/roarequest_confirm_form.html @@ -31,7 +31,7 @@ <div class='form-actions'> <input class='btn btn-primary' type='submit' value='Create'/> - <a class='btn' href='{% url rpki.gui.app.views.roa_list %}'>Cancel</a> + <a class='btn' href='{% url rpki.gui.app.views.dashboard %}'>Cancel</a> </div> </form> </div><!-- /alert-message --> diff --git a/rpkid/rpki/gui/app/urls.py b/rpkid/rpki/gui/app/urls.py index dc625222..99e0c7dc 100644 --- a/rpkid/rpki/gui/app/urls.py +++ b/rpkid/rpki/gui/app/urls.py @@ -18,7 +18,8 @@ __version__ = '$Id$' from django.conf.urls.defaults import * from rpki.gui.app import views -urlpatterns = patterns('', +urlpatterns = patterns( + '', (r'^$', views.dashboard), (r'^conf/export$', views.conf_export), (r'^conf/list$', views.conf_list), @@ -50,7 +51,6 @@ urlpatterns = patterns('', (r'^repo/(?P<pk>\d+)/delete$', views.repository_delete), (r'^roa/create$', views.roa_create), (r'^roa/confirm$', views.roa_create_confirm), - (r'^roa/(?P<pk>\d+)/$', views.roa_detail), (r'^roa/(?P<pk>\d+)/delete$', views.roa_delete), (r'^route/$', views.route_view), (r'^route/(?P<pk>\d+)/$', views.route_detail), diff --git a/rpkid/rpki/gui/app/views.py b/rpkid/rpki/gui/app/views.py index 0df25311..05d6380b 100644 --- a/rpkid/rpki/gui/app/views.py +++ b/rpkid/rpki/gui/app/views.py @@ -33,6 +33,7 @@ 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 @@ -148,7 +149,6 @@ def generic_import(request, queryset, configure, form_class=None, @handle_required def dashboard(request): - log = request.META['wsgi.errors'] conf = request.session['handle'] used_asns = range_list.RangeList() @@ -198,6 +198,8 @@ def dashboard(request): unused_prefixes = my_prefixes.difference(used_prefixes) unused_prefixes_v6 = my_prefixes_v6.difference(used_prefixes_v6) + clients = models.Client.objects.all() if request.user.is_superuser else None + return render(request, 'app/dashboard.html', { 'conf': conf, 'unused_asns': unused_asns, @@ -206,6 +208,7 @@ def dashboard(request): 'asns': asns, 'prefixes': prefixes, 'prefixes_v6': prefixes_v6, + 'clients': clients, }) @@ -269,20 +272,20 @@ def parent_delete(request, pk): conf = request.session['handle'] obj = get_object_or_404(conf.parents, pk=pk) # confirm permission log = request.META['wsgi.errors'] - form_class = forms.UserDeleteForm if request.method == 'POST': - form = form_class(request.POST, request.FILES) + form = forms.Empty(request.POST, request.FILES) if form.is_valid(): z = Zookeeper(handle=conf.handle, logstream=log) z.delete_parent(obj.handle) - z.synchronize() + z.synchronize(conf.handle) return http.HttpResponseRedirect(reverse(dashboard)) else: - form = form_class() - return render(request, 'app/object_confirm_delete.html', - {'object': obj, - 'form': form, - 'parent_template': 'app/parent_detail.html'}) + form = forms.Empty() + return render(request, 'app/object_confirm_delete.html', { + 'object': obj, + 'form': form, + 'parent_template': 'app/parent_detail.html' + }) @handle_required @@ -307,7 +310,7 @@ def child_add_prefix(request, pk): conf = request.session['handle'] child = get_object_or_404(conf.children, pk=pk) if request.method == 'POST': - form = forms.AddNetForm(request.GET, child=child) + form = forms.AddNetForm(request.POST, child=child) if form.is_valid(): address_range = form.cleaned_data.get('address_range') if ':' in address_range: @@ -319,7 +322,8 @@ def child_add_prefix(request, pk): child.address_ranges.create(start_ip=str(r.min), end_ip=str(r.max), version=version) z = Zookeeper(handle=conf.handle, logstream=logstream) - z.run_rpkid_now() + if settings.RPKID_RUN: + z.run_rpkid_now() return http.HttpResponseRedirect(child.get_absolute_url()) else: form = forms.AddNetForm(child=child) @@ -333,16 +337,17 @@ def child_add_asn(request, pk): conf = request.session['handle'] child = get_object_or_404(conf.children, pk=pk) if request.method == 'POST': - form = forms.AddASNForm(request.GET, child=child) + form = forms.AddASNForm(request.POST, child=child) if form.is_valid(): asns = form.cleaned_data.get('asns') r = resource_range_as.parse_str(asns) child.asns.create(start_as=r.min, end_as=r.max) - z = Zookeeper(handle=conf.handle, logstream=logstream) - z.run_rpkid_now() + if settings.RPKID_RUN: + z = Zookeeper(handle=conf.handle, logstream=logstream) + z.run_rpkid_now() return http.HttpResponseRedirect(child.get_absolute_url()) else: - form = forms.AddNetForm(child=child) + form = forms.AddASNForm(child=child) return render(request, 'app/app_form.html', {'object': child, 'form': form}) @@ -368,7 +373,8 @@ 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() - Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() + if settings.RPKID_RUN: + Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() return http.HttpResponseRedirect(child.get_absolute_url()) else: form = form_class(initial={ @@ -397,33 +403,20 @@ def child_response(request, pk): return resp -class GenericDeleteView(DeleteView): - """Subclasses should implement the get_queryset() method. - - """ - template_name = 'app/object_confirm_delete.html' - success_url = reverse_lazy(dashboard) - - def get_context_data(self, **kwargs): - context = super(GenericDeleteView, self).get_context_data(**kwargs) - context['parent_template'] = 'app/%s_detail.html' % self.object.__class__.__name__.lower() - return context - - @handle_required def child_delete(request, pk): logstream = request.META['wsgi.errors'] conf = request.session['handle'] child = get_object_or_404(conf.children, pk=pk) if request.method == 'POST': - form = forms.Form(request.POST) + form = forms.Empty(request.POST) if form.is_valid(): z = Zookeeper(handle=conf.handle, logstream=logstream) z.delete_child(child.handle) - z.synchronize() + z.synchronize(conf.handle) return http.HttpResponseRedirect(reverse(dashboard)) else: - form = forms.Form() + form = forms.Empty() return render(request, 'app/object_confirm_delete.html', { 'object': child, 'form': form, @@ -463,16 +456,16 @@ def roa_create(request): # if the AS matches, it is valid, otherwise invalid if (route.asn != 0 and route.asn == asn and route.prefixlen() <= max_prefixlen): route.status = 'valid' - route.status_label = 'success' + route.status_label = 'label-success' else: route.status = 'invalid' - route.status_label = 'important' + route.status_label = 'label-important' elif route.status == 'invalid': # if the route was previously invalid, but this new ROA # matches the ASN, it is now valid if route.asn != 0 and route.asn == asn and route.prefixlen() <= max_prefixlen: route.status = 'valid' - route.status_label = 'success' + route.status_label = 'label-success' routes.append(route) @@ -514,7 +507,8 @@ def roa_create_confirm(request): roa.prefixes.create(version=v, prefix=str(rng.min), prefixlen=rng.prefixlen(), max_prefixlen=max_prefixlen) - Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() + if settings.RPKID_RUN: + 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 @@ -522,20 +516,8 @@ def roa_create_confirm(request): @handle_required -def roa_detail(request, pk): - """Not implemented. - - This is a placeholder so that - models.ROARequestPrefix.get_absolute_url works. The only reason it - exist is so that the /delete URL works. - - """ - pass - - -@handle_required def roa_delete(request, pk): - """Handles deletion of a single ROARequestPrefix object. + """Handles deletion of a single ROARequest object. Uses a form for double confirmation, displaying how the route validation status may change as a result. @@ -543,23 +525,17 @@ def roa_delete(request, pk): """ conf = request.session['handle'] - obj = get_object_or_404(models.ROARequestPrefix.objects, - roa_request__issuer=conf, pk=pk) - + roa = get_object_or_404(conf.roas, pk=pk) if request.method == 'POST': - roa = obj.roa_request - obj.delete() - # if this was the last prefix on the ROA, delete the ROA request - if not roa.prefixes.exists(): - roa.delete() - Zookeeper(handle=conf.handle).run_rpkid_now() + roa.delete() + if settings.RPKID_RUN: + Zookeeper(handle=conf.handle).run_rpkid_now() return http.HttpResponseRedirect(reverse(dashboard)) ### Process GET ### - - match = roa_match(obj.as_resource_range()) - + obj = roa.prefixes.all()[0] roa_pfx = obj.as_roa_prefix() + match = roa_match(obj.as_resource_range()) pfx = 'prefixes' if isinstance(roa_pfx, roa_prefix_ipv4) else 'prefixes_v6' args = {'%s__prefix_min' % pfx: roa_pfx.min(), @@ -569,12 +545,12 @@ def roa_delete(request, pk): # exclude ROAs which seem to match this request and display the result routes = [] for route, roas in match: - qs = roas.exclude(asid=obj.roa_request.asn, **args) + qs = roas.exclude(asid=roa.asn, **args) validate_route(route, qs) routes.append(route) return render(request, 'app/roa_request_confirm_delete.html', - {'object': obj, 'routes': routes}) + {'object': roa, 'routes': routes}) class GhostbusterDetailView(DetailView): @@ -582,6 +558,19 @@ class GhostbusterDetailView(DetailView): return self.request.session['handle'].ghostbusters +class GenericDeleteView(DeleteView): + """Subclasses should implement the get_queryset() method. + + """ + template_name = 'app/object_confirm_delete.html' + success_url = reverse_lazy(dashboard) + + def get_context_data(self, **kwargs): + context = super(GenericDeleteView, self).get_context_data(**kwargs) + context['parent_template'] = 'app/%s_detail.html' % self.object.__class__.__name__.lower() + return context + + class GhostbusterDeleteView(GenericDeleteView): def get_queryset(self): return self.request.session['handle'].ghostbusters @@ -725,16 +714,15 @@ def repository_delete(request, pk): conf = request.session['handle'] # Ensure the repository being deleted belongs to the current user. obj = get_object_or_404(models.Repository, issuer=conf, pk=pk) - form_class = forms.UserDeleteForm # FIXME if request.method == 'POST': - form = form_class(request.POST, request.FILES) + form = forms.Empty(request.POST, request.FILES) if form.is_valid(): z = Zookeeper(handle=conf.handle, logstream=log) z.delete_repository(obj.handle) - z.synchronize() + z.synchronize(conf.handle) return http.HttpResponseRedirect(reverse(dashboard)) else: - form = form_class() + form = forms.Empty() return render(request, 'app/repository_detail.html', {'object': obj, 'form': form, 'confirm_delete': True}) @@ -751,25 +739,28 @@ def repository_import(request): @superuser_required def client_detail(request, pk): - return object_detail(request, queryset=models.Client.objects, object_id=pk) + return render(request, 'app/client_detail.html', + {'object': get_object_or_404(models.Client, pk=pk)}) @superuser_required def client_delete(request, pk): log = request.META['wsgi.errors'] obj = get_object_or_404(models.Client, pk=pk) - form_class = forms.UserDeleteForm # FIXME if request.method == 'POST': - form = form_class(request.POST, request.FILES) + form = forms.Empty(request.POST, request.FILES) if form.is_valid(): z = Zookeeper(logstream=log) z.delete_publication_client(obj.handle) z.synchronize() return http.HttpResponseRedirect(reverse(dashboard)) else: - form = form_class() - return render(request, 'app/client_detail.html', - {'object': obj, 'form': form, 'confirm_delete': True}) + form = forms.Empty() + return render(request, 'app/object_confirm_delete.html', { + 'object': obj, + 'form': form, + 'parent_template': 'app/client_detail.html' + }) @superuser_required @@ -817,7 +808,7 @@ def user_delete(request, pk): conf = models.Conf.objects.get(pk=pk) log = request.META['wsgi.errors'] if request.method == 'POST': - form = forms.UserDeleteForm(request.POST) + form = forms.Empty(request.POST) if form.is_valid(): User.objects.filter(username=conf.handle).delete() z = Zookeeper(handle=conf.handle, logstream=log) @@ -825,7 +816,7 @@ def user_delete(request, pk): z.synchronize() return http.HttpResponseRedirect(reverse(user_list)) else: - form = forms.UserDeleteForm() + form = forms.Empty() return render(request, 'app/user_confirm_delete.html', {'object': conf, 'form': form}) |