summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2012-12-05 15:23:23 +0100
committerAlexander Sulfrian <alexander@sulfrian.net>2013-01-30 01:29:29 +0100
commit428f7cea160faf91796a2baf907ada3fa1cd674b (patch)
treee78d00847058d9f118d2d2985c50082a9f7ff2fe /src
parent801ffae02f40ba5f95f6b6c7b2fdf83dd5a46e14 (diff)
downloadbcfg2-428f7cea160faf91796a2baf907ada3fa1cd674b.tar.gz
bcfg2-428f7cea160faf91796a2baf907ada3fa1cd674b.tar.bz2
bcfg2-428f7cea160faf91796a2baf907ada3fa1cd674b.zip
Server/Plugin: backported XMLMatch from bcfg2-1.3
Diffstat (limited to 'src')
-rw-r--r--src/lib/Server/Plugin.py83
1 files changed, 58 insertions, 25 deletions
diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py
index 28299d8c7..7298bc552 100644
--- a/src/lib/Server/Plugin.py
+++ b/src/lib/Server/Plugin.py
@@ -647,36 +647,37 @@ class StructFile(XMLFileBacked):
def __init__(self, name):
XMLFileBacked.__init__(self, name)
+ def _include_element(self, item, metadata):
+ """ determine if an XML element matches the metadata """
+ if isinstance(item, lxml.etree._Comment): # pylint: disable=W0212
+ return False
+ negate = item.get('negate', 'false').lower() == 'true'
+ if item.tag == 'Group':
+ return negate == (item.get('name') not in metadata.groups)
+ elif item.tag == 'Client':
+ return negate == (item.get('name') != metadata.hostname)
+ else:
+ return True
+
def _match(self, item, metadata):
""" recursive helper for Match() """
- if isinstance(item, lxml.etree._Comment):
- return []
- elif item.tag == 'Group':
- rv = []
- if ((item.get('negate', 'false').lower() == 'true' and
- item.get('name') not in metadata.groups) or
- (item.get('negate', 'false').lower() == 'false' and
- item.get('name') in metadata.groups)):
- for child in item.iterchildren():
- rv.extend(self._match(child, metadata))
- return rv
- elif item.tag == 'Client':
- rv = []
- if ((item.get('negate', 'false').lower() == 'true' and
- item.get('name') != metadata.hostname) or
- (item.get('negate', 'false').lower() == 'false' and
- item.get('name') == metadata.hostname)):
+ if self._include_element(item, metadata):
+ if item.tag == 'Group' or item.tag == 'Client':
+ rv = []
+ if self._include_element(item, metadata):
+ for child in item.iterchildren():
+ rv.extend(self._match(child, metadata))
+ return rv
+ else:
+ rv = copy.deepcopy(item)
+ for child in rv.iterchildren():
+ rv.remove(child)
for child in item.iterchildren():
rv.extend(self._match(child, metadata))
- return rv
+ return [rv]
else:
- rv = copy.copy(item)
- for child in rv.iterchildren():
- rv.remove(child)
- for child in item.iterchildren():
- rv.extend(self._match(child, metadata))
- return [rv]
-
+ return []
+
def Match(self, metadata):
"""Return matching fragments of independent."""
rv = []
@@ -684,6 +685,38 @@ class StructFile(XMLFileBacked):
rv.extend(self._match(child, metadata))
return rv
+ def _xml_match(self, item, metadata):
+ """ recursive helper for XMLMatch """
+ if self._include_element(item, metadata):
+ if item.tag == 'Group' or item.tag == 'Client':
+ for child in item.iterchildren():
+ item.remove(child)
+ item.getparent().append(child)
+ self._xml_match(child, metadata)
+ item.getparent().remove(item)
+ else:
+ for child in item.iterchildren():
+ self._xml_match(child, metadata)
+ else:
+ item.getparent().remove(item)
+
+ def XMLMatch(self, metadata):
+ """ Return a rebuilt XML document that only contains the
+ matching portions of the original file. A tag is considered
+ to match if all ``<Group>`` and ``<Client>`` tags that are its
+ ancestors match the metadata given. Unlike :func:`Match`, the
+ document returned by XMLMatch will only contain matching data.
+ All ``<Group>`` and ``<Client>`` tags will have been stripped
+ out.
+
+ :param metadata: Client metadata to match against.
+ :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata
+ :returns: lxml.etree._Element """
+ rv = copy.deepcopy(self.xdata)
+ for child in rv.iterchildren():
+ self._xml_match(child, metadata)
+ return rv
+
class INode:
"""