diff options
Diffstat (limited to 'rpkid/rpki/irdb/zookeeper.py')
-rw-r--r-- | rpkid/rpki/irdb/zookeeper.py | 563 |
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) |