summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2011-06-15 12:21:17 -0400
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2011-06-15 12:21:17 -0400
commit5f93d780fc2dcd6ba35179acd61c05754d1e4fbc (patch)
tree41ad024f9da76953161a4fb6a3b7e193e481e941
parentac578f15ca785d9b1fcd0d42bfa3ffd017985e78 (diff)
downloadbcfg2-5f93d780fc2dcd6ba35179acd61c05754d1e4fbc.tar.gz
bcfg2-5f93d780fc2dcd6ba35179acd61c05754d1e4fbc.tar.bz2
bcfg2-5f93d780fc2dcd6ba35179acd61c05754d1e4fbc.zip
made StructFile.Match() work with Group/Client tags inside other tags
-rw-r--r--src/lib/Server/Plugin.py80
-rw-r--r--src/lib/Server/Plugins/Properties.py45
2 files changed, 46 insertions, 79 deletions
diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py
index 3a36baf8e..aff9af12b 100644
--- a/src/lib/Server/Plugin.py
+++ b/src/lib/Server/Plugin.py
@@ -457,51 +457,45 @@ class StructFile(XMLFileBacked):
"""This file contains a set of structure file formatting logic."""
def __init__(self, name):
XMLFileBacked.__init__(self, name)
- self.fragments = {}
-
- def Index(self):
- """Build internal data structures."""
- try:
- xdata = lxml.etree.XML(self.data)
- except lxml.etree.XMLSyntaxError:
- logger.error("Failed to parse file %s" % self.name)
- return
- self.fragments = {}
- work = {lambda x: True: xdata.getchildren()}
- while work:
- (predicate, worklist) = work.popitem()
- self.fragments[predicate] = \
- [item for item in worklist
- if (item.tag != 'Group' and
- item.tag != 'Client' and
- not isinstance(item,
- lxml.etree._Comment))]
- for item in worklist:
- cmd = None
- if item.tag == 'Group':
- if item.get('negate', 'false').lower() == 'true':
- cmd = "lambda x:'%s' not in x.groups and predicate(x)"
- else:
- cmd = "lambda x:'%s' in x.groups and predicate(x)"
- elif item.tag == 'Client':
- if item.get('negate', 'false').lower() == 'true':
- cmd = "lambda x:x.hostname != '%s' and predicate(x)"
- else:
- cmd = "lambda x:x.hostname == '%s' and predicate(x)"
- # else, ignore item
- if cmd is not None:
- newpred = eval(cmd % item.get('name'),
- {'predicate':predicate})
- work[newpred] = item.getchildren()
-
+ self.matches = {}
+
+ 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('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('name') == metadata.hostname):
+ 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]
+
def Match(self, metadata):
"""Return matching fragments of independent."""
- matching = [frag for (pred, frag) in list(self.fragments.items())
- if pred(metadata)]
- if matching:
- return reduce(lambda x, y: x + y, matching)
- logger.error("File %s got null match" % (self.name))
- return []
+ rv = []
+ if metadata.hostname not in self.matches:
+ for child in self.entries():
+ rv.extend(self._match(child, metadata))
+ if not rv:
+ logger.error("File %s got null match" % (self.name))
+ return rv
class INode:
diff --git a/src/lib/Server/Plugins/Properties.py b/src/lib/Server/Plugins/Properties.py
index dea797a10..95565f2e4 100644
--- a/src/lib/Server/Plugins/Properties.py
+++ b/src/lib/Server/Plugins/Properties.py
@@ -7,42 +7,15 @@ import Bcfg2.Server.Plugin
class PropertyFile(Bcfg2.Server.Plugin.StructFile):
"""Class for properties files."""
def Index(self):
- """Build internal data structures."""
- if type(self.data) is not lxml.etree._Element:
- try:
- self.data = lxml.etree.XML(self.data)
- except lxml.etree.XMLSyntaxError:
- Bcfg2.Server.Plugin.logger.error("Failed to parse %s" %
- self.name)
-
- self.fragments = {}
- work = {lambda x: True: self.data.getchildren()}
- while work:
- (predicate, worklist) = work.popitem()
- self.fragments[predicate] = \
- [item for item in worklist
- if (item.tag != 'Group' and
- item.tag != 'Client' and
- not isinstance(item,
- lxml.etree._Comment))]
- for item in worklist:
- cmd = None
- if item.tag == 'Group':
- if item.get('negate', 'false').lower() == 'true':
- cmd = "lambda x:'%s' not in x.groups and predicate(x)"
- else:
- cmd = "lambda x:'%s' in x.groups and predicate(x)"
- elif item.tag == 'Client':
- if item.get('negate', 'false').lower() == 'true':
- cmd = "lambda x:x.hostname != '%s' and predicate(x)"
- else:
- cmd = "lambda x:x.hostname == '%s' and predicate(x)"
- # else, ignore item
- if cmd is not None:
- newpred = eval(cmd % item.get('name'),
- {'predicate':predicate})
- work[newpred] = item.getchildren()
-
+ """Build local data structures."""
+ try:
+ xdata = XML(self.data)
+ except XMLSyntaxError:
+ self.label = None
+ self.entries = []
+ return
+ self.label = xdata.attrib[self.__identifier__]
+ self.entries = xdata.getchildren()
class PropDirectoryBacked(Bcfg2.Server.Plugin.DirectoryBacked):