aboutsummaryrefslogtreecommitdiff
path: root/rpki/gui
diff options
context:
space:
mode:
Diffstat (limited to 'rpki/gui')
-rw-r--r--rpki/gui/app/forms.py2
-rw-r--r--rpki/gui/app/models.py25
-rw-r--r--rpki/gui/app/templates/app/roarequest_confirm_multi_form.html37
-rw-r--r--rpki/gui/app/templates/app/roarequest_multi_form.html11
-rw-r--r--rpki/gui/app/views.py14
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)