diff options
Diffstat (limited to 'rpkid/rpki/gui/app/glue.py')
-rw-r--r-- | rpkid/rpki/gui/app/glue.py | 99 |
1 files changed, 90 insertions, 9 deletions
diff --git a/rpkid/rpki/gui/app/glue.py b/rpkid/rpki/gui/app/glue.py index 70ec255e..9245fa71 100644 --- a/rpkid/rpki/gui/app/glue.py +++ b/rpkid/rpki/gui/app/glue.py @@ -20,6 +20,7 @@ PERFORMANCE OF THIS SOFTWARE. from __future__ import with_statement import os, os.path, csv, stat, sys +from datetime import datetime, timedelta from django.db.models import F @@ -27,7 +28,7 @@ import rpki, rpki.async, rpki.http, rpki.x509, rpki.left_right from rpki.myrpki import CA, IRDB, csv_writer from rpki.gui.app import models, settings -def conf(*handle): +def confpath(*handle): """ Return the absolute pathname to the configuration directory for the given resource handle. If additional arguments are given, they @@ -40,7 +41,7 @@ def conf(*handle): 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: + with open(confpath(handle, fname), 'r') as fp: data = fp.read() mtime = os.fstat(fp.fileno())[stat.ST_MTIME] return data, mtime @@ -81,7 +82,7 @@ def build_rpkid_caller(cfg, verbose=False): """ bpki_servers_dir = cfg.get("bpki_servers_directory") if not bpki_servers_dir.startswith('/'): - bpki_servers_dir = conf(cfg.get('handle'), bpki_servers_dir) + bpki_servers_dir = confpath(cfg.get('handle'), bpki_servers_dir) bpki_servers = CA(cfg.filename, bpki_servers_dir) rpkid_base = "http://%s:%s/" % (cfg.get("rpkid_server_host"), cfg.get("rpkid_server_port")) @@ -129,7 +130,7 @@ def configure_resources(log, handle): files for use with the myrpki.py command line script. """ - path = conf(handle.handle) + path = confpath(handle.handle) cfg = rpki.config.parser(os.path.join(path, 'rpki.conf'), 'myrpki') output_asns(qualify_path(path, cfg.get('asn_csv')), handle) @@ -150,7 +151,7 @@ def configure_resources(log, handle): children = [] for child in handle.children.all(): - asns = rpki.resource_set.resource_set_as(a.as_resource_range() for a in child.asns.all()) + asns = rpki.resource_set.resource_set_as([a.as_resource_range() for a in child.address_range.all()]) v4 = rpki.resource_set.resource_set_ipv4() v6 = rpki.resource_set.resource_set_ipv6() @@ -175,16 +176,96 @@ def configure_resources(log, handle): else: ghostbusters.append((None, vcard)) + # for hosted handles, get the config for the irdbd/rpkid host + if handle.host: + cfg = rpki.config.parser(confpath(handle.host.handle, 'rpki.conf'), 'myrpki') + irdb = IRDB(cfg) irdb.update(handle, roa_requests, children, ghostbusters) irdb.close() - # for hosted handles, get the config for the rpkid host - if handle.host: - cfg = rpki.config.parser(conf(handle.host.handle, 'rpki.conf'), 'myrpki') - # contact rpkid to request immediate update call_rpkid = build_rpkid_caller(cfg) call_rpkid(rpki.left_right.self_elt.make_pdu(action='set', self_handle=handle.handle, run_now=True)) +def list_received_resources(conf): + """ + Query rpkid for this resource handle's children and received resources. + """ + # if this handle is hosted, get the cfg for the host + rpki_conf = conf.host if conf.host else conf + cfg = rpki.config.parser(confpath(rpki_conf.handle, 'rpki.conf'), 'myrpki') + call_rpkid = build_rpkid_caller(cfg) + pdus = call_rpkid(rpki.left_right.list_received_resources_elt.make_pdu(self_handle=conf.handle), + rpki.left_right.child_elt.make_pdu(action="list", self_handle=conf.handle)) + + for pdu in pdus: + if isinstance(pdu, rpki.left_right.child_elt): + # have we seen this child before? + child_set = conf.children.filter(handle=pdu.child_handle) + if not child_set: + # default to 1 year. no easy way to query irdb for the + # current value. + valid_until = datetime.now() + timedelta(days=365) + child = models.Child(conf=conf, handle=pdu.child_handle, + valid_until=valid_until) + child.save() + + elif isinstance(pdu, rpki.left_right.list_received_resources_elt): + + # have we seen this parent before? + parent_set = conf.parents.filter(handle=pdu.parent_handle) + if not parent_set: + parent = models.Parent(conf=conf, handle=pdu.parent_handle) + parent.save() + else: + parent = parent_set[0] + + not_before = datetime.strptime(pdu.notBefore, "%Y-%m-%dT%H:%M:%SZ") + not_after = datetime.strptime(pdu.notAfter, "%Y-%m-%dT%H:%M:%SZ") + + # have we seen this resource cert before? + cert_set = parent.resources.filter(uri=pdu.uri) + if cert_set.count() == 0: + cert = models.ResourceCert(uri=pdu.uri, parent=parent, + not_before=not_before, not_after=not_after) + else: + cert = cert_set[0] + # update timestamps since it could have been modified + cert.not_before = not_before + cert.not_after = not_after + cert.save() + + for asn in rpki.resource_set.resource_set_as(pdu.asn): + # see if this resource is already part of the cert + if cert.asn.filter(lo=asn.min, hi=asn.max).count() == 0: + # ensure this range wasn't seen from another of our parents + for v in models.Asn.objects.filter(lo=asn.min, hi=asn.max): + # determine if resource is delegated from another parent + if v.from_cert.filter(parent__in=conf.parents.all()).count(): + cert.asn.add(v) + break + else: + cert.asn.create(lo=asn.min, hi=asn.max) + cert.save() + + # IPv4/6 - not separated in the django db + def add_missing_address(addr_set): + for ip in addr_set: + lo=str(ip.min) + hi=str(ip.max) + if cert.address_range.filter(lo=lo, hi=hi).count() == 0: + # ensure that this range wasn't previously seen from another of our parents + for v in models.AddressRange.objects.filter(lo=lo, hi=hi): + # determine if this resource is delegated from another parent as well + if v.from_cert.filter(parent__in=conf.parents.all()).count(): + cert.address_range.add(v) + break + else: + cert.address_range.create(lo=lo, hi=hi) + cert.save() + + add_missing_address(rpki.resource_set.resource_set_ipv4(pdu.ipv4)) + add_missing_address(rpki.resource_set.resource_set_ipv6(pdu.ipv6)) + # vim:sw=4 ts=8 expandtab |