diff options
35 files changed, 205 insertions, 206 deletions
diff --git a/doc/development/core.txt b/doc/development/core.txt index 3607533ea..205eb5c59 100644 --- a/doc/development/core.txt +++ b/doc/development/core.txt @@ -59,7 +59,7 @@ Builtin Core The builtin server core consists of the core implementation (:class:`Bcfg2.Server.BuiltinCore.Core`) and the XML-RPC server -implementation (:mod:`Bcfg2.SSLServer`). +implementation (:mod:`Bcfg2.Server.SSLServer`). Core ~~~~ @@ -69,7 +69,7 @@ Core XML-RPC Server ~~~~~~~~~~~~~~ -.. automodule:: Bcfg2.SSLServer +.. automodule:: Bcfg2.Server.SSLServer CherryPy Core ------------- diff --git a/doc/development/plugins.txt b/doc/development/plugins.txt index 91a4e6868..04b9ff7b1 100644 --- a/doc/development/plugins.txt +++ b/doc/development/plugins.txt @@ -128,13 +128,15 @@ The two attributes you need to know about are: of the caching mode. See :ref:`server-caching` for a description of each mode. * :attr:`Bcfg2.Server.Core.metadata_cache`: A dict-like - :class:`Bcfg2.Cache.Cache` object that stores the cached data. + :class:`Bcfg2.Server.Cache.Cache` object that stores the cached + data. :class:`Bcfg2.Server.Plugin.base.Plugin` objects have access to the :class:`Bcfg2.Server.Core` object as ``self.core``. In general, -you'll be interested in the :func:`Bcfg2.Cache.Cache.expire` method; -if called with no arguments, it expires all cached data; if called -with one string argument, it expires cached data for the named client. +you'll be interested in the :func:`Bcfg2.Server.Cache.Cache.expire` +method; if called with no arguments, it expires all cached data; if +called with one string argument, it expires cached data for the named +client. It's important, therefore, that your Connector plugin can either track when changes are made to the group membership it reports, and expire @@ -163,7 +165,7 @@ Tracking Execution Time .. versionadded:: 1.3.0 Statistics can and should track execution time statistics using -:mod:`Bcfg2.Statistics`. This module tracks execution time for the +:mod:`Bcfg2.Server.Statistics`. This module tracks execution time for the server core and for plugins, and exposes that data via ``bcfg2-admin perf``. This data can be invaluable for locating bottlenecks or other performance issues. @@ -175,7 +177,7 @@ decorate functions that you would like to track execution times for: .. code-block:: python from Bcfg2.Server.Plugin import track_statistics - + @track_statistics() def do_something(self, ...): ... @@ -184,13 +186,13 @@ This will track the execution time of ``do_something``. More granular usage is possible by using :func:`time.time` to manually determine the execution time of a given event and calling -:func:`Bcfg2.Statistics.Statistics.add_value` with an appropriate +:func:`Bcfg2.Server.Statistics.Statistics.add_value` with an appropriate statistic name. -Bcfg2.Statistics -^^^^^^^^^^^^^^^^ +Bcfg2.Server.Statistics +^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: Bcfg2.Statistics +.. automodule:: Bcfg2.Server.Statistics Plugin Helper Classes --------------------- diff --git a/doc/server/encryption.txt b/doc/server/encryption.txt index 1f6cb72e6..09b1ea183 100644 --- a/doc/server/encryption.txt +++ b/doc/server/encryption.txt @@ -233,4 +233,4 @@ is the default an XML file can specify ``decrypt="lax"``. Encryption API ============== -.. automodule:: Bcfg2.Encryption +.. automodule:: Bcfg2.Server.Encryption diff --git a/osx/macports/files/patch-setup.py.diff b/osx/macports/files/patch-setup.py.diff index ececb8a33..01b21eadf 100644 --- a/osx/macports/files/patch-setup.py.diff +++ b/osx/macports/files/patch-setup.py.diff @@ -1,6 +1,6 @@ --- setup.py 2010-11-15 15:30:28.000000000 -0600 +++ setup.py.macports 2010-11-18 19:06:49.155292524 -0600 -@@ -11,38 +11,22 @@ +@@ -11,38 +11,21 @@ setup(cmdclass=cmdclass, name="Bcfg2", version="1.1.1", @@ -20,7 +20,6 @@ - "Bcfg2.Server.Reports.reports.templatetags", ], + py_modules = ["Bcfg2.Options", -+ "Bcfg2.Proxy", + "Bcfg2.Logger", + ], package_dir = {'Bcfg2':'src/lib'}, diff --git a/redhat/bcfg2.spec.in b/redhat/bcfg2.spec.in index 9527cae7b..57c6221e6 100644 --- a/redhat/bcfg2.spec.in +++ b/redhat/bcfg2.spec.in @@ -203,12 +203,6 @@ fi %dir %{python_sitelib}/Bcfg2 %{python_sitelib}/Bcfg2/*.py* %{python_sitelib}/Bcfg2/Client -%{python_sitelib}/Bcfg2/Component.* -%{python_sitelib}/Bcfg2/Logger.* -%{python_sitelib}/Bcfg2/Options.* -%{python_sitelib}/Bcfg2/Proxy.* -%{python_sitelib}/Bcfg2/SSLServer.* -%{python_sitelib}/Bcfg2/Statistics.* %{_sbindir}/bcfg2 %{_mandir}/man1/bcfg2.1* diff --git a/solaris/prototype.bcfg2 b/solaris/prototype.bcfg2 index 46483381f..9e92c84b4 100644 --- a/solaris/prototype.bcfg2 +++ b/solaris/prototype.bcfg2 @@ -4,8 +4,6 @@ d none lib/PYVERSION 0755 root bin d none lib/PYVERSION/site-packages 0755 root bin d none lib/PYVERSION/site-packages/Bcfg2 0755 bin bin f none lib/PYVERSION/site-packages/Bcfg2/__init__.py 0644 bin bin -f none lib/PYVERSION/site-packages/Bcfg2/Statistics.py 0644 bin bin -f none lib/PYVERSION/site-packages/Bcfg2/SSLServer.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Component.py 0644 bin bin d none lib/PYVERSION/site-packages/Bcfg2/Client 0755 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Client/XML.py 0644 bin bin @@ -31,8 +29,8 @@ f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/Encap.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/SMF.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Client/__init__.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Client/Frame.py 0644 bin bin +f none lib/PYVERSION/site-packages/Bcfg2/Client/Proxy.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Logger.py 0644 bin bin -f none lib/PYVERSION/site-packages/Bcfg2/Proxy.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Options.py 0644 bin bin d none bin 0755 root bin f none bin/bcfg2 0755 bin bin diff --git a/solaris/prototype.bcfg2-server b/solaris/prototype.bcfg2-server index 0a1ff64e4..91fa83dca 100644 --- a/solaris/prototype.bcfg2-server +++ b/solaris/prototype.bcfg2-server @@ -42,11 +42,10 @@ f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Git.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Server/FileMonitor.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Server/Core.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/__init__.py 0644 bin bin -f none lib/PYVERSION/site-packages/Bcfg2/Statistics.py 0644 bin bin -f none lib/PYVERSION/site-packages/Bcfg2/SSLServer.py 0644 bin bin +f none lib/PYVERSION/site-packages/Bcfg2/Server/Statistics.py 0644 bin bin +f none lib/PYVERSION/site-packages/Bcfg2/Server/SSLServer.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Component.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Logger.py 0644 bin bin -f none lib/PYVERSION/site-packages/Bcfg2/Proxy.py 0644 bin bin f none lib/PYVERSION/site-packages/Bcfg2/Options.py 0644 bin bin d none bin 0755 bin bin f none bin/bcfg2-server 0755 bin bin diff --git a/src/lib/Bcfg2/Client/Client.py b/src/lib/Bcfg2/Client/Client.py index ea898c42b..e26a6d07a 100644 --- a/src/lib/Bcfg2/Client/Client.py +++ b/src/lib/Bcfg2/Client/Client.py @@ -8,10 +8,10 @@ import fcntl import socket import logging import tempfile -import Bcfg2.Proxy import Bcfg2.Logger import Bcfg2.Options import Bcfg2.Client.XML +import Bcfg2.Client.Proxy import Bcfg2.Client.Frame import Bcfg2.Client.Tools from Bcfg2.Compat import xmlrpclib @@ -121,7 +121,7 @@ class Client(object): def proxy(self): """ get an XML-RPC proxy to the server """ if self._proxy is None: - self._proxy = Bcfg2.Proxy.ComponentProxy( + self._proxy = Bcfg2.Client.Proxy.ComponentProxy( self.setup['server'], self.setup['user'], self.setup['password'], @@ -141,8 +141,8 @@ class Client(object): try: probes = Bcfg2.Client.XML.XML(str(self.proxy.GetProbes())) - except (Bcfg2.Proxy.ProxyError, - Bcfg2.Proxy.CertificateError, + except (Bcfg2.Client.Proxy.ProxyError, + Bcfg2.Client.Proxy.CertificateError, socket.gaierror, socket.error): err = sys.exc_info()[1] @@ -165,7 +165,7 @@ class Client(object): self.proxy.RecvProbeData(Bcfg2.Client.XML.tostring( probedata, xml_declaration=False).decode('UTF-8')) - except Bcfg2.Proxy.ProxyError: + except Bcfg2.Client.Proxy.ProxyError: err = sys.exc_info()[1] self.fatal_error("Failed to upload probe data: %s" % err) @@ -191,7 +191,7 @@ class Client(object): if self.setup['profile']: try: self.proxy.AssertProfile(self.setup['profile']) - except Bcfg2.Proxy.ProxyError: + except Bcfg2.Client.Proxy.ProxyError: err = sys.exc_info()[1] self.fatal_error("Failed to set client profile: %s" % err) @@ -206,8 +206,8 @@ class Client(object): "client version") else: self.logger.error("Failed to declare version: %s" % err) - except (Bcfg2.Proxy.ProxyError, - Bcfg2.Proxy.CertificateError, + except (Bcfg2.Client.Proxy.ProxyError, + Bcfg2.Client.Proxy.CertificateError, socket.gaierror, socket.error): err = sys.exc_info()[1] @@ -221,13 +221,13 @@ class Client(object): self.proxy.GetDecisionList(self.setup['decision']) self.logger.info("Got decision list from server:") self.logger.info(self.setup['decision_list']) - except Bcfg2.Proxy.ProxyError: + except Bcfg2.Client.Proxy.ProxyError: err = sys.exc_info()[1] self.fatal_error("Failed to get decision list: %s" % err) try: rawconfig = self.proxy.GetConfig().encode('UTF-8') - except Bcfg2.Proxy.ProxyError: + except Bcfg2.Client.Proxy.ProxyError: err = sys.exc_info()[1] self.fatal_error("Failed to download configuration from " "Bcfg2: %s" % err) @@ -324,7 +324,7 @@ class Client(object): self.proxy.RecvStats(Bcfg2.Client.XML.tostring( feedback, xml_declaration=False).decode('UTF-8')) - except Bcfg2.Proxy.ProxyError: + except Bcfg2.Client.Proxy.ProxyError: err = sys.exc_info()[1] self.logger.error("Failed to upload configuration statistics: " "%s" % err) diff --git a/src/lib/Bcfg2/Proxy.py b/src/lib/Bcfg2/Client/Proxy.py index 3b406c78e..1276c3ce9 100644 --- a/src/lib/Bcfg2/Proxy.py +++ b/src/lib/Bcfg2/Client/Proxy.py @@ -119,8 +119,6 @@ class SSLHTTPConnection(httplib.HTTPConnection): implements SSL and related behaviors. """ - logger = logging.getLogger('Bcfg2.Proxy.SSLHTTPConnection') - def __init__(self, host, port=None, strict=None, timeout=90, key=None, cert=None, ca=None, scns=None, protocol='xmlrpc/ssl'): """Initializes the `httplib.HTTPConnection` object and stores security @@ -172,6 +170,9 @@ class SSLHTTPConnection(httplib.HTTPConnection): httplib.HTTPConnection.__init__(self, host, port, strict) else: httplib.HTTPConnection.__init__(self, host, port, strict, timeout) + self.logger = logging.getLogger("%s.%s" % (self.__class__.__module__, + self.__class__.__name__)) + self.key = key self.cert = cert self.ca = ca diff --git a/src/lib/Bcfg2/Server/Admin/Perf.py b/src/lib/Bcfg2/Server/Admin/Perf.py index 7448855ce..a7e67c956 100644 --- a/src/lib/Bcfg2/Server/Admin/Perf.py +++ b/src/lib/Bcfg2/Server/Admin/Perf.py @@ -2,7 +2,7 @@ import sys import Bcfg2.Options -import Bcfg2.Proxy +import Bcfg2.Client.Proxy import Bcfg2.Server.Admin @@ -22,13 +22,13 @@ class Perf(Bcfg2.Server.Admin.Mode): opts = sys.argv[1:] opts.remove(self.__class__.__name__.lower()) setup.reparse(argv=opts) - proxy = Bcfg2.Proxy.ComponentProxy(setup['server'], - setup['user'], - setup['password'], - key=setup['key'], - cert=setup['certificate'], - ca=setup['ca'], - timeout=setup['timeout']) + proxy = Bcfg2.Client.Proxy.ComponentProxy(setup['server'], + setup['user'], + setup['password'], + key=setup['key'], + cert=setup['certificate'], + ca=setup['ca'], + timeout=setup['timeout']) data = proxy.get_statistics() for key in sorted(data.keys()): output.append((key, ) + diff --git a/src/lib/Bcfg2/Server/Admin/Xcmd.py b/src/lib/Bcfg2/Server/Admin/Xcmd.py index 7f9f32816..13077c7ad 100644 --- a/src/lib/Bcfg2/Server/Admin/Xcmd.py +++ b/src/lib/Bcfg2/Server/Admin/Xcmd.py @@ -2,7 +2,7 @@ import sys import Bcfg2.Options -import Bcfg2.Proxy +import Bcfg2.Client.Proxy import Bcfg2.Server.Admin from Bcfg2.Compat import xmlrpclib @@ -23,14 +23,14 @@ class Xcmd(Bcfg2.Server.Admin.Mode): opts = sys.argv[1:] opts.remove(self.__class__.__name__.lower()) setup.reparse(argv=opts) - Bcfg2.Proxy.RetryMethod.max_retries = 1 - proxy = Bcfg2.Proxy.ComponentProxy(setup['server'], - setup['user'], - setup['password'], - key=setup['key'], - cert=setup['certificate'], - ca=setup['ca'], - timeout=setup['timeout']) + Bcfg2.Client.Proxy.RetryMethod.max_retries = 1 + proxy = Bcfg2.Client.Proxy.ComponentProxy(setup['server'], + setup['user'], + setup['password'], + key=setup['key'], + cert=setup['certificate'], + ca=setup['ca'], + timeout=setup['timeout']) if len(setup['args']) == 0: print("Usage: xcmd <xmlrpc method> <optional arguments>") return @@ -46,7 +46,7 @@ class Xcmd(Bcfg2.Server.Admin.Mode): return else: raise - except Bcfg2.Proxy.ProxyError: + except Bcfg2.Client.Proxy.ProxyError: err = sys.exc_info()[1] print("Proxy Error: %s" % err) return diff --git a/src/lib/Bcfg2/Server/BuiltinCore.py b/src/lib/Bcfg2/Server/BuiltinCore.py index 14b64ff40..663ee6f92 100644 --- a/src/lib/Bcfg2/Server/BuiltinCore.py +++ b/src/lib/Bcfg2/Server/BuiltinCore.py @@ -4,10 +4,10 @@ import sys import time import socket import daemon -import Bcfg2.Statistics +import Bcfg2.Server.Statistics from Bcfg2.Server.Core import BaseCore, NoExposedMethod from Bcfg2.Compat import xmlrpclib, urlparse -from Bcfg2.SSLServer import XMLRPCServer +from Bcfg2.Server.SSLServer import XMLRPCServer from lockfile import LockFailed # pylint: disable=E0611 @@ -25,8 +25,8 @@ class Core(BaseCore): def __init__(self): BaseCore.__init__(self) - #: The :class:`Bcfg2.SSLServer.XMLRPCServer` instance powering - #: this server core + #: The :class:`Bcfg2.Server.SSLServer.XMLRPCServer` instance + #: powering this server core self.server = None daemon_args = dict(uid=self.setup['daemon_uid'], @@ -68,8 +68,9 @@ class Core(BaseCore): try: return method_func(*args) finally: - Bcfg2.Statistics.stats.add_value(method, - time.time() - method_start) + Bcfg2.Server.Statistics.stats.add_value( + method, + time.time() - method_start) except xmlrpclib.Fault: raise except Exception: diff --git a/src/lib/Bcfg2/Cache.py b/src/lib/Bcfg2/Server/Cache.py index 842098eda..842098eda 100644 --- a/src/lib/Bcfg2/Cache.py +++ b/src/lib/Bcfg2/Server/Cache.py diff --git a/src/lib/Bcfg2/Server/CherryPyCore.py b/src/lib/Bcfg2/Server/CherryPyCore.py index 79768df20..936279508 100644 --- a/src/lib/Bcfg2/Server/CherryPyCore.py +++ b/src/lib/Bcfg2/Server/CherryPyCore.py @@ -3,7 +3,7 @@ server. """ import sys import time -import Bcfg2.Statistics +import Bcfg2.Server.Statistics from Bcfg2.Compat import urlparse, xmlrpclib, b64decode from Bcfg2.Server.Core import BaseCore import cherrypy @@ -96,8 +96,8 @@ class Core(BaseCore): try: body = handler(*rpcparams, **params) finally: - Bcfg2.Statistics.stats.add_value(rpcmethod, - time.time() - method_start) + Bcfg2.Server.Statistics.stats.add_value(rpcmethod, + time.time() - method_start) xmlrpcutil.respond(body, 'utf-8', True) return cherrypy.serving.response.body diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index c7797a711..a2c4ee1cb 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -13,14 +13,13 @@ import lxml.etree import Bcfg2.Server import Bcfg2.Logger import Bcfg2.settings -import Bcfg2.Statistics +import Bcfg2.Server.Statistics import Bcfg2.Server.FileMonitor from itertools import chain -from Bcfg2.Cache import Cache +from Bcfg2.Server.Cache import Cache from Bcfg2.Options import get_option_parser, SERVER_FAM_IGNORE from Bcfg2.Compat import xmlrpclib # pylint: disable=W0622 -from Bcfg2.Server.Plugin import PluginInitError, PluginExecutionError, \ - track_statistics +from Bcfg2.Server.Plugin import PluginInitError, PluginExecutionError try: import psyco @@ -292,7 +291,7 @@ class BaseCore(object): #: :func:`Bcfg2.Server.FileMonitor.FileMonitor.handle_event_set` self.lock = threading.Lock() - #: A :class:`Bcfg2.Cache.Cache` object for caching client + #: A :class:`Bcfg2.Server.Cache.Cache` object for caching client #: metadata self.metadata_cache = Cache() @@ -429,11 +428,11 @@ class BaseCore(object): self.logger.error("%s: Error invoking hook %s: %s" % (plugin, hook, err)) finally: - Bcfg2.Statistics.stats.add_value("%s:client_run_hook:%s" % + Bcfg2.Server.Statistics.stats.add_value("%s:client_run_hook:%s" % (self.__class__.__name__, hook), time.time() - start) - @track_statistics() + @Bcfg2.Server.Statistics.track_statistics() def validate_structures(self, metadata, data): """ Checks the data structures by calling the :func:`Bcfg2.Server.Plugin.interfaces.StructureValidator.validate_structures` @@ -460,7 +459,7 @@ class BaseCore(object): self.logger.error("Plugin %s: unexpected structure validation " "failure" % plugin.name, exc_info=1) - @track_statistics() + @Bcfg2.Server.Statistics.track_statistics() def validate_goals(self, metadata, data): """ Checks that the config matches the goals enforced by :class:`Bcfg2.Server.Plugin.interfaces.GoalValidator` plugins @@ -485,7 +484,7 @@ class BaseCore(object): self.logger.error("Plugin %s: unexpected goal validation " "failure" % plugin.name, exc_info=1) - @track_statistics() + @Bcfg2.Server.Statistics.track_statistics() def GetStructures(self, metadata): """ Get all structures (i.e., bundles) for the given client @@ -502,7 +501,7 @@ class BaseCore(object): (metadata.hostname, ':'.join(missing))) return structures - @track_statistics() + @Bcfg2.Server.Statistics.track_statistics() def BindStructures(self, structures, metadata, config): """ Given a list of structures (i.e. bundles), bind all the entries in them and add the structures to the config. @@ -522,7 +521,7 @@ class BaseCore(object): except: self.logger.error("error in BindStructure", exc_info=1) - @track_statistics() + @Bcfg2.Server.Statistics.track_statistics() def BindStructure(self, structure, metadata): """ Bind all elements in a single structure (i.e., bundle). @@ -595,7 +594,7 @@ class BaseCore(object): raise PluginExecutionError("No matching generator: %s:%s" % (entry.tag, entry.get('name'))) finally: - Bcfg2.Statistics.stats.add_value("%s:Bind:%s" % + Bcfg2.Server.Statistics.stats.add_value("%s:Bind:%s" % (self.__class__.__name__, entry.tag), time.time() - start) @@ -744,7 +743,7 @@ class BaseCore(object): % plugin.name, exc_info=1) return result - @track_statistics() + @Bcfg2.Server.Statistics.track_statistics() def build_metadata(self, client_name): """ Build initial client metadata for a client @@ -1094,11 +1093,11 @@ class BaseCore(object): @exposed def get_statistics(self, _): """ Get current statistics about component execution from - :attr:`Bcfg2.Statistics.stats`. + :attr:`Bcfg2.Server.Statistics.stats`. :returns: dict - The statistics data as returned by - :func:`Bcfg2.Statistics.Statistics.display` """ - return Bcfg2.Statistics.stats.display() + :func:`Bcfg2.Server.Statistics.Statistics.display` """ + return Bcfg2.Server.Statistics.stats.display() @exposed def toggle_debug(self, address): diff --git a/src/lib/Bcfg2/Encryption.py b/src/lib/Bcfg2/Server/Encryption.py index 341956e03..c931ed2a7 100755 --- a/src/lib/Bcfg2/Encryption.py +++ b/src/lib/Bcfg2/Server/Encryption.py @@ -1,6 +1,6 @@ -""" Bcfg2.Encryption provides a number of convenience methods for -handling encryption in Bcfg2. See :ref:`server-encryption` for more -details. """ +""" Bcfg2.Server.Encryption provides a number of convenience methods +for handling encryption in Bcfg2. See :ref:`server-encryption` for +more details. """ import os import Bcfg2.Options diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py index 871b5eb4e..bc82ee6c2 100644 --- a/src/lib/Bcfg2/Server/Plugin/helpers.py +++ b/src/lib/Bcfg2/Server/Plugin/helpers.py @@ -4,14 +4,12 @@ import os import re import sys import copy -import time import genshi import logging import operator import lxml.etree import Bcfg2.Server import Bcfg2.Options -import Bcfg2.Statistics import Bcfg2.Server.FileMonitor from Bcfg2.Compat import CmpMixin, wraps from Bcfg2.Server.Plugin.base import Debuggable, Plugin @@ -20,7 +18,7 @@ from Bcfg2.Server.Plugin.exceptions import SpecificityError, \ PluginExecutionError try: - import Bcfg2.Encryption + import Bcfg2.Server.Encryption HAS_CRYPTO = True except ImportError: HAS_CRYPTO = False @@ -94,40 +92,6 @@ def bind_info(entry, metadata, infoxml=None, default=None): entry.set(attr, val) -class track_statistics(object): # pylint: disable=C0103 - """ Decorator that tracks execution time for the given - :class:`Plugin` method with :mod:`Bcfg2.Statistics` for reporting - via ``bcfg2-admin perf`` """ - - def __init__(self, name=None): - """ - :param name: The name under which statistics for this function - will be tracked. By default, the name will be - the name of the function concatenated with the - name of the class the function is a member of. - :type name: string - """ - # if this is None, it will be set later during __call_ - self.name = name - - def __call__(self, func): - if self.name is None: - self.name = func.__name__ - - @wraps(func) - def inner(obj, *args, **kwargs): - """ The decorated function """ - name = "%s:%s" % (obj.__class__.__name__, self.name) - - start = time.time() - try: - return func(obj, *args, **kwargs) - finally: - Bcfg2.Statistics.stats.add_value(name, time.time() - start) - - return inner - - class DatabaseBacked(Plugin): """ Provides capabilities for a plugin to read and write to a database. @@ -620,8 +584,8 @@ class StructFile(XMLFileBacked, Debuggable): if self.encryption and HAS_CRYPTO: strict = self.xdata.get( "decrypt", - self.setup.cfp.get(Bcfg2.Encryption.CFG_SECTION, "decrypt", - default="strict")) == "strict" + self.setup.cfp.get(Bcfg2.Server.Encryption.CFG_SECTION, + "decrypt", default="strict")) == "strict" for el in self.xdata.xpath("//*[@encrypted]"): try: el.text = self._decrypt(el).encode('ascii', @@ -629,7 +593,7 @@ class StructFile(XMLFileBacked, Debuggable): except UnicodeDecodeError: self.logger.info("%s: Decrypted %s to gibberish, skipping" % (self.name, el.tag)) - except Bcfg2.Encryption.EVPError: + except Bcfg2.Server.Encryption.EVPError: msg = "Failed to decrypt %s element in %s" % (el.tag, self.name) if strict: @@ -642,19 +606,20 @@ class StructFile(XMLFileBacked, Debuggable): """ Decrypt a single encrypted properties file element """ if not element.text or not element.text.strip(): return - passes = Bcfg2.Encryption.get_passphrases() + passes = Bcfg2.Server.Encryption.get_passphrases() try: passphrase = passes[element.get("encrypted")] try: - return Bcfg2.Encryption.ssl_decrypt(element.text, passphrase) - except Bcfg2.Encryption.EVPError: + return Bcfg2.Server.Encryption.ssl_decrypt(element.text, + passphrase) + except Bcfg2.Server.Encryption.EVPError: # error is raised below pass except KeyError: # bruteforce_decrypt raises an EVPError with a sensible # error message, so we just let it propagate up the stack - return Bcfg2.Encryption.bruteforce_decrypt(element.text) - raise Bcfg2.Encryption.EVPError("Failed to decrypt") + return Bcfg2.Server.Encryption.bruteforce_decrypt(element.text) + raise Bcfg2.Server.Encryption.EVPError("Failed to decrypt") def _include_element(self, item, metadata): """ determine if an XML element matches the metadata """ diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenerator.py index 3b3b95ff5..516eba2f6 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenerator.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenerator.py @@ -4,7 +4,7 @@ from Bcfg2.Server.Plugin import PluginExecutionError from Bcfg2.Server.Plugins.Cfg import CfgGenerator try: - from Bcfg2.Encryption import bruteforce_decrypt, EVPError + from Bcfg2.Server.Encryption import bruteforce_decrypt, EVPError HAS_CRYPTO = True except ImportError: HAS_CRYPTO = False diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenshiGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenshiGenerator.py index 215e4c1f1..a285eecd8 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenshiGenerator.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgEncryptedGenshiGenerator.py @@ -6,7 +6,7 @@ from Bcfg2.Server.Plugin import PluginExecutionError from Bcfg2.Server.Plugins.Cfg.CfgGenshiGenerator import CfgGenshiGenerator try: - from Bcfg2.Encryption import bruteforce_decrypt + from Bcfg2.Server.Encryption import bruteforce_decrypt HAS_CRYPTO = True except ImportError: HAS_CRYPTO = False @@ -21,7 +21,7 @@ except ImportError: class EncryptedTemplateLoader(TemplateLoader): """ Subclass :class:`genshi.template.TemplateLoader` to decrypt the data on the fly as it's read in using - :func:`Bcfg2.Encryption.bruteforce_decrypt` """ + :func:`Bcfg2.Server.Encryption.bruteforce_decrypt` """ def _instantiate(self, cls, fileobj, filepath, filename, encoding=None): plaintext = StringIO(bruteforce_decrypt(fileobj.read())) return TemplateLoader._instantiate(self, cls, plaintext, filepath, diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py index 4d6639e4d..1711cc655 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py @@ -9,7 +9,7 @@ from Bcfg2.Server.Plugin import StructFile from Bcfg2.Server.Plugins.Cfg import CfgCreator, CfgCreationError from Bcfg2.Server.Plugins.Cfg.CfgPublicKeyCreator import CfgPublicKeyCreator try: - import Bcfg2.Encryption + from Bcfg2.Server.Encryption import get_passphrases, ssl_encrypt HAS_CRYPTO = True except ImportError: HAS_CRYPTO = False @@ -50,9 +50,8 @@ class CfgPrivateKeyCreator(CfgCreator, StructFile): if (HAS_CRYPTO and self.setup.cfp.has_section("sshkeys") and self.setup.cfp.has_option("sshkeys", "passphrase")): - return Bcfg2.Encryption.get_passphrases()[self.setup.cfp.get( - "sshkeys", - "passphrase")] + return get_passphrases()[self.setup.cfp.get("sshkeys", + "passphrase")] return None def handle_event(self, event): @@ -198,8 +197,7 @@ class CfgPrivateKeyCreator(CfgCreator, StructFile): privkey = open(filename).read() if HAS_CRYPTO and self.passphrase: self.debug_log("Cfg: Encrypting key data at %s" % filename) - privkey = Bcfg2.Encryption.ssl_encrypt(privkey, - self.passphrase) + privkey = ssl_encrypt(privkey, self.passphrase) specificity['ext'] = '.crypt' self.write_data(privkey, **specificity) diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py b/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py index cf4234ed0..3ad64b242 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py @@ -81,6 +81,7 @@ import Bcfg2.Server.Plugin from Bcfg2.Server.FileMonitor import get_fam from Bcfg2.Options import get_option_parser from Bcfg2.Compat import any, md5 # pylint: disable=W0622 +from Bcfg2.Server.Statistics import track_statistics LOGGER = logging.getLogger(__name__) @@ -213,7 +214,7 @@ class Collection(list, Bcfg2.Server.Plugin.Debuggable): cachefiles.add(source.cachefile) return list(cachefiles) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def get_groups(self, grouplist): """ Given a list of package group names, return a dict of ``<group name>: <list of packages>``. This method is provided @@ -234,7 +235,7 @@ class Collection(list, Bcfg2.Server.Plugin.Debuggable): rv[group] = self.get_group(group, ptype) return rv - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def get_group(self, group, ptype=None): """ Get the list of packages of the given type in a package group. @@ -469,7 +470,7 @@ class Collection(list, Bcfg2.Server.Plugin.Debuggable): """ return list(complete.difference(initial)) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def complete(self, packagelist): # pylint: disable=R0912,R0914 """ Build a complete list of all packages and their dependencies. diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py index 876ee6090..782e077bb 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py @@ -5,6 +5,7 @@ import os import sys import Bcfg2.Server.Plugin from Bcfg2.Options import get_option_parser +from Bcfg2.Server.Statistics import track_statistics from Bcfg2.Server.Plugins.Packages.Source import SourceInitError @@ -109,7 +110,7 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile, load its data. """ return sorted(list(self.parsed)) == sorted(self.extras) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def Index(self): Bcfg2.Server.Plugin.StructFile.Index(self) self.entries = [] @@ -122,7 +123,7 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile, ``Index`` is responsible for calling :func:`source_from_xml` for each ``Source`` tag in each file. """ - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def source_from_xml(self, xsource): """ Create a :class:`Bcfg2.Server.Plugins.Packages.Source.Source` subclass diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py index 7a8b2827a..5cf90e188 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py @@ -54,6 +54,7 @@ from Bcfg2.Options import get_option_parser from Bcfg2.Compat import HTTPError, HTTPBasicAuthHandler, \ HTTPPasswordMgrWithDefaultRealm, install_opener, build_opener, \ urlopen, cPickle, md5 +from Bcfg2.Server.Statistics import track_statistics def fetch_url(url): @@ -320,7 +321,7 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 self.essentialpkgs), cache, 2) cache.close() - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def setup_data(self, force_update=False): """ Perform all data fetching and setup tasks. For most backends, this involves downloading all metadata from the diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index c5d59eb24..4057ed230 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -69,6 +69,7 @@ from Bcfg2.Compat import StringIO, cPickle, HTTPError, URLError, \ from Bcfg2.Server.Plugins.Packages.Collection import Collection from Bcfg2.Server.Plugins.Packages.Source import SourceInitError, Source, \ fetch_url +from Bcfg2.Server.Statistics import track_statistics LOGGER = logging.getLogger(__name__) @@ -363,7 +364,7 @@ class YumCollection(Collection): cachefiles.add(self.cachefile) return list(cachefiles) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def write_config(self): """ Write the server-side config file to :attr:`cfgfile` based on the data from :func:`get_config`""" @@ -465,7 +466,7 @@ class YumCollection(Collection): return "# This config was generated automatically by the Bcfg2 " \ "Packages plugin\n\n" + buf.getvalue() - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def build_extra_structures(self, independent): """ Add additional entries to the ``<Independent/>`` section of the final configuration. This adds several kinds of @@ -572,7 +573,7 @@ class YumCollection(Collection): name=self.pulp_cert_set.certpath) self.pulp_cert_set.bind_entry(crt, self.metadata) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def _get_pulp_consumer(self, consumerapi=None): """ Get a Pulp consumer object for the client. @@ -601,7 +602,7 @@ class YumCollection(Collection): "%s" % err) return consumer - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def _add_gpg_instances(self, keyentry, localkey, remotekey, keydata=None): """ Add GPG keys instances to a ``Package`` entry. This is called from :func:`build_extra_structures` to add GPG keys to @@ -644,7 +645,7 @@ class YumCollection(Collection): self.logger.error("Packages: Could not read GPG key %s: %s" % (localkey, err)) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def get_groups(self, grouplist): """ If using the yum libraries, given a list of package group names, return a dict of ``<group name>: <list of packages>``. @@ -806,7 +807,7 @@ class YumCollection(Collection): new.append(pkg) return new - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def complete(self, packagelist): """ Build a complete list of all packages and their dependencies. @@ -846,7 +847,7 @@ class YumCollection(Collection): else: return set(), set() - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def call_helper(self, command, inputdata=None): """ Make a call to :ref:`bcfg2-yum-helper`. The yum libs have horrific memory leaks, so apparently the right way to get @@ -1067,7 +1068,7 @@ class YumSource(Source): self.file_to_arch[self.escape_url(fullurl)] = arch return urls - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def read_files(self): """ When using the builtin yum parser, read and parse locally downloaded metadata files. This diverges from the stock @@ -1109,7 +1110,7 @@ class YumSource(Source): self.packages[key].difference(self.packages['global']) self.save_state() - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def parse_filelist(self, data, arch): """ parse filelists.xml.gz data """ if arch not in self.filemap: @@ -1123,7 +1124,7 @@ class YumSource(Source): self.filemap[arch][fentry.text] = \ set([pkg.get('name')]) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def parse_primary(self, data, arch): """ parse primary.xml.gz data """ if arch not in self.packages: diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py index 169dcd588..ca7b7c530 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py @@ -13,6 +13,7 @@ from Bcfg2.Compat import ConfigParser, urlopen, HTTPError from Bcfg2.Server.Plugins.Packages.Collection import Collection, \ get_collection_class from Bcfg2.Server.Plugins.Packages.PackagesSources import PackagesSources +from Bcfg2.Server.Statistics import track_statistics #: The default path for generated yum configs YUM_CONFIG_DEFAULT = "/etc/yum.repos.d/bcfg2.repo" @@ -235,7 +236,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin, return True return False - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def validate_structures(self, metadata, structures): """ Do the real work of Packages. This does two things: @@ -270,7 +271,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin, collection.build_extra_structures(indep) structures.append(indep) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def _build_packages(self, metadata, independent, structures, collection=None): """ Perform dependency resolution and build the complete list @@ -341,7 +342,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin, newpkgs.sort() collection.packages_to_entry(newpkgs, independent) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def Refresh(self): """ Packages.Refresh() => True|False @@ -349,7 +350,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin, self._load_config(force_update=True) return True - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def Reload(self): """ Packages.Refresh() => True|False @@ -445,7 +446,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin, if kfile not in keyfiles: os.unlink(kfile) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def get_collection(self, metadata): """ Get a :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection` diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py index 7b8ef2209..2ea5088de 100644 --- a/src/lib/Bcfg2/Server/Plugins/Probes.py +++ b/src/lib/Bcfg2/Server/Plugins/Probes.py @@ -10,6 +10,7 @@ import lxml.etree import Bcfg2.Server import Bcfg2.Server.Plugin import Bcfg2.Server.FileMonitor +from Bcfg2.Server.Statistics import track_statistics try: from django.db import models @@ -190,7 +191,7 @@ class Probes(Bcfg2.Server.Plugin.Probing, self.load_data() __init__.__doc__ = Bcfg2.Server.Plugin.DatabaseBacked.__init__.__doc__ - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def write_data(self, client): """ Write probe data out for use with bcfg2-info """ if self._use_db: @@ -293,12 +294,12 @@ class Probes(Bcfg2.Server.Plugin.Probing, self.cgroups[pgroup.hostname] = [] self.cgroups[pgroup.hostname].append(pgroup.group) - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def GetProbes(self, meta): return self.probes.get_probe_data(meta) GetProbes.__doc__ = Bcfg2.Server.Plugin.Probing.GetProbes.__doc__ - @Bcfg2.Server.Plugin.track_statistics() + @track_statistics() def ReceiveData(self, client, datalist): if self.core.metadata_cache_mode in ['cautious', 'aggressive']: if client.hostname in self.cgroups: diff --git a/src/lib/Bcfg2/Server/Plugins/Properties.py b/src/lib/Bcfg2/Server/Plugins/Properties.py index b7ede594c..762f9f8f0 100644 --- a/src/lib/Bcfg2/Server/Plugins/Properties.py +++ b/src/lib/Bcfg2/Server/Plugins/Properties.py @@ -10,11 +10,6 @@ import lxml.etree from Bcfg2.Options import get_option_parser import Bcfg2.Server.Plugin from Bcfg2.Server.Plugin import PluginExecutionError -try: - import Bcfg2.Encryption - HAS_CRYPTO = True -except ImportError: - HAS_CRYPTO = False try: import json diff --git a/src/lib/Bcfg2/SSLServer.py b/src/lib/Bcfg2/Server/SSLServer.py index 5e3c6232a..eeaeb9516 100644 --- a/src/lib/Bcfg2/SSLServer.py +++ b/src/lib/Bcfg2/Server/SSLServer.py @@ -18,8 +18,6 @@ from Bcfg2.Compat import xmlrpclib, SimpleXMLRPCServer, SocketServer, \ class XMLRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher): """ An XML-RPC dispatcher. """ - logger = logging.getLogger("Bcfg2.SSLServer.XMLRPCDispatcher") - def __init__(self, allow_none, encoding): try: SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self, @@ -29,6 +27,8 @@ class XMLRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher): # Python 2.4? SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self) + self.logger = logging.getLogger("%s.%s" % (self.__class__.__module__, + self.__class__.__name__)) self.allow_none = allow_none self.encoding = encoding @@ -62,9 +62,7 @@ class XMLRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher): class SSLServer(SocketServer.TCPServer, object): """ TCP server supporting SSL encryption. """ - allow_reuse_address = True - logger = logging.getLogger("Bcfg2.SSLServer.SSLServer") def __init__(self, listen_all, server_address, RequestHandlerClass, keyfile=None, certfile=None, reqCert=False, ca=None, @@ -97,6 +95,9 @@ class SSLServer(SocketServer.TCPServer, object): if ':' in server_address[0]: self.address_family = socket.AF_INET6 + self.logger = logging.getLogger("%s.%s" % (self.__class__.__module__, + self.__class__.__name__)) + try: SocketServer.TCPServer.__init__(self, listen_address, RequestHandlerClass) @@ -183,7 +184,11 @@ class XMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): Adds support for HTTP authentication. """ - logger = logging.getLogger("Bcfg2.SSLServer.XMLRPCRequestHandler") + def __init__(self, *args, **kwargs): + SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.__init__(self, *args, + **kwargs) + self.logger = logging.getLogger("%s.%s" % (self.__class__.__module__, + self.__class__.__name__)) def authenticate(self): try: diff --git a/src/lib/Bcfg2/Statistics.py b/src/lib/Bcfg2/Server/Statistics.py index a869b03cd..8a6ff54c4 100644 --- a/src/lib/Bcfg2/Statistics.py +++ b/src/lib/Bcfg2/Server/Statistics.py @@ -2,6 +2,8 @@ server core. This data is exposed by :func:`Bcfg2.Server.Core.BaseCore.get_statistics`.""" +import time +from Bcfg2.Compat import wraps class Statistic(object): """ A single named statistic, tracking minimum, maximum, and @@ -80,3 +82,37 @@ class Statistics(object): #: A module-level :class:`Statistics` objects used to track all #: execution time metrics for the server. stats = Statistics() # pylint: disable=C0103 + + +class track_statistics(object): # pylint: disable=C0103 + """ Decorator that tracks execution time for the given method with + :mod:`Bcfg2.Server.Statistics` for reporting via ``bcfg2-admin + perf`` """ + + def __init__(self, name=None): + """ + :param name: The name under which statistics for this function + will be tracked. By default, the name will be + the name of the function concatenated with the + name of the class the function is a member of. + :type name: string + """ + # if this is None, it will be set later during __call_ + self.name = name + + def __call__(self, func): + if self.name is None: + self.name = func.__name__ + + @wraps(func) + def inner(obj, *args, **kwargs): + """ The decorated function """ + name = "%s:%s" % (obj.__class__.__name__, self.name) + + start = time.time() + try: + return func(obj, *args, **kwargs) + finally: + stats.add_value(name, time.time() - start) + + return inner diff --git a/src/lib/Bcfg2/__init__.py b/src/lib/Bcfg2/__init__.py deleted file mode 100644 index 3fe2a0d75..000000000 --- a/src/lib/Bcfg2/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -"""Base modules definition.""" - -__all__ = ['Server', 'Client', 'Logger', 'Options', 'Proxy', 'Statistics'] diff --git a/src/sbin/bcfg2-crypt b/src/sbin/bcfg2-crypt index 0bee7e9b9..810406567 100755 --- a/src/sbin/bcfg2-crypt +++ b/src/sbin/bcfg2-crypt @@ -12,7 +12,7 @@ import Bcfg2.Options from Bcfg2.Server import XMLParser from Bcfg2.Compat import input # pylint: disable=W0622 try: - import Bcfg2.Encryption + import Bcfg2.Server.Encryption except ImportError: print("Could not import %s. Is M2Crypto installed?" % sys.exc_info()[1]) raise SystemExit(1) @@ -55,8 +55,8 @@ class Encryptor(object): def set_passphrase(self): """ set the passphrase for the current file """ - if (not self.setup.cfp.has_section(Bcfg2.Encryption.CFG_SECTION) or - len(Bcfg2.Encryption.get_passphrases()) == 0): + if (not self.setup.cfp.has_section(Bcfg2.Server.Encryption.CFG_SECTION) + or len(Bcfg2.Server.Encryption.get_passphrases()) == 0): self.logger.error("No passphrases available in %s" % self.setup['configfile']) return False @@ -70,10 +70,10 @@ class Encryptor(object): self.pname = self.setup['passphrase'] if self.pname: - if self.setup.cfp.has_option(Bcfg2.Encryption.CFG_SECTION, + if self.setup.cfp.has_option(Bcfg2.Server.Encryption.CFG_SECTION, self.pname): self.passphrase = \ - self.setup.cfp.get(Bcfg2.Encryption.CFG_SECTION, + self.setup.cfp.get(Bcfg2.Server.Encryption.CFG_SECTION, self.pname) self.logger.debug("Using passphrase %s specified on command " "line" % self.pname) @@ -83,7 +83,7 @@ class Encryptor(object): (self.pname, self.setup['configfile'])) return False else: - pnames = Bcfg2.Encryption.get_passphrases() + pnames = Bcfg2.Server.Encryption.get_passphrases() if len(pnames) == 1: self.pname = pnames.keys()[0] self.passphrase = pnames[self.pname] @@ -127,7 +127,7 @@ class Encryptor(object): # pylint: disable=W0613 def _encrypt(self, plaintext, passphrase, name=None): """ encrypt a single chunk of a file """ - return Bcfg2.Encryption.ssl_encrypt(plaintext, passphrase) + return Bcfg2.Server.Encryption.ssl_encrypt(plaintext, passphrase) # pylint: enable=W0613 def decrypt(self, fname): @@ -148,7 +148,7 @@ class Encryptor(object): passphrase, pname = self.get_passphrase(chunk) try: plaintext.append(self._decrypt(chunk, passphrase)) - except Bcfg2.Encryption.EVPError: + except Bcfg2.Server.Encryption.EVPError: self.logger.info("Could not decrypt %s with the " "specified passphrase" % fname) continue @@ -160,12 +160,12 @@ class Encryptor(object): except TypeError: pchunk = None for pname, passphrase in \ - Bcfg2.Encryption.get_passphrases().items(): + Bcfg2.Server.Encryption.get_passphrases().items(): self.logger.debug("Trying passphrase %s" % pname) try: pchunk = self._decrypt(chunk, passphrase) break - except Bcfg2.Encryption.EVPError: + except Bcfg2.Server.Encryption.EVPError: pass except: err = sys.exc_info()[1] @@ -194,7 +194,7 @@ class Encryptor(object): def _decrypt(self, crypted, passphrase): """ decrypt a single chunk """ - return Bcfg2.Encryption.ssl_decrypt(crypted, passphrase) + return Bcfg2.Server.Encryption.ssl_decrypt(crypted, passphrase) def write_encrypted(self, fname, data=None): """ write encrypted data to disk """ @@ -239,10 +239,11 @@ class Encryptor(object): self.logger.info("No passphrase given on command line or " "found in file") return False - elif self.setup.cfp.has_option(Bcfg2.Encryption.CFG_SECTION, + elif self.setup.cfp.has_option(Bcfg2.Server.Encryption.CFG_SECTION, pname): - passphrase = self.setup.cfp.get(Bcfg2.Encryption.CFG_SECTION, - pname) + passphrase = self.setup.cfp.get( + Bcfg2.Server.Encryption.CFG_SECTION, + pname) else: self.logger.error("Could not find passphrase %s in %s" % (pname, self.setup['configfile'])) @@ -283,8 +284,9 @@ class PropertiesEncryptor(Encryptor): if name is None: name = "true" if plaintext.text and plaintext.text.strip(): - plaintext.text = Bcfg2.Encryption.ssl_encrypt(plaintext.text, - passphrase).strip() + plaintext.text = \ + Bcfg2.Server.Encryption.ssl_encrypt(plaintext.text, + passphrase).strip() plaintext.set("encrypted", name) return plaintext @@ -352,8 +354,8 @@ class PropertiesEncryptor(Encryptor): if not crypted.text or not crypted.text.strip(): self.logger.warning("Skipping empty element %s" % crypted.tag) return crypted - decrypted = Bcfg2.Encryption.ssl_decrypt(crypted.text, - passphrase).strip() + decrypted = Bcfg2.Server.Encryption.ssl_decrypt(crypted.text, + passphrase).strip() try: crypted.text = decrypted.encode('ascii', 'xmlcharrefreplace') except UnicodeDecodeError: diff --git a/testsuite/Testsrc/Testlib/TestEncryption.py b/testsuite/Testsrc/Testlib/TestServer/TestEncryption.py index f8fcaa98d..8f69f3bf0 100644 --- a/testsuite/Testsrc/Testlib/TestEncryption.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestEncryption.py @@ -16,7 +16,7 @@ while path != "/": from common import * try: - from Bcfg2.Encryption import * + from Bcfg2.Server.Encryption import * HAS_CRYPTO = True except ImportError: HAS_CRYPTO = False @@ -124,7 +124,7 @@ baz dict(foo="passphrase", bar="passphrase")) - @patch("Bcfg2.Encryption.get_passphrases") + @patch("Bcfg2.Server.Encryption.get_passphrases") def test_bruteforce_decrypt(self, mock_passphrases): passwd = "a simple passphrase" crypted = ssl_encrypt(self.plaintext, passwd) diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py index 0d44e7284..9eb584e90 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py @@ -23,7 +23,7 @@ from TestServer.TestPlugin.Testbase import TestPlugin, TestDebuggable from TestServer.TestPlugin.Testinterfaces import TestGenerator try: - from Bcfg2.Encryption import EVPError + from Bcfg2.Server.Encryption import EVPError HAS_CRYPTO = True except: HAS_CRYPTO = False @@ -766,9 +766,9 @@ class TestStructFile(TestXMLFileBacked): [call(el) for el in sf.xdata.xpath("//*[@encrypted]")]) @skipUnless(HAS_CRYPTO, "No crypto libraries found, skipping") - @patchIf(HAS_CRYPTO, "Bcfg2.Encryption.ssl_decrypt") - @patchIf(HAS_CRYPTO, "Bcfg2.Encryption.get_passphrases") - @patchIf(HAS_CRYPTO, "Bcfg2.Encryption.bruteforce_decrypt") + @patchIf(HAS_CRYPTO, "Bcfg2.Server.Encryption.ssl_decrypt") + @patchIf(HAS_CRYPTO, "Bcfg2.Server.Encryption.get_passphrases") + @patchIf(HAS_CRYPTO, "Bcfg2.Server.Encryption.bruteforce_decrypt") def test_decrypt(self, mock_bruteforce, mock_get_passphrases, mock_ssl): sf = self.get_obj() diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py index bf34d4c3c..2982825a9 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py @@ -7,7 +7,7 @@ from Bcfg2.Server.Plugins.Cfg.CfgPrivateKeyCreator import * from Bcfg2.Server.Plugin import PluginExecutionError import Bcfg2.Server.Plugins.Cfg.CfgPrivateKeyCreator try: - from Bcfg2.Encryption import EVPError + from Bcfg2.Server.Encryption import EVPError HAS_CRYPTO = True except: HAS_CRYPTO = False @@ -66,7 +66,8 @@ class TestCfgPrivateKeyCreator(TestCfgCreator, TestStructFile): pkc.setup.cfp.get.assert_called_with("sshkeys", "category") @skipUnless(HAS_CRYPTO, "No crypto libraries found, skipping") - @patchIf(HAS_CRYPTO, "Bcfg2.Encryption.get_passphrases") + @patchIf(HAS_CRYPTO, + "Bcfg2.Server.Plugins.Cfg.CfgPrivateKeyCreator.get_passphrases") def test_passphrase(self, mock_get_passphrases): pkc = self.get_obj() pkc.setup = Mock() @@ -281,7 +282,7 @@ class TestCfgPrivateKeyCreator(TestCfgCreator, TestStructFile): if HAS_CRYPTO: @patch(passphrase, "foo") - @patch("Bcfg2.Encryption.ssl_encrypt") + @patch("Bcfg2.Server.Plugins.Cfg.CfgPrivateKeyCreator.ssl_encrypt") def inner2(mock_ssl_encrypt): reset() mock_ssl_encrypt.return_value = "encryptedprivatekey" diff --git a/testsuite/Testsrc/test_code_checks.py b/testsuite/Testsrc/test_code_checks.py index 323f64f49..73ffe954a 100644 --- a/testsuite/Testsrc/test_code_checks.py +++ b/testsuite/Testsrc/test_code_checks.py @@ -58,8 +58,9 @@ contingent_checks = { # perform only error checking on the listed files error_checks = { "sbin": ["bcfg2-reports"], - "lib/Bcfg2": ["Proxy.py", "SSLServer.py", "Reporting"], - "lib/Bcfg2/Server": ["Reports", "SchemaUpdater"], + "lib/Bcfg2": ["Reporting"], + "lib/Bcfg2/Client": ["Proxy.py"], + "lib/Bcfg2/Server": ["Reports", "SchemaUpdater", "SSLServer.py"], "lib/Bcfg2/Server/Admin": ["Compare.py"], "lib/Bcfg2/Client/Tools": ["launchd.py", "OpenCSW.py", |