.. -*- mode: rst -*-

.. _server-plugins-grouping-metadata:

========
Metadata
========

The metadata mechanism has two types of information, client metadata
and group metadata. The client metadata describes which top level
group a client is associated with.The group metadata describes groups
in terms of what bundles and other groups they include. Group data and
clients' memberships are reflected in the `groups.xml`_ and
`clients.xml`_ files, respectively.

Usage of Groups in Metadata
===========================

Clients are assigned membership of groups in the Metadata
descriptions.  Clients can be directly assigned to *'profile'* or
*'public'* groups.  Client membership of all other groups is by those
groups being associated with the profile or public groups. This file
can be indirectly modified from clients through use of the ``-p`` flag
to ``bcfg2``.

Clients are associated with profile groups in `clients.xml`_
as shown below.

.. _server-plugins-grouping-metadata-clients-xml:

clients.xml
===========

The ``clients.xml`` file contains the mappings of Profile Groups
to clients. The file is just a series of ``<Client />`` tags, each of which
describe one host. A sample file is below:

.. code-block:: xml

    <Clients version="3.0">
      <Client profile="backup-server" name="backup.example.com"/>
      <Client profile="console-server" name="con.example.com"/>
      <Client profile="kerberos-master" name="kdc.example.com"/>
      <Client profile="mail-server" name="mail.example.com"/>
      <Client name='foo' address='10.0.0.1'>
        <Alias name='foo-mgmt' address='10.1.0.1'/>
      </Client>
    </Clients>

.. xml:schema:: clients.xsd

For detailed information on client authentication see
:ref:`appendix-guides-authentication`

.. _server-plugins-grouping-metadata-clients-database:

Clients Database
----------------

.. versionadded:: 1.3.0

It is also possible to store client records in a database rather than
writing back to `clients.xml`_.  This provides several advantages:

* `clients.xml`_ will never be written by the server, removing an
  area of contention between the user and server.
* `clients.xml`_ can be removed entirely for many sites.
* The Bcfg2 client list can be queried by other machines without
  obtaining and parsing `clients.xml`_.
* A single client list can be shared amongst multiple Bcfg2 servers.

In general, storing clients in the database works almost the same as
`clients.xml`_.  `groups.xml`_ is parsed identically.  If
`clients.xml`_ is present, it is parsed, but ``<Client>`` tags in
`clients.xml`_ *do not* assert client existence; they are only used
to set client options *if* the client exists (in the database).  That
is, the two purposes of `clients.xml`_ -- to track which clients
exist, and to set client options -- have been separated.

With the improvements in `groups.xml`_ parsing in 1.3, client groups
can now be set directly in `groups.xml`_ with ``<Client>`` tags. (See
:xml:type:`clientType` for more details.)  As a result, `clients.xml`_
is only necessary if you need to set options (e.g., aliases, floating
clients, per-client passwords, etc.) on clients.

To use the database backend instead of `clients.xml`_, set
``use_database`` in the ``[metadata]`` section of ``bcfg2.conf`` to
``true``.  You will also need to configure the :ref:`Global Server
Database Settings <server-database>`.

The `clients.xml`_-based model remains the default.

.. _server-plugins-grouping-metadata-groups-xml:

groups.xml
==========

The ``groups.xml`` file contains Group and Profile definitions. Here's
a simple ``groups.xml`` file:

.. code-block:: xml

    <Groups>
      <Group name='mail-server' profile='true'
                                comment='Top level mail server group' >
        <Bundle name='mail-server'/>
        <Bundle name='mailman-server'/>
        <Group name='apache-server'/>
        <Group name='nfs-client'/>
        <Group name='server'/>
        <Group name='rhel5'>
          <Group name='sendmail-server'/>
        </Group>
        <Group name='rhel6'>
          <Group name='postfix-server'/>
        </Group>
      </Group>
      <Group name='rhel'>
        <Group name='selinux-enabled'/>
      </Group>
      <Group name='oracle-server'>
        <Group name='selinux-enabled' negate='true'/>
      </Group>
      <Client name='foo.example.com'>
        <Group name='oracle-server'/>
        <Group name='apache-server'/>
      </Client>
    </Groups>

A Group tag that does not contain any child tags is a declaration of
membership; a Group or Client tag that does contain children is a
conditional.  So the example above does not assign either the
``rhel5`` or ``rhel6`` groups to machines in the ``mail-server``
group, but conditionally assigns the ``sendmail-server`` or
``postfix-server`` groups depending on the OS of the client.
(Presumably in this example the OS groups are set by a probe.)

Consequently, a client that is RHEL 5 and a member of the
``mail-server`` profile group would also be a member of the
``apache-server``, ``nfs-client``, ``server``, and ``sendmail-server``
groups; a RHEL 6 client that is a member of the ``mail-server``
profile group would be a member of the ``apache-server``,
``nfs-client``, ``server``, and ``postfix-server`` groups.

Client tags in `groups.xml`_ allow you to supplement the profile
group declarations in `clients.xml`_ and/or client group assignments
with the :ref:`server-plugins-grouping-grouppatterns` plugin.  They
should be used sparingly.  (They are more useful when you are using
the database backend for client records.)

You can also declare that a group should be negated; this allows you
to set defaults and override them efficiently.  Negation is applied
after other group memberships are calculated, so it doesn't matter how
many times a client is assigned to a group or how many times it is
negated; a single group negation is sufficient to remove a client from
that group.  For instance, in the following example,
``foo.example.com`` is **not** a member of ``selinux-enabled``, even
though it is a member of the ``foo-server`` and ``every-server``
groups:

.. code-block:: xml

    <Groups>
      <Group name="foo-server">
        <Group name="apache-server"/>
        <Group name="selinux-enabled"/>
      </Group>
      <Group name="apache-server">
        <Group name="selinux-enabled"/>
      </Group>
      <Group name="every-server">
        <Group name="selinux-enabled"/>
      </Group>
      <Client name="foo.example.com">
        <Group name="selinux-enabled" negate="true"/>
      </Client>

Negated groups can also be used to declare other Group assignments,
but not to declare Bundle assignments.

.. note::

    Nested Group conditionals, Client tags, and negated Group tags are
    all new in 1.3.0.

.. xml:schema:: metadata.xsd

Metadata Caching
================

.. versionadded:: 1.3.0

Client metadata can be cached in order to improve performance.  This
is particularly important if you have lots of templates that use
metadata from other clients (e.g., with the `MetadataQuery`_ interface
described below.  See :ref:`server-caching` for a full description of
the caching features available.

.. _server-plugins-grouping-metadata-clientmetadata:


ClientMetadata
==============

A special client metadata class is available to
:ref:`server-plugins-generators-cfg-genshi` and
:ref:`server-plugins-generators-cfg-cheetah`.

.. autoclass:: Bcfg2.Server.Plugins.Metadata.ClientMetadata

MetadataQuery
-------------

.. autoclass:: Bcfg2.Server.Plugins.Metadata.MetadataQuery