diff options
Diffstat (limited to 'rpki/gui')
-rw-r--r-- | rpki/gui/app/forms.py | 2 | ||||
-rw-r--r-- | rpki/gui/app/models.py | 25 | ||||
-rw-r--r-- | rpki/gui/app/templates/app/roarequest_confirm_multi_form.html | 37 | ||||
-rw-r--r-- | rpki/gui/app/templates/app/roarequest_multi_form.html | 11 | ||||
-rw-r--r-- | rpki/gui/app/views.py | 14 |
5 files changed, 65 insertions, 24 deletions
diff --git a/rpki/gui/app/forms.py b/rpki/gui/app/forms.py index f173c15d..a1214297 100644 --- a/rpki/gui/app/forms.py +++ b/rpki/gui/app/forms.py @@ -193,7 +193,7 @@ def ROARequestFormFactory(conf): 'class': 'span1' }) ) - confirmed = forms.BooleanField(widget=forms.HiddenInput, required=False) + protect_children = forms.BooleanField(required=False) def __init__(self, *args, **kwargs): kwargs['auto_id'] = False diff --git a/rpki/gui/app/models.py b/rpki/gui/app/models.py index d3b0733d..40bdbe2c 100644 --- a/rpki/gui/app/models.py +++ b/rpki/gui/app/models.py @@ -18,6 +18,7 @@ __version__ = '$Id$' from django.db import models from django.contrib.auth.models import User from django.core.mail import send_mail +from django.db.models import Q import rpki.resource_set import rpki.exceptions @@ -65,6 +66,15 @@ class Child(rpki.irdb.models.Child): proxy = True verbose_name_plural = 'children' + @property + def routes(self): + "Return a list of RouteOrigin objects (potentially) originated by this child." + query = Q() + for r in self.address_ranges.filter(version='IPv4'): + rng = r.as_resource_range() + query |= Q(prefix_min__gte=rng.min, prefix_max__lte=rng.max) + return RouteOrigin.objects.filter(query) + class ChildASN(rpki.irdb.models.ChildASN): """Proxy model for irdb ChildASN.""" @@ -130,8 +140,21 @@ class Conf(rpki.irdb.models.ResourceHolderCA): """Simulates irdb.models.Child.objects, but returns app.models.Child proxy objects. + When running rootd, we need to exclude the Child object for self. + + """ + return Child.objects.filter(issuer=self).exclude(handle=self.handle) + + @property + def child_routes(self): + """Return currently announced routes for prefixes covered by child + sub-allocations. """ - return Child.objects.filter(issuer=self) + query = Q() + for pfx in ChildNet.objects.filter(child__issuer=self, version='IPv4'): + rng = pfx.as_resource_range() + query |= Q(prefix_min__gte=rng.min, prefix_max__lte=rng.max) + return RouteOrigin.objects.filter(query) @property def ghostbusters(self): diff --git a/rpki/gui/app/templates/app/roarequest_confirm_multi_form.html b/rpki/gui/app/templates/app/roarequest_confirm_multi_form.html index 4a06a4aa..d1d8171f 100644 --- a/rpki/gui/app/templates/app/roarequest_confirm_multi_form.html +++ b/rpki/gui/app/templates/app/roarequest_confirm_multi_form.html @@ -1,5 +1,4 @@ {% extends "app/app_base.html" %} -{% load url from future %} {% load app_extras %} {% block content %} @@ -9,17 +8,20 @@ <div class='row-fluid'> <div class='span6'> - <div class='alert alert-block-message alert-warning'> - <p><strong>Please confirm</strong> that you would like to create the following ROA(s). + <div class='alert'> + <strong>Please confirm</strong> that you would like to create the following ROA(s). The accompanying table indicates how the validation status may change as a result. </div> <table class='table table-condensed table-striped'> - <tr> - <th>Prefix</th> - <th>Max Length</th> - <th>AS</th> - </tr> + <thead> + <tr> + <th>Prefix</th> + <th>Max Length</th> + <th>AS</th> + </tr> + </thead> + <tbody> {% for roa in roas %} <tr> <td>{{ roa.prefix }}</td> @@ -27,6 +29,7 @@ <td>{{ roa.asn }}</td> </tr> {% endfor %} + </tbody> </table> <form method='POST' action='{% url "rpki.gui.app.views.roa_create_multi_confirm" %}'> @@ -47,18 +50,22 @@ <h2>Matched Routes</h2> <table class='table table-striped table-condensed'> - <tr> - <th>Prefix</th> - <th>Origin AS</th> - <th>Validation Status</th> - </tr> + <thead> + <tr> + <th>Prefix</th> + <th>Origin AS</th> + <th>Validation Status</th> + </tr> + </thead> + <tbody> {% for r in routes %} <tr> - <td>{{ r.get_prefix_display }}</td> - <td>{{ r.asn }}</td> + <td>{{ r.get_prefix_display }}</td> + <td>{{ r.asn }}</td> <td>{% validity_label r.newstatus %}</td> </tr> {% endfor %} + </tbody> </table> </div> diff --git a/rpki/gui/app/templates/app/roarequest_multi_form.html b/rpki/gui/app/templates/app/roarequest_multi_form.html index 0fbc49ae..ed2135ed 100644 --- a/rpki/gui/app/templates/app/roarequest_multi_form.html +++ b/rpki/gui/app/templates/app/roarequest_multi_form.html @@ -1,27 +1,28 @@ {% extends "app/app_base.html" %} -{% load url from future %} {% block content %} <div class='page-title'> <h1>Create ROAs</h1> </div> -<form method='POST' action='{{ request.get_full_path }}'> +<form class='form-inline' method='POST' action='{{ request.get_full_path }}'> {% csrf_token %} {{ formset.management_form }} {% for form in formset %} - <div class="controls controls-row"> + {{ form.prefix }} {{ form.max_prefixlen }} {{ form.asn }} + <label class="checkbox" title='create additional ROAs for child routes'>{{ form.protect_children }} Protect children</label> + {# <label class="checkbox inline span1">{{ form.DELETE }} Delete</label> #} {% if form.errors %}<span class="help-inline">{{ form.errors }}</span>{% endif %} {% if form.non_field_errors %}<span class="help-inline">{{ form.non_field_errors }}</span>{% endif %} - </div> + {% endfor %} <div class="form-actions"> - <input class="btn" type="submit" value="Preview"> + <button class='btn btn-primary' type='submit'>Preview</button> <a class="btn" href="{% url "rpki.gui.app.views.dashboard" %}">Cancel</a> </div> </form> diff --git a/rpki/gui/app/views.py b/rpki/gui/app/views.py index c739b55e..95b6f431 100644 --- a/rpki/gui/app/views.py +++ b/rpki/gui/app/views.py @@ -39,7 +39,6 @@ from django.contrib.auth.models import User from django.views.generic import DetailView, ListView, DeleteView, FormView from django.core.paginator import Paginator, InvalidPage from django.forms.formsets import formset_factory, BaseFormSet -import django.db.models from django.contrib import messages from rpki.irdb import Zookeeper, ChildASN, ChildNet, ROARequestPrefix @@ -728,13 +727,24 @@ def roa_create_multi(request): asn = form.cleaned_data['asn'] rng = resource_range_ip.parse_str(form.cleaned_data['prefix']) max_prefixlen = int(form.cleaned_data['max_prefixlen']) + protect_children = form.cleaned_data['protect_children'] + # FIXME: This won't do the right thing in the event that a # route is covered by multiple ROAs created in the form. # You will see duplicate entries, each with a potentially # different validation status. - routes.extend(get_covered_routes(rng, max_prefixlen, asn)) + covered = get_covered_routes(rng, max_prefixlen, asn) + routes.extend(covered) v.append({'prefix': str(rng), 'max_prefixlen': max_prefixlen, 'asn': asn}) + + if protect_children: + for r in conf.child_routes.filter(pk__in=[c.pk for c in covered if c.newstatus == 'invalid']): + rng = r.as_resource_range() + v.append({'prefix': str(rng), + 'max_prefixlen': rng.prefixlen, + 'asn': r.asn}) + # if there were no rows, skip the confirmation step if v: formset = formset_factory(forms.ROARequestConfirm, extra=0)(initial=v) |