URL: https://github.com/freeipa/freeipa/pull/241 Author: tiran Title: #241: Port ipapython.dnssec.odsmgr to xml.etree Action: synchronized
To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/241/head:pr241 git checkout pr241
From d22d1017657020582d30018b67887f3df8fb82fd Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Tue, 15 Nov 2016 12:57:13 +0100 Subject: [PATCH 1/2] Port ipapython.dnssec.odsmgr to xml.etree The module ipapython.dnssec.odsmgr is the only module in ipalib, ipaclient, ipapython and ipaplatform that uses lxml.etree. https://fedorahosted.org/freeipa/ticket/6469 Signed-off-by: Christian Heimes <chei...@redhat.com> --- freeipa.spec.in | 3 +-- ipapython/dnssec/odsmgr.py | 38 ++++++++++++++++++------------- ipatests/test_ipapython/test_dnssec.py | 41 ++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 ipatests/test_ipapython/test_dnssec.py diff --git a/freeipa.spec.in b/freeipa.spec.in index 7dbbf87..c7aeb52 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -248,6 +248,7 @@ Requires: %{name}-server-common = %{version}-%{release} Requires: %{name}-common = %{version}-%{release} Requires: python2-ipaclient = %{version}-%{release} Requires: python-ldap >= 2.4.15 +Requires: python-lxml Requires: python-gssapi >= 1.1.2 Requires: python-sssdconfig Requires: python-pyasn1 @@ -509,7 +510,6 @@ Requires: keyutils Requires: pyOpenSSL Requires: python-nss >= 0.16 Requires: python-cryptography >= 0.9 -Requires: python-lxml Requires: python-netaddr Requires: python-libipa_hbac Requires: python-qrcode-core >= 5.0.0 @@ -559,7 +559,6 @@ Requires: keyutils Requires: python3-pyOpenSSL Requires: python3-nss >= 0.16 Requires: python3-cryptography -Requires: python3-lxml Requires: python3-netaddr Requires: python3-libipa_hbac Requires: python3-qrcode-core >= 5.0.0 diff --git a/ipapython/dnssec/odsmgr.py b/ipapython/dnssec/odsmgr.py index fb6d696..0308408 100644 --- a/ipapython/dnssec/odsmgr.py +++ b/ipapython/dnssec/odsmgr.py @@ -3,8 +3,11 @@ # Copyright (C) 2014 FreeIPA Contributors see COPYING for license # -from lxml import etree import dns.name +try: + from xml.etree import cElementTree as etree +except ImportError: + from xml.etree import ElementTree as etree from ipapython import ipa_log_manager, ipautil @@ -59,13 +62,15 @@ class ODSZoneListReader(ZoneListReader): """One-shot parser for ODS zonelist.xml.""" def __init__(self, zonelist_text): super(ODSZoneListReader, self).__init__() - xml = etree.fromstring(zonelist_text) - self._parse_zonelist(xml) + root = etree.fromstring(zonelist_text) + self._parse_zonelist(root) - def _parse_zonelist(self, xml): + def _parse_zonelist(self, root): """iterate over Zone elements with attribute 'name' and add IPA zones to self.zones""" - for zone_xml in xml.xpath('/ZoneList/Zone[@name]'): + if not root.tag == 'ZoneList': + raise ValueError(root.tag) + for zone_xml in root.findall('./Zone[@name]'): name, zid = self._parse_ipa_zone(zone_xml) self._add_zone(name, zid) @@ -79,16 +84,19 @@ def _parse_ipa_zone(self, zone_xml): tuple (zone name, ID) """ name = zone_xml.get('name') - in_adapters = zone_xml.xpath( - 'Adapters/Input/Adapter[@type="File" ' - 'and starts-with(text(), "%s")]' % ENTRYUUID_PREFIX) - assert len(in_adapters) == 1, 'only IPA zones are supported: %s' \ - % etree.tostring(zone_xml) - - path = in_adapters[0].text - # strip prefix from path - zid = path[ENTRYUUID_PREFIX_LEN:] - return (name, zid) + zids = [] + for in_adapter in zone_xml.findall( + './Adapters/Input/Adapter[@type="File"]'): + path = in_adapter.text + if path.startswith(ENTRYUUID_PREFIX): + # strip prefix from path + zids.append(path[ENTRYUUID_PREFIX_LEN:]) + + if len(zids) != 1: + raise ValueError('only IPA zones are supported: {}'.format( + etree.tostring(zone_xml))) + + return name, zids[0] class LDAPZoneListReader(ZoneListReader): diff --git a/ipatests/test_ipapython/test_dnssec.py b/ipatests/test_ipapython/test_dnssec.py new file mode 100644 index 0000000..c4b830e --- /dev/null +++ b/ipatests/test_ipapython/test_dnssec.py @@ -0,0 +1,41 @@ +# +# Copyright (C) 2016 FreeIPA Contributors see COPYING for license +# +""" +Test the `ipapython/dnssec` package. +""" +import dns.name + +from ipapython.dnssec.odsmgr import ODSZoneListReader + + +ZONELIST_XML = """<?xml version="1.0" encoding="UTF-8"?> +<ZoneList> + <Zone name="ipa.example"> + <Policy>default</Policy> + <Adapters> + <Input> + <Adapter type="File">/var/lib/ipa/dns/zone/entryUUID/12345</Adapter> + </Input> + <Output> + <Adapter type="File">/var/lib/ipa/dns/zone/entryUUID/12345</Adapter> + </Output> + </Adapters> + </Zone> +</ZoneList> +""" + + +def test_ods_zonelist_reader(): + uuid = '12345' + name = dns.name.from_text('ipa.example.') + + reader = ODSZoneListReader("<ZoneList/>") + assert reader.mapping == {} + assert reader.names == set() + assert reader.uuids == set() + + reader = ODSZoneListReader(ZONELIST_XML) + assert reader.mapping == {uuid: name} + assert reader.names == {name} + assert reader.uuids == {uuid} From e6e7e66c54717f993bfe3671fbc2fea27b0cb876 Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Wed, 16 Nov 2016 11:11:13 +0100 Subject: [PATCH 2/2] Use xml.etree in ipa-client-automount script The ipa-client-automount script used lxml.etree to modify /etc/autofs_ldap_auth.conf. Signed-off-by: Christian Heimes <chei...@redhat.com> --- client/ipa-client-automount | 47 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/client/ipa-client-automount b/client/ipa-client-automount index fc619d0..b4aa7e8 100755 --- a/client/ipa-client-automount +++ b/client/ipa-client-automount @@ -29,6 +29,11 @@ import time import tempfile import gssapi +try: + from xml.etree import cElementTree as etree +except ImportError: + from xml.etree import ElementTree as etree + import SSSDConfig # pylint: disable=import-error from six.moves.urllib.parse import urlsplit @@ -94,40 +99,34 @@ def wait_for_sssd(): print("This may mean that sssd didn't re-start properly after the configuration changes.") def configure_xml(fstore): - from lxml import etree - - fstore.backup_file(paths.AUTOFS_LDAP_AUTH_CONF) + authconf = paths.AUTOFS_LDAP_AUTH_CONF + fstore.backup_file(authconf) try: - f = open(paths.AUTOFS_LDAP_AUTH_CONF, 'r') - lines = f.read() - f.close() - - saslconf = etree.fromstring(lines) - element = saslconf.xpath('//autofs_ldap_sasl_conf') - root = saslconf.getroottree() + tree = etree.parse(authconf) except IOError as e: root_logger.debug('Unable to open file %s' % e) root_logger.debug('Creating new from template') - element = [etree.Element('autofs_ldap_sasl_conf')] - root = element[0].getroottree() + tree = etree.ElementTree( + element=etree.Element('autofs_ldap_sasl_conf') + ) - if len(element) != 1: - raise RuntimeError('Unable to parse %s' % paths.AUTOFS_LDAP_AUTH_CONF) + element = tree.getroot() + if element.tag != 'autofs_ldap_sasl_conf': + raise RuntimeError('Invalid XML root in file %s' % authconf) - element[0].set('usetls', 'no') - element[0].set('tlsrequired', 'no') - element[0].set('authrequired', 'yes') - element[0].set('authtype', 'GSSAPI') - element[0].set('clientprinc', 'host/%s@%s' % (api.env.host, api.env.realm)) + element.set('usetls', 'no') + element.set('tlsrequired', 'no') + element.set('authrequired', 'yes') + element.set('authtype', 'GSSAPI') + element.set('clientprinc', 'host/%s@%s' % (api.env.host, api.env.realm)) - newconf = open(paths.AUTOFS_LDAP_AUTH_CONF, 'w') try: - root.write(newconf, pretty_print=True, xml_declaration=True, encoding='UTF-8') - newconf.close() + tree.write(authconf, xml_declaration=True, encoding='UTF-8') except IOError as e: - print("Unable to write %s: %s" % (paths.AUTOFS_LDAP_AUTH_CONF, e)) - print("Configured %s" % paths.AUTOFS_LDAP_AUTH_CONF) + print("Unable to write %s: %s" % (authconf, e)) + else: + print("Configured %s" % authconf) def configure_nsswitch(fstore, options): """
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code