sampledoc

Properties

The Properties plugin is a connector plugin that adds information from XML, JSON, and YAML files into client metadata instances.

Enabling Properties

First, mkdir /var/lib/bcfg2/Properties. Each property file goes in this directory. Each will automatically be cached by the server, and reread/reparsed upon changes. Add Properties to your plugins line in /etc/bcfg2.conf.

Data Structures

Properties adds a new dictionary to client metadata instances that maps property file names to PropertyFile instances.

A property file can be one of three types:

The XML interface is undoubtably the most powerful, as it natively supports schemas to check the data validity, client- and group-specific data, and data encryption.

Usage

Common Interface

Different data types have different interfaces, but there are some usage patterns common to all properties files.

Specific property files can be referred to in templates as metadata.Properties[<filename>].

The data in property files is accessible via different attributes:

Data Type Data Attribute
XML xdata
JSON json
YAML yaml

For instance, in a Genshi template, you might do:

{% for item in metadata.Properties['foo.json'].json %}\
${item}
{% end %}\

{% for key, value in metadata.Properties['foo.yml'].yaml %}\
${key} = ${value}
{% end %}\

{% for el in metadata.Properties['foo.xml'].xdata.findall("Tag") %}\
${el.get("name")} = ${el.text}
{% end %}\

The raw contents of a properties file as a string are available via the data attribute, e.g., metadata.Properties['prop-file'].data.

Writing to Properties files

New in version 1.2.0.

If you need to make persistent changes to properties data, you can use the write method of the Bcfg2.Server.Plugins.Properties.PropertyFile class:

{% python
import lxml.etree
from genshi.template import TemplateError
lxml.etree.SubElement(metadata.Properties['foo.xml'],
                      "Client",
                      name=metadata.hostname)
if not metadata.Properties['foo.xml'].write():
    raise TemplateError("Failed to write changes back to foo.xml")

The interface is the same for YAML or JSON data.

If writing XML data, the write method checks the data in the object against its schema before writing it; see Data Structures for details.

Note that use of the write method can cause race conditions if you run more than one Bcfg2 server. If you run more than one Bcfg2 server, you can disable Properties write-back by setting the following in bcfg2.conf:

[properties]
writes_enabled = false

XML Property Files

The data in an XML property file can be accessed with the xdata attribute, an lxml.etree._Element object documented here.

In addition to the xdata attribute that can be used to access the raw data, the following access methods are defined:

  • Match() parses the Group and Client tags in the file and returns a list of elements that apply to the client described by a set of metadata. For instance:

    {% python
    ntp_servers = [el.text
                   for el in metadata.Properties['ntp.xml'].Match(metadata)
                   if el.tag == "Server"]
    %}
  • XMLMatch() parses the Group and Client tags in the file and returns an XML document containing only the data that applies to the client described by a set of metadata. (The Group and Client tags themselves are also removed, leaving only the tags and data contained in them.) For instance:

    {% python
    ntp_servers = [el.text
                   for el in metadata.Properties['ntp.xml'].XMLMatch(metadata).findall("//Server")]
    %}

    XMLMatch() can be run automatically on properties files by using the Automatch feature.

You can also access the XML data that comprises a property file directly in one of several ways:

  • metadata.Properties['prop-file'].xdata is an lxml.etree._Element object representing the top-level element in the file.
  • metadata.Properties['prop-file'].data is the raw contents of the property file as a string.
  • metadata.Properties['prop-file'].entries is a list of lxml.etree._Element objects representing the direct children of the top-level element. (I.e., everything directly under the <Properties> tag.)

The XML data in a property file is arbitrary, but a matching .xsd file can be created to assign a schema to a property file, which will be checked when running bcfg2-lint. For instance, given:

Properties/dns-config.xml
Properties/dns-config.xsd

dns-config.xml will be validated against dns-config.xsd.

Although Properties files are technically freeform XML, the top-level XML tag should be <Properties>.

JSON Property Files

New in version 1.3.0.

The data in a JSON property file can be accessed with the json attribute, which is the loaded JSON data. The JSON properties interface does not provide any additional functionality beyond the Common Interface.

YAML Property Files

New in version 1.3.0.

The data in a YAML property file can be accessed with the yaml attribute, which is the loaded YAML data. Only a single YAML document may be included in a file.

The YAML properties interface does not provide any additional functionality beyond the Common Interface.

Automatch

New in version 1.3.0.

You can enable Bcfg2.Server.Plugin.helpers.StructFile.XMLMatch() for all XML Property files by setting automatch to true in the [properties] section of bcfg2.conf. This makes metadata.Properties values lxml.etree._Element objects that contain only matching data. (This makes it impossible to do Writing to Properties files as a side-effect.)

In Python terms, setting automatch=true is the same as doing the following at the top of each template:

{% python
for prop in metadata.Properties.values():
    prop = prop.XMLMatch(metadata)
%}

The example above that describes XMLMatch() would then become simply:

{% python
ntp_servers = [el.text
               for el in metadata.Properties['ntp.xml'].findall("//Server")]
%}

You can also enable automatch for individual Property files by setting the attribute automatch="true" on the top-level <Properties> tag. Conversely, if automatch is enabled by default in bcfg2.conf, you can disable it for an individual Property file by setting automatch="false" on the top-level <Properties> tag.

If you want to see what XMLMatch()/automatch would produce for a given client on a given Properties file, you can use bcfg2-info:

bcfg2-info automatch props.xml foo.example.com

If automatch is not enabled, you can force bcfg2-info to perform it anyway with -f:

bcfg2-info automatch -f props.xml foo.example.com

Note

Be sure to notice that enabling automatch changes the type of the data in metadata.Properties; with automatch disabled, the values of the metadata.Properties dict are Bcfg2.Server.Plugins.Properties.PropertyFile objects. With automatch enabled, they are lxml.etree._Element objects.

Encrypted Properties data

New in version 1.3.0.

You can encrypt selected data in XML Properties files to protect that data from other people who need access to the repository. See Configuring Encryption for details on configuring encryption passphrases. The data is decrypted transparently on-the-fly by the server; you never need to decrypt the data in your templates. Encryption is only supported on XML properties files.

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.

Properties 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. If you wish for parsing to continue, with unencryptable elements simply skipped, then you can set decryption to lax in one of two ways:

  • Set decrypt=lax in the [encryption] section of bcfg2.conf to set lax decryption on all files by default; or
  • Set the decrypt="lax" attribute on the top-level Properties tag of a Properties file to set lax decryption for a single file.

Note that you could, for instance, set lax decryption by default, and then set strict decryption on individual files.

To encrypt or decrypt a file, use bcfg2-crypt.

See Bcfg2 Data Encryption for more details on encryption in Bcfg2 in general.

Accessing Properties contents from Genshi Templates

Access contents of Properties/auth.xml:

${metadata.Properties['auth.xml'].xdata.find('file').find('bcfg2.key').text}

Configuration

bcfg2.conf contains several miscellaneous configuration options for the Properties plugin, which can be set in the [properties] section. Any booleans in the config file accept the values “1”, “yes”, “true”, and “on” for True, and “0”, “no”, “false”, and “off” for False.

It understands the following directives:

Module Documentation

The properties plugin maps property files into client metadata instances.

class Bcfg2.Server.Plugins.Properties.JSONPropertyFile(name, fam=None)[source]

Bases: Bcfg2.Server.Plugin.helpers.FileBacked, Bcfg2.Server.Plugins.Properties.PropertyFile

Handle JSON Properties files.

Parameters:
Index()[source]

Index() is called by HandleEvent() every time the data changes, and parses the data into usable data as required.

validate_data()[source]

Verify that the data in this file is valid.

class Bcfg2.Server.Plugins.Properties.Properties(core, datastore)[source]

Bases: Bcfg2.Server.Plugin.base.Plugin, Bcfg2.Server.Plugin.interfaces.Connector, Bcfg2.Server.Plugin.helpers.DirectoryBacked

The properties plugin maps property files into client metadata instances.

Parameters:
  • core (Bcfg2.Server.Core) – The Bcfg2.Server.Core initializing the plugin
  • datastore (string) – The path to the Bcfg2 repository on the filesystem
Raises :

OSError if adding a file monitor failed; Bcfg2.Server.Plugin.exceptions.PluginInitError on other errors

Debuggable.__rmi__ = ['toggle_debug', 'set_debug']

List of names of methods to be exposed as XML-RPC functions

extensions = ['xml', 'json']

Extensions that are understood by Properties.

get_additional_data(metadata)[source]

Return arbitrary additional data for the given ClientMetadata object. By convention this is usually a dict object, but doesn’t need to be.

Parameters:metadata (Bcfg2.Server.Plugins.Metadata.ClientMetadata) – The client metadata
Returns:dict
ignore = <_sre.SRE_Pattern object at 0x8eb2240>

Ignore XML schema (.xsd) files

patterns = <_sre.SRE_Pattern object at 0x9c3e8a0>

Only track and include files whose names and paths match this regex. Created on-the-fly based on which libraries are installed (and thus which data formats are supported). Candidates are .xml (always supported), .json, .yaml, and .yml.

property_dispatcher(fname, fam)[source]

Dispatch an event on a Properties file to the appropriate object.

Parameters:
Returns:

An object of the appropriate subclass of PropertyFile

class Bcfg2.Server.Plugins.Properties.PropertyFile(name)[source]

Bases: object

Base Properties file handler

Parameters:name – The filename of this properties file.
_write()[source]

Write the data in this data structure back to the property file.

get_additional_data(metadata)[source]

Get file data for inclusion in client metadata.

validate_data()[source]

Verify that the data in this file is valid.

write()[source]

Write the data in this data structure back to the property file. This public method performs checking to ensure that writing is possible and then calls _write().

class Bcfg2.Server.Plugins.Properties.XMLPropertyFile(name, fam=None, should_monitor=False)[source]

Bases: Bcfg2.Server.Plugin.helpers.StructFile, Bcfg2.Server.Plugins.Properties.PropertyFile

Handle XML Properties files.

validate_data()[source]

ensure that the data in this object validates against the XML schema for this property file (if a schema exists)

class Bcfg2.Server.Plugins.Properties.YAMLPropertyFile(name, fam=None)[source]

Bases: Bcfg2.Server.Plugin.helpers.FileBacked, Bcfg2.Server.Plugins.Properties.PropertyFile

Handle YAML Properties files.

Parameters:
Index()[source]

Index() is called by HandleEvent() every time the data changes, and parses the data into usable data as required.

validate_data()[source]

Verify that the data in this file is valid.