Common XML Features¶
Most of the XML files in Bcfg2 have a common set of features that are supported. These are described in some detail below, and a precise rundown of which features are supported by which files is provided.
Group and Client tags¶
These allow the portions of an XML document inside a Client or Group tag to only apply to the given client group. That is, they can be thought of as conditionals, where the following are roughly equivalent:
<Group name="group1">
<Path name="/etc/foo.conf"/>
</Group>
And:
If client is a member of group1 then
Manage the abstract path "/etc/foo.conf"
Nested Group and Client tags are conjunctive (logical AND
). For
instance, the following are roughly equivalent:
<Group name="group1">
<Client name="foo.example.com">
<Package name="bar"/>
</Client>
<Package name="baz"/>
</Group>
And:
If client is a member of group1 and has hostname "foo.example.com" then
Manage the abstract package "bar"
If client is a member of group1 then
Manage the abstract package "baz"
There is no convenient else
; you must specify all conditions
explicitly. To do this, Group and Client tags may be negated, as in:
<Group name="group1">
<Service name="foo"/>
</Group>
<Group name="group1" negate="true">
<Service name="bar"/>
</Group>
This is roughly equivalent to:
If client is a member of group1 then
Manage the abstract service "foo"
If client is not a member of group 1 then
Manage the abstract service "bar"
Or, more compactly:
- If client is a member of group1 then
- Manage the abstract service “foo”
- Else
- Manage the abstract service “bar”
As an example, consider the following bundle:
<Bundle>
<Path glob='/etc/ssh/*'/>
<Group name='rpm'>
<Package name='openssh'/>
<Package name='openssh-askpass'/>
<Service name='sshd'/>
<Group name='fedora' >
<Group name='fedora14' negate='true'>
<Package name='openssh-clients'/>
</Group>
<Package name='openssh-server'/>
</Group>
</Group>
<Group name='deb'>
<Package name='ssh'/>
<Service name='ssh'/>
</Group>
<Client name='trust.example.com'>
<Path name='/etc/ssh/shosts.equiv'/>
</Client>
</Bundle>
In this bundle, most of the entries are common to all systems. Clients
in group deb
get one extra package and service, while clients in
group rpm
get two extra packages and an extra service. In
addition, clients in group fedora
and group rpm
get one
extra package entries, unless they are not in the fedora14
group,
in which case, they get an extra package. The client
trust.example.com
gets one extra file that is not distributed to
any other clients.
Group/Hostname | Entry |
---|---|
all | /etc/ssh/* |
rpm |
Package openssh |
rpm |
Package openssh-askpass |
rpm |
Service sshd |
rpm AND fedora |
Package openssh-server |
rpm AND fedora
AND NOT fedora14 |
Package openssh-clients |
deb |
Package ssh |
deb |
Service ssh |
trust.example.com |
/etc/ssh/shosts.equiv |
Genshi templating¶
Genshi XML templates allow you to use the Genshi templating system to dynamically generate XML file content for a given client. Genshi templating can be enabled on a file by adding the Genshi namespace to the top-level tag, e.g.:
<Bundle xmlns:py="http://genshi.edgewall.org/">
Several variables are pre-defined inside Genshi XML templates:
Name | Description |
---|---|
metadata | Client metadata |
repo | The path to the Bcfg2 repository on the filesystem |
Note
<Group>
and <Client>
tags can be used inside templates as
of Bcfg2 1.2, but they do not behave the same as using a Genshi
conditional, e.g.:
<py:if test="'groupname' in metadata.groups">
</py:if>
The conditional is evaluated when the template is rendered, so
code inside the conditional is not executed if the conditional
fails. A <Group>
tag is evaluated after the template is
rendered, so code inside the tag is always executed. This is an
important distinction: if you have code that will fail on some
groups, you must use a Genshi conditional, not a <Group>
tag. The same caveats apply to <Client>
tags.
Genshi XML Template Reference¶
The Genshi XML templating language is described in depth at Genshi. The XML schema reference follows.
Genshi Tags¶
- group py:genshiElements¶
- Most Genshi templating directives can be used either as standalone elements or as attributes on existing elements. This element group defines the standalone tags.
- Elements:
- element py:with¶
-
- Attributes:
Name Description Values Required Default py:vars
A semicolon-delimited list of variables to define and their values.string
Yes None - Text content:
- Any
Any arbitrary child elements allowed
- element py:replace¶
-
- Attributes:
Name Description Values Required Default py:value
The value to replace the contents with.string
Yes None - Text content:
- Any
Any arbitrary child elements allowed
- element py:choose¶
-
- Attributes:
Name Description Values Required Default py:test
Iftest
is set, the childpy:when
directives are tested for equality to the value of the expression.string
No None - Child elements:
- element py:when¶
The
when
directive is used insidepy:chooseType
orchoose
to handle a single specific condition.- Attributes:
Name Description Values Required Default py:test
The statement giving the value to teststring
Yes None - Text content:
Any
Any arbitrary child elements allowed
- element py:otherwise¶
-
- Text content:
Any
Any arbitrary child elements allowed
- Text content:
- Any
- element py:for¶
-
- Attributes:
Name Description Values Required Default py:each
The loop iteratorstring
Yes None - Text content:
- Any
Any arbitrary child elements allowed
- element py:if¶
-
- Attributes:
Name Description Values Required Default py:test
The statement giving the value to teststring
Yes None - Text content:
- Any
Any arbitrary child elements allowed
- element py:match¶
-
- Attributes:
Name Description Values Required Default py:path
XPath expression to search for in the template.string
Yes None py:buffer
Whether the matched content should be buffered in memory. Buffering can improve performance a bit at the cost of needing more memory during rendering. Buffering is required for match templates that contain more than one invocation of theselect()
function. If there is only one call, and the matched content can potentially be very long, consider disabling buffering to avoid excessive memory use.true
|false
No true
py:once
Whether the engine should stop looking for more matching elements after the first match. Use this on match templates that match elements that can only occur once in the stream, such as the <head> or <body> elements in an HTML template, or elements with a specific ID.true
|false
No false
py:recursive
Whether the match template should be applied to its own output. Note that once implies non-recursive behavior, so this attribute only needs to be set for match templates that don’t also have once set.true
|false
No true
- Text content:
- Any
Any arbitrary child elements allowed
Genshi Attributes¶
- attributeGroup py:genshiAttrs¶
- Most Genshi templating directives can be used either as standalone elements or as attributes on existing elements. This attribute group defines the attribute directives.
Name Description Values Required Default py:attrs
string
No None py:choose
string
No None py:content
string
No None py:def
string
No None py:for
string
No None py:if
string
No None py:match
string
No None py:otherwise
Theotherwise
directive is used insidepy:chooseType
orchoose
to handle all conditions not handled by apy:when
.string
No None py:replace
string
No None py:strip
string
No None py:when
string
No None py:with
string
No None
Encryption¶
You can encrypt data in XML files to protect that data from other people who need access to the repository. The data is decrypted transparently on-the-fly by the server.
Note
This feature is not intended to secure the files against a
malicious attacker who has gained access to your Bcfg2 server, as
the encryption passphrases are held in plaintext in
bcfg2.conf
. This is only intended to make it easier to use a
single Bcfg2 repository with multiple admins who should not
necessarily have access to each other’s sensitive data.
XML files are encrypted on a per-element basis; that is, rather than encrypting the whole file, only the character content of individual elements is encrypted. This makes it easier to track changes to the file in a VCS, and also lets unprivileged users work with the other data in the file. Only character content of an element can be encrypted; attribute content and XML elements themselves cannot be encrypted.
By default, decryption is strict; that is, if any element cannot be decrypted, parsing of the file is aborted. See Lax vs. Strict decryption for information on changing this on a global or per-file basis.
To encrypt or decrypt a file, use bcfg2-crypt.
See Bcfg2 Data Encryption for more details on encryption in Bcfg2 in general.
XInclude¶
New in version 0.9.0.
XInclude is a W3C specification
for the inclusion of external XML documents into XML source files,
allowing complex definitions to be split into smaller, more manageable
pieces. For instance, in the Metadata
groups.xml
file, you might do:
<Groups xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="my-groups.xml" />
<xi:include href="their-groups.xml" />
</Groups>
To enable XInclude on a file, you need only add the XInclude namespace to the top-level tag.
You can also optionally include a file that may or may not exist
with the fallback
tag:
<Groups xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="my-groups.xml"/>
<xi:include href="their-groups.xml"><xi:fallback/></xi:include>
</Groups>
In this case, if their-groups.xml
does not exist, no error will be
raised and everything will work fine. (You can also use fallback
to include a different file, or explicit content in the case that the
parent include does not exist.)
XInclude can only include complete, well-formed XML files. In some cases, it may not be entirely obvious or intuitive how to structure such an included file to conform to the schema, although in general the included files should be structure exactly like the parent file.
Wildcard XInclude¶
New in version 1.3.1.
Bcfg2 supports an extension to XInclude that allows you to use shell globbing in the hrefs. (Stock XInclude doesn’t support this, since the href is supposed to be a URL.)
For instance:
<Groups xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="groups/*.xml"/>
</Groups>
This would include all *.xml
files in the groups
subdirectory.
Note that if a glob finds no files, that is treated the same as if a
single included file does not exist. You should use the fallback
tag, described above, if a glob may potentially find no files.
Feature Matrix¶
File | Group/Client | Genshi | Encryption | XInclude |
---|---|---|---|---|
ACL ip.xml | No | No | No | Yes |
ACL metadata.xml | Yes | Yes | Yes | Yes |
Bundler | Yes | Yes | Yes | Yes |
info.xml | Yes [1] | Yes | Yes | Yes |
privkey.xml and pubkey.xml | Yes | Yes | Yes | Yes [2] |
authorizedkeys.xml | Yes | Yes | Yes | Yes |
sslcert.xml and sslkey.xml | Yes | Yes | Yes | Yes |
Decisions | Yes | Yes | Yes | Yes |
Defaults | Yes | Yes | Yes | Yes |
FileProbes | Yes | Yes | Yes | Yes |
GroupPatterns | No | No | No | Yes |
Metadata clients.xml | No | No | No | Yes |
Metadata groups.xml | Yes [3] | No | No | Yes |
NagiosGen | Yes | Yes | Yes | Yes |
Packages | Yes | Yes | Yes | Yes |
Pkgmgr | Yes | No | No | No |
Properties | Yes [4] | Yes | Yes | Yes |
Rules | Yes | Yes | Yes | Yes |
Footnotes
[1] | info.xml also supports conditional Path tags; see
info.xml for more. |
[2] | XInclude is supported, but the schema has not been modified to allow including files that are structured exactly like the parent. You may need to read the schema to understand how to use XInclude properly. |
[3] | The semantics of Group tags in groups.xml is slightly
different; see
groups.xml for
details. |
[4] | Group and Client tags in XML Properties are not automatic by
default; they can be resolved by use of either the
Match() or XMLMatch() methods, or by use of the
Automatch
feature. See XML Property Files
for details. |