# Point of the exercise is to generate examples, so put them first. def main(): alice_ta = "You can hack anything you want with TECO and DDT" bob_ta = "God is real unless declared integer" carol_ta = "I've had fun before. This isn't it." auth_cms = "Go, lemmings, go!" for handle, ta in (("Alice", alice_ta), ("Bob", bob_ta), ("Carol", carol_ta)): e = Element("child_request") e.set("xmlns", xmlns) e.set("version", version) e.set("child_handle", handle) TextElement(e, "child_bpki_ta", ta) prettyprint(e) ee = Element("error") ee.set("xmlns", xmlns) ee.set("version", version) ee.set("reason", "refused") ee.append(e) prettyprint(ee) e = Element("parent_response") e.set("xmlns", xmlns) e.set("version", version) e.set("service_uri", "http://a.example/up-down/Alice/Bob-42") e.set("child_handle", "Bob-42") e.set("parent_handle", "Alice") TextElement(e, "parent_bpki_ta", alice_ta) SubElement(e, "offer") prettyprint(e) e = Element("publisher_request") e.set("xmlns", xmlns) e.set("version", version) e.set("tag", "A0001") e.set("publisher_handle", "Bob") TextElement(e, "publisher_bpki_ta", bob_ta) prettyprint(e) e = Element("repository_response") e.set("xmlns", xmlns) e.set("version", version) e.set("tag", "A0001") e.set("service_uri", "http://a.example/publication/Alice/Bob-42") e.set("publisher_handle", "Alice/Bob-42") e.set("sia_base", "rsync://a.example/rpki/Alice/Bob-42/") e.set("rrdp_notification_uri", "https://rpki.example/rrdp/notify.xml") TextElement(e, "repository_bpki_ta", alice_ta) prettyprint(e) e = TextElement(None, "authorization", carol_ta) e.set("xmlns", xmlns) e.set("version", version) e.set("authorized_sia_base", "rsync://a.example/rpki/Alice/Bob-42/Carol/") prettyprint(e) e = Element("parent_response") e.set("xmlns", xmlns) e.set("version", version) e.set("service_uri", "http://bob.example/up-down/Bob/Carol") e.set("child_handle", "Carol") e.set("parent_handle", "Bob") TextElement(e, "parent_bpki_ta", bob_ta) TextElement(e, "referral", auth_cms, referrer = "Alice/Bob-42") prettyprint(e) e = Element("publisher_request") e.set("xmlns", xmlns) e.set("version", version) e.set("tag", "A0002") e.set("publisher_handle", "Carol") TextElement(e, "publisher_bpki_ta", carol_ta) TextElement(e, "referral", auth_cms, referrer = "Alice/Bob-42") prettyprint(e) e = Element("repository_response") e.set("xmlns", xmlns) e.set("version", version) e.set("tag", "A0002") e.set("service_uri", "http://a.example/publication/Alice/Bob-42/Carol") e.set("publisher_handle", "Alice/Bob-42/Carol") e.set("sia_base", "rsync://a.example/rpki/Alice/Bob-42/Carol/") TextElement(e, "repository_bpki_ta", alice_ta) prettyprint(e) # Rest of file is the machinery to generate the examples. from lxml.etree import ElementTree, Element, SubElement, tostring as ElementToString, RelaxNG, XML from base64 import b64encode import copy import sys import re matcher = re.compile(r"( *<[^/ >]+)([^>]*)>(.*)$") schema = ElementTree(file = "rpki-setup.rng") version = schema.xpath("*[local-name() = 'define' and @name = 'version']")[0][0].text xmlns = schema.getroot().get("ns") schema = RelaxNG(schema) dashes = ("-" * 69) + "\n" def TextElement(e, tag, text, **kwargs): s = Element(tag, **kwargs) s.text = b64encode(text) if e is not None: e.append(s) return s def make_tag(e, tag): if tag: return tag tag = e.tag if tag == "error": return tag + "." + make_tag(e[0], None) for handle in ("parent_handle", "child_handle", "publisher_handle", "signer_handle"): if e.get(handle): tag += "." + e.get(handle) break return tag.replace("/", ".") def validate(e): if e.get("xmlns"): e = XML(ElementToString(e)) if not schema.validate(e): sys.exit("Failure validating\n%s%s" % ( ElementToString(e, pretty_print = True, encoding = "us-ascii", xml_declaration = False), schema.error_log.last_error)) def prettyprint(e, tag = None): e = copy.deepcopy(e) validate(e) s = ElementToString(e, pretty_print = True, encoding = "us-ascii", xml_declaration = False) lines = [] for line in s.splitlines(): line = line.expandtabs() m = matcher.match(line) if not m: lines.append(line) else: elt, attrs, rest = m.groups() attrs = attrs.split() if attrs == ["/"] and not rest: elt += "/" attrs = [] lines.append(elt) if attrs: indent = " " * (elt.find("<") + 4) lines.extend(indent + a for a in attrs) lines[-1] += ">" if rest: i = rest.find("") if __name__ == "__main__": main()