aboutsummaryrefslogtreecommitdiff
path: root/rpki/rpkidb/models.py
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2015-10-11 21:01:18 +0000
committerRob Austein <sra@hactrn.net>2015-10-11 21:01:18 +0000
commitc67ce5844729e3d2a96b020ed18c953e29d44f75 (patch)
tree714a2ec68359d552bf1c80d9dfc9f6cf5899a5fe /rpki/rpkidb/models.py
parent79bf6b0c42fd6e19cf215cc44137650b976e070e (diff)
Checkpoint updated XML code.
svn path=/branches/tk705/; revision=6112
Diffstat (limited to 'rpki/rpkidb/models.py')
-rw-r--r--rpki/rpkidb/models.py141
1 files changed, 93 insertions, 48 deletions
diff --git a/rpki/rpkidb/models.py b/rpki/rpkidb/models.py
index 8963c1ef..5ba743de 100644
--- a/rpki/rpkidb/models.py
+++ b/rpki/rpkidb/models.py
@@ -56,79 +56,120 @@ class XMLTemplate(object):
self.attributes = attributes
self.booleans = booleans
self.elements = elements
-
- def encode(self, obj):
+
+ def encode(self, obj, r_msg):
"""
Encode an ORM object as XML.
"""
- xml = Element(rpki.left_right.xmlns + self.name, nsmap = rpki.left_right.nsmap)
- xml.set(self.name + "_handle", getattr(obj, self.name + "_handle"))
- for k in self.handles:
- v = getattr(obj, k.xml.name)
+ r_pdu = SubElement(r_msg, rpki.left_right.xmlns + self.name, nsmap = rpki.left_right.nsmap)
+ r_pdu.set(self.name + "_handle", getattr(obj, self.name + "_handle"))
+ if self.name != "self":
+ r_pdu.set("self_handle", getattr(obj, "self_handle"))
+ for h in self.handles:
+ k = h.xml_template.name
+ v = getattr(obj, k)
if v is not None:
- xml.set(k.xml.name + "_handle", getattr(v, k.xml.name + "_handle"))
+ r_pdu.set(k + "_handle", getattr(v, k + "_handle"))
for k in self.attributes:
v = getattr(obj, k)
if v is not None:
- xml.set(k, str(v))
+ r_pdu.set(k, str(v))
for k in self.booleans:
if getattr(obj, k):
- xml.set(k, "yes")
+ r_pdu.set(k, "yes")
for k in self.elements:
v = getattr(obj, k)
if v is not None and not v.empty():
- SubElement(xml, rpki.left_right.xmlns + k).text = v.get_Base64()
- return xml
+ SubElement(r_pdu, rpki.left_right.xmlns + k).text = v.get_Base64()
+
+ def acknowledge(self, obj, q_pdu, r_msg):
+ """
+ Add an acknowledgement PDU in response to a create, set, or
+ destroy action.
- def decode(self, obj, xml):
+ This includes a bit of special-case code for BSC objects which has
+ to go somewhere; we could handle it via some kind method of
+ call-out to the BSC model, but it's not worth building a general
+ mechanism for one case, so we do it inline and have done.
+ """
+
+ assert q_pdu.tag == rpki.left_right.xmlns + self.name
+ r_pdu = SubElement(r_msg, rpki.left_right.xmlns + self.name, nsmap = rpki.left_right.nsmap)
+ r_pdu.set(self.name + "_handle", getattr(obj, self.name + "_handle"))
+ if self.name != "self":
+ r_pdu.set("self_handle", getattr(obj, "self_handle"))
+ if self.name == "bsc" and q_pdu.get("action") != "destroy" and obj.pkcs11_request is not None:
+ assert not obj.pkcs11_request.empty()
+ SubElement(r_pdu, rpki.left_right.xmlns + "pkcs11_request").text = obj.pkcs11_request.get_Base64()
+
+ def decode(self, obj, q_pdu):
"""
Decode XML into an ORM object.
"""
- assert xml.tag == rpki.left_right.xmlns + self.name
- setattr(obj, self.name + "_handle", xml.get(self.name + "_handle"))
- for k in self.handles:
- v = xml.get(k.xml.name + "_handle")
+ assert q_pdu.tag == rpki.left_right.xmlns + self.name
+ for h in self.handles:
+ k = h.xml_template.name
+ v = q_pdu.get(k + "_handle")
if v is not None:
- d = { k.xml.name + "_handle" : v }
- if k.xml.name != "self":
- d.update(self = obj.self)
- setattr(obj, k.xml.name, k.objects.get(**d))
+ setattr(obj, k, h.objects.get(**{k + "_handle" : v, "self" : obj.self}))
for k in self.attributes:
- v = xml.get(k)
+ v = q_pdu.get(k)
if v is not None:
v.encode("ascii")
if v.isdigit():
v = long(v)
setattr(obj, k, v)
for k in self.booleans:
- v = xml.get(k)
+ v = q_pdu.get(k)
if v is not None:
setattr(obj, k, v == "yes")
for k in self.elements:
- v = xml.findtext(rpki.left_right.xmlns + k)
+ v = q_pdu.findtext(rpki.left_right.xmlns + k)
if v and v.strip():
setattr(obj, k, self.element_type[k](Base64 = v))
class XMLManager(models.Manager):
"""
- Add a .xml_find() method which looks up the object corresponding to
- the handles in an XML element.
+ Add a few methods which locate or create an object or objects
+ corresponding to the handles in an XML element, as appropriate.
This assumes that models which use it have an "xml" class attribute
holding an XMLTemplate object (above).
"""
- def xml_find(self, xml):
- name = self.model.xml.name
- assert xml.tag == rpki.left_right.xmlns + name
+ 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.objects.get(self_handle = xml.get("self_handle"))
+ elif name != "self":
+ d["self__self_handle"] = xml.get("self_handle")
+ return self.model(**d) if action == "create" else self.get(**d)
+
+ def xml_list(self, xml):
+ name = self.model.xml_template.name
+ action = xml.get("action")
+ assert xml.tag == rpki.left_right.xmlns + name and action in ("get", "list")
+ d = {}
+ if action == "get":
+ d[name + "_handle"] = xml.get(name + "_handle")
if name != "self":
- d.update(self__self_handle = xml.get("self_handle"))
- return self.get(**d)
+ d["self__self_handle"] = xml.get("self_handle")
+ return self.filter(**d) if d else self.all()
+ def xml_get_for_delete(self, xml):
+ name = self.model.xml_template.name
+ 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")
+ return self.get(**d)
# Models
@@ -141,10 +182,11 @@ class Self(models.Model):
bpki_glue = CertificateField(null = True)
objects = XMLManager()
- xml = XMLTemplate(name = "self",
- attributes = ("crl_interval", "regen_margin"),
- booleans = ("use_hsm",),
- elements = ("bpki_cert", "bpki_glue"))
+ xml_template = XMLTemplate(
+ name = "self",
+ attributes = ("crl_interval", "regen_margin"),
+ booleans = ("use_hsm",),
+ elements = ("bpki_cert", "bpki_glue"))
class BSC(models.Model):
bsc_handle = models.SlugField(max_length = 255)
@@ -159,9 +201,9 @@ class BSC(models.Model):
class Meta:
unique_together = ("self", "bsc_handle")
- xml = XMLTemplate(name = "bsc",
- handles = (Self,),
- elements = ("signing_cert", "signing_cert_crl", "pkcs10_request"))
+ xml_template = XMLTemplate(
+ name = "bsc",
+ elements = ("signing_cert", "signing_cert_crl", "pkcs10_request"))
class Repository(models.Model):
repository_handle = models.SlugField(max_length = 255)
@@ -176,10 +218,11 @@ class Repository(models.Model):
class Meta:
unique_together = ("self", "repository_handle")
- xml = XMLTemplate(name = "repository",
- handles = (Self, BSC),
- attributes = ("peer_contact_uri",),
- elements = ("bpki_cert", "bpki_glue"))
+ xml_template = XMLTemplate(
+ name = "repository",
+ handles = (BSC,),
+ attributes = ("peer_contact_uri",),
+ elements = ("bpki_cert", "bpki_glue"))
class Parent(models.Model):
@@ -199,10 +242,11 @@ class Parent(models.Model):
class Meta:
unique_together = ("self", "parent_handle")
- xml = XMLTemplate(name = "parent",
- handles = (Self, BSC, Repository),
- attributes = ("peer_contact_uri", "sia_base", "sender_name", "recipient_name"),
- elements = ("bpki_cms_cert", "bpki_cms_glue"))
+ xml_template = XMLTemplate(
+ name = "parent",
+ handles = (BSC, Repository),
+ attributes = ("peer_contact_uri", "sia_base", "sender_name", "recipient_name"),
+ elements = ("bpki_cms_cert", "bpki_cms_glue"))
class CA(models.Model):
last_crl_sn = models.BigIntegerField()
@@ -241,9 +285,10 @@ class Child(models.Model):
class Meta:
unique_together = ("self", "child_handle")
- xml = XMLTemplate(name = "child",
- handles = (Self, BSC),
- elements = ("bpki_cert", "bpki_glue"))
+ xml_template = XMLTemplate(
+ name = "child",
+ handles = (BSC,),
+ elements = ("bpki_cert", "bpki_glue"))
class ChildCert(models.Model):
cert = CertificateField()