<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Bcfg2.Server.Plugin.interfaces — Bcfg2 1.3.0 documentation</title> <link rel="stylesheet" href="../../../../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../../../../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../../../../', VERSION: '1.3.0', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../../../_static/jquery.js"></script> <script type="text/javascript" src="../../../../_static/underscore.js"></script> <script type="text/javascript" src="../../../../_static/doctools.js"></script> <script type="text/javascript" src="../../../../_static/sidebar.js"></script> <link rel="shortcut icon" href="../../../../_static/favicon.ico"/> <link rel="top" title="Bcfg2 1.3.0 documentation" href="../../../../index.html" /> <link rel="up" title="Bcfg2.Server.Plugin" href="../Plugin.html" /> <link rel="stylesheet" href="../../../../_static/bcfg2.css" type=""/> </head> <body> <div style="text-align: left; padding: 10px 10px 15px 15px"> <a href="../../../../index.html"><img src="../../../../_static/bcfg2_logo.png" border="0" alt="sampledoc"/></a> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../../../../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="../../../../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li><a href="../../../../index.html">home</a> | </li> <!--<li><a href="../../../../search.html">search</a> | </li>--> <li><a href="../../../../help/index.html">help</a> | </li> <li><a href="../../../../contents.html">documentation </a> »</li> <li><a href="../../../index.html" >Module code</a> »</li> <li><a href="../Plugin.html" accesskey="U">Bcfg2.Server.Plugin</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <h1>Source code for Bcfg2.Server.Plugin.interfaces</h1><div class="highlight"><pre> <span class="sd">""" Interface definitions for Bcfg2 server plugins """</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">copy</span> <span class="kn">import</span> <span class="nn">threading</span> <span class="kn">import</span> <span class="nn">lxml.etree</span> <span class="kn">import</span> <span class="nn">Bcfg2.Server</span> <span class="kn">from</span> <span class="nn">Bcfg2.Compat</span> <span class="kn">import</span> <span class="n">Queue</span><span class="p">,</span> <span class="n">Empty</span><span class="p">,</span> <span class="n">Full</span><span class="p">,</span> <span class="n">cPickle</span> <span class="kn">from</span> <span class="nn">Bcfg2.Server.Plugin.base</span> <span class="kn">import</span> <span class="n">Plugin</span> <span class="kn">from</span> <span class="nn">Bcfg2.Server.Plugin.exceptions</span> <span class="kn">import</span> <span class="n">PluginInitError</span><span class="p">,</span> \ <span class="n">MetadataRuntimeError</span><span class="p">,</span> <span class="n">MetadataConsistencyError</span> <div class="viewcode-block" id="Generator"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Generator">[docs]</a><span class="k">class</span> <span class="nc">Generator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" Generator plugins contribute to literal client configurations.</span> <span class="sd"> That is, they generate entry contents.</span> <span class="sd"> An entry is generated in one of two ways:</span> <span class="sd"> #. The Bcfg2 core looks in the ``Entries`` dict attribute of the</span> <span class="sd"> plugin object. ``Entries`` is expected to be a dict whose keys</span> <span class="sd"> are entry tags (e.g., ``"Path"``, ``"Service"``, etc.) and</span> <span class="sd"> whose values are dicts; those dicts should map the ``name``</span> <span class="sd"> attribute of an entry to a callable that will be called to</span> <span class="sd"> generate the content. The callable will receive two arguments:</span> <span class="sd"> the abstract entry (as an lxml.etree._Element object), and the</span> <span class="sd"> client metadata object the entry is being generated for.</span> <span class="sd"> #. If the entry is not listed in ``Entries``, the Bcfg2 core calls</span> <span class="sd"> :func:`HandlesEntry`; if that returns True, then it calls</span> <span class="sd"> :func:`HandleEntry`.</span> <span class="sd"> """</span> <div class="viewcode-block" id="Generator.HandlesEntry"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Generator.HandlesEntry">[docs]</a> <span class="k">def</span> <span class="nf">HandlesEntry</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="c"># pylint: disable=W0613</span> <span class="sd">""" HandlesEntry is the slow path method for routing</span> <span class="sd"> configuration binding requests. It is called if the</span> <span class="sd"> ``Entries`` dict does not contain a method for binding the</span> <span class="sd"> entry.</span> <span class="sd"> :param entry: The entry to bind</span> <span class="sd"> :type entry: lxml.etree._Element</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: bool - Whether or not this plugin can handle the entry</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions.PluginExecutionError`</span> <span class="sd"> """</span> <span class="k">return</span> <span class="bp">False</span> </div> <div class="viewcode-block" id="Generator.HandleEntry"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Generator.HandleEntry">[docs]</a> <span class="k">def</span> <span class="nf">HandleEntry</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="c"># pylint: disable=W0613</span> <span class="sd">""" HandleEntry is the slow path method for binding</span> <span class="sd"> configuration binding requests. It is called if the</span> <span class="sd"> ``Entries`` dict does not contain a method for binding the</span> <span class="sd"> entry, and :func:`HandlesEntry`</span> <span class="sd"> returns True.</span> <span class="sd"> :param entry: The entry to bind</span> <span class="sd"> :type entry: lxml.etree._Element</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: lxml.etree._Element - The fully bound entry</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions.PluginExecutionError`</span> <span class="sd"> """</span> <span class="k">return</span> <span class="n">entry</span> </div></div> <div class="viewcode-block" id="Structure"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Structure">[docs]</a><span class="k">class</span> <span class="nc">Structure</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" Structure Plugins contribute to abstract client</span> <span class="sd"> configurations. That is, they produce lists of entries that will</span> <span class="sd"> be generated for a client. """</span> <div class="viewcode-block" id="Structure.BuildStructures"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Structure.BuildStructures">[docs]</a> <span class="k">def</span> <span class="nf">BuildStructures</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Build a list of lxml.etree._Element objects that will be</span> <span class="sd"> added to the top-level ``<Configuration>`` tag of the client</span> <span class="sd"> configuration. Consequently, each object in the list returned</span> <span class="sd"> by ``BuildStructures()`` must consist of a container tag</span> <span class="sd"> (e.g., ``<Bundle>`` or ``<Independent>``) which contains the</span> <span class="sd"> entry tags. It must not return a list of entry tags.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: list of lxml.etree._Element objects</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="Metadata"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata">[docs]</a><span class="k">class</span> <span class="nc">Metadata</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" Metadata plugins handle initial metadata construction,</span> <span class="sd"> accumulating data from :class:`Connector` plugins, and producing</span> <span class="sd"> :class:`Bcfg2.Server.Plugins.Metadata.ClientMetadata` objects. """</span> <div class="viewcode-block" id="Metadata.viz"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata.viz">[docs]</a> <span class="k">def</span> <span class="nf">viz</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hosts</span><span class="p">,</span> <span class="n">bundles</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">only_client</span><span class="p">,</span> <span class="n">colors</span><span class="p">):</span> <span class="sd">""" Return a string containing a graphviz document that maps</span> <span class="sd"> out the Metadata for :ref:`bcfg2-admin viz <server-admin-viz>`</span> <span class="sd"> :param hosts: Include hosts in the graph</span> <span class="sd"> :type hosts: bool</span> <span class="sd"> :param bundles: Include bundles in the graph</span> <span class="sd"> :type bundles: bool</span> <span class="sd"> :param key: Include a key in the graph</span> <span class="sd"> :type key: bool</span> <span class="sd"> :param only_client: Only include data for the specified client</span> <span class="sd"> :type only_client: string</span> <span class="sd"> :param colors: Use the specified graphviz colors</span> <span class="sd"> :type colors: list of strings</span> <span class="sd"> :return: string</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div> <div class="viewcode-block" id="Metadata.set_version"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata.set_version">[docs]</a> <span class="k">def</span> <span class="nf">set_version</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">version</span><span class="p">):</span> <span class="sd">""" Set the version for the named client to the specified</span> <span class="sd"> version string.</span> <span class="sd"> :param client: Hostname of the client</span> <span class="sd"> :type client: string</span> <span class="sd"> :param profile: Client Bcfg2 version</span> <span class="sd"> :type profile: string</span> <span class="sd"> :return: None</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions.MetadataRuntimeError`,</span> <span class="sd"> :class:`Bcfg2.Server.Plugin.exceptions.MetadataConsistencyError`</span> <span class="sd"> """</span> <span class="k">pass</span> </div> <div class="viewcode-block" id="Metadata.set_profile"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata.set_profile">[docs]</a> <span class="k">def</span> <span class="nf">set_profile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">profile</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span> <span class="sd">""" Set the profile for the named client to the named profile</span> <span class="sd"> group.</span> <span class="sd"> :param client: Hostname of the client</span> <span class="sd"> :type client: string</span> <span class="sd"> :param profile: Name of the profile group</span> <span class="sd"> :type profile: string</span> <span class="sd"> :param address: Address pair of ``(<ip address>, <hostname>)``</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :return: None</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions.MetadataRuntimeError`,</span> <span class="sd"> :class:`Bcfg2.Server.Plugin.exceptions.MetadataConsistencyError`</span> <span class="sd"> """</span> <span class="k">pass</span> <span class="c"># pylint: disable=W0613</span></div> <div class="viewcode-block" id="Metadata.resolve_client"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata.resolve_client">[docs]</a> <span class="k">def</span> <span class="nf">resolve_client</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">cleanup_cache</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span> <span class="sd">""" Resolve the canonical name of this client. If this method</span> <span class="sd"> is not implemented, the hostname claimed by the client is</span> <span class="sd"> used. (This may be a security risk; it's highly recommended</span> <span class="sd"> that you implement ``resolve_client`` if you are writing a</span> <span class="sd"> Metadata plugin.)</span> <span class="sd"> :param address: Address pair of ``(<ip address>, <hostname>)``</span> <span class="sd"> :type address: tuple</span> <span class="sd"> :param cleanup_cache: Whether or not to remove expire the</span> <span class="sd"> entire client hostname resolution class</span> <span class="sd"> :type cleanup_cache: bool</span> <span class="sd"> :return: string - canonical client hostname</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions.MetadataRuntimeError`,</span> <span class="sd"> :class:`Bcfg2.Server.Plugin.exceptions.MetadataConsistencyError`</span> <span class="sd"> """</span> <span class="k">return</span> <span class="n">address</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="c"># pylint: enable=W0613</span> </div> <div class="viewcode-block" id="Metadata.AuthenticateConnection"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata.AuthenticateConnection">[docs]</a> <span class="k">def</span> <span class="nf">AuthenticateConnection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cert</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span> <span class="sd">""" Authenticate the given client.</span> <span class="sd"> :param cert: an x509 certificate</span> <span class="sd"> :type cert: dict</span> <span class="sd"> :param user: The username of the user trying to authenticate</span> <span class="sd"> :type user: string</span> <span class="sd"> :param password: The password supplied by the client</span> <span class="sd"> :type password: string</span> <span class="sd"> :param addresspair: An address pair of ``(<ip address>,</span> <span class="sd"> <hostname>)``</span> <span class="sd"> :type addresspair: tuple</span> <span class="sd"> :return: bool - True if the authenticate succeeds, False otherwise</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div> <div class="viewcode-block" id="Metadata.get_initial_metadata"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata.get_initial_metadata">[docs]</a> <span class="k">def</span> <span class="nf">get_initial_metadata</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client_name</span><span class="p">):</span> <span class="sd">""" Return a</span> <span class="sd"> :class:`Bcfg2.Server.Plugins.Metadata.ClientMetadata` object</span> <span class="sd"> that fully describes everything the Metadata plugin knows</span> <span class="sd"> about the named client.</span> <span class="sd"> :param client_name: The hostname of the client</span> <span class="sd"> :type client_name: string</span> <span class="sd"> :return: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div> <div class="viewcode-block" id="Metadata.merge_additional_data"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata.merge_additional_data">[docs]</a> <span class="k">def</span> <span class="nf">merge_additional_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">imd</span><span class="p">,</span> <span class="n">source</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="sd">""" Add arbitrary data from a</span> <span class="sd"> :class:`Connector` plugin to the given</span> <span class="sd"> metadata object.</span> <span class="sd"> :param imd: An initial metadata object</span> <span class="sd"> :type imd: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param source: The name of the plugin providing this data</span> <span class="sd"> :type source: string</span> <span class="sd"> :param data: The data to add</span> <span class="sd"> :type data: any</span> <span class="sd"> :return: None</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div> <div class="viewcode-block" id="Metadata.merge_additional_groups"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Metadata.merge_additional_groups">[docs]</a> <span class="k">def</span> <span class="nf">merge_additional_groups</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">imd</span><span class="p">,</span> <span class="n">groups</span><span class="p">):</span> <span class="sd">""" Add groups from a</span> <span class="sd"> :class:`Connector` plugin to the given</span> <span class="sd"> metadata object.</span> <span class="sd"> :param imd: An initial metadata object</span> <span class="sd"> :type imd: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param groups: The groups to add</span> <span class="sd"> :type groups: list of strings</span> <span class="sd"> :return: None</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="Connector"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Connector">[docs]</a><span class="k">class</span> <span class="nc">Connector</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" Connector plugins augment client metadata instances with</span> <span class="sd"> additional data, additional groups, or both. """</span> <div class="viewcode-block" id="Connector.get_additional_groups"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Connector.get_additional_groups">[docs]</a> <span class="k">def</span> <span class="nf">get_additional_groups</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="c"># pylint: disable=W0613</span> <span class="sd">""" Return a list of additional groups for the given client.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: list of strings</span> <span class="sd"> """</span> <span class="k">return</span> <span class="nb">list</span><span class="p">()</span> </div> <div class="viewcode-block" id="Connector.get_additional_data"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Connector.get_additional_data">[docs]</a> <span class="k">def</span> <span class="nf">get_additional_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="c"># pylint: disable=W0613</span> <span class="sd">""" Return arbitrary additional data for the given</span> <span class="sd"> ClientMetadata object. By convention this is usually a dict</span> <span class="sd"> object, but doesn't need to be.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: dict</span> <span class="sd"> """</span> <span class="k">return</span> <span class="nb">dict</span><span class="p">()</span> </div></div> <div class="viewcode-block" id="Probing"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Probing">[docs]</a><span class="k">class</span> <span class="nc">Probing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" Probing plugins can collect data from clients and process it.</span> <span class="sd"> """</span> <div class="viewcode-block" id="Probing.GetProbes"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Probing.GetProbes">[docs]</a> <span class="k">def</span> <span class="nf">GetProbes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Return a list of probes for the given client. Each probe</span> <span class="sd"> should be an lxml.etree._Element object that adheres to</span> <span class="sd"> the following specification. Each probe must the following</span> <span class="sd"> attributes:</span> <span class="sd"> * ``name``: The unique name of the probe.</span> <span class="sd"> * ``source``: The origin of the probe; probably the name of</span> <span class="sd"> the plugin that supplies the probe.</span> <span class="sd"> * ``interpreter``: The command that will be run on the client</span> <span class="sd"> to interpret the probe script. Compiled (i.e.,</span> <span class="sd"> non-interpreted) probes are not supported.</span> <span class="sd"> The text of the XML tag should be the contents of the probe,</span> <span class="sd"> i.e., the code that will be run on the client.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :return: list of lxml.etree._Element objects</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div> <div class="viewcode-block" id="Probing.ReceiveData"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Probing.ReceiveData">[docs]</a> <span class="k">def</span> <span class="nf">ReceiveData</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">datalist</span><span class="p">):</span> <span class="sd">""" Process data returned from the probes for the given</span> <span class="sd"> client. ``datalist`` is a list of lxml.etree._Element</span> <span class="sd"> objects, each of which is a single tag; the ``name`` attribute</span> <span class="sd"> holds the unique name of the probe that was run, and the text</span> <span class="sd"> contents of the tag hold the results of the probe.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param datalist: The probe data</span> <span class="sd"> :type datalist: list of lxml.etree._Element objects</span> <span class="sd"> :return: None</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="Statistics"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Statistics">[docs]</a><span class="k">class</span> <span class="nc">Statistics</span><span class="p">(</span><span class="n">Plugin</span><span class="p">):</span> <span class="sd">""" Statistics plugins handle statistics for clients. In general,</span> <span class="sd"> you should avoid using Statistics and use</span> <span class="sd"> :class:`ThreadedStatistics` instead."""</span> <div class="viewcode-block" id="Statistics.process_statistics"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Statistics.process_statistics">[docs]</a> <span class="k">def</span> <span class="nf">process_statistics</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">xdata</span><span class="p">):</span> <span class="sd">""" Process the given XML statistics data for the specified</span> <span class="sd"> client.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param data: The statistics data</span> <span class="sd"> :type data: lxml.etree._Element</span> <span class="sd"> :return: None</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="Threaded"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Threaded">[docs]</a><span class="k">class</span> <span class="nc">Threaded</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" Threaded plugins use threads in any way. The thread must be</span> <span class="sd"> started after daemonization, so this class implements a single</span> <span class="sd"> method, :func:`start_threads`, that can be used to start threads</span> <span class="sd"> after daemonization of the server core. """</span> <div class="viewcode-block" id="Threaded.start_threads"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Threaded.start_threads">[docs]</a> <span class="k">def</span> <span class="nf">start_threads</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Start this plugin's threads after daemonization.</span> <span class="sd"> :return: None</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions.PluginInitError`</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="ThreadedStatistics"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.ThreadedStatistics">[docs]</a><span class="k">class</span> <span class="nc">ThreadedStatistics</span><span class="p">(</span><span class="n">Statistics</span><span class="p">,</span> <span class="n">Threaded</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span> <span class="sd">""" ThreadedStatistics plugins process client statistics in a</span> <span class="sd"> separate thread. """</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">core</span><span class="p">,</span> <span class="n">datastore</span><span class="p">):</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">core</span><span class="p">,</span> <span class="n">datastore</span><span class="p">)</span> <span class="n">Threaded</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="c"># Event from the core signaling an exit</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span> <span class="o">=</span> <span class="n">core</span><span class="o">.</span><span class="n">terminate</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span> <span class="o">=</span> <span class="n">Queue</span><span class="p">(</span><span class="mi">100000</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_file</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">datastore</span><span class="p">,</span> <span class="s">"etc"</span><span class="p">,</span> <span class="s">"</span><span class="si">%s</span><span class="s">.pending"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">def</span> <span class="nf">start_threads</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="k">def</span> <span class="nf">_save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""Save any pending data to a file."""</span> <span class="n">pending_data</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">try</span><span class="p">:</span> <span class="k">while</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span><span class="o">.</span><span class="n">empty</span><span class="p">():</span> <span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span><span class="o">.</span><span class="n">get_nowait</span><span class="p">()</span> <span class="n">pending_data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span> <span class="p">(</span><span class="n">metadata</span><span class="o">.</span><span class="n">hostname</span><span class="p">,</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">tostring</span><span class="p">(</span> <span class="n">data</span><span class="p">,</span> <span class="n">xml_declaration</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">"UTF-8"</span><span class="p">)))</span> <span class="k">except</span> <span class="n">Empty</span><span class="p">:</span> <span class="k">pass</span> <span class="k">try</span><span class="p">:</span> <span class="n">savefile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pending_file</span><span class="p">,</span> <span class="s">'w'</span><span class="p">)</span> <span class="n">cPickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">pending_data</span><span class="p">,</span> <span class="n">savefile</span><span class="p">)</span> <span class="n">savefile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Saved pending </span><span class="si">%s</span><span class="s"> data"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="k">except</span> <span class="p">(</span><span class="ne">IOError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">"Failed to save pending data: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_load</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""Load any pending data from a file."""</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pending_file</span><span class="p">):</span> <span class="k">return</span> <span class="bp">True</span> <span class="n">pending_data</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">try</span><span class="p">:</span> <span class="n">savefile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pending_file</span><span class="p">,</span> <span class="s">'r'</span><span class="p">)</span> <span class="n">pending_data</span> <span class="o">=</span> <span class="n">cPickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">savefile</span><span class="p">)</span> <span class="n">savefile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="k">except</span> <span class="p">(</span><span class="ne">IOError</span><span class="p">,</span> <span class="n">cPickle</span><span class="o">.</span><span class="n">UnpicklingError</span><span class="p">):</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">"Failed to load pending data: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span> <span class="k">return</span> <span class="bp">False</span> <span class="k">for</span> <span class="p">(</span><span class="n">pmetadata</span><span class="p">,</span> <span class="n">pdata</span><span class="p">)</span> <span class="ow">in</span> <span class="n">pending_data</span><span class="p">:</span> <span class="c"># check that shutdown wasnt called early</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span><span class="o">.</span><span class="n">isSet</span><span class="p">():</span> <span class="k">return</span> <span class="bp">False</span> <span class="k">try</span><span class="p">:</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">metadata</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">build_metadata</span><span class="p">(</span><span class="n">pmetadata</span><span class="p">)</span> <span class="k">break</span> <span class="k">except</span> <span class="n">MetadataRuntimeError</span><span class="p">:</span> <span class="k">pass</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span><span class="o">.</span><span class="n">isSet</span><span class="p">():</span> <span class="k">return</span> <span class="bp">False</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span><span class="o">.</span><span class="n">put_nowait</span><span class="p">(</span> <span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="n">pdata</span><span class="p">,</span> <span class="n">parser</span><span class="o">=</span><span class="n">Bcfg2</span><span class="o">.</span><span class="n">Server</span><span class="o">.</span><span class="n">XMLParser</span><span class="p">)))</span> <span class="k">except</span> <span class="n">Full</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">"Queue.Full: Failed to load queue data"</span><span class="p">)</span> <span class="k">break</span> <span class="k">except</span> <span class="n">lxml</span><span class="o">.</span><span class="n">etree</span><span class="o">.</span><span class="n">LxmlError</span><span class="p">:</span> <span class="n">lxml_error</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Unable to load saved interaction: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">lxml_error</span><span class="p">)</span> <span class="k">except</span> <span class="n">MetadataConsistencyError</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Unable to load metadata for save "</span> <span class="s">"interaction: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">pmetadata</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pending_file</span><span class="p">)</span> <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Failed to unlink save file: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_file</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Loaded pending </span><span class="si">%s</span><span class="s"> data"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_load</span><span class="p">():</span> <span class="k">return</span> <span class="k">while</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">terminate</span><span class="o">.</span><span class="n">isSet</span><span class="p">()</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">xdata</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">block</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="k">except</span> <span class="n">Empty</span><span class="p">:</span> <span class="k">continue</span> <span class="k">except</span><span class="p">:</span> <span class="n">err</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">"ThreadedStatistics: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span> <span class="k">continue</span> <span class="bp">self</span><span class="o">.</span><span class="n">handle_statistic</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">xdata</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span> <span class="o">!=</span> <span class="bp">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span><span class="o">.</span><span class="n">empty</span><span class="p">():</span> <span class="bp">self</span><span class="o">.</span><span class="n">_save</span><span class="p">()</span> <span class="k">def</span> <span class="nf">process_statistics</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">work_queue</span><span class="o">.</span><span class="n">put_nowait</span><span class="p">((</span><span class="n">metadata</span><span class="p">,</span> <span class="n">copy</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">data</span><span class="p">)))</span> <span class="k">except</span> <span class="n">Full</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">"</span><span class="si">%s</span><span class="s">: Queue is full. Dropping interactions."</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <div class="viewcode-block" id="ThreadedStatistics.handle_statistic"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.ThreadedStatistics.handle_statistic">[docs]</a> <span class="k">def</span> <span class="nf">handle_statistic</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="sd">""" Process the given XML statistics data for the specified</span> <span class="sd"> client object. This differs from the</span> <span class="sd"> :func:`Statistics.process_statistics` method only in that</span> <span class="sd"> ThreadedStatistics first adds the data to a queue, and then</span> <span class="sd"> processes them in a separate thread.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param data: The statistics data</span> <span class="sd"> :type data: lxml.etree._Element</span> <span class="sd"> :return: None</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> <span class="c"># pylint: disable=C0111</span> <span class="c"># Someone who understands these interfaces better needs to write docs</span> <span class="c"># for PullSource and PullTarget</span></div></div> <span class="k">class</span> <span class="nc">PullSource</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="k">def</span> <span class="nf">GetExtra</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">):</span> <span class="c"># pylint: disable=W0613</span> <span class="k">return</span> <span class="p">[]</span> <span class="k">def</span> <span class="nf">GetCurrentEntry</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">e_type</span><span class="p">,</span> <span class="n">e_name</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> <span class="k">class</span> <span class="nc">PullTarget</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="k">def</span> <span class="nf">AcceptChoices</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">entry</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> <span class="k">def</span> <span class="nf">AcceptPullData</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">specific</span><span class="p">,</span> <span class="n">new_entry</span><span class="p">,</span> <span class="n">verbose</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> <span class="c"># pylint: enable=C0111</span> <div class="viewcode-block" id="Decision"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Decision">[docs]</a><span class="k">class</span> <span class="nc">Decision</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" Decision plugins produce decision lists for affecting which</span> <span class="sd"> entries are actually installed on clients. """</span> <div class="viewcode-block" id="Decision.GetDecisions"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Decision.GetDecisions">[docs]</a> <span class="k">def</span> <span class="nf">GetDecisions</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span> <span class="sd">""" Return a list of tuples of ``(<entry type>, <entry</span> <span class="sd"> name>)`` to be used as the decision list for the given</span> <span class="sd"> client in the specified mode.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param mode: The decision mode ("whitelist" or "blacklist")</span> <span class="sd"> :type mode: string</span> <span class="sd"> :return: list of tuples</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="StructureValidator"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.StructureValidator">[docs]</a><span class="k">class</span> <span class="nc">StructureValidator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" StructureValidator plugins can modify the list of structures</span> <span class="sd"> after it has been created but before the entries have been</span> <span class="sd"> concretely bound. """</span> <div class="viewcode-block" id="StructureValidator.validate_structures"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.StructureValidator.validate_structures">[docs]</a> <span class="k">def</span> <span class="nf">validate_structures</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">structures</span><span class="p">):</span> <span class="sd">""" Given a list of structures (i.e., of tags that contain</span> <span class="sd"> entry tags), modify that list or the structures in it</span> <span class="sd"> in-place.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param config: A list of lxml.etree._Element objects</span> <span class="sd"> describing the structures (i.e., bundles) for</span> <span class="sd"> this client. This can be modified in place.</span> <span class="sd"> :type config: list of lxml.etree._Element</span> <span class="sd"> :returns: None</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions.ValidationError`</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="GoalValidator"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.GoalValidator">[docs]</a><span class="k">class</span> <span class="nc">GoalValidator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" GoalValidator plugins can modify the concretely-bound configuration of</span> <span class="sd"> a client as a last stage before the configuration is sent to the</span> <span class="sd"> client. """</span> <div class="viewcode-block" id="GoalValidator.validate_goals"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.GoalValidator.validate_goals">[docs]</a> <span class="k">def</span> <span class="nf">validate_goals</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">config</span><span class="p">):</span> <span class="sd">""" Given a monolithic XML document of the full configuration,</span> <span class="sd"> modify the document in-place.</span> <span class="sd"> :param metadata: The client metadata</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :param config: The full configuration for the client</span> <span class="sd"> :type config: lxml.etree._Element</span> <span class="sd"> :returns: None</span> <span class="sd"> :raises: :class:`Bcfg2.Server.Plugin.exceptions:ValidationError`</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="Version"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Version">[docs]</a><span class="k">class</span> <span class="nc">Version</span><span class="p">(</span><span class="n">Plugin</span><span class="p">):</span> <span class="sd">""" Version plugins interact with various version control systems. """</span> <span class="c">#: The path to the VCS metadata file or directory, relative to the</span> <span class="c">#: base of the Bcfg2 repository. E.g., for Subversion this would</span> <span class="c">#: be ".svn"</span> <span class="n">__vcs_metadata_path__</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">core</span><span class="p">,</span> <span class="n">datastore</span><span class="p">):</span> <span class="n">Plugin</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">core</span><span class="p">,</span> <span class="n">datastore</span><span class="p">)</span> <span class="k">if</span> <span class="n">core</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'vcs_root'</span><span class="p">]:</span> <span class="bp">self</span><span class="o">.</span><span class="n">vcs_root</span> <span class="o">=</span> <span class="n">core</span><span class="o">.</span><span class="n">setup</span><span class="p">[</span><span class="s">'vcs_root'</span><span class="p">]</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">vcs_root</span> <span class="o">=</span> <span class="n">datastore</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__vcs_metadata_path__</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">vcs_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vcs_root</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">__vcs_metadata_path__</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vcs_path</span><span class="p">):</span> <span class="k">raise</span> <span class="n">PluginInitError</span><span class="p">(</span><span class="s">"</span><span class="si">%s</span><span class="s"> is not present"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">vcs_path</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">vcs_path</span> <span class="o">=</span> <span class="bp">None</span> <span class="n">__init__</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="n">Plugin</span><span class="o">.</span><span class="n">__init__</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">+</span> <span class="s">"""</span> <span class="s">.. autoattribute:: __vcs_metadata_path__ """</span> <div class="viewcode-block" id="Version.get_revision"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.Version.get_revision">[docs]</a> <span class="k">def</span> <span class="nf">get_revision</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">""" Return the current revision of the Bcfg2 specification.</span> <span class="sd"> This will be included in the ``revision`` attribute of the</span> <span class="sd"> top-level tag of the XML configuration sent to the client.</span> <span class="sd"> :returns: string - the current version</span> <span class="sd"> """</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span> </div></div> <div class="viewcode-block" id="ClientRunHooks"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.ClientRunHooks">[docs]</a><span class="k">class</span> <span class="nc">ClientRunHooks</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">""" ClientRunHooks can hook into various parts of a client run to</span> <span class="sd"> perform actions at various times without needing to pretend to be</span> <span class="sd"> a different plugin type. """</span> <div class="viewcode-block" id="ClientRunHooks.start_client_run"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.ClientRunHooks.start_client_run">[docs]</a> <span class="k">def</span> <span class="nf">start_client_run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Invoked at the start of a client run, after all probe data</span> <span class="sd"> has been received and decision lists have been queried (if</span> <span class="sd"> applicable), but before the configuration is generated.</span> <span class="sd"> :param metadata: The client metadata object</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :returns: None</span> <span class="sd"> """</span> <span class="k">pass</span> </div> <div class="viewcode-block" id="ClientRunHooks.end_client_run"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.ClientRunHooks.end_client_run">[docs]</a> <span class="k">def</span> <span class="nf">end_client_run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Invoked at the end of a client run, immediately after</span> <span class="sd"> :class:`GoalValidator` plugins have been run and just before</span> <span class="sd"> the configuration is returned to the client.</span> <span class="sd"> :param metadata: The client metadata object</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :returns: None</span> <span class="sd"> """</span> <span class="k">pass</span> </div> <div class="viewcode-block" id="ClientRunHooks.end_statistics"><a class="viewcode-back" href="../../../../development/plugins.html#Bcfg2.Server.Plugin.interfaces.ClientRunHooks.end_statistics">[docs]</a> <span class="k">def</span> <span class="nf">end_statistics</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span> <span class="sd">""" Invoked after statistics are processed for a client.</span> <span class="sd"> :param metadata: The client metadata object</span> <span class="sd"> :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata</span> <span class="sd"> :returns: None</span> <span class="sd"> """</span> <span class="k">pass</span></div></div> </pre></div> </div> </div> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../../../../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../../../../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="../../../../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li><a href="../../../../index.html">home</a> | </li> <!--<li><a href="../../../../search.html">search</a> | </li>--> <li><a href="../../../../help/index.html">help</a> | </li> <li><a href="../../../../contents.html">documentation </a> »</li> <li><a href="../../../index.html" >Module code</a> »</li> <li><a href="../Plugin.html" >Bcfg2.Server.Plugin</a> »</li> </ul> </div> <div class="footer"> © Copyright 2009-2013, Narayan Desai. Last updated on Mar 20, 2013. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. </div> </body> </html>