| ================== |
| reclass operations |
| ================== |
| |
| YAML FS storage |
| --------------- |
| While |reclass| has been built to support different storage backends through |
| plugins, currently only the ``yaml_fs`` storage backend exists. This is a very |
| simple, yet powerful, YAML-based backend, using flat files on the filesystem |
| (as suggested by the ``_fs`` postfix). |
| |
| ``yaml_fs`` works with two directories, one for node definitions, and another |
| for class definitions. The two directories must not be the same, nor can one |
| be a parent of the other. |
| |
| Files in those directories are YAML-files, specifying key-value pairs. The |
| following three keys are read by |reclass|: |
| |
| ============ ================================================================ |
| Key Description |
| ============ ================================================================ |
| classes a list of parent classes |
| appliations a list of applications to append to the applications defined by |
| ancestors. If an application name starts with ``~``, it would |
| remove this application from the list, if it had already been |
| added — but it does not prevent a future addition. |
| E.g. ``~firewalled`` |
| parameters key-value pairs to set defaults in class definitions, override |
| existing data, or provide node-specific information in node |
| specifications. |
| \ |
| By convention, parameters corresponding to an application |
| should be provided as subkey-value pairs, keyed by the name of |
| the application, e.g.:: |
| |
| applications: |
| - ssh.server |
| parameters: |
| ssh.server: |
| permit_root_login: no |
| environment only relevant for nodes, this allows to specify an "environment" |
| into which the node definition is supposed to be place. |
| ============ ================================================================ |
| |
| Classes files may reside in subdirectories, which act as namespaces. For |
| instance, a class ``ssh.server`` will result in the class definition to be |
| read from ``ssh/server.yml``. Specifying just ``ssh`` will cause the class |
| data to be read from ``ssh/init.yml`` or ``ssh.yml``. Note, however, that only |
| one of those two may be present. |
| |
| Nodes may also be defined in subdirectories. However, node names (filename) |
| must be unique across all subdirectories, and |reclass| will exit with an |
| error if a node is defined multiple times. Subdirectories therefore really |
| only exist for the administrator's local data structuring. They may be used in |
| mappings (see below) to tag additional classes onto nodes. |
| |
| Data merging |
| ------------ |
| |reclass| has two modes of operation: node information retrieval and inventory |
| listing. The second is really just a loop of the first across all defined |
| nodes, and needs not be further described. |
| |
| When retrieving information about a node, |reclass| first obtains the node |
| definition from the storage backend. Then, it iterates the list of classes |
| defined for the node and recursively asks the storage backend for each class |
| definition (unless already cached). |
| |
| Next, |reclass| recursively descends each class, looking at the classes it |
| defines, and so on, until a leaf node is reached, i.e. a class that references |
| no other classes. |
| |
| Now, the merging starts. At every step, the list of applications and the set |
| of parameters at each level is merged into what has been accumulated so far. |
| |
| Merging of parameters is done "deeply", meaning that lists and dictionaries |
| are extended (recursively), rather than replaced. However, a scalar value |
| *does* overwrite a dictionary or list value. While the scalar could be |
| appended to an existing list, there is no sane default assumption in the |
| context of a dictionary, so this behaviour seems the most logical. Plus, it |
| allows for a dictionary to be erased by overwriting it with the null value. |
| |
| After all classes (and the classes they reference) have been visited, |
| |reclass| finally merges the applications list and parameters defined for the |
| node into what has been accumulated during the processing of the classes, and |
| returns the final result. |
| |
| Wildcard/Regexp mappings |
| ------------------------ |
| Using the :doc:`configuration file <configfile>`, it is also possible to |
| provide a list mappings between node names and classes. For instance:: |
| |
| class_mappings: |
| - \* default |
| - /^www\d+/ webserver |
| - \*.ch hosted@switzerland another_class_to_show_that_it_can_take_lists |
| |
| This will assign the ``default`` class to all nodes (make sure to escape |
| a leading asterisk (\*) to keep YAML happy), ``webserver`` to all nodes named |
| ``www1`` or ``www999``, and ``hosted-in-switzerland`` to all nodes whose names |
| end with ``.ch`` (again, note the escaped leading asterisk). Multiple classes |
| can be assigned to each mapping by providing a space-separated list (class |
| names cannot contain spaces anyway). |
| |
| By default the class mappings regex match is done against the node name. This can |
| be changed to do the match against the path of the node file from the classes |
| directory, but dropping the .yml extension at the end of the node file. This is |
| controlled with the setting class_mappings_match_path. When False (the |
| default) the match is done again the node name and when true the match is done |
| against the node file path. |
| |
| .. warning:: |
| |
| The class mappings do not really belong in the configuration file, as they |
| are data, not configuration inmformation. Therefore, they are likely going |
| to move elsewhere, but I have not quite figured out to where. Most likely, |
| there will be an additional file, specified in the configuration file, which |
| then lists the mappings. |
| |
| Note that mappings are not designed to replace node definitions. Mappings can |
| be used to pre-populate the classes of existing nodes, but you still need to |
| define all nodes (and if only to allow them to be enumerated for the |
| inventory). |
| |
| The mapped classes can also contain backreferences when regular expressions |
| are used, although they need to be escaped, e.g.:: |
| |
| class_mappings: |
| - /\.(\S+)$/ tld-\\1 |
| |
| Furthermore, since the outer slashes ('/') are used to "quote" the regular |
| expression, *any* slashes within the regular expression must be escaped. For |
| instance, the following class mapping assigns a ``subdir-X`` class to all |
| nodes that are defined in a subdirectory (using yaml_fs):: |
| |
| class_mappings: |
| - /^([^\/]+)\// subdir-\\1 |
| |
| Parameter interpolation |
| ------------------------ |
| Parameters may reference each other, including deep references, e.g.:: |
| |
| parameters: |
| location: Munich, Germany |
| motd: |
| header: This node sits in ${location} |
| for_demonstration: ${motd:header} |
| dict_reference: ${motd} |
| |
| After merging and interpolation, which happens automatically inside the |
| storage modules, the ``for_demonstration`` parameter will have a value of |
| "This node sits in Munich, Germany". |
| |
| Types are preserved if the value contains nothing but a reference. Hence, the |
| value of ``dict_reference`` will actually be a dictionary. |
| |
| You should now be ready to :doc:`use reclass <usage>`! |
| |
| .. include:: substs.inc |