aboutsummaryrefslogtreecommitdiff
path: root/rpki/rpkidb/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpki/rpkidb/models.py')
-rw-r--r--rpki/rpkidb/models.py119
1 files changed, 53 insertions, 66 deletions
diff --git a/rpki/rpkidb/models.py b/rpki/rpkidb/models.py
index d17b6fae..91e6e5c0 100644
--- a/rpki/rpkidb/models.py
+++ b/rpki/rpkidb/models.py
@@ -27,16 +27,6 @@ logger = logging.getLogger(__name__)
# wait for its shave, particularly since disallowing null should be a
# very simple change given migrations.
-# The <self/> element was really badly named, but we weren't using
-# Python when we named it. Perhaps <tenant/> would be a better name?
-# Would want to rename it in left-right too.
-#
-# To make things worse, <self/> elements are handled slightly
-# differently in many places, so there are a number of occurances of
-# "self" or "self_handle" as special case magic. Feh.
-#
-# Cope for now, just be careful.
-
class XMLTemplate(object):
"""
Encapsulate all the voodoo for transcoding between lxml and ORM.
@@ -66,8 +56,8 @@ class XMLTemplate(object):
"""
r_pdu = SubElement(r_msg, rpki.left_right.xmlns + self.name, nsmap = rpki.left_right.nsmap, action = q_pdu.get("action"))
- if self.name != "self":
- r_pdu.set("self_handle", obj.self.self_handle)
+ if self.name != "tenant":
+ r_pdu.set("tenant_handle", obj.tenant.tenant_handle)
r_pdu.set(self.name + "_handle", getattr(obj, self.name + "_handle"))
if q_pdu.get("tag"):
r_pdu.set("tag", q_pdu.get("tag"))
@@ -104,8 +94,8 @@ class XMLTemplate(object):
assert q_pdu.tag == rpki.left_right.xmlns + self.name
action = q_pdu.get("action")
r_pdu = SubElement(r_msg, rpki.left_right.xmlns + self.name, nsmap = rpki.left_right.nsmap, action = action)
- if self.name != "self":
- r_pdu.set("self_handle", obj.self.self_handle)
+ if self.name != "tenant":
+ r_pdu.set("tenant_handle", obj.tenant.tenant_handle)
r_pdu.set(self.name + "_handle", getattr(obj, self.name + "_handle"))
if q_pdu.get("tag"):
r_pdu.set("tag", q_pdu.get("tag"))
@@ -126,7 +116,7 @@ class XMLTemplate(object):
k = h.xml_template.name
v = q_pdu.get(k + "_handle")
if v is not None:
- setattr(obj, k, h.objects.get(**{k + "_handle" : v, "self__exact" : obj.self}))
+ setattr(obj, k, h.objects.get(**{k + "_handle" : v, "tenant" : obj.tenant}))
for k in self.attributes:
v = q_pdu.get(k)
if v is not None:
@@ -153,20 +143,17 @@ class XMLManager(models.Manager): # pylint: disable=W0232
holding an XMLTemplate object (above).
"""
- # Additional complication: "self" is a bad keyword argument, which
- # requires a two-step process.
-
def xml_get_or_create(self, xml):
name = self.model.xml_template.name
action = xml.get("action")
assert xml.tag == rpki.left_right.xmlns + name and action in ("create", "set")
d = { name + "_handle" : xml.get(name + "_handle") }
- if name != "self" and action != "create":
- d["self__self_handle"] = xml.get("self_handle")
+ if name != "tenant" and action != "create":
+ d["tenant__tenant_handle"] = xml.get("tenant_handle")
logger.debug("XMLManager.xml_get_or_create(): name %s action %s filter %r", name, action, d)
result = self.model(**d) if action == "create" else self.get(**d)
- if name != "self" and action == "create":
- result.self = Self.objects.get(self_handle = xml.get("self_handle"))
+ if name != "tenant" and action == "create":
+ result.tenant = Tenant.objects.get(tenant_handle = xml.get("tenant_handle"))
logger.debug("XMLManager.xml_get_or_create(): name %s action %s filter %r result %r", name, action, d, result)
return result
@@ -177,8 +164,8 @@ class XMLManager(models.Manager): # pylint: disable=W0232
d = {}
if action == "get":
d[name + "_handle"] = xml.get(name + "_handle")
- if name != "self":
- d["self__self_handle"] = xml.get("self_handle")
+ if name != "tenant":
+ d["tenant__tenant_handle"] = xml.get("tenant_handle")
logger.debug("XMLManager.xml_list(): name %s action %s filter %r", name, action, d)
result = self.filter(**d) if d else self.all()
logger.debug("XMLManager.xml_list(): name %s action %s filter %r result %r", name, action, d, result)
@@ -189,8 +176,8 @@ class XMLManager(models.Manager): # pylint: disable=W0232
action = xml.get("action")
assert xml.tag == rpki.left_right.xmlns + name and action == "destroy"
d = { name + "_handle" : xml.get(name + "_handle") }
- if name != "self":
- d["self__self_handle"] = xml.get("self_handle")
+ if name != "tenant":
+ d["tenant__tenant_handle"] = xml.get("tenant_handle")
logger.debug("XMLManager.xml_get_for_delete(): name %s action %s filter %r", name, action, d)
result = self.get(**d)
logger.debug("XMLManager.xml_get_for_delete(): name %s action %s filter %r result %r", name, action, d, result)
@@ -228,8 +215,8 @@ def xml_hooks(cls):
# Models
@xml_hooks
-class Self(models.Model):
- self_handle = models.SlugField(max_length = 255)
+class Tenant(models.Model):
+ tenant_handle = models.SlugField(max_length = 255)
use_hsm = models.BooleanField(default = False)
crl_interval = models.BigIntegerField(null = True)
regen_margin = models.BigIntegerField(null = True)
@@ -238,7 +225,7 @@ class Self(models.Model):
objects = XMLManager()
xml_template = XMLTemplate(
- name = "self",
+ name = "tenant",
attributes = ("crl_interval", "regen_margin"),
booleans = ("use_hsm",),
elements = ("bpki_cert", "bpki_glue"))
@@ -311,7 +298,7 @@ class Self(models.Model):
publisher.queue(uri = uri, new_obj = obj, old_hash = h, repository = repository)
def done():
- for ca_detail in CADetail.objects.filter(ca__parent__self = self, state = "active"):
+ for ca_detail in CADetail.objects.filter(ca__parent__tenant = self, state = "active"):
repository = ca_detail.ca.parent.repository
reconcile(uri = ca_detail.crl_uri, obj = ca_detail.latest_crl, repository = repository)
reconcile(uri = ca_detail.manifest_uri, obj = ca_detail.latest_manifest, repository = repository)
@@ -332,7 +319,7 @@ class Self(models.Model):
def serve_run_now(self, rpkid, cb, eb):
- logger.debug("Forced immediate run of periodic actions for self %s[%r]", self.self_handle, self)
+ logger.debug("Forced immediate run of periodic actions for tenant %s[%r]", self.tenant_handle, self)
completion = rpki.rpkid_tasks.CompletionHandler(cb)
self.schedule_cron_tasks(rpkid, completion)
assert completion.count > 0
@@ -351,18 +338,18 @@ class Self(models.Model):
def find_covering_ca_details(self, resources):
"""
- Return all active CADetails for this <self/> which cover a
+ Return all active CADetails for this <tenant/> which cover a
particular set of resources.
If we expected there to be a large number of CADetails, we
could add index tables and write fancy SQL query to do this, but
for the expected common case where there are only one or two
- active CADetails per <self/>, it's probably not worth it. In
+ active CADetails per <tenant/>, it's probably not worth it. In
any case, this is an optimization we can leave for later.
"""
return set(ca_detail
- for ca_detail in CADetail.objects.filter(ca__parent__self = self, state = "active")
+ for ca_detail in CADetail.objects.filter(ca__parent__tenant = self, state = "active")
if ca_detail.covers(resources))
@@ -374,11 +361,11 @@ class BSC(models.Model):
hash_alg = EnumField(choices = ("sha256",), default = "sha256")
signing_cert = CertificateField(null = True)
signing_cert_crl = CRLField(null = True)
- self = models.ForeignKey(Self, related_name = "bscs")
+ tenant = models.ForeignKey(Tenant, related_name = "bscs")
objects = XMLManager()
class Meta: # pylint: disable=C1001,W0232
- unique_together = ("self", "bsc_handle")
+ unique_together = ("tenant", "bsc_handle")
xml_template = XMLTemplate(
name = "bsc",
@@ -403,11 +390,11 @@ class Repository(models.Model):
bpki_glue = CertificateField(null = True)
last_cms_timestamp = SundialField(null = True)
bsc = models.ForeignKey(BSC, related_name = "repositories")
- self = models.ForeignKey(Self, related_name = "repositories")
+ tenant = models.ForeignKey(Tenant, related_name = "repositories")
objects = XMLManager()
class Meta: # pylint: disable=C1001,W0232
- unique_together = ("self", "repository_handle")
+ unique_together = ("tenant", "repository_handle")
xml_template = XMLTemplate(
name = "repository",
@@ -450,7 +437,7 @@ class Repository(models.Model):
bsc = self.bsc
q_der = rpki.publication.cms_msg().wrap(q_msg, bsc.private_key_id, bsc.signing_cert, bsc.signing_cert_crl)
- bpki_ta_path = (rpkid.bpki_ta, self.self.bpki_cert, self.self.bpki_glue, self.bpki_cert, self.bpki_glue)
+ bpki_ta_path = (rpkid.bpki_ta, self.tenant.bpki_cert, self.tenant.bpki_glue, self.bpki_cert, self.bpki_glue)
def done(r_der):
try:
@@ -494,13 +481,13 @@ class Parent(models.Model):
sender_name = models.TextField(null = True)
recipient_name = models.TextField(null = True)
last_cms_timestamp = SundialField(null = True)
- self = models.ForeignKey(Self, related_name = "parents")
+ tenant = models.ForeignKey(Tenant, related_name = "parents")
bsc = models.ForeignKey(BSC, related_name = "parents")
repository = models.ForeignKey(Repository, related_name = "parents")
objects = XMLManager()
class Meta: # pylint: disable=C1001,W0232
- unique_together = ("self", "parent_handle")
+ unique_together = ("tenant", "parent_handle")
xml_template = XMLTemplate(
name = "parent",
@@ -678,8 +665,8 @@ class Parent(models.Model):
try:
r_cms = rpki.up_down.cms_msg(DER = r_der)
r_msg = r_cms.unwrap((rpkid.bpki_ta,
- self.self.bpki_cert,
- self.self.bpki_glue,
+ self.tenant.bpki_cert,
+ self.tenant.bpki_glue,
self.bpki_cert,
self.bpki_glue))
r_cms.check_replay_sql(self, self.peer_contact_uri)
@@ -779,7 +766,7 @@ class CA(models.Model):
if rc_cert is None:
logger.warning("SKI %s in resource class %s is in database but missing from list_response to %s from %s, "
"maybe parent certificate went away?",
- ca_detail.public_key.gSKI(), class_name, parent.self.self_handle, parent.parent_handle)
+ ca_detail.public_key.gSKI(), class_name, parent.tenant.tenant_handle, parent.parent_handle)
publisher = rpki.rpkid.publication_queue(rpkid)
ca_detail.destroy(ca = ca_detail.ca, publisher = publisher)
return publisher.call_pubd(iterator, eb)
@@ -812,14 +799,14 @@ class CA(models.Model):
def done():
if cert_map:
logger.warning("Unknown certificate SKI%s %s in resource class %s in list_response to %s from %s, maybe you want to \"revoke_forgotten\"?",
- "" if len(cert_map) == 1 else "s", ", ".join(cert_map), class_name, parent.self.self_handle, parent.parent_handle)
+ "" if len(cert_map) == 1 else "s", ", ".join(cert_map), class_name, parent.tenant.tenant_handle, parent.parent_handle)
cb()
ca_details = self.ca_details.exclude(state = "revoked")
if ca_details:
rpki.async.iterator(ca_details, loop, done)
else:
logger.warning("Existing resource class %s to %s from %s with no certificates, rekeying",
- class_name, parent.self.self_handle, parent.parent_handle)
+ class_name, parent.tenant.tenant_handle, parent.parent_handle)
self.rekey(rpkid, cb, eb)
@@ -1115,7 +1102,7 @@ class CADetail(models.Model):
if r_msg[0].get("ski") != gski:
raise rpki.exceptions.SKIMismatch
logger.debug("Parent revoked %s, starting cleanup", gski)
- crl_interval = rpki.sundial.timedelta(seconds = parent.self.crl_interval)
+ crl_interval = rpki.sundial.timedelta(seconds = parent.tenant.crl_interval)
nextUpdate = rpki.sundial.now()
if self.latest_manifest is not None:
self.latest_manifest.extract_if_needed()
@@ -1281,7 +1268,7 @@ class CADetail(models.Model):
"""
self.check_failed_publication(publisher)
- crl_interval = rpki.sundial.timedelta(seconds = self.ca.parent.self.crl_interval)
+ crl_interval = rpki.sundial.timedelta(seconds = self.ca.parent.tenant.crl_interval)
now = rpki.sundial.now()
if nextUpdate is None:
nextUpdate = now + crl_interval
@@ -1327,7 +1314,7 @@ class CADetail(models.Model):
self.check_failed_publication(publisher)
- crl_interval = rpki.sundial.timedelta(seconds = self.ca.parent.self.crl_interval)
+ crl_interval = rpki.sundial.timedelta(seconds = self.ca.parent.tenant.crl_interval)
now = rpki.sundial.now()
uri = self.manifest_uri
if nextUpdate is None:
@@ -1476,12 +1463,12 @@ class Child(models.Model):
bpki_cert = CertificateField(null = True)
bpki_glue = CertificateField(null = True)
last_cms_timestamp = SundialField(null = True)
- self = models.ForeignKey(Self, related_name = "children")
+ tenant = models.ForeignKey(Tenant, related_name = "children")
bsc = models.ForeignKey(BSC, related_name = "children")
objects = XMLManager()
class Meta: # pylint: disable=C1001,W0232
- unique_together = ("self", "child_handle")
+ unique_together = ("tenant", "child_handle")
xml_template = XMLTemplate(
name = "child",
@@ -1522,7 +1509,7 @@ class Child(models.Model):
if irdb_resources.valid_until < rpki.sundial.now():
logger.debug("Child %s's resources expired %s", self.child_handle, irdb_resources.valid_until)
else:
- for ca_detail in CADetail.objects.filter(ca__parent__self = self.self, state = "active"):
+ for ca_detail in CADetail.objects.filter(ca__parent__tenant = self.tenant, state = "active"):
resources = ca_detail.latest_ca_cert.get_3779resources() & irdb_resources
if resources.empty():
logger.debug("No overlap between received resources and what child %s should get ([%s], [%s])",
@@ -1540,7 +1527,7 @@ class Child(models.Model):
c.text = child_cert.cert.get_Base64()
SubElement(rc, rpki.up_down.tag_issuer).text = ca_detail.latest_ca_cert.get_Base64()
callback()
- rpkid.irdb_query_child_resources(self.self.self_handle, self.child_handle, got_resources, errback)
+ rpkid.irdb_query_child_resources(self.tenant.tenant_handle, self.child_handle, got_resources, errback)
def up_down_handle_issue(self, rpkid, q_msg, r_msg, callback, errback):
@@ -1610,12 +1597,12 @@ class Child(models.Model):
sia = pkcs10.get_SIA()
logger.debug("Child.up_down_handle_issue(): PKCS #10 SIA %r (%r, %r, %r, %r) %r",
type(sia), type(sia[0]), type(sia[1]), type(sia[2]), type(sia[3]), sia)
-
+
pkcs10.check_valid_request_ca()
- ca_detail = CADetail.objects.get(ca__parent__self = self.self,
+ ca_detail = CADetail.objects.get(ca__parent__tenant = self.tenant,
ca__parent_resource_class = class_name,
state = "active")
- rpkid.irdb_query_child_resources(self.self.self_handle, self.child_handle, got_resources, errback)
+ rpkid.irdb_query_child_resources(self.tenant.tenant_handle, self.child_handle, got_resources, errback)
def up_down_handle_revoke(self, rpkid, q_msg, r_msg, callback, errback):
@@ -1627,7 +1614,7 @@ class Child(models.Model):
class_name = key.get("class_name")
ski = base64.urlsafe_b64decode(key.get("ski") + "=")
publisher = rpki.rpkid.publication_queue(rpkid)
- for child_cert in ChildCert.objects.filter(ca_detail__ca__parent__self = self.self,
+ for child_cert in ChildCert.objects.filter(ca_detail__ca__parent__tenant = self.tenant,
ca_detail__ca__parent_resource_class = class_name,
ski = ski):
child_cert.revoke(publisher = publisher)
@@ -1654,8 +1641,8 @@ class Child(models.Model):
raise rpki.exceptions.BSCNotFound("Could not find BSC")
q_cms = rpki.up_down.cms_msg(DER = q_der)
q_msg = q_cms.unwrap((rpkid.bpki_ta,
- self.self.bpki_cert,
- self.self.bpki_glue,
+ self.tenant.bpki_cert,
+ self.tenant.bpki_glue,
self.bpki_cert,
self.bpki_glue))
q_cms.check_replay_sql(self, "child", self.child_handle)
@@ -1797,7 +1784,7 @@ class EECertificate(models.Model):
ski = BlobField()
cert = CertificateField()
published = SundialField(null = True)
- self = models.ForeignKey(Self, related_name = "ee_certificates")
+ tenant = models.ForeignKey(Tenant, related_name = "ee_certificates")
ca_detail = models.ForeignKey(CADetail, related_name = "ee_certificates")
@@ -1854,7 +1841,7 @@ class EECertificate(models.Model):
sn = sn,
eku = eku)
self = cls(ca_detail = ca_detail, cert = cert, ski = subject_key.get_SKI())
- self.self = ca_detail.ca.parent.self
+ self.tenant = ca_detail.ca.parent.tenant
publisher.queue(
uri = self.uri,
new_obj = self.cert,
@@ -1962,7 +1949,7 @@ class Ghostbuster(models.Model):
cert = CertificateField()
ghostbuster = GhostbusterField()
published = SundialField(null = True)
- self = models.ForeignKey(Self, related_name = "ghostbusters")
+ tenant = models.ForeignKey(Tenant, related_name = "ghostbusters")
ca_detail = models.ForeignKey(CADetail, related_name = "ghostbusters")
@@ -1976,7 +1963,7 @@ class Ghostbuster(models.Model):
return self.generate(publisher = publisher, fast = fast)
now = rpki.sundial.now()
- regen_time = self.cert.getNotAfter() - rpki.sundial.timedelta(seconds = self.self.regen_margin)
+ regen_time = self.cert.getNotAfter() - rpki.sundial.timedelta(seconds = self.tenant.regen_margin)
if now > regen_time and self.cert.getNotAfter() < self.ca_detail.latest_ca_cert.getNotAfter():
logger.debug("%r past threshold %s, regenerating", self, regen_time)
@@ -2133,7 +2120,7 @@ class ROA(models.Model):
cert = CertificateField()
roa = ROAField()
published = SundialField(null = True)
- self = models.ForeignKey(Self, related_name = "roas")
+ tenant = models.ForeignKey(Tenant, related_name = "roas")
ca_detail = models.ForeignKey(CADetail, related_name = "roas")
@@ -2155,7 +2142,7 @@ class ROA(models.Model):
return self.regenerate(publisher = publisher, fast = fast)
now = rpki.sundial.now()
- regen_time = self.cert.getNotAfter() - rpki.sundial.timedelta(seconds = self.self.regen_margin)
+ regen_time = self.cert.getNotAfter() - rpki.sundial.timedelta(seconds = self.tenant.regen_margin)
if now > regen_time and self.cert.getNotAfter() < self.ca_detail.latest_ca_cert.getNotAfter():
logger.debug("%r past threshold %s, regenerating", self, regen_time)
@@ -2221,7 +2208,7 @@ class ROA(models.Model):
logger.debug("Keeping old ca_detail %r for ROA %r", ca_detail, self)
else:
logger.debug("Searching for new ca_detail for ROA %r", self)
- for ca_detail in CADetail.objects.filter(ca__parent__self = self.self, state = "active"):
+ for ca_detail in CADetail.objects.filter(ca__parent__tenant = self.tenant, state = "active"):
resources = ca_detail.latest_ca_cert.get_3779resources()
if not ca_detail.has_expired() and v4.issubset(resources.v4) and v6.issubset(resources.v6):
logger.debug("Using new ca_detail %r for ROA %r", ca_detail, self)