New in version 1.3.2.
GroupLogic is a connector plugin that lets you use an XML Genshi template to dynamically set additional groups for clients.
To use the GroupLogic plugin, first do mkdir /var/lib/bcfg2/GroupLogic. Add GroupLogic to your plugins line in /etc/bcfg2.conf. Next, create /var/lib/bcfg2/GroupLogic/groups.xml:
<GroupLogic xmlns:py="http://genshi.edgewall.org/">
</GroupLogic>
groups.xml is structured very similarly to the Metadata groups.xml. A Group tag that contains no children is a declaration of membership; a Group or Client tag that does contain children is a conditional.
Unlike Metadata/groups.xml, GroupLogic supports genshi templating, so you can dynamically create groups. GroupLogic/groups.xml is rendered for each client, and the groups set in it are added to the client metadata.
Note
Also unlike Metadata/groups.xml, GroupLogic can not be used to associate bundles with clients directly, or to negate groups. But you can use GroupLogic to assign a group that is associated with a bundle in Metadata.
Consider the case where you have four environments – dev, test, staging, and production – and four components to a web application – the frontend, the API, the database server, and the caching proxy. In order to make files specific to the component and to the environment, you need groups to describe each combination: webapp-frontend-dev, webapp-frontend-test, and so on. You could do this in Metadata/groups.xml:
<Groups>
<Group name="webapp-frontend">
<Group name="dev">
<Group name="webapp-frontend-dev"/>
</Group>
<Group name="test">
<Group name="webapp-frontend-test"/>
</Group>
...
</Group>
<Group name="webapp-api">
...
</Group>
...
</Groups>
Creating the sixteen groups this way is incredibly tedious, and this is a quite small site. GroupLogic can automate this process.
Assume that we’ve declared the groups thusly in Metadata/groups.xml:
<Groups>
<Group name="webapp-frontend" category="webapp-component"/>
<Group name="webapp-api" category="webapp-component"/>
<Group name="webapp-db" category="webapp-component"/>
<Group name="webapp-proxy" category="webapp-component"/>
<Group name="dev" category="environment"/>
<Group name="test" category="environment"/>
<Group name="staging" category="environment"/>
<Group name="prod" category="environment"/>
</Groups>
One way to automate the creation of the groups would be to simply generate the tedious config:
<GroupLogic xmlns:py="http://genshi.edgewall.org/">
<py:for each="component in metadata.query.all_groups_in_category("webapp-component")>
<Group name="${component}">
<py:for each="env in metadata.query.all_groups_in_category("environment")>
<Group name="${env}">
<Group name="${component}-${env}"/>
</Group>
</py:for>
</Group>
</py:for>
</GroupLogic>
But, since GroupLogic/groups.xml is rendered for each client individually, there’s a more elegant way to accomplish the same thing:
<GroupLogic xmlns:py="http://genshi.edgewall.org/">
<?python
component = metadata.group_in_category("webapp-component")
env = metadata.group_in_category("environment")
?>
<py:if test="component and env">
<Group name="${component}-${env}"/>
</py:if>
</GroupLogic>
This gets only the component and environment for the current client, and, if both are set, sets the single appropriate group.