diff options
author | Alexander Sulfrian <alexander.sulfrian@fu-berlin.de> | 2015-07-22 18:39:32 +0200 |
---|---|---|
committer | Alexander Sulfrian <alexander.sulfrian@fu-berlin.de> | 2015-08-26 19:12:30 +0200 |
commit | 6851a2931869aa9d9181b7b2d95f048aa5415a23 (patch) | |
tree | 5d56dbf8ecc48ff6a9f1970d91445366e34534f0 /src | |
parent | c7e67299381df961ff8274e9b53827c2bddbb47b (diff) | |
download | bcfg2-6851a2931869aa9d9181b7b2d95f048aa5415a23.tar.gz bcfg2-6851a2931869aa9d9181b7b2d95f048aa5415a23.tar.bz2 bcfg2-6851a2931869aa9d9181b7b2d95f048aa5415a23.zip |
Rules: New options replace_name to replace %{name} in attributes
If you use the regex feature of Rules/Defaults you may need the real name
of the matched entry in an attribute (for example home of POSIXUser).
You can now enable replace_name for rules or defaults and %{name} will be
replaces in the attribues of the Element before adding them to the target
entry.
This allows you to write something like that in Defaults to assing a default
home directory somewhere else to all users with unset home:
<POSIXUser name='.*' home='/somewhere/%{name}'/>
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/Bcfg2/Server/Plugin/helpers.py | 14 | ||||
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Defaults.py | 12 | ||||
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Rules.py | 27 |
3 files changed, 51 insertions, 2 deletions
diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py index 3b62a3217..6b521dfd6 100644 --- a/src/lib/Bcfg2/Server/Plugin/helpers.py +++ b/src/lib/Bcfg2/Server/Plugin/helpers.py @@ -1064,6 +1064,20 @@ class PrioDir(Plugin, Generator, XMLDirectoryBacked): data = candidate break + self._apply(entry, data) + + def _apply(self, entry, data): + """ Apply all available values from data onto entry. This + sets the available attributes (for all attribues unset in + the entry), adds all children and copies the text from data + to entry. + + :param entry: The entry to apply the changes + :type entry: lxml.etree._Element + :param data: The entry to get the data from + :type data: lxml.etree._Element + """ + if data.text is not None and data.text.strip() != '': entry.text = data.text for item in data.getchildren(): diff --git a/src/lib/Bcfg2/Server/Plugins/Defaults.py b/src/lib/Bcfg2/Server/Plugins/Defaults.py index 79e2ca0e2..2242e3825 100644 --- a/src/lib/Bcfg2/Server/Plugins/Defaults.py +++ b/src/lib/Bcfg2/Server/Plugins/Defaults.py @@ -1,5 +1,6 @@ """This generator provides rule-based entry mappings.""" +import Bcfg2.Options import Bcfg2.Server.Plugin import Bcfg2.Server.Plugins.Rules @@ -9,7 +10,10 @@ class Defaults(Bcfg2.Server.Plugins.Rules.Rules, """Set default attributes on bound entries""" __author__ = 'bcfg-dev@mcs.anl.gov' - options = Bcfg2.Server.Plugin.PrioDir.options + options = Bcfg2.Server.Plugin.PrioDir.options + [ + Bcfg2.Options.BooleanOption( + cf=("defaults", "replace_name"), dest="defaults_replace_name", + help="Replace %{name} in attributes with name of target entry")] # Rules is a Generator that happens to implement all of the # functionality we want, so we overload it, but Defaults should @@ -41,3 +45,9 @@ class Defaults(Bcfg2.Server.Plugins.Rules.Rules, def _regex_enabled(self): """ Defaults depends on regex matching, so force it enabled """ return True + + @property + def _replace_name_enabled(self): + """ Return True if the replace_name feature is enabled, + False otherwise """ + return Bcfg2.Options.setup.defaults_replace_name diff --git a/src/lib/Bcfg2/Server/Plugins/Rules.py b/src/lib/Bcfg2/Server/Plugins/Rules.py index a3f682ed6..cf659251c 100644 --- a/src/lib/Bcfg2/Server/Plugins/Rules.py +++ b/src/lib/Bcfg2/Server/Plugins/Rules.py @@ -1,10 +1,17 @@ """This generator provides rule-based entry mappings.""" +import copy import re +import string import Bcfg2.Options import Bcfg2.Server.Plugin +class NameTemplate(string.Template): + """Simple subclass of string.Template with a custom delimiter.""" + delimiter = '%' + + class Rules(Bcfg2.Server.Plugin.PrioDir): """This is a generator that handles service assignments.""" __author__ = 'bcfg-dev@mcs.anl.gov' @@ -12,7 +19,10 @@ class Rules(Bcfg2.Server.Plugin.PrioDir): options = Bcfg2.Server.Plugin.PrioDir.options + [ Bcfg2.Options.BooleanOption( cf=("rules", "regex"), dest="rules_regex", - help="Allow regular expressions in Rules")] + help="Allow regular expressions in Rules"), + Bcfg2.Options.BooleanOption( + cf=("rules", "replace_name"), dest="rules_replace_name", + help="Replace %{name} in attributes with name of target entry")] def __init__(self, core): Bcfg2.Server.Plugin.PrioDir.__init__(self, core) @@ -46,7 +56,22 @@ class Rules(Bcfg2.Server.Plugin.PrioDir): return True return False + def _apply(self, entry, data): + if self._replace_name_enabled: + data = copy.deepcopy(data) + for key, val in list(data.attrib.items()): + data.attrib[key] = NameTemplate(val).safe_substitute( + name=entry.get('name')) + + Bcfg2.Server.Plugin.PrioDir._apply(self, entry, data) + @property def _regex_enabled(self): """ Return True if rules regexes are enabled, False otherwise """ return Bcfg2.Options.setup.rules_regex + + @property + def _replace_name_enabled(self): + """ Return True if the replace_name feature is enabled, + False otherwise """ + return Bcfg2.Options.setup.rules_replace_name |