aboutsummaryrefslogtreecommitdiff
path: root/portal-gui/rpkigui/myrpki
diff options
context:
space:
mode:
Diffstat (limited to 'portal-gui/rpkigui/myrpki')
-rw-r--r--portal-gui/rpkigui/myrpki/AllocationTree.py148
-rw-r--r--portal-gui/rpkigui/myrpki/__init__.py0
-rw-r--r--portal-gui/rpkigui/myrpki/admin.py52
-rw-r--r--portal-gui/rpkigui/myrpki/asnset.py40
-rw-r--r--portal-gui/rpkigui/myrpki/forms.py147
-rw-r--r--portal-gui/rpkigui/myrpki/glue.py.in139
-rw-r--r--portal-gui/rpkigui/myrpki/misc.py47
-rw-r--r--portal-gui/rpkigui/myrpki/models.py207
-rw-r--r--portal-gui/rpkigui/myrpki/urls.py50
-rw-r--r--portal-gui/rpkigui/myrpki/views.py557
10 files changed, 0 insertions, 1387 deletions
diff --git a/portal-gui/rpkigui/myrpki/AllocationTree.py b/portal-gui/rpkigui/myrpki/AllocationTree.py
deleted file mode 100644
index 13936797..00000000
--- a/portal-gui/rpkigui/myrpki/AllocationTree.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# $Id$
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-from rpkigui.myrpki import misc, models
-from rpki import resource_set
-
-class AllocationTree(object):
- '''Virtual class representing a tree of unallocated resource ranges.
- Keeps track of which subsets of a resource range have been
- allocated.'''
-
- def __init__(self, resource):
- self.resource = resource
- self.range = resource.as_resource_range()
- self.need_calc = True
-
- def calculate(self):
- if self.need_calc:
- self.children = []
- self.alloc = self.__class__.set_type()
- self.unalloc = self.__class__.set_type()
-
- if self.is_allocated():
- self.alloc.append(self.range)
- else:
- for child in self.resource.children.all():
- c = self.__class__(child)
- if c.unallocated():
- self.children.append(c)
- self.alloc = self.alloc.union(c.alloc)
- total = self.__class__.set_type()
- total.append(self.range)
- self.unalloc = total.difference(self.alloc)
- self.need_calc=False
-
- def unallocated(self):
- self.calculate()
- return self.unalloc
-
- def as_ul(self):
- '''Returns a string of the tree as an unordered HTML list.'''
- s = []
- s.append('<a href="%s">%s</a>' % (self.resource.get_absolute_url(), self.resource))
-
- # when the unallocated range is a subset of the current range,
- # display the missing ranges
- u = self.unallocated()
- if len(u) != 1 or self.range != u[0]:
- s.append(' (missing: ')
- s.append(', '.join(str(x) for x in u))
- s.append(')')
-
- # quick access links
- if self.resource.parent:
- s.append(' | <a href="%s/delete">delete</a>' % (self.resource.get_absolute_url(),))
- s.append(' | <a href="%s/allocate">give</a>' % (self.resource.get_absolute_url(),))
- if self.range.min != self.range.max:
- s.append(' | <a href="%s/split">split</a>' % (self.resource.get_absolute_url(),))
- # add type-specific actions
- a = self.supported_actions()
- if a:
- s.extend(a)
-
- if self.children:
- s.append('\n<ul>\n')
- for c in self.children:
- s.append('<li>' + c.as_ul())
- s.append('\n</ul>')
-
- return ''.join(s)
-
- def supported_actions(self):
- '''Virtual method allowing subclasses to add actions to the HTML list.'''
- return None
-
- @classmethod
- def from_resource_range(cls, resource):
- if isinstance(resource, resource_set.resource_range_as):
- return AllocationTreeAS(resource)
- if isinstance(resource, resoute_set.resource_range_ip):
- return AllocationTreeIP(resource)
- raise ValueError, 'Unsupported resource range type'
-
-class AllocationTreeAS(AllocationTree):
- set_type = resource_set.resource_set_as
-
- def __init__(self, *args, **kwargs):
- AllocationTree.__init__(self, *args, **kwargs)
- self.conf = misc.top_parent(self.resource).from_cert.all()[0].parent.conf
-
- def is_allocated(self):
- '''Returns true if this AS has been allocated to a child or
- used in a ROA request.'''
- # FIXME: detect use in ROA requests
-
- if self.resource.allocated:
- return True
-
- # for individual ASNs
- if self.range.min == self.range.max:
- # is this ASN used in any roa?
- if self.conf.roas.filter(asn=self.range.min):
- return True
-
- return False
-
-class AllocationTreeIP(AllocationTree):
- '''virtual class representing a tree of IP address ranges.'''
-
- @classmethod
- def from_prefix(cls, prefix):
- r = prefix.as_resource_range()
- if isinstance(r, resource_set.resource_range_ipv4):
- return AllocationTreeIPv4(prefix)
- elif isinstance(r, resource_set.resource_range_ipv6):
- return AllocationTreeIPv6(prefix)
- raise ValueError, 'Unsupported IP range type'
-
- def supported_actions(self):
- '''add a link to issue a roa for this IP range'''
- return[' | <a href="%s/roa">roa</a>' % (self.resource.get_absolute_url(),)]
-
- def is_allocated(self):
- '''Return True if this IP range is allocated to a child or used
- in a ROA request.'''
- return self.resource.allocated or self.resource.roa_requests.count()
-
-class AllocationTreeIPv4(AllocationTreeIP):
- set_type = resource_set.resource_set_ipv4
-
-class AllocationTreeIPv6(AllocationTreeIP):
- set_type = resource_set.resource_set_ipv6
-
-# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/myrpki/__init__.py b/portal-gui/rpkigui/myrpki/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/portal-gui/rpkigui/myrpki/__init__.py
+++ /dev/null
diff --git a/portal-gui/rpkigui/myrpki/admin.py b/portal-gui/rpkigui/myrpki/admin.py
deleted file mode 100644
index b5d7ab66..00000000
--- a/portal-gui/rpkigui/myrpki/admin.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-from django import forms
-from django.contrib import admin
-from rpkigui.myrpki import models
-
-class ConfAdmin( admin.ModelAdmin ):
- pass
-
-class ChildAdmin( admin.ModelAdmin ):
- pass
-
-class AddressRangeAdmin( admin.ModelAdmin ):
- pass
-
-class AsnAdmin( admin.ModelAdmin ):
- pass
-
-class ParentAdmin( admin.ModelAdmin ):
- pass
-
-class RoaAdmin( admin.ModelAdmin ):
- pass
-
-class ResourceCertAdmin(admin.ModelAdmin):
- pass
-
-class RoaRequestAdmin(admin.ModelAdmin):
- pass
-
-admin.site.register(models.Conf, ConfAdmin)
-admin.site.register(models.Child, ChildAdmin)
-admin.site.register(models.AddressRange, AddressRangeAdmin)
-admin.site.register(models.Asn, AsnAdmin)
-admin.site.register(models.Parent, ParentAdmin)
-admin.site.register(models.Roa, RoaAdmin)
-admin.site.register(models.RoaRequest, RoaRequestAdmin)
-admin.site.register(models.ResourceCert, ResourceCertAdmin)
diff --git a/portal-gui/rpkigui/myrpki/asnset.py b/portal-gui/rpkigui/myrpki/asnset.py
deleted file mode 100644
index 6a2d562c..00000000
--- a/portal-gui/rpkigui/myrpki/asnset.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# $Id$
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-class asnset(object):
- """A set-like object for containing sets of ASN values."""
- v = set()
-
- def __init__(self, init=None):
- """
- May be initialized from a comma separated list of positive integers.
- """
- if init:
- self.v = set(int(x) for x in init.split(',') if x.strip() != '')
- if any([x for x in self.v if x < 0]):
- raise ValueError, "Can't contain negative values."
-
- def __str__(self):
- return ','.join(str(x) for x in sorted(self.v))
-
- def __iter__(self):
- return iter(self.v)
-
- def add(self, n):
- assert isinstance(n, int)
- assert n > 0
- self.v.add(n)
diff --git a/portal-gui/rpkigui/myrpki/forms.py b/portal-gui/rpkigui/myrpki/forms.py
deleted file mode 100644
index 959d5a20..00000000
--- a/portal-gui/rpkigui/myrpki/forms.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# $Id$
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-from django import forms
-
-import rpki.ipaddrs
-
-from rpkigui.myrpki import models, misc
-from rpkigui.myrpki.asnset import asnset
-
-class AddConfForm(forms.Form):
- handle = forms.CharField(required=True,
- help_text='your handle for your rpki instance')
- run_rpkid = forms.BooleanField(required=False, initial=True,
- label='Run rpkid?',
- help_text='do you want to run your own instance of rpkid?')
- rpkid_server_host = forms.CharField(initial='rpkid.example.org',
- label='rpkid hostname',
- help_text='publicly visible hostname for your rpkid instance')
- rpkid_server_port = forms.IntegerField(initial=4404,
- label='rpkid port')
- run_pubd = forms.BooleanField(required=False, initial=False,
- label='Run pubd?',
- help_text='do you want to run your own instance of pubd?')
- pubd_server_host = forms.CharField(initial='pubd.example.org',
- label='pubd hostname',
- help_text='publicly visible hostname for your pubd instance')
- pubd_server_port = forms.IntegerField(initial=4402, label='pubd port')
- pubd_contact_info = forms.CharField(initial='repo-man@rpki.example.org',
- label='Pubd contact',
- help_text='email address for the operator of your pubd instance')
-
-class ImportForm(forms.Form):
- '''Form used for uploading parent/child identity xml files'''
- handle = forms.CharField()
- xml = forms.FileField()
-
-def PrefixSplitForm(parent, *args, **kwargs):
- class _wrapper(forms.Form):
- prefix = forms.CharField(max_length=200, help_text='CIDR or range')
-
- def clean(self):
- p = self.cleaned_data.get('prefix')
- try:
- r = misc.parse_resource_range(p)
- except ValueError, err:
- print err
- raise forms.ValidationError, 'invalid prefix or range'
- # we get AssertionError is the range is misordered (hi before lo)
- except AssertionError, err:
- print err
- raise forms.ValidationError, 'invalid prefix or range'
- pr = parent.as_resource_range()
- if r.min < pr.min or r.max > pr.max:
- raise forms.ValidationError, \
- 'range is outside parent range'
- if r.min == pr.min and r.max == pr.max:
- raise forms.ValidationError, \
- 'range is equal to parent'
- if parent.allocated:
- raise forms.ValidationError, 'prefix is assigned to child'
- for p in parent.children.all():
- c = p.as_resource_range()
- if c.min <= r.min <= c.max or c.min <= r.max <= c.max:
- raise forms.ValidationError, \
- 'overlap with another child prefix: %s' % (c,)
-
- return self.cleaned_data
- return _wrapper(*args, **kwargs)
-
-def PrefixAllocateForm(iv, child_set, *args, **kwargs):
- class _wrapper(forms.Form):
- child = forms.ModelChoiceField(initial=iv, queryset=child_set,
- required=False)
- return _wrapper(*args, **kwargs)
-
-def PrefixRoaForm(prefix, *args, **kwargs):
- prefix_range = prefix.as_resource_range()
-
- class _wrapper(forms.Form):
- asns = forms.CharField(max_length=200, required=False,
- help_text='Comma-separated list of ASNs')
- max_length = forms.IntegerField(required=False,
- min_value=prefix_range.prefixlen(),
- max_value=prefix_range.datum_type.bits)
-
- def clean_max_length(self):
- v = self.cleaned_data.get('max_length')
- if not v:
- v = prefix_range.prefixlen()
- return v
-
- def clean_asns(self):
- try:
- v = asnset(self.cleaned_data.get('asns'))
- return ','.join(str(x) for x in sorted(v))
- except ValueError:
- raise forms.ValidationError, \
- 'Must be a list of integers separated by commas.'
- return self.cleaned_data['asns']
-
- def clean(self):
- if not prefix.is_prefix():
- raise forms.ValidationError, \
- '%s can not be represented as a prefix.' % (prefix,)
- if prefix.allocated:
- raise forms.ValidationError, \
- 'Prefix is allocated to a child.'
- return self.cleaned_data
-
- return _wrapper(*args, **kwargs)
-
-def PrefixDeleteForm(prefix, *args, **kwargs):
- class _wrapped(forms.Form):
- delete = forms.BooleanField(label='Yes, I want to delete this prefix:')
-
- def clean(self):
- v = self.cleaned_data.get('delete')
- if v:
- if not prefix.parent:
- raise forms.ValidationError, \
- 'Can not delete prefix received from parent'
- if prefix.allocated:
- raise forms.ValidationError, 'Prefix is allocated to child'
- if prefix.roa_requests.all():
- raise forms.ValidationError, 'Prefix is used in your ROAs'
- if prefix.children.all():
- raise forms.ValidationError, 'Prefix has been subdivided'
- return self.cleaned_data
-
- return _wrapped(*args, **kwargs)
-
-# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/myrpki/glue.py.in b/portal-gui/rpkigui/myrpki/glue.py.in
deleted file mode 100644
index 897b23d4..00000000
--- a/portal-gui/rpkigui/myrpki/glue.py.in
+++ /dev/null
@@ -1,139 +0,0 @@
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-# $Id$
-
-from __future__ import with_statement
-
-import os
-import os.path
-import csv
-import stat
-import sys
-
-from django.db.models import F
-
-import rpki
-import rpki.config
-
-from rpkigui.myrpki import models
-
-confdir = '@CONFDIR@'
-
-def conf(handle):
- return confdir + '/' + handle
-
-#def form_to_conf(data):
-# """Write out a rpki.conf based on the given form data."""
-# handle = data['handle']
-# confdir = settings.MYRPKI_DATA_DIR + '/' + handle
-# if os.path.exists(confdir):
-# raise RuntimeError, '%s: directory already exists!' % (confdir, )
-# os.makedirs(confdir)
-# template = open(settings.MYRPKI_DATA_DIR + '/examples/rpki.conf', 'r').read()
-# # stuff the appropriate output directory into the dict
-# data['MYRPKI_DATA_DIR'] = confdir
-# with open(confdir + '/rpki.conf', 'w') as conf:
-# print >>conf, template % data
-# invoke_rpki(handle, ['initialize'])
-
-def invoke_rpki(handle, args):
- """Invoke the myrpki cli for the specified configuration."""
- myrpki_dir = confdir(handle)
- config = myrpki_dir + '/rpki.conf'
- # default rpki.conf uses relative paths, so chdir() to the repo first
- cmd = 'cd %s && @MYRPKI@ %s' % (myrpki_dir, ' '.join(['--config=' + config] + args))
- print >>sys.stderr, 'invoking', cmd
- os.system(cmd)
-
-def read_file_from_handle(handle, fname):
- """read a filename relative to the directory for the given resource handle. returns
- a tuple of (content, mtime)"""
- with open(conf(handle) + '/' + fname, 'r') as fp:
- data = fp.read()
- mtime = os.fstat(fp.fileno())[stat.ST_MTIME]
- return data, mtime
-
-#def read_identity(handle):
-# fname = settings.MYRPKI_DATA_DIR + '/' + handle + '/entitydb/identity.xml'
-# with open(fname, 'r') as fp:
-# data = fp.read()
-# return data
-read_identity = lambda h: read_file_from_handle(h, 'entitydb/identity.xml')[0]
-
-def read_child_response(handle, child):
- fname = '%s/entitydb/children/%s.xml' % (conf(handle), child)
- with open(fname, 'r') as fp:
- data = fp.read()
- return data
-
-# FIXME - remove this once rpki.myrpki.csv_writer is an object with a
-# .file field
-def csv_writer(f):
- return csv.writer(f, dialect = csv.get_dialect("excel-tab"))
-
-def output_asns(path, handle):
- '''Write out csv file containing asns delegated to my children.'''
- qs = models.Asn.objects.filter(lo=F('hi'), allocated__in=handle.children.all())
- with open(path, 'w') as f:
- w = csv_writer(f)
- w.writerows([asn.allocated.handle, asn.lo] for asn in qs)
-
-def output_prefixes(path, handle):
- '''Write out csv file containing prefixes delegated to my children.'''
- qs = models.AddressRange.objects.filter(allocated__in=handle.children.all())
- with open(path, 'w') as f:
- w = csv_writer(f)
- w.writerows([p.allocated.handle, p.as_resource_range()] for p in qs)
-
-def output_roas(path, handle):
- '''Write out csv file containing my roas.'''
- qs = models.RoaRequest.objects.filter(roa__in=handle.roas.all())
- with open(path, 'w') as f:
- w = csv_writer(f)
- w.writerows([req.as_roa_prefix(), req.roa.asn,
- '%s-group-%d' % (handle.handle, req.roa.pk)] for req in qs)
-
-def configure_daemons(handle):
- args = ['configure_daemons']
- for hosted in handle.hosting.all():
- args.append(conf(hosted.handle) + '/myrpki.xml')
- invoke_rpki(handle.handle, args)
-
-def configure_resources(handle):
- '''Write out the csv files and invoke the myrpki.py command line tool.'''
- # chdir to the repo dir since the default rpki.conf uses relative
- # pathnames..
- os.chdir(conf(handle.handle))
- cfg = rpki.config.parser('rpki.conf', 'myrpki')
- output_asns(cfg.get('asn_csv'), handle)
- output_prefixes(cfg.get('prefix_csv'), handle)
- output_roas(cfg.get('roa_csv'), handle)
- run_rpkidemo = cfg.getboolean('run_rpkidemo', False)
- if not run_rpkidemo:
- run_rpkid = cfg.getboolean('run_rpkid')
- if run_rpkid:
- configure_daemons(handle)
- else:
- invoke_rpki(handle.handle, ['configure_resources'])
-
- # send the myrpki.xml to the rpkid hosting me
- configure_daemons(handle.host)
-
- # process the response
- invoke_rpki(handle.handle, ['configure_resources'])
-
-# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/myrpki/misc.py b/portal-gui/rpkigui/myrpki/misc.py
deleted file mode 100644
index 5d3cba93..00000000
--- a/portal-gui/rpkigui/myrpki/misc.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# $Id$
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import rpki.resource_set
-import rpki.ipaddrs
-
-def str_to_range(lo, hi):
- """Convert IP address strings to resource_range_ip."""
- x = rpki.ipaddrs.parse(lo)
- y = rpki.ipaddrs.parse(hi)
- assert type(x) == type(y)
- if isinstance(x, rpki.ipaddrs.v4addr):
- return rpki.resource_set.resource_range_ipv4(x, y)
- else:
- return rpki.resource_set.resource_range_ipv6(x, y)
-
-def parse_resource_range(s):
- '''Parse an IPv4/6 resource range.'''
- # resource_set functions only accept str
- if isinstance(s, unicode):
- s = s.encode()
- try:
- return rpki.resource_set.resource_range_ipv4.parse_str(s)
- except ValueError:
- return rpki.resource_set.resource_range_ipv6.parse_str(s)
-
-def top_parent(prefix):
- '''Returns the topmost resource from which the specified argument derives'''
- while prefix.parent:
- prefix = prefix.parent
- return prefix
-
-# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/myrpki/models.py b/portal-gui/rpkigui/myrpki/models.py
deleted file mode 100644
index 7db5ef1d..00000000
--- a/portal-gui/rpkigui/myrpki/models.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# $Id$
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import socket
-
-from django.db import models
-from django.contrib.auth.models import User
-
-from rpkigui.myrpki.misc import str_to_range
-
-import rpki.resource_set
-import rpki.exceptions
-
-class HandleField(models.CharField):
- def __init__(self, **kwargs):
- models.CharField.__init__(self, max_length=255, **kwargs)
-
-class IPAddressField(models.CharField):
- def __init__( self, **kwargs ):
- models.CharField.__init__(self, max_length=40, **kwargs)
-
-class Conf(models.Model):
- '''This is the center of the universe, also known as a place to
- have a handle on a resource-holding entity. It's the <self>
- in the rpkid schema.'''
- handle = HandleField(unique=True, db_index=True)
- owner = models.ManyToManyField(User)
-
- # NULL if self-hosted, otherwise the conf that is hosting us
- host = models.ForeignKey('Conf', related_name='hosting', null=True)
-
- def __unicode__(self):
- return self.handle
-
-class AddressRange(models.Model):
- '''An address range/prefix.'''
- lo = IPAddressField(blank=False)
- hi = IPAddressField(blank=False)
- # parent address range
- parent = models.ForeignKey('AddressRange', related_name='children',
- blank=True, null=True)
- # child to which this resource is delegated
- allocated = models.ForeignKey('Child', related_name='address_range',
- blank=True, null=True)
-
- def __unicode__(self):
- if self.lo == self.hi:
- return u"%s" % (self.lo,)
-
- try:
- # pretty print cidr
- return unicode(self.as_resource_range())
- except socket.error, err:
- print err
- # work around for bug when hi/lo get reversed
- except AssertionError, err:
- print err
- return u'%s - %s' % (self.lo, self.hi)
-
- @models.permalink
- def get_absolute_url(self):
- return ('rpkigui.myrpki.views.address_view', [str(self.pk)])
-
- def as_resource_range(self):
- '''Convert to rpki.resource_set.resource_range_ip.'''
- return str_to_range(self.lo, self.hi)
-
- def is_prefix(self):
- '''Returns True if this address range can be represented as a
- prefix.'''
- try:
- self.as_resource_range().prefixlen()
- except rpki.exceptions.MustBePrefix, err:
- print err
- return False
- return True
-
-class RoaRequest(models.Model):
- roa = models.ForeignKey('Roa', related_name='from_roa_request')
- max_length = models.IntegerField()
- prefix = models.ForeignKey('AddressRange', related_name='roa_requests')
-
- def __unicode__(self):
- return u'roa request for asn %d on %s-%d' % (self.roa.asn, self.prefix,
- self.max_length)
-
- def as_roa_prefix(self):
- '''Convert to a rpki.resouce_set.roa_prefix subclass.'''
- r = self.prefix.as_resource_range()
- if isinstance(r, rpki.resource_set.resource_set_ipv4):
- return rpki.resource_set.roa_prefix_ipv4(r.min, r.prefixlen(),
- self.max_length)
- else:
- return rpki.resource_set.roa_prefix_ipv6(r.min, r.prefixlen(),
- self.max_length)
-
-class Asn(models.Model):
- '''An ASN or range thereof.'''
- lo = models.IntegerField(blank=False)
- hi = models.IntegerField(blank=False)
- # parent asn range
- parent = models.ForeignKey('Asn', related_name='children',
- blank=True, null=True)
- # child to which this resource is delegated
- allocated = models.ForeignKey('Child', related_name='asn',
- blank=True, null=True)
-
- def __unicode__(self):
- if self.lo == self.hi:
- return u"ASN %d" % (self.lo,)
- else:
- return u"ASNs %d - %d" % (self.lo, self.hi)
-
- @models.permalink
- def get_absolute_url(self):
- return ('rpkigui.myrpki.views.asn_view', [str(self.pk)])
-
- def as_resource_range(self):
- # we force conversion to long() here because resource_range_as() wants
- # the type of both arguments to be identical, and models.IntegerField
- # will be a long when the value is large
- return rpki.resource_set.resource_range_as(long(self.lo), long(self.hi))
-
-class Child(models.Model):
- conf = models.ForeignKey(Conf, related_name='children')
- handle = HandleField() # parent's name for child
-
- def __unicode__(self):
- return u"%s's child %s" % (self.conf, self.handle)
-
- @models.permalink
- def get_absolute_url(self):
- return ('rpkigui.myrpki.views.child_view', [self.handle])
-
- class Meta:
- verbose_name_plural = "children"
- # children of a specific configuration should be unique
- unique_together = ('conf', 'handle')
-
-class Parent(models.Model):
- conf = models.ForeignKey(Conf, related_name='parents')
- handle = HandleField() # my name for this parent
-
- def __unicode__(self):
- return u"%s's parent %s" % (self.conf, self.handle)
-
- @models.permalink
- def get_absolute_url(self):
- return ('rpkigui.myrpki.views.parent_view', [self.handle])
-
- class Meta:
- # parents of a specific configuration should be unique
- unique_together = ('conf', 'handle')
-
-class ResourceCert(models.Model):
- parent = models.ForeignKey(Parent, related_name='resources')
-
- # resources granted from my parent
- asn = models.ManyToManyField(Asn, related_name='from_cert', blank=True,
- null=True)
- address_range = models.ManyToManyField(AddressRange,
- related_name='from_cert', blank=True, null=True)
-
- # unique id for this resource certificate
- # FIXME: URLField(verify_exists=False) doesn't seem to work - the admin
- # editor won't accept a rsync:// scheme as valid
- uri = models.CharField(max_length=200)
-
- # certificate validity period
- not_before = models.DateTimeField()
- not_after = models.DateTimeField()
-
- def __unicode__(self):
- return u"%s's resource cert from parent %s" % (self.parent.conf.handle,
- self.parent.handle)
-
-class Roa(models.Model):
- '''Maps an ASN to the set of prefixes it can originate routes for.
- This differs from a real ROA in that prefixes from multiple
- parents/resource certs can be selected. The glue module contains
- code to split the ROAs into groups by common resource certs.'''
-
- conf = models.ForeignKey(Conf, related_name='roas')
- asn = models.IntegerField()
- active = models.BooleanField()
-
- # the resource cert from which all prefixes for this roa are derived
- cert = models.ForeignKey(ResourceCert, related_name='roas')
-
- def __unicode__(self):
- return u"%s's ROA for %d" % (self.conf, self.asn)
-
-# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/myrpki/urls.py b/portal-gui/rpkigui/myrpki/urls.py
deleted file mode 100644
index 96d93e2d..00000000
--- a/portal-gui/rpkigui/myrpki/urls.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# $Id$
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-from django.conf.urls.defaults import *
-from django.views.generic.list_detail import object_list
-from rpkigui.myrpki import views
-
-urlpatterns = patterns('',
- (r'^$', views.dashboard),
-# (r'^conf/add$', views.conf_add),
- (r'^conf/export$', views.conf_export),
- (r'^conf/list$', views.conf_list),
- (r'^conf/select$', views.conf_select),
-# (r'^import/parent$', views.parent_import),
-# (r'^import/child$', views.child_import),
- (r'^parent/(?P<parent_handle>[^/]+)$', views.parent_view),
- (r'^child/(?P<child_handle>[^/]+)$', views.child_view),
-# (r'^parent/(?P<parent_handle>[^/]+)/address$', views.parent_address),
-# (r'^parent/(?P<parent_handle>[^/]+)/asn$', views.parent_asn),
- (r'^address/(?P<pk>\d+)$', views.address_view),
- (r'^address/(?P<pk>\d+)/split$', views.prefix_split_view),
- (r'^address/(?P<pk>\d+)/allocate$', views.prefix_allocate_view),
- (r'^address/(?P<pk>\d+)/roa$', views.prefix_roa_view),
- (r'^address/(?P<pk>\d+)/delete$', views.prefix_delete_view),
- (r'^asn/(?P<pk>\d+)$', views.asn_view),
- (r'^asn/(?P<pk>\d+)/allocate$', views.asn_allocate_view),
- (r'^roa/(?P<pk>\d+)/delete$', views.roa_request_delete_view),
- (r'^demo/down/asns/(?P<self_handle>[^/]+)$', views.download_asns),
- (r'^demo/down/prefixes/(?P<self_handle>[^/]+)$', views.download_prefixes),
- (r'^demo/down/roas/(?P<self_handle>[^/]+)$', views.download_roas),
- (r'^upload-parent-request/(?P<self_handle>[^/]+)$', views.upload_parent_request),
- (r'^upload-repository-request/(?P<self_handle>[^/]+)$', views.upload_repository_request),
- (r'^upload-myrpki-xml/(?P<self_handle>[^/]+)$', views.upload_myrpki_xml),
-)
-
-# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/myrpki/views.py b/portal-gui/rpkigui/myrpki/views.py
deleted file mode 100644
index f15ebbdd..00000000
--- a/portal-gui/rpkigui/myrpki/views.py
+++ /dev/null
@@ -1,557 +0,0 @@
-# $Id$
-"""
-Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import email.utils
-import os
-import os.path
-import tempfile
-import sys
-
-from django.contrib.auth.decorators import login_required
-from django.shortcuts import get_object_or_404, render_to_response
-from django.utils.http import urlquote
-from django.template import RequestContext
-from django.db import IntegrityError
-from django import http
-from django.views.generic.list_detail import object_list
-from django.views.decorators.csrf import csrf_exempt
-from django.conf import settings
-from django.core.urlresolvers import reverse
-
-from rpkigui.myrpki import models, forms, glue, misc, AllocationTree
-from rpkigui.myrpki.asnset import asnset
-
-debug = False
-
-# For each type of object, we have a detail view, a create view and
-# an update view. We heavily leverage the generic views, only
-# adding our own idea of authorization.
-
-def handle_required(f):
- @login_required
- def wrapped_fn(request, *args, **kwargs):
- if 'handle' not in request.session:
- if request.user.is_superuser:
- conf = models.Conf.objects.all()
- else:
- conf = models.Conf.objects.filter(owner=request.user)
- if conf.count() == 1:
- handle = conf[0]
- elif conf.count() == 0:
- return render('myrpki/conf_empty.html', {}, request)
- #return http.HttpResponseRedirect('/myrpki/conf/add')
- else:
- # Should reverse the view for this instead of hardcoding
- # the URL.
- return http.HttpResponseRedirect(
- reverse(conf_list) + '?next=' + urlquote(request.get_full_path()))
- request.session[ 'handle' ] = handle
- return f(request, *args, **kwargs)
- return wrapped_fn
-
-def render(template, context, request):
- return render_to_response(template, context,
- context_instance=RequestContext(request))
-
-@handle_required
-def dashboard(request):
- '''The user's dashboard.'''
- handle = request.session[ 'handle' ]
- # ... pick out data for the dashboard and return it
- # my parents
- # the resources that my parents have given me
- # the resources that I have accepted from my parents
- # my children
- # the resources that I have given my children
- # my roas
-
- # get list of ASNs used in my ROAs
- roa_asns = [r.asn for r in handle.roas.all()]
- asns=[]
- for a in models.Asn.objects.filter(from_cert__parent__in=handle.parents.all()):
- f = AllocationTree.AllocationTreeAS(a)
- if f.unallocated():
- asns.append(f)
-
- prefixes = []
- for p in models.AddressRange.objects.filter(from_cert__parent__in=handle.parents.all()):
- f = AllocationTree.AllocationTreeIP.from_prefix(p)
- if f.unallocated():
- prefixes.append(f)
-
- asns.sort(key=lambda x: x.range.min)
- prefixes.sort(key=lambda x: x.range.min)
-
- return render('myrpki/dashboard.html', { 'conf': handle, 'asns': asns,
- 'ars': prefixes }, request)
-
-#@login_required
-#def conf_add(request):
-# '''Allow the user to create a new configuration.'''
-# errors = []
-# if request.method == 'POST':
-# form = forms.AddConfForm(request.POST)
-# if form.is_valid():
-# try:
-# handle = form.cleaned_data['handle']
-# # ensure this user is in the group for this handle
-# grps = request.user.groups.filter(name=handle)
-# if len(grps) == 0:
-# errors.append(
-# 'You are not in the proper group for that handle.')
-# else:
-# conf = models.Conf.objects.create(
-# handle=form.cleaned_data['handle'], owner=grps[0])
-# conf.save()
-# glue.form_to_conf(form.cleaned_data)
-# return http.HttpResponseRedirect('/myrpki/')
-# # data model will ensure the handle is unique
-# except IntegrityError, e:
-# print e
-# errors.append('That handle already exists.')
-# else:
-# errors.append("The form wasn't valid.")
-# else:
-# form = forms.AddConfForm()
-# return render_to_response('myrpki/add_conf.html',
-# { 'form': form, 'errors': errors })
-
-@login_required
-def conf_list(request):
- """Allow the user to select a handle."""
- if request.user.is_superuser:
- queryset = models.Conf.objects.all()
- else:
- queryset = models.Conf.objects.filter(owner=request.user)
- return object_list(request, queryset,
- template_name='myrpki/conf_list.html', template_object_name='conf', extra_context={ 'select_url' : reverse(conf_select) })
-
-@login_required
-def conf_select(request):
- '''Change the handle for the current session.'''
- if not 'handle' in request.GET:
- return http.HttpResponseRedirect('/myrpki/conf/select')
- handle = request.GET['handle']
- next_url = request.GET.get('next', reverse(dashboard))
- if next_url == '':
- next_url = reverse(dashboard)
-
- if request.user.is_superuser:
- conf = models.Conf.objects.filter(handle=handle)
- else:
- # since the handle is passed in as a parameter, need to verify that
- # the user is actually in the group
- conf = models.Conf.objects.filter(handle=handle,
- owner=request.user)
- if conf:
- request.session['handle'] = conf[0]
- return http.HttpResponseRedirect(next_url)
-
- return http.HttpResponseRedirect(reverse(conf_list) + '?next=' + next_url)
-
-def serve_xml(content, basename):
- resp = http.HttpResponse(content , mimetype='application/xml')
- resp['Content-Disposition'] = 'attachment; filename=%s.xml' % (basename, )
- return resp
-
-@handle_required
-def conf_export(request):
- """Return the identity.xml for the current handle."""
- handle = request.session['handle']
- return serve_xml(glue.read_identity(handle.handle), 'identity')
-
-@handle_required
-def parent_import(request):
- handle = request.session['handle'].handle
- errs = []
- if request.method == 'POST':
- form = forms.ImportForm(request.POST, request.FILES)
- if form.is_valid():
- input_file = tempfile.NamedTemporaryFile(delete=False)
- try:
- parent_handle = form.cleaned_data['handle']
- parent = models.Parent(
- conf=request.session['handle'], handle=parent_handle)
- parent.save()
-
- input_file.write(request.FILES['xml'].read())
- input_file.close()
-
- args = ['configure_parent', '--parent_handle=' + parent_handle,
- input_file.name]
- glue.invoke_rpki(handle, args)
-
- return http.HttpResponseRedirect('/myrpki/')
- except IntegrityError, e:
- print e
- errs.append('A parent with that handle already exists.')
- finally:
- os.remove(input_file.name)
- else:
- print 'invalid form'
- errs.append('The form was invalid.')
- else:
- form = forms.ImportForm()
- return render('myrpki/xml_import.html', { 'form': form,
- 'kind': 'parent', 'post_url': '/myrpki/import/parent',
- 'errors': errs }, request)
-
-@handle_required
-def parent_view(request, parent_handle):
- """Detail view for a particular parent."""
- handle = request.session['handle']
- parent = get_object_or_404(handle.parents, handle__exact=parent_handle)
- return render('myrpki/parent_view.html', { 'parent': parent }, request)
-
-@handle_required
-def child_import(request):
- handle = request.session['handle'].handle
- if request.method == 'POST':
- form = forms.ImportForm(request.POST, request.FILES)
- if form.is_valid():
- input_file = tempfile.NamedTemporaryFile(delete=False)
- try:
- child_handle = form.cleaned_data['handle']
- child = models.Child(
- conf=request.session['handle'], handle=child_handle,
- validity=form.cleaned_data['validity'])
- child.save()
-
- input_file.write(request.FILES['xml'].read())
- input_file.close()
- args = ['configure_child', '--child_handle=' + child_handle,
- input_file.name]
- glue.invoke_rpki(handle, args)
-
- # send response back to user
- return serve_xml(glue.read_child_response(handle,
- child_handle), child_handle)
- finally:
- os.remove(input_file.name)
- else:
- form = forms.ImportForm()
- return render('myrpki/xml_import.html',
- { 'form': form, 'kind': 'child',
- 'post_url': '/myrpki/import/child'}, request)
-
-def get_parents_or_404(handle, obj):
- '''Return the Parent object(s) that the given address range derives
- from, or raise a 404 error.'''
- cert_set = misc.top_parent(obj).from_cert.filter(parent__in=handle.parents.all())
- if cert_set.count() == 0:
- raise http.Http404, 'Object is not delegated from any parent'
- return [c.parent for c in cert_set]
-
-@handle_required
-def asn_view(request, pk):
- '''view/subdivide an asn range.'''
- handle = request.session['handle']
- obj = get_object_or_404(models.Asn.objects, pk=pk)
- # ensure this resource range belongs to a parent of the current conf
- parent_set = get_parents_or_404(handle, obj)
- roas = handle.roas.filter(asn=obj.lo) # roas which contain this asn
- unallocated = AllocationTree.AllocationTreeAS(obj).unallocated()
-
- return render('myrpki/asn_view.html',
- { 'asn': obj, 'parent': parent_set, 'roas': roas,
- 'unallocated' : unallocated }, request)
-
-@handle_required
-def child_view(request, child_handle):
- '''Detail view of child for the currently selected handle.'''
- handle = request.session['handle']
- child = get_object_or_404(handle.children, handle__exact=child_handle)
-
- return render('myrpki/child_view.html', { 'child': child }, request)
-
-class PrefixView(object):
- '''Extensible view for address ranges/prefixes. This view can be
- subclassed to add form handling for editing the prefix.'''
-
- def __init__(self, request, pk, form_class=None):
- self.handle = request.session['handle']
- self.obj = get_object_or_404(models.AddressRange.objects, pk=pk)
- # ensure this resource range belongs to a parent of the current conf
- self.parent_set = get_parents_or_404(self.handle, self.obj)
- self.form = None
- self.form_class = form_class
- self.request = request
-
- def __call__(self, *args, **kwargs):
- if self.request.method == 'POST':
- resp = self.handle_post()
- else:
- resp = self.handle_get()
-
- # allow get/post handlers to return a custom response
- if resp:
- return resp
-
- u = AllocationTree.AllocationTreeIP.from_prefix(self.obj).unallocated()
-
- return render('myrpki/prefix_view.html',
- { 'addr': self.obj, 'parent': self.parent_set, 'unallocated': u, 'form': self.form },
- self.request)
-
- def handle_get(self):
- '''Virtual method for extending GET handling. Default action is
- to call the form class constructor with the prefix object.'''
- if self.form_class:
- self.form = self.form_class(self.obj)
-
- def form_valid(self):
- '''Virtual method for handling a valid form. Called by the default
- implementation of handle_post().'''
- pass
-
- def handle_post(self):
- '''Virtual method for extending POST handling. Default implementation
- creates a form object using the form_class in the constructor and passing
- the prefix object. If the form's is_valid() method is True, it then
- invokes this class's form_valid() method.'''
- resp = None
- if self.form_class:
- self.form = self.form_class(self.obj, self.request.POST)
- if self.form.is_valid():
- resp = self.form_valid()
- return resp
-
-@handle_required
-def address_view(request, pk):
- return PrefixView(request, pk)()
-
-class PrefixSplitView(PrefixView):
- '''Class for handling the prefix split form.'''
- def form_valid(self):
- r = misc.parse_resource_range(self.form.cleaned_data['prefix'])
- obj = models.AddressRange(lo=str(r.min), hi=str(r.max), parent=self.obj)
- obj.save()
- return http.HttpResponseRedirect(obj.get_absolute_url())
-
-@handle_required
-def prefix_split_view(request, pk):
- return PrefixSplitView(request, pk, form_class=forms.PrefixSplitForm)()
-
-class PrefixAllocateView(PrefixView):
- '''Class to handle the allocation to child form.'''
- def handle_get(self):
- self.form = forms.PrefixAllocateForm(
- self.obj.allocated.pk if self.obj.allocated else None,
- self.handle.children.all())
-
- def handle_post(self):
- self.form = forms.PrefixAllocateForm(None, self.handle.children.all(), self.request.POST)
- if self.form.is_valid():
- self.obj.allocated = self.form.cleaned_data['child']
- self.obj.save()
- glue.configure_resources(self.handle)
- return http.HttpResponseRedirect(self.obj.get_absolute_url())
-
-@handle_required
-def prefix_allocate_view(request, pk):
- return PrefixAllocateView(request, pk)()
-
-def add_roa_requests(handle, prefix, asns, max_length):
- for asid in asns:
- if debug:
- print 'searching for a roa for AS %d containing %s-%d' % (asid, prefix, max_length)
- req_set = prefix.roa_requests.filter(roa__asn=asid, max_length=max_length)
- if not req_set:
- if debug:
- print 'no roa for AS %d containing %s-%d' % (asid, prefix, max_length)
-
- # find ROAs for prefixes derived from the same resource cert
- # as this prefix
- certs = misc.top_parent(prefix).from_cert.all()
- roa_set = handle.roas.filter(asn=asid, cert__in=certs)
-
- # FIXME: currently only creates a ROA/request for the first
- # resource cert, not all of them
- if roa_set:
- roa = roa_set[0]
- else:
- if debug:
- print 'creating new roa for AS %d containg %s-%d' % (asid, prefix, max_length)
- # no roa is present for this ASN, create a new one
- roa = models.Roa.objects.create(asn=asid, conf=handle,
- active=False, cert=certs[0])
- roa.save()
-
- req = models.RoaRequest.objects.create(prefix=prefix, roa=roa,
- max_length=max_length)
- req.save()
-
-class PrefixRoaView(PrefixView):
- '''Class for handling the ROA creation form.'''
- def form_valid(self):
- asns = asnset(self.form.cleaned_data['asns'])
- add_roa_requests(self.handle, self.obj, asns, self.form.cleaned_data['max_length'])
- glue.configure_resources(self.handle)
- return http.HttpResponseRedirect(self.obj.get_absolute_url())
-
-@handle_required
-def prefix_roa_view(request, pk):
- return PrefixRoaView(request, pk, form_class=forms.PrefixRoaForm)()
-
-class PrefixDeleteView(PrefixView):
- def form_valid(self):
- if self.form.cleaned_data['delete']:
- self.obj.delete()
- return http.HttpResponseRedirect('/myrpki/')
-
-@handle_required
-def prefix_delete_view(request, pk):
- return PrefixDeleteView(request, pk, form_class=forms.PrefixDeleteForm)()
-
-@handle_required
-def roa_request_delete_view(request, pk):
- '''Remove a roa request from a particular prefix.'''
- handle = request.session['handle']
- obj = get_object_or_404(models.RoaRequest.objects, pk=pk)
- prefix = obj.prefix
- # ensure this resource range belongs to a parent of the current conf
- parent_set = get_parents_or_404(handle, prefix)
-
- roa = obj.roa
- obj.delete()
- if not roa.from_roa_request.all():
- roa.delete()
- glue.configure_resources(handle)
-
- return http.HttpResponseRedirect(prefix.get_absolute_url())
-
-@handle_required
-def asn_allocate_view(request, pk):
- handle = request.session['handle']
- obj = get_object_or_404(models.Asn.objects, pk=pk)
- # ensure this resource range belongs to a parent of the current conf
- parent_set = get_parents_or_404(handle, obj)
-
- if request.method == 'POST':
- form = forms.PrefixAllocateForm(None, handle.children.all(), request.POST)
- if form.is_valid():
- obj.allocated = form.cleaned_data['child']
- obj.save()
- glue.configure_resources(handle)
- return http.HttpResponseRedirect(obj.get_absolute_url())
- else:
- form = forms.PrefixAllocateForm(obj.allocated.pk if obj.allocated else None,
- handle.children.all())
-
- return render('myrpki/asn_view.html', { 'form': form,
- 'asn': obj, 'form': form, 'parent': parent_set }, request)
-
-# this is similar to handle_required, except that the handle is given in URL
-def handle_or_404(request, handle):
- "ensure the requested handle is available to this user"
- if request.user.is_superuser:
- conf_set = models.Conf.objects.filter(handle=handle)
- else:
- conf_set = models.Conf.objects.filter(owner=request.user, handle=handle)
- if not conf_set:
- raise http.Http404, 'resource handle not found'
- return conf_set[0]
-
-def serve_file(handle, fname, content_type):
- content, mtime = glue.read_file_from_handle(handle, fname)
- resp = http.HttpResponse(content , mimetype=content_type)
- resp['Content-Disposition'] = 'attachment; filename=%s' % (os.path.basename(fname), )
- resp['Last-Modified'] = email.utils.formatdate(mtime, usegmt=True)
- return resp
-
-@login_required
-def download_csv(request, self_handle, fname):
- conf = handle_or_404(request, self_handle)
- return serve_file(conf.handle, fname + '.csv', 'text/csv')
-
-def download_asns(request, self_handle):
- return download_csv(request, self_handle, 'asns')
-
-def download_roas(request, self_handle):
- return download_csv(request, self_handle, 'roas')
-
-def download_prefixes(request, self_handle):
- return download_csv(request, self_handle, 'prefixes')
-
-def get_parent_handle(conf):
- "determine who my parent is. for now just assume its hardcoded into the django db"
- parent_set = models.Parent.objects.filter(conf=conf)
- if parent_set:
- return parent_set[0].handle
- else:
- raise http.Http404, 'you have no parents'
-
-@csrf_exempt
-@login_required
-def upload_parent_request(request, self_handle):
- conf = handle_or_404(request, self_handle)
- parent_handle = get_parent_handle(conf)
-
- if request.method == 'POST':
- input_file = tempfile.NamedTemporaryFile(delete=False)
- input_file.write(request.raw_post_data)
- input_file.close()
-
- args = ['configure_child', input_file.name ]
- glue.invoke_rpki(parent_handle, args)
-
- os.remove(input_file.name)
-
- return serve_file(parent_handle, 'entitydb/children/%s.xml' % self_handle, 'application/xml')
-
-@csrf_exempt
-@login_required
-def upload_repository_request(request, self_handle):
- conf = handle_or_404(request, self_handle)
- parent_handle = get_parent_handle(conf)
-
- if request.method == 'POST':
- input_file = tempfile.NamedTemporaryFile(delete=False)
- input_file.write(request.raw_post_data)
- input_file.close()
-
- args = ['configure_publication_client', input_file.name ]
- glue.invoke_rpki(parent_handle, args)
-
- os.remove(input_file.name)
-
- # FIXME: this assumes that the parent is running pubd. the actual filename
- # will be different if the parent is not running pubd. see
- # rpki.myrpki.do_configure_publication_client()
- return serve_file(parent_handle, 'entitydb/pubclients/%s.%s.xml' % (parent_handle, self_handle), 'application/xml')
-
-@csrf_exempt
-@login_required
-def upload_myrpki_xml(request, self_handle):
- "handles POST of the myrpki.xml file for a given resource handle."
- conf = handle_or_404(request, self_handle)
-
- if request.method == 'POST':
- try:
- fname = '%s/%s/myrpki.xml' % (settings.MYRPKI_DATA_DIR, self_handle,)
- print >>sys.stderr, 'writing ', fname
- myrpki_xml = open(fname, 'w')
- myrpki_xml.write(request.raw_post_data)
- myrpki_xml.close()
-
- glue.configure_daemons(conf.host)
- except:
- print >>sys.stderr, ''.join(sys.exc_info())
-
- return serve_file(self_handle, 'myrpki.xml', 'application/xml')
-
-# vim:sw=4 ts=8 expandtab