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
|
.. -*- mode: rst -*-
.. _development-lint:
===============================
bcfg2-lint Plugin Development
===============================
``bcfg2-lint``, like most parts of Bcfg2, has a pluggable backend that
lets you easily write your own plugins to verify various parts of your
Bcfg2 specification.
Plugins are loaded in one of two ways:
* They may be included in a module of the same name as the plugin
class in :mod:`Bcfg2.Server.Lint`, e.g.,
:mod:`Bcfg2.Server.Lint.Validate`.
* They may be included directly in a Bcfg2 server plugin, called
"<plugin>Lint", e.g.,
:class:`Bcfg2.Server.Plugins.Metadata.MetadataLint`.
Plugin Types
============
There are two types of ``bcfg2-lint`` plugins:
Serverless plugins
------------------
Serverless plugins are run before ``bcfg2-lint`` starts up a local
Bcfg2 server, so the amount of introspection they can do is fairly
limited. They can directly examine the Bcfg2 specification, of
course, but they can't examine the entries handled by a given plugin
or anything that requires a running server.
If a serverless plugin raises a lint error, however, the server will
not be started and no `Server plugins`_ will be run. This makes them
useful to check for the sorts of errors that might prevent the Bcfg2
server from starting properly.
Serverless plugins must subclass
:class:`Bcfg2.Server.Lint.ServerlessPlugin`.
:mod:`Bcfg2.Server.Lint.Validate` is an example of a serverless
plugin.
Server plugins
--------------
Server plugins are run after a local Bcfg2 server has been started,
and have full access to all of the parsed data and so on. Because of
this, they tend to be easier to use than `Serverless plugins`_, and
thus are more common.
Server plugins are only run if all `Serverless plugins`_ run
successfully (i.e., raise no errors).
Server plugins must subclass :class:`Bcfg2.Server.Lint.ServerPlugin`.
:mod:`Bcfg2.Server.Lint.Genshi` is an example of a server plugin.
Error Handling
==============
The job of a ``bcfg2-lint`` plugin is to find errors. Each error that
a plugin may produce must have a name, a short string that briefly
describes the error and will be used to configure error levels in
``bcfg2.conf``. It must also have a default reporting level.
Possible reporting levels are "error", "warning", or "silent". All of
the errors that may be produced by a plugin must be returned as a dict
by :func:`Bcfg2.Server.Lint.Plugin.Errors`. For instance, consider
:func:`Bcfg2.Server.Lint.InfoXML.InfoXML.Errors`:
.. code-block:: python
@classmethod
def Errors(cls):
return {"no-infoxml": "warning",
"deprecated-info-file": "warning",
"paranoid-false": "warning",
"required-infoxml-attrs-missing": "error"}
This means that the :class:`Bcfg2.Server.Lint.InfoXML.InfoXML` lint
plugin can produce five lint errors, although four of them are just
warnings by default.
The errors returned by each plugin's ``Errors()`` method will be
passed to :func:`Bcfg2.Server.Lint.ErrorHandler.RegisterErrors`, which
will use that information and the information in the config file to
determine how to display (or not display) each error to the end user.
Errors are produced in a plugin with
:func:`Bcfg2.Server.Lint.Plugin.LintError`, which takes two arguments:
the name of the error, which must correspond to a key in the dict
returned by :func:`Bcfg2.Server.Lint.Plugin.Errors`, and a freeform
string that will be displayed to the end user. Note that the error
name and its display are thus only tied together when the error is
produced; that is, a single error (by name) can have two completely
different outputs.
Basics
======
.. automodule:: Bcfg2.Server.Lint
Existing ``bcfg2-lint`` Plugins
===============================
AWSTagsLint
-----------
.. autoclass:: Bcfg2.Server.Plugins.AWSTags.AWSTagsLint
BundlerLint
-----------
.. autoclass:: Bcfg2.Server.Plugins.Bundler.BundlerLint
Comments
--------
.. automodule:: Bcfg2.Server.Lint.Comments
Genshi
------
.. automodule:: Bcfg2.Server.Lint.Genshi
GroupNames
----------
.. automodule:: Bcfg2.Server.Lint.GroupNames
GroupPatternsLint
-----------------
.. autoclass:: Bcfg2.Server.Plugins.GroupPatterns.GroupPatternsLint
InfoXML
-------
.. automodule:: Bcfg2.Server.Lint.InfoXML
MergeFiles
----------
.. automodule:: Bcfg2.Server.Lint.MergeFiles
MetadataLint
------------
.. autoclass:: Bcfg2.Server.Plugins.Metadata.MetadataLint
PkgmgrLint
----------
.. autoclass:: Bcfg2.Server.Plugins.Pkgmgr.PkgmgrLint
RequiredAttrs
-------------
.. automodule:: Bcfg2.Server.Lint.RequiredAttrs
TemplateHelperLint
------------------
.. autoclass:: Bcfg2.Server.Plugins.TemplateHelper.TemplateHelperLint
Validate
--------
.. automodule:: Bcfg2.Server.Lint.Validate
|