summaryrefslogtreecommitdiffstats
path: root/doc/server/plugins/connectors/properties.txt
blob: 0fb7e85113f03a1009c897045ad5834ac9d029bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
.. -*- mode: rst -*-

.. _server-plugins-connectors-properties:

==========
Properties
==========

The Properties plugin is a connector plugin that adds information from
properties files into client metadata instances.

Enabling Properties
===================

First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML 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. PropertyFile instances
contain parsed XML data as the "data" attribute.

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>``.

Usage
=====

Specific property files can be referred to in templates as
``metadata.Properties[<filename>]``. The ``xdata`` attribute is an
lxml.etree._Element object. (Documented `here
<http://codespeak.net/lxml/tutorial.html#the-element-class>`_)

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")]
    %}

As we formulate more common use cases, we will add them to the
``PropertyFile`` class as methods. This will simplify templates.

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.)

.. _server-plugins-connectors-properties-automatch:

Automatch
=========

.. versionadded:: 1.3.0

You can enable
:func:`Bcfg2.Server.Plugins.Properties.PropertyFile.XMLMatch()` for
all Property files by setting ``automatch`` to ``true`` in the
``[properties]`` section of ``bcfg2.conf``.  This makes
``metadata.Properties`` values :class:`lxml.etree._Element` objects
that contain only matching data.  (This makes it impossible to do
:ref:`server-plugins-connectors-properties-write-back` 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 ``<Property>``
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 ``<Property>`` tag.

If you want to see what ``XMLMatch()``/automatch would produce for a
given client on a given Properties file, you can use :ref:`bcfg2-info
<server-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
    :class:`Bcfg2.Server.Plugins.Properties.PropertyFile` objects.
    With automatch enabled, they are :class:`lxml.etree._Element`
    objects.

.. _server-plugins-connectors-properties-write-back:

Writing to Properties files
===========================

.. versionadded:: 1.2.0

If you need to make persistent changes to properties data, you can use
the ``write`` method of the
:class:`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 ``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

.. _server-plugins-connectors-properties-encryption:

Encrypted Properties data
=========================

.. versionadded:: 1.3.0

You can encrypt selected data in Properties files to protect that data
from other people who need access to the repository.  See
:ref:`server-encryption-configuration` 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.

.. 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.

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

See :ref:`server-encryption` for more details on encryption in Bcfg2
in general.


Accessing Properties contents from TGenshi
==========================================

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:

* ``automatch``: Enable
  :ref:`server-plugins-connectors-properties-automatch`.  Default is
  false.
* ``writes_enabled``: Enable
  :ref:`server-plugins-connectors-properties-write-back`.  Default is
  true.