aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2007-09-18 16:45:58 +0000
committerRob Austein <sra@hactrn.net>2007-09-18 16:45:58 +0000
commit0c04890fc5108c58dd9ec0c241c45f6f1038408b (patch)
treef6201a736cddb5f3dd940dc9d613f6df69304ccf
parentf8dbec35dc669ec58d5018ad5b5a73b2cc395551 (diff)
Move bulk of left-right handler to methods on left-right objects (duh).
Add copy hook to handle screwball cases like bsc_cert table. svn path=/scripts/PLAN; revision=984
-rw-r--r--scripts/PLAN32
-rw-r--r--scripts/rpki/left_right.py83
-rwxr-xr-xscripts/rpkid.py59
3 files changed, 107 insertions, 67 deletions
diff --git a/scripts/PLAN b/scripts/PLAN
index fc61268f..051adecf 100644
--- a/scripts/PLAN
+++ b/scripts/PLAN
@@ -101,3 +101,35 @@ objects and database objects, objects shown in green are only database
objects, and left-right PDU objects not shown in that picture are just
left-right PDUs. Or something close to this, details need checking.
So this does look like some kind of mixin would be appropriate.
+
+
+
+Code to pull in an entire self_id context at once turned out to be
+much too complicated. Replacement is more of a demand-paged design.
+Need to be careful about making sure we save out all changes between
+events, objects have a .sql_dirty attribute but I should also add a
+Python set object into which we can insert any object that needs to be
+saved when the current event exits.
+
+Haven't done anything about db.commit() and db.rollback() yet, for
+that matter haven't yet whacked MySQL to enable those features.
+
+Hack du jour is rpki.left_right.data_obj.serve_copy_hook(). I've
+implemented this for bsc objects, seems to work, haven't yet done (eg)
+route_origin objects.
+
+left-right protocol needs boolean flags to reset array values like
+bsc.signing_cert[]. Trivial hack, just haven't done it yet.
+
+Access to object data attributes really ought to be through accessor
+methods so that the .set() method can set the sql_dirty flag
+automagically. Not done yet.
+
+Hmm, do we really need .sql_dirty at all? Maybe just inserting the
+object into the dirty set (above) would suffice? One less thing to
+screw up.
+
+RelaxNG schemas probably ought to be internal rather than files with
+magic names or config variables pointing at files. Makefile hack to
+put a Python wrapper around a .rng file, and automatically convert
+.rng to lxml internal form while we're at it?
diff --git a/scripts/rpki/left_right.py b/scripts/rpki/left_right.py
index c23b0581..7156dc99 100644
--- a/scripts/rpki/left_right.py
+++ b/scripts/rpki/left_right.py
@@ -55,9 +55,7 @@ class base_elt(object):
lxml.etree.tostring(self.toXML(), pretty_print=True, encoding="us-ascii")
class data_elt(base_elt, rpki.sql.sql_persistant):
- """Virtual type for a left-right protocol message elements representing
- top-level persistant data elements.
- """
+ """Virtual class for top-level left-right protocol data elements."""
def sql_decode(self, vals):
rpki.sql.sql_persistant.sql_decode(self, vals)
@@ -70,13 +68,68 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
d["peer_ta"] = self.peer_ta.get_DER()
return d
-def get_ta_DER(thing):
- """None-tolerant wrapper around rpki.x509.X509.get_DER()."""
- if thing is None:
- return None
- else:
- return thing.get_DER()
+ def make_reply(self, r_pdu=None):
+ if r_pdu is None:
+ r_pdu = self.__class__()
+ r_pdu.self_id = self.self_id
+ setattr(r_pdu, self.sql_template.index, getattr(self, self.sql_template.index))
+ r_pdu.action = self.action
+ r_pdu.type = "reply"
+ return r_pdu
+
+ def serve_create(self, db, cur, r_msg):
+ r_pdu = self.make_reply()
+ self.sql_store(db, cur)
+ setattr(r_pdu, self.sql_template.index, getattr(self, self.sql_template.index))
+ r_msg.append(r_pdu)
+
+ def serve_copy_hook(self, db_pdu):
+ pass
+
+ def serve_set(self, db, cur, r_msg):
+ db_pdu = self.sql_fetch(db, cur, getattr(self, self.sql_template.index))
+ if db_pdu is not None:
+ for a in db_pdu.sql_template.columns[1:]:
+ v = getattr(self, a)
+ if v is not None:
+ setattr(db_pdu, a, v)
+ db_pdu.sql_dirty = True
+ self.serve_copy_hook(db_pdu)
+ db_pdu.sql_store(db, cur)
+ r_pdu = self.make_reply()
+ r_msg.append(r_pdu)
+ else:
+ r_msg.append(make_error_report(self))
+ def serve_get(self, db, cur, r_msg):
+ r_pdu = self.sql_fetch(db, cur, getattr(self, self.sql_template.index))
+ if r_pdu is not None:
+ self.make_reply(r_pdu)
+ r_msg.append(r_pdu)
+ else:
+ r_msg.append(make_error_report(self))
+
+ def serve_list(self, db, cur, r_msg):
+ for r_pdu in self.sql_fetch_all(db, cur):
+ self.make_reply(r_pdu)
+ r_msg.append(r_pdu)
+
+ def serve_destroy(self, db, cur, r_msg):
+ db_pdu = self.sql_fetch(db, cur, getattr(self, self.sql_template.index))
+ if db_pdu is not None:
+ db_pdu.sql_delete(db, cur)
+ r_msg.append(self.make_reply())
+ else:
+ r_msg.append(make_error_report(self))
+
+ def serve_dispatch(self, db, cur, r_msg):
+ assert self.type == "query"
+ { "create" : self.serve_create,
+ "set" : self.serve_set,
+ "get" : self.serve_get,
+ "list" : self.serve_list,
+ "destroy" : self.serve_destroy }[self.action](db, cur, r_msg)
+
class extension_preference_elt(base_elt):
"""Container for extension preferences."""
@@ -126,6 +179,18 @@ class bsc_elt(data_elt):
def sql_delete_hook(self, db, cur):
cur.execute("DELETE FROM bsc_cert WHERE bsc_id = %s", self.bsc_id)
+ def serve_copy_hook(self, db_pdu):
+ if self.signing_cert is not None:
+ #
+ # If we had a flag telling us to reset the signing_cert list, we'd
+ # check for it here. For the moment, assume we always concatenate
+ # and never overwrite.
+ #
+ if False:
+ db_pdu.signing_cert = self.signing_cert
+ else:
+ db_pdu.signing_cert = db_pdu.signing_cert + self.signing_cert
+
def startElement(self, stack, name, attrs):
"""Handle <bsc/> element."""
if not name in ("signing_cert", "public_key", "pkcs10_cert_request"):
diff --git a/scripts/rpkid.py b/scripts/rpkid.py
index 6f0f06bf..94d98fed 100755
--- a/scripts/rpkid.py
+++ b/scripts/rpkid.py
@@ -17,57 +17,6 @@ def encode(msg, cms_key, cms_certs):
return rpki.cms.encode(lxml.etree.tostring(msg, pretty_print=True, encoding="us-ascii", xml_declaration=True), cms_key, cms_certs)
def left_right_handler(query, path):
-
- def make_reply(q_pdu, r_pdu=None):
- if r_pdu is None:
- r_pdu = q_pdu.__class__()
- r_pdu.self_id = q_pdu.self_id
- setattr(r_pdu, q_pdu.sql_template.index, getattr(q_pdu, q_pdu.sql_template.index))
- r_pdu.action = q_pdu.action
- r_pdu.type = "reply"
- return r_pdu
-
- def destroy_handler(q_pdu):
- data = q_pdu.sql_fetch(db, cur, getattr(q_pdu, q_pdu.sql_template.index))
- if data is not None:
- data.sql_delete(db, cur)
- r_msg.append(make_reply(q_pdu))
- else:
- r_msg.append(make_error_report(q_pdu))
-
- def create_handler(q_pdu):
- r_pdu = make_reply(q_pdu)
- q_pdu.sql_store(db, cur)
- setattr(r_pdu, q_pdu.sql_template.index, getattr(q_pdu, q_pdu.sql_template.index))
- r_msg.append(r_pdu)
-
- def get_handler(q_pdu):
- r_pdu = q_pdu.sql_fetch(db, cur, getattr(q_pdu, q_pdu.sql_template.index))
- if r_pdu is not None:
- make_reply(q_pdu, r_pdu)
- r_msg.append(r_pdu)
- else:
- r_msg.append(make_error_report(q_pdu))
-
- def set_handler(q_pdu):
- data = q_pdu.sql_fetch(db, cur, getattr(q_pdu, q_pdu.sql_template.index))
- if data is not None:
- for a in data.sql_template.columns[1:]:
- v = getattr(q_pdu, a)
- if v is not None:
- setattr(data, a, v)
- data.sql_dirty = True
- data.sql_store(db, cur)
- r_pdu = make_reply(q_pdu)
- r_msg.append(r_pdu)
- else:
- r_msg.append(make_error_report(q_pdu))
-
- def list_handler(q_pdu):
- for r_pdu in q_pdu.sql_fetch_all(db, cur):
- make_reply(q_pdu, r_pdu)
- r_msg.append(r_pdu)
-
try:
q_elt = decode(query, cms_ta_irbe)
lr_rng.assertValid(q_elt)
@@ -76,12 +25,7 @@ def left_right_handler(query, path):
q_msg = saxer.result
r_msg = rpki.left_right.msg()
for q_pdu in q_msg:
- assert isinstance(q_pdu, rpki.left_right.data_elt) and q_pdu.type == "query"
- { "create" : create_handler,
- "set" : set_handler,
- "get" : get_handler,
- "list" : list_handler,
- "destroy" : destroy_handler }[q_pdu.action](q_pdu)
+ q_pdu.serve_dispatch(db, cur, r_msg)
r_elt = r_msg.toXML()
try:
lr_rng.assertValid(r_elt)
@@ -89,7 +33,6 @@ def left_right_handler(query, path):
print lxml.etree.tostring(r_elt, pretty_print=True, encoding="us-ascii", xml_declaration=True)
raise
return 200, encode(r_elt, cms_key, cms_certs)
-
except Exception, data:
if show_traceback:
traceback.print_exc()