summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-09-05 14:41:51 -0400
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-09-05 14:41:51 -0400
commit8ebb16fed2e768243a98d5333f9316e570870ce3 (patch)
tree75fa8b96988553365532b719a24590bb49b59f4b /src/lib/Bcfg2/Server
parent9fa2293c0bdd71215bc24e371dbd59f0cf922d94 (diff)
parentf8416134cc80d704e6f139aa1ab1ce47e00e4f7f (diff)
downloadbcfg2-8ebb16fed2e768243a98d5333f9316e570870ce3.tar.gz
bcfg2-8ebb16fed2e768243a98d5333f9316e570870ce3.tar.bz2
bcfg2-8ebb16fed2e768243a98d5333f9316e570870ce3.zip
Merge branch 'maint'
Conflicts: src/lib/Bcfg2/Server/Core.py src/lib/Bcfg2/Server/Plugins/GroupLogic.py
Diffstat (limited to 'src/lib/Bcfg2/Server')
-rw-r--r--src/lib/Bcfg2/Server/Core.py36
-rw-r--r--src/lib/Bcfg2/Server/Plugin/interfaces.py24
-rw-r--r--src/lib/Bcfg2/Server/Plugins/GroupLogic.py11
3 files changed, 66 insertions, 5 deletions
diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py
index 20ba62e0a..69d61580f 100644
--- a/src/lib/Bcfg2/Server/Core.py
+++ b/src/lib/Bcfg2/Server/Core.py
@@ -23,6 +23,7 @@ from Bcfg2.Compat import xmlrpclib # pylint: disable=W0622
from Bcfg2.Server.Plugin.exceptions import * # pylint: disable=W0401,W0614
from Bcfg2.Server.Plugin.interfaces import * # pylint: disable=W0401,W0614
from Bcfg2.Server.Plugin import track_statistics
+from Bcfg2.Server.Plugins.Metadata import MetadataGroup
try:
import psyco
@@ -200,6 +201,10 @@ class Core(object):
# load plugins
Bcfg2.settings.read_config()
+ # mapping of group name => plugin name to record where groups
+ # that are created by Connector plugins came from
+ self._dynamic_groups = dict()
+
#: The FAM :class:`threading.Thread`,
#: :func:`_file_monitor_thread`
self.fam_thread = \
@@ -850,8 +855,35 @@ class Core(object):
(client_name, sys.exc_info()[1]))
connectors = self.plugins_by_type(Connector)
for conn in connectors:
- grps = conn.get_additional_groups(imd)
- self.metadata.merge_additional_groups(imd, grps)
+ groups = conn.get_additional_groups(imd)
+ groupnames = []
+ for group in groups:
+ if isinstance(group, MetadataGroup):
+ groupname = group.name
+ if groupname in self._dynamic_groups:
+ if self._dynamic_groups[groupname] == conn.name:
+ self.metadata.groups[groupname] = group
+ else:
+ self.logger.warning(
+ "Refusing to clobber dynamic group %s "
+ "defined by %s" %
+ (self._dynamic_groups[groupname],
+ groupname))
+ elif groupname in self.metadata.groups:
+ # not recorded as a dynamic group, but
+ # present in metadata.groups -- i.e., a
+ # static group
+ self.logger.warning(
+ "Refusing to clobber predefined group %s" %
+ groupname)
+ else:
+ self.metadata.groups[groupname] = group
+ self._dynamic_groups[groupname] = conn.name
+ groupnames.append(groupname)
+ else:
+ groupnames.append(group)
+
+ self.metadata.merge_additional_groups(imd, groupnames)
for conn in connectors:
data = conn.get_additional_data(imd)
self.metadata.merge_additional_data(imd, conn.name, data)
diff --git a/src/lib/Bcfg2/Server/Plugin/interfaces.py b/src/lib/Bcfg2/Server/Plugin/interfaces.py
index 619d72afd..522c6a220 100644
--- a/src/lib/Bcfg2/Server/Plugin/interfaces.py
+++ b/src/lib/Bcfg2/Server/Plugin/interfaces.py
@@ -221,10 +221,32 @@ class Connector(object):
def get_additional_groups(self, metadata): # pylint: disable=W0613
""" Return a list of additional groups for the given client.
+ Each group can be either the name of a group (a string), or a
+ :class:`Bcfg2.Server.Plugins.Metadata.MetadataGroup` object
+ that defines other data besides just the name. Note that you
+ cannot return a
+ :class:`Bcfg2.Server.Plugins.Metadata.MetadataGroup` object
+ that clobbers a group defined by another plugin; the original
+ group will be used instead. For instance, assume the
+ following in ``Metadata/groups.xml``:
+
+ .. code-block:: xml
+
+ <Groups>
+ ...
+ <Group name="foo" public="false"/>
+ </Groups>
+
+ You could not subsequently return a
+ :class:`Bcfg2.Server.Plugins.Metadata.MetadataGroup` object
+ with ``public=True``; a warning would be issued, and the
+ original (non-public) ``foo`` group would be used.
:param metadata: The client metadata
:type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata
- :return: list of strings
+ :return: list of strings or
+ :class:`Bcfg2.Server.Plugins.Metadata.MetadataGroup`
+ objects.
"""
return list()
diff --git a/src/lib/Bcfg2/Server/Plugins/GroupLogic.py b/src/lib/Bcfg2/Server/Plugins/GroupLogic.py
index e8e0ab840..1da7c8fec 100644
--- a/src/lib/Bcfg2/Server/Plugins/GroupLogic.py
+++ b/src/lib/Bcfg2/Server/Plugins/GroupLogic.py
@@ -4,6 +4,7 @@ template to dynamically set additional groups for clients. """
import os
import lxml.etree
import Bcfg2.Server.Plugin
+from Bcfg2.Server.Plugins.Metadata import MetadataGroup
class GroupLogicConfig(Bcfg2.Server.Plugin.StructFile):
@@ -37,5 +38,11 @@ class GroupLogic(Bcfg2.Server.Plugin.Plugin,
should_monitor=True)
def get_additional_groups(self, metadata):
- return [el.get("name")
- for el in self.config.XMLMatch(metadata).findall("Group")]
+ rv = []
+ for el in self.config.XMLMatch(metadata).findall("Group"):
+ if el.get("category"):
+ rv.append(MetadataGroup(el.get("name"),
+ category=el.get("category")))
+ else:
+ rv.append(el.get("name"))
+ return rv