From ee653e81f67a42841c86f7797395643001fa1565 Mon Sep 17 00:00:00 2001 From: r00t Date: Sat, 26 May 2018 08:40:21 -0400 Subject: [PATCH] grrr. validation errors, but i think it's how i'm modifying the thing --- bdisk/bdisk.xsd | 133 ++++++++++++++++++++------------ bdisk/confparse.py | 50 ++++++++---- bdisk/utils.py | 10 +++ docs/examples/multi_profile.xml | 35 +++++---- docs/examples/regen_multi.py | 2 +- 5 files changed, 146 insertions(+), 84 deletions(-) diff --git a/bdisk/bdisk.xsd b/bdisk/bdisk.xsd index e54c4e1..90c6c26 100644 --- a/bdisk/bdisk.xsd +++ b/bdisk/bdisk.xsd @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -90,9 +90,9 @@ - + - + @@ -105,7 +105,7 @@ - + @@ -180,6 +180,8 @@ + + @@ -234,7 +236,7 @@ - + @@ -244,7 +246,7 @@ - + @@ -275,7 +277,7 @@ - + @@ -306,14 +308,14 @@ + type="xs:normalizedString"/> + type="xs:normalizedString"/> - + + + + + + + + + + - + + + + + + + @@ -389,12 +405,20 @@ - + - + + + + + + + + + - - + + @@ -452,15 +478,17 @@ - - + + - + @@ -590,7 +618,7 @@ minOccurs="0"/> - + @@ -600,9 +628,9 @@ - + - + @@ -614,10 +642,10 @@ - - - - + + + + @@ -691,7 +719,7 @@ - + @@ -700,45 +728,45 @@ - + - + - + - + - + - + - + - - + + @@ -752,17 +780,19 @@ - + - + - + - + @@ -773,14 +803,15 @@ - + - + - + @@ -789,9 +820,9 @@ - - - + + + - + diff --git a/bdisk/confparse.py b/bdisk/confparse.py index ab3c608..ec8080f 100644 --- a/bdisk/confparse.py +++ b/bdisk/confparse.py @@ -12,7 +12,8 @@ transform = utils.transform() valid = utils.valid() class Conf(object): - def __init__(self, cfg, profile = None, validate = False): + def __init__(self, cfg, profile = None, validate_cfg = False, + xsd_file = None): """ A configuration object. @@ -40,6 +41,9 @@ class Conf(object): You can provide any combination of these (e.g. "profile={'id': 2, 'name' = 'some_profile'}"). """ + if validate_cfg == 'pre': + # Validate before attempting any other operations + self.validate() self.xml_suppl = utils.xml_supplicant(cfg, profile = profile) self.xml = self.xml_suppl.xml for e in self.xml_suppl.xml.iter(): @@ -48,12 +52,11 @@ class Conf(object): with open('/tmp/parsed.xml', 'wb') as f: f.write(lxml.etree.tostring(self.xml_suppl.xml)) self.profile = self.xml_suppl.profile - self.xsd = None + self.xsd = xsd_file self.cfg = {} - #if validate: - #if not self.validate(): # Need to write the XSD - # raise ValueError('The configuration did not pass XSD/schema ' - # 'validation') + if validate_cfg: + # Validation post-substitution + self.validate() def get_pki_obj(self, pki, pki_type): elem = {} @@ -99,7 +102,7 @@ class Conf(object): _source_item['hash_algo'] = None if item == 'sig': if elem.get('keys', False): - _keys = [i.strip() for i in elem.attrib['keys'].split(',')] + _keys = [i.strip() for i in elem.attrib['keys'].split()] _source_item['keys'] = _keys else: _source_item['keys'] = [] @@ -108,9 +111,9 @@ class Conf(object): else: _source_item['keyserver'] = None _item = elem.text - _flags = elem.get('flags', []) + _flags = elem.get('flags', '') if _flags: - for f in _flags.split(','): + for f in _flags.split(): if f.strip().lower() == 'none': continue _source_item['flags'].append(f.strip().lower()) @@ -129,10 +132,12 @@ class Conf(object): return(_source_item) def get_xsd(self): - path = os.path.join(os.path.dirname(__file__), - 'bdisk.xsd') - with open(path, 'r') as f: - xsd = f.read() + if not self.xsd: + path = os.path.join(os.path.dirname(__file__), 'bdisk.xsd') + else: + path = os.path.abspath(os.path.expanduser(self.xsd)) + with open(path, 'rb') as f: + xsd = lxml.etree.parse(f) return(xsd) def parse_accounts(self): @@ -302,5 +307,20 @@ class Conf(object): return() def validate(self): - self.xsd = etree.XMLSchema(self.get_xsd()) - return(self.xsd.validate(self.xml)) \ No newline at end of file + # TODO: perform further validations that we can't do in XSD. + # TODO: FIX ME. ALWAYS RETURNS INVALID: + # lxml.etree.DocumentInvalid: Element 'bdisk': No matching global declaration available for the validation root. + xsd = self.get_xsd() + self.xsd = etree.XMLSchema(xsd) + # This would return a bool if it validates or not. + #self.xsd.validate(self.xml) + # We want to get a more detailed exception. + #xml = self.xml_suppl.return_full().getroottree() + xml = self.xml_suppl.return_full() + with open('/tmp/bdisk.xml', 'wb') as f: + f.write(etree.tostring(xml)) + with open('/tmp/bdisk.xsd', 'wb') as f: + f.write(etree.tostring(xsd)) + self.xsd.assertValid(xml) + #print(self.xsd.validate(xml)) + return() diff --git a/bdisk/utils.py b/bdisk/utils.py index 7dab775..a057f1b 100644 --- a/bdisk/utils.py +++ b/bdisk/utils.py @@ -975,6 +975,16 @@ class xml_supplicant(object): ).format(element.text)) return(path) + def return_full(self): + #nsmap = self.return_naked_ns() + local_xml = lxml.etree.Element('bdisk', + nsmap = self.orig_xml.nsmap, + attrib = self.orig_xml.attrib) + local_xml.text = '\n ' + for elem in self.xml.xpath('/bdisk/profile'): + local_xml.append(copy.deepcopy(elem)) + return(local_xml) + def return_naked_ns(self): # It's so stupid I have to do this. return(self.orig_xml.nsmap) diff --git a/docs/examples/multi_profile.xml b/docs/examples/multi_profile.xml index b741664..bb9dcb2 100644 --- a/docs/examples/multi_profile.xml +++ b/docs/examples/multi_profile.xml @@ -4,6 +4,7 @@ BDISK + bdisk {xpath%../../../build/paths/pki/text()}/ca.crt @@ -125,7 +126,7 @@ {xpath%//build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.key - some client name + website.tld XX Some City Some State @@ -137,7 +138,7 @@ - + {xpath%../../../meta/dev/author/text()} @@ -162,7 +163,7 @@ - AnotherCD + ALTCD bdisk_alt {xpath%../name/text()} @@ -197,16 +198,16 @@ http://archlinux.mirror.domain.tld /iso/latest - {regex%tarball_x86_64} - sha1sums.txt - {regex%sig_x86_64} + {regex%tarball_x86_64} + sha1sums.txt + {regex%sig_x86_64} http://archlinux32.mirror.domain.tld /iso/latest - {regex%tarball_i686} + {regex%tarball_i686} cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e - {regex%sig_i686} + {regex%sig_i686} @@ -230,7 +231,7 @@ {xpath%//meta/dev/website/text()}/ipxe - + {xpath%../../../build/paths/pki/text()}/ca.crt @@ -252,7 +253,7 @@ {xpath%//build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.key - some client name + website.tld XX Some City Some State @@ -262,7 +263,7 @@ - + {xpath%../../../meta/dev/author/text()} {xpath%../../../meta/dev/email/text()} diff --git a/docs/examples/regen_multi.py b/docs/examples/regen_multi.py index bf32799..1ead8dc 100755 --- a/docs/examples/regen_multi.py +++ b/docs/examples/regen_multi.py @@ -40,7 +40,7 @@ alt_profile.attrib['name'] = 'alternate' alt_profile.attrib['id'] = '2' alt_profile.attrib['uuid'] = '2ed07c19-2071-4d66-8569-da40475ba716' -meta_tags = {'name': 'AnotherCD', +meta_tags = {'name': 'ALTCD', 'uxname': 'bdisk_alt', 'pname': '{xpath%../name/text()}', 'desc': 'Another rescue/restore live environment.',