def fetch_published_objects(): """Query rpkid for all objects published by local users, and look up the current validation status of each object. The validation status is used later to send alerts for objects which have transitioned to invalid. """ logger.info('querying for published objects') handles = [conf.handle for conf in Conf.objects.all()] req = [ rpki.left_right.list_published_objects_elt.make_pdu(action='list', self_handle=h, tag=h) for h in handles ] z = Zookeeper() pdus = z.call_rpkid(*req) for pdu in pdus: if isinstance(pdu, rpki.left_right.list_published_objects_elt): # Look up the object in the rcynic cache qs = models.RepositoryObject.objects.filter(uri=pdu.uri) if qs: # get the current validity state valid = qs[0].statuses.filter(status=object_accepted).exists() uris[pdu.uri] = (pdu.self_handle, valid, False, None) logger.debug('adding ' + pdu.uri) else: # this object is not in the cache. it was either published # recently, or disappared previously. if it disappeared # previously, it has already been alerted. in either case, we # omit the uri from the list since we are interested only in # objects which were valid and are no longer valid pass elif isinstance(pdu, rpki.left_right.report_error_elt): logging.error('rpkid reported an error: %s', pdu.error_code)
def list_received_resources(log, conf): """ Query rpkid for this resource handle's received resources. The semantics are to clear the entire table and populate with the list of certs received. Other models should not reference the table directly with foreign keys. """ z = Zookeeper(handle=conf.handle, disable_signal_handlers=True) req = Element(tag_msg, nsmap=nsmap, type="query", version=version) SubElement(req, tag_list_received_resources, tenant_handle=conf.handle, tag=conf.handle) try: pdus = z.call_rpkid(req) except Exception as err: logger.error('caught exception while attempting to query rpkid') logger.exception(err) return # pdus is sometimes None (see https://trac.rpki.net/ticket/681) if pdus is None: print >> log, 'error: call_rpkid() returned None for handle %s when fetching received resources' % conf.handle return models.ResourceCert.objects.filter(conf=conf).delete() for pdu in pdus: if pdu.get("parent_handle") != conf.handle: parent = models.Parent.objects.get(issuer=conf, handle=pdu.get("parent_handle")) else: # root cert, self-signed parent = None not_before = datetime.strptime(pdu.get("notBefore"), "%Y-%m-%dT%H:%M:%SZ") not_after = datetime.strptime(pdu.get("notAfter"), "%Y-%m-%dT%H:%M:%SZ") cert = models.ResourceCert.objects.create(conf=conf, parent=parent, not_before=not_before, not_after=not_after, uri=pdu.get("uri")) for asn in resource_set_as(pdu.get("asn")): cert.asn_ranges.create(min=asn.min, max=asn.max) for rng in resource_set_ipv4(pdu.get("ipv4")): cert.address_ranges.create(prefix_min=rng.min, prefix_max=rng.max) for rng in resource_set_ipv6(pdu.get("ipv6")): cert.address_ranges_v6.create(prefix_min=rng.min, prefix_max=rng.max)
def list_received_resources(log, conf): """ Query rpkid for this resource handle's received resources. The semantics are to clear the entire table and populate with the list of certs received. Other models should not reference the table directly with foreign keys. """ z = Zookeeper(handle=conf.handle, disable_signal_handlers=True) pdus = z.call_rpkid(list_received_resources_elt.make_pdu(self_handle=conf.handle)) # pdus is sometimes None (see https://trac.rpki.net/ticket/681) if pdus is None: print >>log, 'error: call_rpkid() returned None for handle %s when fetching received resources' % conf.handle return models.ResourceCert.objects.filter(conf=conf).delete() for pdu in pdus: if isinstance(pdu, report_error_elt): # this will cause the db to be rolled back so the above delete() # won't clobber existing resources raise LeftRightError(pdu) elif isinstance(pdu, list_received_resources_elt): if pdu.parent_handle != conf.handle: parent = models.Parent.objects.get(issuer=conf, handle=pdu.parent_handle) else: # root cert, self-signed parent = None not_before = datetime.strptime(pdu.notBefore, "%Y-%m-%dT%H:%M:%SZ") not_after = datetime.strptime(pdu.notAfter, "%Y-%m-%dT%H:%M:%SZ") cert = models.ResourceCert.objects.create( conf=conf, parent=parent, not_before=not_before, not_after=not_after, uri=pdu.uri) for asn in resource_set_as(pdu.asn): cert.asn_ranges.create(min=asn.min, max=asn.max) for rng in resource_set_ipv4(pdu.ipv4): cert.address_ranges.create(prefix_min=rng.min, prefix_max=rng.max) for rng in resource_set_ipv6(pdu.ipv6): cert.address_ranges_v6.create(prefix_min=rng.min, prefix_max=rng.max) else: print >>log, "error: unexpected pdu from rpkid type=%s" % type(pdu)
def list_received_resources(log, conf): """ Query rpkid for this resource handle's received resources. The semantics are to clear the entire table and populate with the list of certs received. Other models should not reference the table directly with foreign keys. """ z = Zookeeper(handle=conf.handle, disable_signal_handlers=True) req = Element(tag_msg, nsmap=nsmap, type="query", version=version) SubElement(req, tag_list_received_resources, tenant_handle=conf.handle, tag=conf.handle) try: pdus = z.call_rpkid(req) except Exception as err: logger.error('caught exception while attempting to query rpkid') logger.exception(err) return # pdus is sometimes None (see https://trac.rpki.net/ticket/681) if pdus is None: print >>log, 'error: call_rpkid() returned None for handle %s when fetching received resources' % conf.handle return models.ResourceCert.objects.filter(conf=conf).delete() for pdu in pdus: if pdu.get("parent_handle") != conf.handle: parent = models.Parent.objects.get(issuer=conf, handle=pdu.get("parent_handle")) else: # root cert, self-signed parent = None not_before = datetime.strptime(pdu.get("notBefore"), "%Y-%m-%dT%H:%M:%SZ") not_after = datetime.strptime(pdu.get("notAfter"), "%Y-%m-%dT%H:%M:%SZ") cert = models.ResourceCert.objects.create( conf=conf, parent=parent, not_before=not_before, not_after=not_after, uri=pdu.get("uri")) for asn in resource_set_as(pdu.get("asn")): cert.asn_ranges.create(min=asn.min, max=asn.max) for rng in resource_set_ipv4(pdu.get("ipv4")): cert.address_ranges.create(prefix_min=rng.min, prefix_max=rng.max) for rng in resource_set_ipv6(pdu.get("ipv6")): cert.address_ranges_v6.create(prefix_min=rng.min, prefix_max=rng.max)
def fetch_published_objects(): """Query rpkid for all objects published by local users, and look up the current validation status of each object. The validation status is used later to send alerts for objects which have transitioned to invalid. """ logger.info('querying for published objects') handles = [conf.handle for conf in Conf.objects.all()] q_msg = Element(rpki.left_right.tag_msg, nsmap = rpki.left_right.nsmap, type = "query", version = rpki.left_right.version) for h in handles: SubElement(q_msg, rpki.left_right.tag_list_published_objects, tenant_handle=h, tag=h) try: z = Zookeeper() r_msg = z.call_rpkid(q_msg) except Exception as err: logger.error('Unable to connect to rpkid to fetch list of published objects') logger.exception(err) # Should be safe to continue processing the rcynic cache, we just don't do any notifications return for r_pdu in r_msg: if r_pdu.tag == rpki.left_right.tag_list_published_objects: # Look up the object in the rcynic cache uri = r_pdu.get('uri') ext = os.path.splitext(uri)[1] if ext in model_map: model = model_map[ext] handle = r_pdu.get('tenant_handle') if model.objects.filter(uri=uri).exists(): v = uris.setdefault(handle, []) v.append(uri) logger.debug('adding %s', uri) #else: # this object is not in the cache. it was either published # recently, or disappared previously. if it disappeared # previously, it has already been alerted. in either case, we # omit the uri from the list since we are interested only in # objects which were valid and are no longer valid else: logger.debug('skipping object ext=%s uri=%s' % (ext, uri)) elif r_pdu.tag == rpki.left_right.tag_report_error: logging.error('rpkid reported an error: %s', r_pdu.get("error_code"))