diff options
-rw-r--r-- | doc/server/info.txt | 26 | ||||
-rw-r--r-- | schemas/info.xsd | 3 | ||||
-rw-r--r-- | src/lib/Server/Plugin.py | 25 |
3 files changed, 36 insertions, 18 deletions
diff --git a/doc/server/info.txt b/doc/server/info.txt index 0d273c2b6..192805ed4 100644 --- a/doc/server/info.txt +++ b/doc/server/info.txt @@ -85,16 +85,16 @@ specification. info.xml files ============== -``info.xml`` files add the ability to specify different -sets of file metadata on a group by group or host by host -basis. These files are XML, and work similarly to those used by -:ref:`Rules <server-plugins-generators-rules>` or :ref:`Pkgmgr +``info.xml`` files add the ability to specify different sets of file +metadata on a group by group or host by host basis, or by path (for +files using :ref:`altsrc <server-plugins-structures-altsrc>`). These +files are XML, and work similarly to those used by :ref:`Rules +<server-plugins-generators-rules>` or :ref:`Pkgmgr <server-plugins-generators-pkgmgr>`. The following specifies a different global set of permissions -(root/sys/0651) than on clients in group webserver (root/root/0652) - -.. code-block:: xml +(root/sys/0651) than on clients in group webserver or named +"foo.example.com" (root/root/0652):: <FileInfo> <Client name='foo.example.com'> @@ -105,3 +105,15 @@ The following specifies a different global set of permissions </Group> <Info owner='root' group='sys' perms='0651'/> </FileInfo> + +The following specifies a different set of permissions depending on +the path of the file:: + + <FileInfo> + <Path name="/etc/bcfg2-web.conf"> + <Info owner="root" group="apache" perms="0640"/> + </Path> + <Path name="/etc/bcfg2-web.conf" negate="true"> + <Info owner="root" group="root" perms="0600"/> + </Path> + </FileInfo> diff --git a/schemas/info.xsd b/schemas/info.xsd index 169310ab6..37232ab23 100644 --- a/schemas/info.xsd +++ b/schemas/info.xsd @@ -25,6 +25,8 @@ maxOccurs='unbounded'/> <xsd:element name='Client' type='GroupType' minOccurs='0' maxOccurs='unbounded'/> + <xsd:element name='Path' type='GroupType' minOccurs='0' + maxOccurs='unbounded'/> </xsd:choice> <xsd:attribute type='xsd:string' name='name' use='required'/> <xsd:attribute type='xsd:boolean' name='negate' /> @@ -35,6 +37,7 @@ <xsd:choice minOccurs='0' maxOccurs='unbounded'> <xsd:element name='Group' type='GroupType'/> <xsd:element name='Client' type='GroupType'/> + <xsd:element name='Path' type='GroupType'/> <xsd:element name='Info' type='InfoType'/> </xsd:choice> </xsd:complexType> diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py index a05c537e5..17547be13 100644 --- a/src/lib/Server/Plugin.py +++ b/src/lib/Server/Plugin.py @@ -510,18 +510,20 @@ class INode: LNodes provide lists of things available at a particular group intersection. """ - raw = {'Client': "lambda x:'%s' == x.hostname and predicate(x)", - 'Group': "lambda x:'%s' in x.groups and predicate(x)"} - nraw = {'Client': "lambda x:'%s' != x.hostname and predicate(x)", - 'Group': "lambda x:'%s' not in x.groups and predicate(x)"} - containers = ['Group', 'Client'] + raw = {'Client': "lambda m, e:'%(name)s' == m.hostname and predicate(m, e)", + 'Group': "lambda m, e:'%(name)s' in m.groups and predicate(m, e)", + 'Path': "lambda m, e:('%(name)s' == e.get('name') or '%(name)s' == e.get('realname')) and predicate(m, e)"} + nraw = {'Client': "lambda m, e:'%(name)s' != m.hostname and predicate(m, e)", + 'Group': "lambda m, e:'%(name)s' not in m.groups and predicate(m, e)", + 'Path': "lambda m, e:('%(name)s' != e.get('name') and '%(name)s' != e.get('realname')) and predicate(m, e)"} + containers = ['Group', 'Client', 'Path'] ignore = [] def __init__(self, data, idict, parent=None): self.data = data self.contents = {} if parent == None: - self.predicate = lambda x: True + self.predicate = lambda m, d: True else: predicate = parent.predicate if data.get('negate', 'false') in ['true', 'True']: @@ -529,7 +531,8 @@ class INode: else: psrc = self.raw if data.tag in list(psrc.keys()): - self.predicate = eval(psrc[data.tag] % (data.get('name')), + self.predicate = eval(psrc[data.tag] % + {'name': data.get('name')}, {'predicate': predicate}) else: raise Exception @@ -552,9 +555,9 @@ class INode: except KeyError: idict[item.tag] = [item.get('name')] - def Match(self, metadata, data): + def Match(self, metadata, data, entry=lxml.etree.Element("None")): """Return a dictionary of package mappings.""" - if self.predicate(metadata): + if self.predicate(metadata, entry): for key in self.contents: try: data[key].update(self.contents[key]) @@ -562,7 +565,7 @@ class INode: data[key] = {} data[key].update(self.contents[key]) for child in self.children: - child.Match(metadata, data) + child.Match(metadata, data, entry=entry) class XMLSrc(XMLFileBacked): @@ -853,7 +856,7 @@ class EntrySet: entry.set(key, self.metadata[key]) if self.infoxml: mdata = {} - self.infoxml.pnode.Match(metadata, mdata) + self.infoxml.pnode.Match(metadata, mdata, entry=entry) if 'Info' not in mdata: logger.error("Failed to set metadata for file %s" % \ (entry.get('name'))) |