aboutsummaryrefslogtreecommitdiff
path: root/rpkid/rpki/irdb/zookeeper.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid/rpki/irdb/zookeeper.py')
-rw-r--r--rpkid/rpki/irdb/zookeeper.py563
1 files changed, 322 insertions, 241 deletions
diff --git a/rpkid/rpki/irdb/zookeeper.py b/rpkid/rpki/irdb/zookeeper.py
index 19bd55f7..9747bb30 100644
--- a/rpkid/rpki/irdb/zookeeper.py
+++ b/rpkid/rpki/irdb/zookeeper.py
@@ -18,17 +18,10 @@ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
"""
-import subprocess
-import csv
-import re
+# pylint: disable=W0612
+
import os
-import getopt
-import sys
-import base64
-import time
-import glob
import copy
-import warnings
import rpki.config
import rpki.cli
import rpki.sundial
@@ -45,10 +38,9 @@ import rpki.irdb
import django.db.transaction
from lxml.etree import (Element, SubElement, ElementTree,
- fromstring as ElementFromString,
- tostring as ElementToString)
+ tostring as ElementToString)
-from rpki.csv_utils import (csv_reader, csv_writer, BadCSVSyntax)
+from rpki.csv_utils import csv_reader
@@ -96,24 +88,34 @@ class PEM_writer(object):
"""
Write PEM files to disk, keeping track of which ones we've already
written and setting the file mode appropriately.
+
+ Comparing the old file with what we're about to write serves no real
+ purpose except to calm users who find repeated messages about
+ writing the same file confusing.
"""
def __init__(self, logstream = None):
self.wrote = set()
self.logstream = logstream
- def __call__(self, filename, obj):
+ def __call__(self, filename, obj, compare = True):
filename = os.path.realpath(filename)
if filename in self.wrote:
return
tempname = filename
+ pem = obj.get_PEM()
if not filename.startswith("/dev/"):
+ try:
+ if compare and pem == open(filename, "r").read():
+ return
+ except: # pylint: disable=W0702
+ pass
tempname += ".%s.tmp" % os.getpid()
mode = 0400 if filename.endswith(".key") else 0444
if self.logstream is not None:
self.logstream.write("Writing %s\n" % filename)
f = os.fdopen(os.open(tempname, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, mode), "w")
- f.write(obj.get_PEM())
+ f.write(pem)
f.close()
if tempname != filename:
os.rename(tempname, filename)
@@ -174,6 +176,11 @@ class etree_wrapper(object):
if self.msg is not None:
logstream.write(self.msg + "\n")
+ @property
+ def file(self):
+ from cStringIO import StringIO
+ return StringIO(ElementToString(self.etree))
+
class Zookeeper(object):
@@ -218,7 +225,7 @@ class Zookeeper(object):
if handle is None:
raise MissingHandle
- self.handle= handle
+ self.handle = handle
def set_logstream(self, logstream):
@@ -514,7 +521,7 @@ class Zookeeper(object):
try:
self.resource_ca.children.get(handle = child_handle).delete()
except rpki.irdb.Child.DoesNotExist:
- self.log("No such child \"%s\"" % arg)
+ self.log("No such child \"%s\"" % child_handle)
@django.db.transaction.commit_on_success
@@ -590,7 +597,7 @@ class Zookeeper(object):
try:
self.resource_ca.parents.get(handle = parent_handle).delete()
except rpki.irdb.Parent.DoesNotExist:
- self.log("No such parent \"%s\"" % arg)
+ self.log("No such parent \"%s\"" % parent_handle)
@django.db.transaction.commit_on_success
@@ -709,7 +716,7 @@ class Zookeeper(object):
try:
self.server_ca.clients.get(handle = client_handle).delete()
except rpki.irdb.Client.DoesNotExist:
- self.log("No such client \"%s\"" % arg)
+ self.log("No such client \"%s\"" % client_handle)
@django.db.transaction.commit_on_success
@@ -758,9 +765,9 @@ class Zookeeper(object):
assert repository_handle is not None
try:
- self.resource_ca.repositories.get(handle = arg).delete()
+ self.resource_ca.repositories.get(handle = repository_handle).delete()
except rpki.irdb.Repository.DoesNotExist:
- self.log("No such repository \"%s\"" % arg)
+ self.log("No such repository \"%s\"" % repository_handle)
@django.db.transaction.commit_on_success
@@ -1062,11 +1069,63 @@ class Zookeeper(object):
def synchronize(self, *handles_to_poke):
"""
Configure RPKI daemons with the data built up by the other
- commands in this program. Most commands which modify the IRDB
- should call this when they're done.
+ commands in this program. Commands which modify the IRDB and want
+ to whack everything into sync should call this when they're done,
+ but be warned that this can be slow with a lot of CAs.
+
+ Any arguments given are handles of CAs which should be poked with a
+ <self run_now="yes"/> operation.
+ """
+
+ for ca in rpki.irdb.ResourceHolderCA.objects.all():
+ self.synchronize_rpkid_one_ca_core(ca, ca.handle in handles_to_poke)
+ self.synchronize_pubd_core()
+ self.synchronize_rpkid_deleted_core()
+
+
+ @django.db.transaction.commit_on_success
+ def synchronize_ca(self, ca = None, poke = False):
+ """
+ Synchronize one CA. Most commands which modify a CA should call
+ this. CA to synchronize defaults to the current resource CA.
+ """
+
+ if ca is None:
+ ca = self.resource_ca
+ self.synchronize_rpkid_one_ca_core(ca, poke)
+
+
+ @django.db.transaction.commit_on_success
+ def synchronize_deleted_ca(self):
+ """
+ Delete CAs which are present in rpkid's database but not in the
+ IRDB.
+ """
+
+ self.synchronize_rpkid_deleted_core()
+
+
+ @django.db.transaction.commit_on_success
+ def synchronize_pubd(self):
+ """
+ Synchronize pubd. Most commands which modify pubd should call this.
+ """
- Any arguments given are handles to be sent to rpkid at the end of
- the synchronization run with a <self run_now="yes"/> operation.
+ self.synchronize_pubd_core()
+
+
+ def synchronize_rpkid_one_ca_core(self, ca, poke = False):
+ """
+ Synchronize one CA. This is the core synchronization code. Don't
+ call this directly, instead call one of the methods that calls
+ this inside a Django commit wrapper.
+
+ This method configures rpkid with data built up by the other
+ commands in this program. Most commands which modify IRDB values
+ related to rpkid should call this when they're done.
+
+ If poke is True, we append a left-right run_now operation for this
+ CA to the end of whatever other commands this method generates.
"""
# We can use a single BSC for everything -- except BSC key
@@ -1082,258 +1141,285 @@ class Zookeeper(object):
self_regen_margin = self.cfg.getint("self_regen_margin", self_crl_interval / 4,
section = myrpki_section)
- # Make sure that pubd's BPKI CRL is up to date.
+ # See what rpkid already has on file for this entity.
- if self.run_pubd:
- self.call_pubd(rpki.publication.config_elt.make_pdu(
- action = "set",
- bpki_crl = self.server_ca.latest_crl))
+ rpkid_reply = self.call_rpkid(
+ rpki.left_right.self_elt.make_pdu( action = "get", tag = "self", self_handle = ca.handle),
+ rpki.left_right.bsc_elt.make_pdu( action = "list", tag = "bsc", self_handle = ca.handle),
+ rpki.left_right.repository_elt.make_pdu(action = "list", tag = "repository", self_handle = ca.handle),
+ rpki.left_right.parent_elt.make_pdu( action = "list", tag = "parent", self_handle = ca.handle),
+ rpki.left_right.child_elt.make_pdu( action = "list", tag = "child", self_handle = ca.handle))
- for ca in rpki.irdb.ResourceHolderCA.objects.all():
+ self_pdu = rpkid_reply[0]
+ bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
+ repository_pdus = dict((x.repository_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.repository_elt))
+ parent_pdus = dict((x.parent_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.parent_elt))
+ child_pdus = dict((x.child_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.child_elt))
- # See what rpkid and pubd already have on file for this entity.
-
- if self.run_pubd:
- pubd_reply = self.call_pubd(rpki.publication.client_elt.make_pdu(action = "list"))
- client_pdus = dict((x.client_handle, x) for x in pubd_reply if isinstance(x, rpki.publication.client_elt))
-
- rpkid_reply = self.call_rpkid(
- rpki.left_right.self_elt.make_pdu( action = "get", tag = "self", self_handle = ca.handle),
- rpki.left_right.bsc_elt.make_pdu( action = "list", tag = "bsc", self_handle = ca.handle),
- rpki.left_right.repository_elt.make_pdu(action = "list", tag = "repository", self_handle = ca.handle),
- rpki.left_right.parent_elt.make_pdu( action = "list", tag = "parent", self_handle = ca.handle),
- rpki.left_right.child_elt.make_pdu( action = "list", tag = "child", self_handle = ca.handle))
-
- self_pdu = rpkid_reply[0]
- bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
- repository_pdus = dict((x.repository_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.repository_elt))
- parent_pdus = dict((x.parent_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.parent_elt))
- child_pdus = dict((x.child_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.child_elt))
-
- pubd_query = []
- rpkid_query = []
-
- self_cert, created = rpki.irdb.HostedCA.objects.get_or_certify(
- issuer = self.server_ca,
- hosted = ca)
-
- # There should be exactly one <self/> object per hosted entity, by definition
-
- if (isinstance(self_pdu, rpki.left_right.report_error_elt) or
- self_pdu.crl_interval != self_crl_interval or
- self_pdu.regen_margin != self_regen_margin or
- self_pdu.bpki_cert != self_cert.certificate):
- rpkid_query.append(rpki.left_right.self_elt.make_pdu(
- action = "create" if isinstance(self_pdu, rpki.left_right.report_error_elt) else "set",
- tag = "self",
- self_handle = ca.handle,
- bpki_cert = ca.certificate,
- crl_interval = self_crl_interval,
- regen_margin = self_regen_margin))
+ rpkid_query = []
+
+ self_cert, created = rpki.irdb.HostedCA.objects.get_or_certify(
+ issuer = self.server_ca,
+ hosted = ca)
+
+ # There should be exactly one <self/> object per hosted entity, by definition
+
+ if (isinstance(self_pdu, rpki.left_right.report_error_elt) or
+ self_pdu.crl_interval != self_crl_interval or
+ self_pdu.regen_margin != self_regen_margin or
+ self_pdu.bpki_cert != self_cert.certificate):
+ rpkid_query.append(rpki.left_right.self_elt.make_pdu(
+ action = "create" if isinstance(self_pdu, rpki.left_right.report_error_elt) else "set",
+ tag = "self",
+ self_handle = ca.handle,
+ bpki_cert = ca.certificate,
+ crl_interval = self_crl_interval,
+ regen_margin = self_regen_margin))
+
+ # In general we only need one <bsc/> per <self/>. BSC objects
+ # are a little unusual in that the keypair and PKCS #10
+ # subelement is generated by rpkid, so complete setup requires
+ # two round trips.
+
+ bsc_pdu = bsc_pdus.pop(bsc_handle, None)
+
+ if bsc_pdu is None:
+ rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
+ action = "create",
+ tag = "bsc",
+ self_handle = ca.handle,
+ bsc_handle = bsc_handle,
+ generate_keypair = "yes"))
+
+ elif bsc_pdu.pkcs10_request is None:
+ rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
+ action = "set",
+ tag = "bsc",
+ self_handle = ca.handle,
+ bsc_handle = bsc_handle,
+ generate_keypair = "yes"))
+
+ rpkid_query.extend(rpki.left_right.bsc_elt.make_pdu(
+ action = "destroy", self_handle = ca.handle, bsc_handle = b) for b in bsc_pdus)
- # In general we only need one <bsc/> per <self/>. BSC objects
- # are a little unusual in that the keypair and PKCS #10
- # subelement is generated by rpkid, so complete setup requires
- # two round trips.
+ # If we've already got actions queued up, run them now, so we
+ # can finish setting up the BSC before anything tries to use it.
+ if rpkid_query:
+ rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(action = "list", tag = "bsc", self_handle = ca.handle))
+ rpkid_reply = self.call_rpkid(*rpkid_query)
+ bsc_pdus = dict((x.bsc_handle, x)
+ for x in rpkid_reply
+ if isinstance(x, rpki.left_right.bsc_elt) and x.action == "list")
bsc_pdu = bsc_pdus.pop(bsc_handle, None)
+ self.check_error_report(rpkid_reply)
+
+ rpkid_query = []
- if bsc_pdu is None:
- rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
- action = "create",
- tag = "bsc",
+ assert bsc_pdu.pkcs10_request is not None
+
+ bsc, created = rpki.irdb.BSC.objects.get_or_certify(
+ issuer = ca,
+ handle = bsc_handle,
+ pkcs10 = bsc_pdu.pkcs10_request)
+
+ if bsc_pdu.signing_cert != bsc.certificate or bsc_pdu.signing_cert_crl != ca.latest_crl:
+ rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
+ action = "set",
+ tag = "bsc",
+ self_handle = ca.handle,
+ bsc_handle = bsc_handle,
+ signing_cert = bsc.certificate,
+ signing_cert_crl = ca.latest_crl))
+
+ # At present we need one <repository/> per <parent/>, not because
+ # rpkid requires that, but because pubd does. pubd probably should
+ # be fixed to support a single client allowed to update multiple
+ # trees, but for the moment the easiest way forward is just to
+ # enforce a 1:1 mapping between <parent/> and <repository/> objects
+
+ for repository in ca.repositories.all():
+
+ repository_pdu = repository_pdus.pop(repository.handle, None)
+
+ if (repository_pdu is None or
+ repository_pdu.bsc_handle != bsc_handle or
+ repository_pdu.peer_contact_uri != repository.service_uri or
+ repository_pdu.bpki_cert != repository.certificate):
+ rpkid_query.append(rpki.left_right.repository_elt.make_pdu(
+ action = "create" if repository_pdu is None else "set",
+ tag = repository.handle,
self_handle = ca.handle,
+ repository_handle = repository.handle,
bsc_handle = bsc_handle,
- generate_keypair = "yes"))
-
- elif bsc_pdu.pkcs10_request is None:
- rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
- action = "set",
- tag = "bsc",
+ peer_contact_uri = repository.service_uri,
+ bpki_cert = repository.certificate))
+
+ rpkid_query.extend(rpki.left_right.repository_elt.make_pdu(
+ action = "destroy", self_handle = ca.handle, repository_handle = r) for r in repository_pdus)
+
+ # <parent/> setup code currently assumes 1:1 mapping between
+ # <repository/> and <parent/>, and further assumes that the handles
+ # for an associated pair are the identical (that is:
+ # parent.repository_handle == parent.parent_handle).
+
+ for parent in ca.parents.all():
+
+ parent_pdu = parent_pdus.pop(parent.handle, None)
+
+ if (parent_pdu is None or
+ parent_pdu.bsc_handle != bsc_handle or
+ parent_pdu.repository_handle != parent.handle or
+ parent_pdu.peer_contact_uri != parent.service_uri or
+ parent_pdu.sia_base != parent.repository.sia_base or
+ parent_pdu.sender_name != parent.child_handle or
+ parent_pdu.recipient_name != parent.parent_handle or
+ parent_pdu.bpki_cms_cert != parent.certificate):
+ rpkid_query.append(rpki.left_right.parent_elt.make_pdu(
+ action = "create" if parent_pdu is None else "set",
+ tag = parent.handle,
self_handle = ca.handle,
+ parent_handle = parent.handle,
bsc_handle = bsc_handle,
- generate_keypair = "yes"))
+ repository_handle = parent.handle,
+ peer_contact_uri = parent.service_uri,
+ sia_base = parent.repository.sia_base,
+ sender_name = parent.child_handle,
+ recipient_name = parent.parent_handle,
+ bpki_cms_cert = parent.certificate))
- rpkid_query.extend(rpki.left_right.bsc_elt.make_pdu(
- action = "destroy", self_handle = ca.handle, bsc_handle = b) for b in bsc_pdus)
+ try:
- # If we've already got actions queued up, run them now, so we
- # can finish setting up the BSC before anything tries to use it.
+ parent_pdu = parent_pdus.pop(ca.handle, None)
+
+ if (parent_pdu is None or
+ parent_pdu.bsc_handle != bsc_handle or
+ parent_pdu.repository_handle != ca.handle or
+ parent_pdu.peer_contact_uri != ca.rootd.service_uri or
+ parent_pdu.sia_base != ca.rootd.repository.sia_base or
+ parent_pdu.sender_name != ca.handle or
+ parent_pdu.recipient_name != ca.handle or
+ parent_pdu.bpki_cms_cert != ca.rootd.certificate):
+ rpkid_query.append(rpki.left_right.parent_elt.make_pdu(
+ action = "create" if parent_pdu is None else "set",
+ tag = ca.handle,
+ self_handle = ca.handle,
+ parent_handle = ca.handle,
+ bsc_handle = bsc_handle,
+ repository_handle = ca.handle,
+ peer_contact_uri = ca.rootd.service_uri,
+ sia_base = ca.rootd.repository.sia_base,
+ sender_name = ca.handle,
+ recipient_name = ca.handle,
+ bpki_cms_cert = ca.rootd.certificate))
+
+ except rpki.irdb.Rootd.DoesNotExist:
+ pass
- if rpkid_query:
- rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(action = "list", tag = "bsc", self_handle = ca.handle))
- rpkid_reply = self.call_rpkid(*rpkid_query)
- bsc_pdus = dict((x.bsc_handle, x)
- for x in rpkid_reply
- if isinstance(x, rpki.left_right.bsc_elt) and x.action == "list")
- bsc_pdu = bsc_pdus.pop(bsc_handle, None)
- self.check_error_report(rpkid_reply)
+ rpkid_query.extend(rpki.left_right.parent_elt.make_pdu(
+ action = "destroy", self_handle = ca.handle, parent_handle = p) for p in parent_pdus)
- rpkid_query = []
+ # Children are simpler than parents, because they call us, so no URL
+ # to construct and figuring out what certificate to use is their
+ # problem, not ours.
- assert bsc_pdu.pkcs10_request is not None
+ for child in ca.children.all():
- bsc, created = rpki.irdb.BSC.objects.get_or_certify(
- issuer = ca,
- handle = bsc_handle,
- pkcs10 = bsc_pdu.pkcs10_request)
+ child_pdu = child_pdus.pop(child.handle, None)
- if bsc_pdu.signing_cert != bsc.certificate or bsc_pdu.signing_cert_crl != ca.latest_crl:
- rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
- action = "set",
- tag = "bsc",
+ if (child_pdu is None or
+ child_pdu.bsc_handle != bsc_handle or
+ child_pdu.bpki_cert != child.certificate):
+ rpkid_query.append(rpki.left_right.child_elt.make_pdu(
+ action = "create" if child_pdu is None else "set",
+ tag = child.handle,
self_handle = ca.handle,
+ child_handle = child.handle,
bsc_handle = bsc_handle,
- signing_cert = bsc.certificate,
- signing_cert_crl = ca.latest_crl))
-
- # At present we need one <repository/> per <parent/>, not because
- # rpkid requires that, but because pubd does. pubd probably should
- # be fixed to support a single client allowed to update multiple
- # trees, but for the moment the easiest way forward is just to
- # enforce a 1:1 mapping between <parent/> and <repository/> objects
-
- for repository in ca.repositories.all():
-
- repository_pdu = repository_pdus.pop(repository.handle, None)
-
- if (repository_pdu is None or
- repository_pdu.bsc_handle != bsc_handle or
- repository_pdu.peer_contact_uri != repository.service_uri or
- repository_pdu.bpki_cert != repository.certificate):
- rpkid_query.append(rpki.left_right.repository_elt.make_pdu(
- action = "create" if repository_pdu is None else "set",
- tag = repository.handle,
- self_handle = ca.handle,
- repository_handle = repository.handle,
- bsc_handle = bsc_handle,
- peer_contact_uri = repository.service_uri,
- bpki_cert = repository.certificate))
-
- rpkid_query.extend(rpki.left_right.repository_elt.make_pdu(
- action = "destroy", self_handle = ca.handle, repository_handle = r) for r in repository_pdus)
-
- # <parent/> setup code currently assumes 1:1 mapping between
- # <repository/> and <parent/>, and further assumes that the handles
- # for an associated pair are the identical (that is:
- # parent.repository_handle == parent.parent_handle).
-
- for parent in ca.parents.all():
-
- parent_pdu = parent_pdus.pop(parent.handle, None)
-
- if (parent_pdu is None or
- parent_pdu.bsc_handle != bsc_handle or
- parent_pdu.repository_handle != parent.handle or
- parent_pdu.peer_contact_uri != parent.service_uri or
- parent_pdu.sia_base != parent.repository.sia_base or
- parent_pdu.sender_name != parent.child_handle or
- parent_pdu.recipient_name != parent.parent_handle or
- parent_pdu.bpki_cms_cert != parent.certificate):
- rpkid_query.append(rpki.left_right.parent_elt.make_pdu(
- action = "create" if parent_pdu is None else "set",
- tag = parent.handle,
- self_handle = ca.handle,
- parent_handle = parent.handle,
- bsc_handle = bsc_handle,
- repository_handle = parent.handle,
- peer_contact_uri = parent.service_uri,
- sia_base = parent.repository.sia_base,
- sender_name = parent.child_handle,
- recipient_name = parent.parent_handle,
- bpki_cms_cert = parent.certificate))
+ bpki_cert = child.certificate))
- try:
+ rpkid_query.extend(rpki.left_right.child_elt.make_pdu(
+ action = "destroy", self_handle = ca.handle, child_handle = c) for c in child_pdus)
+
+ # If caller wants us to poke rpkid, add that to the very end of the message
+
+ if poke:
+ rpkid_query.append(rpki.left_right.self_elt.make_pdu(
+ action = "set", self_handle = ca.handle, run_now = "yes"))
+
+ # If we changed anything, ship updates off to rpkid
+
+ if rpkid_query:
+ rpkid_reply = self.call_rpkid(*rpkid_query)
+ bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
+ if bsc_handle in bsc_pdus and bsc_pdus[bsc_handle].pkcs10_request:
+ bsc_req = bsc_pdus[bsc_handle].pkcs10_request
+ self.check_error_report(rpkid_reply)
- parent_pdu = parent_pdus.pop(ca.handle, None)
-
- if (parent_pdu is None or
- parent_pdu.bsc_handle != bsc_handle or
- parent_pdu.repository_handle != ca.handle or
- parent_pdu.peer_contact_uri != ca.rootd.service_uri or
- parent_pdu.sia_base != ca.rootd.repository.sia_base or
- parent_pdu.sender_name != ca.handle or
- parent_pdu.recipient_name != ca.handle or
- parent_pdu.bpki_cms_cert != ca.rootd.certificate):
- rpkid_query.append(rpki.left_right.parent_elt.make_pdu(
- action = "create" if parent_pdu is None else "set",
- tag = ca.handle,
- self_handle = ca.handle,
- parent_handle = ca.handle,
- bsc_handle = bsc_handle,
- repository_handle = ca.handle,
- peer_contact_uri = ca.rootd.service_uri,
- sia_base = ca.rootd.repository.sia_base,
- sender_name = ca.handle,
- recipient_name = ca.handle,
- bpki_cms_cert = ca.rootd.certificate))
-
- except rpki.irdb.Rootd.DoesNotExist:
- pass
- rpkid_query.extend(rpki.left_right.parent_elt.make_pdu(
- action = "destroy", self_handle = ca.handle, parent_handle = p) for p in parent_pdus)
+ def synchronize_pubd_core(self):
+ """
+ Configure pubd with data built up by the other commands in this
+ program. This is the core synchronization code. Don't call this
+ directly, instead call a methods that calls this inside a Django
+ commit wrapper.
- # Children are simpler than parents, because they call us, so no URL
- # to construct and figuring out what certificate to use is their
- # problem, not ours.
+ This method configures pubd with data built up by the other
+ commands in this program. Commands which modify IRDB fields
+ related to pubd should call this when they're done.
+ """
- for child in ca.children.all():
+ # If we're not running pubd, the rest of this is a waste of time
- child_pdu = child_pdus.pop(child.handle, None)
+ if not self.run_pubd:
+ return
+
+ # Make sure that pubd's BPKI CRL is up to date.
- if (child_pdu is None or
- child_pdu.bsc_handle != bsc_handle or
- child_pdu.bpki_cert != child.certificate):
- rpkid_query.append(rpki.left_right.child_elt.make_pdu(
- action = "create" if child_pdu is None else "set",
- tag = child.handle,
- self_handle = ca.handle,
- child_handle = child.handle,
- bsc_handle = bsc_handle,
- bpki_cert = child.certificate))
+ self.call_pubd(rpki.publication.config_elt.make_pdu(
+ action = "set",
+ bpki_crl = self.server_ca.latest_crl))
- rpkid_query.extend(rpki.left_right.child_elt.make_pdu(
- action = "destroy", self_handle = ca.handle, child_handle = c) for c in child_pdus)
+ # See what pubd already has on file
- # Publication setup.
+ pubd_reply = self.call_pubd(rpki.publication.client_elt.make_pdu(action = "list"))
+ client_pdus = dict((x.client_handle, x) for x in pubd_reply if isinstance(x, rpki.publication.client_elt))
+ pubd_query = []
- # Um, why are we doing this per resource holder?
+ # Check all clients
- if self.run_pubd:
+ for client in self.server_ca.clients.all():
- for client in self.server_ca.clients.all():
+ client_pdu = client_pdus.pop(client.handle, None)
- client_pdu = client_pdus.pop(client.handle, None)
+ if (client_pdu is None or
+ client_pdu.base_uri != client.sia_base or
+ client_pdu.bpki_cert != client.certificate):
+ pubd_query.append(rpki.publication.client_elt.make_pdu(
+ action = "create" if client_pdu is None else "set",
+ client_handle = client.handle,
+ bpki_cert = client.certificate,
+ base_uri = client.sia_base))
- if (client_pdu is None or
- client_pdu.base_uri != client.sia_base or
- client_pdu.bpki_cert != client.certificate):
- pubd_query.append(rpki.publication.client_elt.make_pdu(
- action = "create" if client_pdu is None else "set",
- client_handle = client.handle,
- bpki_cert = client.certificate,
- base_uri = client.sia_base))
+ # Delete any unknown clients
- pubd_query.extend(rpki.publication.client_elt.make_pdu(
+ pubd_query.extend(rpki.publication.client_elt.make_pdu(
action = "destroy", client_handle = p) for p in client_pdus)
- # If we changed anything, ship updates off to daemons
+ # If we changed anything, ship updates off to pubd
- if rpkid_query:
- rpkid_reply = self.call_rpkid(*rpkid_query)
- bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
- if bsc_handle in bsc_pdus and bsc_pdus[bsc_handle].pkcs10_request:
- bsc_req = bsc_pdus[bsc_handle].pkcs10_request
- self.check_error_report(rpkid_reply)
+ if pubd_query:
+ pubd_reply = self.call_pubd(*pubd_query)
+ self.check_error_report(pubd_reply)
- if pubd_query:
- assert self.run_pubd
- pubd_reply = self.call_pubd(*pubd_query)
- self.check_error_report(pubd_reply)
- # Clean up any <self/> objects rpkid might be holding that don't
- # match a ResourceCA object.
+ def synchronize_rpkid_deleted_core(self):
+ """
+ Remove any <self/> objects present in rpkid's database but not
+ present in the IRDB. This is the core synchronization code.
+ Don't call this directly, instead call a methods that calls this
+ inside a Django commit wrapper.
+ """
rpkid_reply = self.call_rpkid(rpki.left_right.self_elt.make_pdu(action = "list"))
self.check_error_report(rpkid_reply)
@@ -1345,11 +1431,6 @@ class Zookeeper(object):
rpkid_query = [rpki.left_right.self_elt.make_pdu(action = "destroy", self_handle = handle)
for handle in (self_handles - ca_handles)]
- # Poke rpkid to run immediately for any requested handles.
-
- rpkid_query.extend(rpki.left_right.self_elt.make_pdu(
- action = "set", self_handle = h, run_now = "yes") for h in handles_to_poke)
-
if rpkid_query:
rpkid_reply = self.call_rpkid(*rpkid_query)
self.check_error_report(rpkid_reply)