diff options
Diffstat (limited to 'src/lib/Bcfg2')
30 files changed, 163 insertions, 86 deletions
diff --git a/src/lib/Bcfg2/Client/Proxy.py b/src/lib/Bcfg2/Client/Proxy.py index cf6efac89..679b4c52b 100644 --- a/src/lib/Bcfg2/Client/Proxy.py +++ b/src/lib/Bcfg2/Client/Proxy.py @@ -119,7 +119,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): """ def __init__(self, host, port=None, strict=None, timeout=90, key=None, - cert=None, ca=None, scns=None, protocol='xmlrpc/ssl'): + cert=None, ca=None, scns=None, protocol='xmlrpc/tlsv1'): """Initializes the `httplib.HTTPConnection` object and stores security parameters @@ -144,15 +144,15 @@ class SSLHTTPConnection(httplib.HTTPConnection): specify the same file as `cert` if using a file that contains both. See http://docs.python.org/library/ssl.html#ssl-certificates - for details. Required if using xmlrpc/ssl with client - certificate authentication. + for details. Required if using client certificate + authentication. cert : string, optional The file system path to the local endpoint's SSL certificate. May specify the same file as `cert` if using a file that contains both. See http://docs.python.org/library/ssl.html#ssl-certificates - for details. Required if using xmlrpc/ssl with client - certificate authentication. + for details. Required if using client certificate + authentication. ca : string, optional The file system path to a set of concatenated certificate authority certs, which are used to validate certificates @@ -232,7 +232,8 @@ class SSLHTTPConnection(httplib.HTTPConnection): class XMLRPCTransport(xmlrpclib.Transport): def __init__(self, key=None, cert=None, ca=None, - scns=None, use_datetime=0, timeout=90): + scns=None, use_datetime=0, timeout=90, + protocol='xmlrpc/tlsv1'): if hasattr(xmlrpclib.Transport, '__init__'): xmlrpclib.Transport.__init__(self, use_datetime) self.key = key @@ -240,6 +241,7 @@ class XMLRPCTransport(xmlrpclib.Transport): self.ca = ca self.scns = scns self.timeout = timeout + self.protocol = protocol def make_connection(self, host): host, self._extra_headers = self.get_host_info(host)[0:2] @@ -248,7 +250,8 @@ class XMLRPCTransport(xmlrpclib.Transport): cert=self.cert, ca=self.ca, scns=self.scns, - timeout=self.timeout) + timeout=self.timeout, + protocol=self.protocol) def request(self, host, handler, request_body, verbose=0): """Send request to server and return response.""" @@ -291,9 +294,15 @@ class ComponentProxy(xmlrpclib.ServerProxy): """Constructs proxies to components. """ options = [ - Bcfg2.Options.Common.location, Bcfg2.Options.Common.ssl_key, - Bcfg2.Options.Common.ssl_cert, Bcfg2.Options.Common.ssl_ca, + Bcfg2.Options.Common.location, Bcfg2.Options.Common.ssl_ca, Bcfg2.Options.Common.password, Bcfg2.Options.Common.client_timeout, + Bcfg2.Options.Common.protocol, + Bcfg2.Options.PathOption( + '--ssl-key', cf=('communication', 'key'), dest="key", + help='Path to SSL key'), + Bcfg2.Options.PathOption( + cf=('communication', 'certificate'), dest="cert", + help='Path to SSL certificate'), Bcfg2.Options.Option( "-u", "--user", default="root", cf=('communication', 'user'), help='The user to provide for authentication'), @@ -323,10 +332,12 @@ class ComponentProxy(xmlrpclib.ServerProxy): path) else: url = Bcfg2.Options.setup.server - ssl_trans = XMLRPCTransport(Bcfg2.Options.setup.key, - Bcfg2.Options.setup.cert, - Bcfg2.Options.setup.ca, - Bcfg2.Options.setup.ssl_cns, - Bcfg2.Options.setup.client_timeout) + ssl_trans = XMLRPCTransport( + key=Bcfg2.Options.setup.key, + cert=Bcfg2.Options.setup.cert, + ca=Bcfg2.Options.setup.ca, + scns=Bcfg2.Options.setup.ssl_cns, + timeout=Bcfg2.Options.setup.client_timeout, + protocol=Bcfg2.Options.setup.protocol) xmlrpclib.ServerProxy.__init__(self, url, allow_none=True, transport=ssl_trans) diff --git a/src/lib/Bcfg2/Client/Tools/Action.py b/src/lib/Bcfg2/Client/Tools/Action.py index 5549b1717..dedc50d89 100644 --- a/src/lib/Bcfg2/Client/Tools/Action.py +++ b/src/lib/Bcfg2/Client/Tools/Action.py @@ -36,7 +36,7 @@ class Action(Bcfg2.Client.Tools.Tool): shell = True shell_string = '(in shell) ' - if not Bcfg2.Options.setup.dryrun: + if not Bcfg2.Options.setup.dry_run: if Bcfg2.Options.setup.interactive: prompt = ('Run Action %s%s, %s: (y/N): ' % (shell_string, entry.get('name'), diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/File.py b/src/lib/Bcfg2/Client/Tools/POSIX/File.py index 0452ea258..fc445e07c 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/File.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/File.py @@ -220,8 +220,12 @@ class POSIXFile(POSIXTool): def _diff(self, content1, content2, filename=None): """ Return a unified diff of the two strings """ - fromfile = "%s (on disk)" % filename if filename else "" - tofile = "%s (from bcfg2)" % filename if filename else "" + if filename: + fromfile = "%s (on disk)" % filename + tofile = "%s (from bcfg2)" % filename + else: + fromfile = "" + tofile = "" return difflib.unified_diff(content1.split('\n'), content2.split('\n'), fromfile=fromfile, diff --git a/src/lib/Bcfg2/Client/Tools/RPM.py b/src/lib/Bcfg2/Client/Tools/RPM.py index 173623f61..464b7e389 100644 --- a/src/lib/Bcfg2/Client/Tools/RPM.py +++ b/src/lib/Bcfg2/Client/Tools/RPM.py @@ -1120,7 +1120,7 @@ class RPM(Bcfg2.Client.Tools.PkgTool): help="Install missing packages"), Bcfg2.Options.Option( cf=('RPM', 'erase_flags'), default=["allmatches"], - dest="rpm_erase_flags", + dest="rpm_erase_flags", type=Bcfg2.Options.Types.comma_list, help="RPM erase flags"), Bcfg2.Options.BooleanOption( cf=('RPM', 'fix_version'), default=True, @@ -1131,7 +1131,8 @@ class RPM(Bcfg2.Client.Tools.PkgTool): dest="rpm_reinstall_broken", help="Reinstall packages that fail to verify"), Bcfg2.Options.Option( - cf=('RPM', 'verify_flags'), default=[], dest="rpm_verify_flags", + cf=('RPM', 'verify_flags'), default=[], + dest="rpm_verify_flags", type=Bcfg2.Options.Types.comma_list, help="RPM verify flags")] __execs__ = ['/bin/rpm', '/var/lib/rpm'] diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py index ee1cd6fad..21fc05b0d 100644 --- a/src/lib/Bcfg2/Client/Tools/YUM.py +++ b/src/lib/Bcfg2/Client/Tools/YUM.py @@ -133,7 +133,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): help="Install missing packages"), Bcfg2.Options.Option( cf=('YUM', 'erase_flags'), default=["allmatches"], - dest="yum_erase_flags", + dest="yum_erase_flags", type=Bcfg2.Options.Types.comma_list, help="YUM erase flags"), Bcfg2.Options.BooleanOption( cf=('YUM', 'fix_version'), default=True, @@ -144,8 +144,17 @@ class YUM(Bcfg2.Client.Tools.PkgTool): dest="yum_reinstall_broken", help="Reinstall packages that fail to verify"), Bcfg2.Options.Option( - cf=('YUM', 'verify_flags'), default=[], dest="yum_verify_flags", - help="YUM verify flags")] + cf=('YUM', 'verify_flags'), default=[], + dest="yum_verify_flags", type=Bcfg2.Options.Types.comma_list, + help="YUM verify flags"), + Bcfg2.Options.Option( + cf=('YUM', 'disabled_plugins'), default=[], + type=Bcfg2.Options.Types.comma_list, dest="yum_disabled_plugins", + help="YUM disabled plugins"), + Bcfg2.Options.Option( + cf=('YUM', 'enabled_plugins'), default=[], + type=Bcfg2.Options.Types.comma_list, dest="yum_enabled_plugins", + help="YUM enabled plugins")] pkgtype = 'yum' __execs__ = [] @@ -218,6 +227,10 @@ class YUM(Bcfg2.Client.Tools.PkgTool): self.logger.debug("Yum: installonlypkgs: %s" % self.installonlypkgs) self.logger.debug("Yum: verify_flags: %s" % Bcfg2.Options.setup.yum_verify_flags) + self.logger.debug("Yum: disabled_plugins: %s" % + Bcfg2.Options.setup.yum_disabled_plugins) + self.logger.debug("Yum: enabled_plugins: %s" % + Bcfg2.Options.setup.yum_enabled_plugins) def _loadYumBase(self): ''' this may be called before PkgTool.__init__() is called on @@ -240,6 +253,14 @@ class YUM(Bcfg2.Client.Tools.PkgTool): else: debuglevel = 0 + if len(Bcfg2.Options.setup.yum_disabled_plugins) > 0: + rv.preconf.disabled_plugins = \ + Bcfg2.Options.setup.yum_disabled_plugins + + if len(Bcfg2.Options.setup.yum_enabled_plugins) > 0: + rv.preconf.enabled_plugins = \ + Bcfg2.Options.setup.yum_enabled_plugins + # pylint: disable=E1121,W0212 try: rv.preconf.debuglevel = debuglevel diff --git a/src/lib/Bcfg2/Client/__init__.py b/src/lib/Bcfg2/Client/__init__.py index 073aa7694..5f4f15dcc 100644 --- a/src/lib/Bcfg2/Client/__init__.py +++ b/src/lib/Bcfg2/Client/__init__.py @@ -873,15 +873,21 @@ class Client(object): def GenerateStats(self): """Generate XML summary of execution statistics.""" + states = {} + for (item, val) in list(self.states.items()): + if not Bcfg2.Options.setup.only_important or \ + item.get('important', 'false').lower() == 'true': + states[item] = val + feedback = XML.Element("upload-statistics") stats = XML.SubElement(feedback, - 'Statistics', total=str(len(self.states)), + 'Statistics', total=str(len(states)), version='2.0', revision=self.config.get('revision', '-1')) - good_entries = [key for key, val in list(self.states.items()) if val] + good_entries = [key for key, val in list(states.items()) if val] good = len(good_entries) stats.set('good', str(good)) - if any(not val for val in list(self.states.values())): + if any(not val for val in list(states.values())): stats.set('state', 'dirty') else: stats.set('state', 'clean') @@ -890,8 +896,8 @@ class Client(object): for (data, ename) in [(self.modified, 'Modified'), (self.extra, "Extra"), (good_entries, "Good"), - ([entry for entry in self.states - if not self.states[entry]], "Bad")]: + ([entry for entry in states + if not states[entry]], "Bad")]: container = XML.SubElement(stats, ename) for item in data: item.set('qtext', '') diff --git a/src/lib/Bcfg2/DBSettings.py b/src/lib/Bcfg2/DBSettings.py index 12dba7fba..b817ecb94 100644 --- a/src/lib/Bcfg2/DBSettings.py +++ b/src/lib/Bcfg2/DBSettings.py @@ -8,6 +8,7 @@ import Bcfg2.Options try: import django + import django.core.management import django.conf HAS_DJANGO = True except ImportError: diff --git a/src/lib/Bcfg2/Options/Common.py b/src/lib/Bcfg2/Options/Common.py index 8f5cf8f06..620a7604c 100644 --- a/src/lib/Bcfg2/Options/Common.py +++ b/src/lib/Bcfg2/Options/Common.py @@ -107,20 +107,16 @@ class Common(object): '-x', '--password', cf=('communication', 'password'), metavar='<password>', help="Communication Password") - #: Path to SSL key - ssl_key = PathOption( - '--ssl-key', cf=('communication', 'key'), dest="key", - help='Path to SSL key', default="/etc/pki/tls/private/bcfg2.key") - - #: Path to SSL certificate - ssl_cert = PathOption( - cf=('communication', 'certificate'), dest="cert", - help='Path to SSL certificate', default="/etc/pki/tls/certs/bcfg2.crt") - #: Path to SSL CA certificate ssl_ca = PathOption( cf=('communication', 'ca'), help='Path to SSL CA Cert') + #: Communication protocol + protocol = Option( + cf=('communication', 'protocol'), default='xmlrpc/tlsv1', + choices=['xmlrpc/ssl', 'xmlrpc/tlsv1'], + help='Communication protocol to use.') + #: Default Path paranoid setting default_paranoid = Option( cf=('mdata', 'paranoid'), dest="default_paranoid", default='true', diff --git a/src/lib/Bcfg2/Server/BuiltinCore.py b/src/lib/Bcfg2/Server/BuiltinCore.py index 0023e9313..769addf55 100644 --- a/src/lib/Bcfg2/Server/BuiltinCore.py +++ b/src/lib/Bcfg2/Server/BuiltinCore.py @@ -113,7 +113,8 @@ class BuiltinCore(NetworkCore): keyfile=Bcfg2.Options.setup.key, certfile=Bcfg2.Options.setup.cert, register=False, - ca=Bcfg2.Options.setup.ca) + ca=Bcfg2.Options.setup.ca, + protocol=Bcfg2.Options.setup.protocol) except: # pylint: disable=W0702 err = sys.exc_info()[1] self.logger.error("Server startup failed: %s" % err) diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index a2f9499f2..892f2832a 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -1370,8 +1370,16 @@ class NetworkCore(Core): daemonized, etc.""" options = Core.options + [ Bcfg2.Options.Common.daemon, Bcfg2.Options.Common.syslog, - Bcfg2.Options.Common.location, Bcfg2.Options.Common.ssl_key, - Bcfg2.Options.Common.ssl_cert, Bcfg2.Options.Common.ssl_ca, + Bcfg2.Options.Common.location, Bcfg2.Options.Common.ssl_ca, + Bcfg2.Options.Common.protocol, + Bcfg2.Options.PathOption( + '--ssl-key', cf=('communication', 'key'), dest="key", + help='Path to SSL key', + default="/etc/pki/tls/private/bcfg2.key"), + Bcfg2.Options.PathOption( + cf=('communication', 'certificate'), dest="cert", + help='Path to SSL certificate', + default="/etc/pki/tls/certs/bcfg2.crt"), Bcfg2.Options.BooleanOption( '--listen-all', cf=('server', 'listen_all'), default=False, help="Listen on all interfaces"), diff --git a/src/lib/Bcfg2/Server/Lint/AWSTags.py b/src/lib/Bcfg2/Server/Lint/AWSTags.py index 25ad4ef61..c6d7a3a30 100644 --- a/src/lib/Bcfg2/Server/Lint/AWSTags.py +++ b/src/lib/Bcfg2/Server/Lint/AWSTags.py @@ -9,6 +9,7 @@ import Bcfg2.Server.Lint class AWSTags(Bcfg2.Server.Lint.ServerPlugin): """ ``bcfg2-lint`` plugin to check all given :ref:`AWSTags <server-plugins-connectors-awstags>` patterns for validity. """ + __serverplugin__ = 'AWSTags' def Run(self): cfg = self.core.plugins['AWSTags'].config diff --git a/src/lib/Bcfg2/Server/Lint/Bundler.py b/src/lib/Bcfg2/Server/Lint/Bundler.py index aee15cb5d..576e157ad 100644 --- a/src/lib/Bcfg2/Server/Lint/Bundler.py +++ b/src/lib/Bcfg2/Server/Lint/Bundler.py @@ -7,6 +7,7 @@ from Bcfg2.Server.Lint import ServerPlugin class Bundler(ServerPlugin): """ Perform various :ref:`Bundler <server-plugins-structures-bundler>` checks. """ + __serverplugin__ = 'Bundler' def Run(self): self.missing_bundles() diff --git a/src/lib/Bcfg2/Server/Lint/Cfg.py b/src/lib/Bcfg2/Server/Lint/Cfg.py index 7716cd5c7..13b04a6b8 100644 --- a/src/lib/Bcfg2/Server/Lint/Cfg.py +++ b/src/lib/Bcfg2/Server/Lint/Cfg.py @@ -10,6 +10,7 @@ from Bcfg2.Server.Plugins.Cfg import CfgGenerator class Cfg(ServerPlugin): """ warn about Cfg issues """ + __serverplugin__ = 'Cfg' def Run(self): for basename, entry in list(self.core.plugins['Cfg'].entries.items()): diff --git a/src/lib/Bcfg2/Server/Lint/Comments.py b/src/lib/Bcfg2/Server/Lint/Comments.py index fc4506c12..fbe84de87 100644 --- a/src/lib/Bcfg2/Server/Lint/Comments.py +++ b/src/lib/Bcfg2/Server/Lint/Comments.py @@ -93,13 +93,21 @@ class Comments(Bcfg2.Server.Lint.ServerPlugin): type=Bcfg2.Options.Types.comma_list, default=[], help="Required comments for info.xml files"), Bcfg2.Options.Option( - cf=("Comments", "probe_keywords"), + cf=("Comments", "probes_keywords"), type=Bcfg2.Options.Types.comma_list, default=[], help="Required keywords for probes"), Bcfg2.Options.Option( - cf=("Comments", "probe_comments"), + cf=("Comments", "probes_comments"), type=Bcfg2.Options.Types.comma_list, default=[], - help="Required comments for probes")] + help="Required comments for probes"), + Bcfg2.Options.Option( + cf=("Comments", "metadata_keywords"), + type=Bcfg2.Options.Types.comma_list, default=[], + help="Required keywords for metadata files"), + Bcfg2.Options.Option( + cf=("Comments", "metadata_comments"), + type=Bcfg2.Options.Types.comma_list, default=[], + help="Required comments for metadata files")] def __init__(self, *args, **kwargs): Bcfg2.Server.Lint.ServerPlugin.__init__(self, *args, **kwargs) @@ -248,7 +256,7 @@ class Comments(Bcfg2.Server.Lint.ServerPlugin): rtype = "jinja2" elif isinstance(entry, CfgInfoXML): self.check_xml(entry.infoxml.name, - entry.infoxml.pnode.data, + entry.infoxml.xdata, "infoxml") continue if rtype: diff --git a/src/lib/Bcfg2/Server/Lint/Genshi.py b/src/lib/Bcfg2/Server/Lint/Genshi.py index a2581e70b..a2581e70b 100755..100644 --- a/src/lib/Bcfg2/Server/Lint/Genshi.py +++ b/src/lib/Bcfg2/Server/Lint/Genshi.py diff --git a/src/lib/Bcfg2/Server/Lint/GroupPatterns.py b/src/lib/Bcfg2/Server/Lint/GroupPatterns.py index d8142cab9..8ddb9e796 100644 --- a/src/lib/Bcfg2/Server/Lint/GroupPatterns.py +++ b/src/lib/Bcfg2/Server/Lint/GroupPatterns.py @@ -13,6 +13,7 @@ class GroupPatterns(ServerPlugin): :class:`Bcfg2.Server.Plugins.GroupPatterns.PatternMap` object for each pattern, and catching exceptions and presenting them as ``bcfg2-lint`` errors.""" + __serverplugin__ = 'GroupPatterns' def Run(self): cfg = self.core.plugins['GroupPatterns'].config diff --git a/src/lib/Bcfg2/Server/Lint/InfoXML.py b/src/lib/Bcfg2/Server/Lint/InfoXML.py index 4b1513a11..950a86f01 100644 --- a/src/lib/Bcfg2/Server/Lint/InfoXML.py +++ b/src/lib/Bcfg2/Server/Lint/InfoXML.py @@ -15,6 +15,7 @@ class InfoXML(Bcfg2.Server.Lint.ServerPlugin): * Paranoid mode disabled in an ``info.xml`` file; * Required attributes missing from ``info.xml`` """ + __serverplugin__ = 'Cfg' options = Bcfg2.Server.Lint.ServerPlugin.options + [ Bcfg2.Options.Common.default_paranoid, diff --git a/src/lib/Bcfg2/Server/Lint/Jinja2.py b/src/lib/Bcfg2/Server/Lint/Jinja2.py index 333249cc2..333249cc2 100755..100644 --- a/src/lib/Bcfg2/Server/Lint/Jinja2.py +++ b/src/lib/Bcfg2/Server/Lint/Jinja2.py diff --git a/src/lib/Bcfg2/Server/Lint/Metadata.py b/src/lib/Bcfg2/Server/Lint/Metadata.py index 248b1610c..e445892d1 100644 --- a/src/lib/Bcfg2/Server/Lint/Metadata.py +++ b/src/lib/Bcfg2/Server/Lint/Metadata.py @@ -15,6 +15,7 @@ class Metadata(ServerPlugin): * Multiple default groups or a default group that isn't a profile group. """ + __serverplugin__ = 'Metadata' def Run(self): self.nested_clients() diff --git a/src/lib/Bcfg2/Server/Lint/Pkgmgr.py b/src/lib/Bcfg2/Server/Lint/Pkgmgr.py index 3f0b9477c..eed6d4c19 100644 --- a/src/lib/Bcfg2/Server/Lint/Pkgmgr.py +++ b/src/lib/Bcfg2/Server/Lint/Pkgmgr.py @@ -12,6 +12,7 @@ class Pkgmgr(ServerlessPlugin): """ Find duplicate :ref:`Pkgmgr <server-plugins-generators-pkgmgr>` entries with the same priority. """ + __serverplugin__ = 'Pkgmgr' def Run(self): pset = set() diff --git a/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py b/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py index 5a80a5884..a437c1318 100644 --- a/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py +++ b/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py @@ -62,7 +62,7 @@ class TemplateAbuse(Bcfg2.Server.Lint.ServerPlugin): # finally, check for executable permissions in info.xml for entry in entryset.entries.values(): if isinstance(entry, CfgInfoXML): - for pinfo in entry.infoxml.pnode.data.xpath("//FileInfo"): + for pinfo in entry.infoxml.xdata.xpath("//FileInfo/Info"): try: mode = int( pinfo.get("mode", diff --git a/src/lib/Bcfg2/Server/Lint/TemplateHelper.py b/src/lib/Bcfg2/Server/Lint/TemplateHelper.py index a952da724..9d05516f1 100644 --- a/src/lib/Bcfg2/Server/Lint/TemplateHelper.py +++ b/src/lib/Bcfg2/Server/Lint/TemplateHelper.py @@ -20,6 +20,7 @@ class TemplateHelper(ServerPlugin): * Bogus symbols listed in ``__export__``, including symbols that don't exist, that are reserved, or that start with underscores. """ + __serverplugin__ = 'TemplateHelper' def __init__(self, *args, **kwargs): ServerPlugin.__init__(self, *args, **kwargs) diff --git a/src/lib/Bcfg2/Server/Lint/Validate.py b/src/lib/Bcfg2/Server/Lint/Validate.py index 0b3f1e24d..cab5d248d 100644 --- a/src/lib/Bcfg2/Server/Lint/Validate.py +++ b/src/lib/Bcfg2/Server/Lint/Validate.py @@ -18,7 +18,7 @@ class Validate(Bcfg2.Server.Lint.ServerlessPlugin): options = Bcfg2.Server.Lint.ServerlessPlugin.options + [ Bcfg2.Options.PathOption( "--schema", cf=("Validate", "schema"), - default="/usr/share/bcfg2/schema", + default="/usr/share/bcfg2/schemas", help="The full path to the XML schema files")] def __init__(self, *args, **kwargs): diff --git a/src/lib/Bcfg2/Server/Lint/__init__.py b/src/lib/Bcfg2/Server/Lint/__init__.py index 9b3e6ece2..526bdf159 100644 --- a/src/lib/Bcfg2/Server/Lint/__init__.py +++ b/src/lib/Bcfg2/Server/Lint/__init__.py @@ -14,6 +14,7 @@ import Bcfg2.Options import Bcfg2.Server.Core import Bcfg2.Server.Plugins from Bcfg2.Compat import walk_packages +from Bcfg2.Options import _debug def _ioctl_GWINSZ(fd): # pylint: disable=C0103 @@ -48,6 +49,11 @@ def get_termsize(): class Plugin(object): """ Base class for all bcfg2-lint plugins """ + #: Name of the matching server plugin or None if there is no + #: matching one. If this is None the lint plugin will only loaded + #: by default if the matching server plugin is enabled, too. + __serverplugin__ = None + options = [Bcfg2.Options.Common.repository] def __init__(self, errorhandler=None, files=None): @@ -291,19 +297,41 @@ class ServerPlugin(Plugin): # pylint: disable=W0223 class LintPluginAction(Bcfg2.Options.ComponentAction): - """ We want to load all lint plugins that pertain to server - plugins. In order to do this, we hijack the __call__() method of - this action and add all of the server plugins on the fly """ - + """ Option parser action to load lint plugins """ bases = ['Bcfg2.Server.Lint'] - def __call__(self, parser, namespace, values, option_string=None): - plugins = getattr(Bcfg2.Options.setup, "plugins", []) - for lint_plugin in walk_packages(path=__path__): - if lint_plugin[1] in plugins: - values.append(lint_plugin[1]) - Bcfg2.Options.ComponentAction.__call__(self, parser, namespace, values, - option_string) + +class LintPluginOption(Bcfg2.Options.Option): + """ Option class for the lint_plugins """ + + def early_parsing_hook(self, namespace): + """ + We want a usefull default for the enabled lint plugins. + Therfore we use all importable plugins, that either pertain + with enabled server plugins or that has no matching plugin. + """ + + plugins = [p.__name__ for p in namespace.plugins] + for loader, name, _is_pkg in walk_packages(path=__path__): + try: + module = loader.find_module(name).load_module(name) + plugin = getattr(module, name) + if plugin.__serverplugin__ is None or \ + plugin.__serverplugin__ in plugins: + _debug("Automatically adding lint plugin %s" % + plugin.__name__) + self.default.append(plugin.__name__) + except ImportError: + pass + + +class _EarlyOptions(object): + """ We need the server.plugins options in an early parsing hook + for determining the default value for the lint_plugins. So we + create a component that is parsed before the other options. """ + + parse_first = True + options = [Bcfg2.Options.Common.plugins] class CLI(object): @@ -313,7 +341,7 @@ class CLI(object): '--lint-config', default='/etc/bcfg2-lint.conf', action=Bcfg2.Options.ConfigFileAction, help='Specify bcfg2-lint configuration file'), - Bcfg2.Options.Option( + LintPluginOption( "--lint-plugins", cf=('lint', 'plugins'), default=[], type=Bcfg2.Options.Types.comma_list, action=LintPluginAction, help='bcfg2-lint plugin list'), @@ -328,28 +356,11 @@ class CLI(object): def __init__(self): parser = Bcfg2.Options.get_parser( description="Manage a running Bcfg2 server", - components=[self]) + components=[self, _EarlyOptions]) parser.parse() self.logger = logging.getLogger(parser.prog) - # automatically add Lint plugins for loaded server plugins - for plugin in Bcfg2.Options.setup.plugins: - try: - Bcfg2.Options.setup.lint_plugins.append( - getattr( - __import__("Bcfg2.Server.Lint.%s" % plugin.__name__, - fromlist=[plugin.__name__]), - plugin.__name__)) - self.logger.debug("Automatically adding lint plugin %s" % - plugin.__name__) - except ImportError: - # no lint plugin for this server plugin - self.logger.debug("No lint plugin for %s" % plugin.__name__) - except AttributeError: - self.logger.error("Failed to load plugin %s: %s" % - (plugin.__name__, sys.exc_info()[1])) - self.logger.debug("Running lint with plugins: %s" % [p.__name__ for p in Bcfg2.Options.setup.lint_plugins]) @@ -428,9 +439,9 @@ class CLI(object): def run_server_plugins(self): """ run plugins that require a running server to run """ core = Bcfg2.Server.Core.Core() - core.load_plugins() - core.block_for_fam_events(handle_events=True) try: + core.load_plugins() + core.block_for_fam_events(handle_events=True) self.logger.debug("Running server plugins: %s" % [p.__name__ for p in self.serverplugins]) for plugin in self.serverplugins: diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py index 456038c2f..559612d1e 100644 --- a/src/lib/Bcfg2/Server/Plugin/helpers.py +++ b/src/lib/Bcfg2/Server/Plugin/helpers.py @@ -947,7 +947,7 @@ class InfoXML(StructFile): _include_tests = copy.copy(StructFile._include_tests) _include_tests['Path'] = lambda el, md, entry, *args: \ - entry.get("name") == el.get("name") + entry.get('realname', entry.get('name')) == el.get("name") def Match(self, metadata, entry): # pylint: disable=W0221 """ Implementation of diff --git a/src/lib/Bcfg2/Server/Plugins/ACL.py b/src/lib/Bcfg2/Server/Plugins/ACL.py index 1c1e54312..37f51a2a1 100644 --- a/src/lib/Bcfg2/Server/Plugins/ACL.py +++ b/src/lib/Bcfg2/Server/Plugins/ACL.py @@ -62,6 +62,7 @@ def ip_matches(ip, entry): class IPACLFile(Bcfg2.Server.Plugin.XMLFileBacked): """ representation of ACL ip.xml, for IP-based ACLs """ + __identifier__ = None actions = dict(Allow=True, Deny=False, Defer=None) diff --git a/src/lib/Bcfg2/Server/Plugins/Decisions.py b/src/lib/Bcfg2/Server/Plugins/Decisions.py index 3d3ef8f8c..b30a9acea 100644 --- a/src/lib/Bcfg2/Server/Plugins/Decisions.py +++ b/src/lib/Bcfg2/Server/Plugins/Decisions.py @@ -31,4 +31,4 @@ class Decisions(Bcfg2.Server.Plugin.Plugin, self.blacklist = DecisionFile(os.path.join(self.data, "blacklist.xml")) def GetDecisions(self, metadata, mode): - return getattr(self, mode).get_decision(metadata) + return getattr(self, mode).get_decisions(metadata) diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py b/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py index 13f2c84e5..e393cabfe 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py @@ -21,8 +21,7 @@ class PkgngCollection(Collection): overrides nothing, and defers all operations to :class:`PacSource` """ - def __init__(self, metadata, sources, cachepath, basepath, fam, - debug=False): + def __init__(self, metadata, sources, cachepath, basepath, debug=False): # we define an __init__ that just calls the parent __init__, # so that we can set the docstring on __init__ to something # different from the parent __init__ -- namely, the parent @@ -30,7 +29,7 @@ class PkgngCollection(Collection): # which we use to delineate the actual docs from the # .. autoattribute hacks we have to do to get private # attributes included in sphinx 1.0 """ - Collection.__init__(self, metadata, sources, cachepath, basepath, fam, + Collection.__init__(self, metadata, sources, cachepath, basepath, debug=debug) __init__.__doc__ = Collection.__init__.__doc__.split(".. -----")[0] diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py index 0171800a8..d11ac60fe 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py @@ -101,7 +101,8 @@ class Packages(Bcfg2.Server.Plugin.Plugin, cf=("packages", "backends"), dest="packages_backends", help="Packages backends to load", type=Bcfg2.Options.Types.comma_list, - action=PackagesBackendAction, default=['Yum', 'Apt', 'Pac']), + action=PackagesBackendAction, + default=['Yum', 'Apt', 'Pac', 'Pkgng']), Bcfg2.Options.PathOption( cf=("packages", "cache"), dest="packages_cache", help="Path to the Packages cache", diff --git a/src/lib/Bcfg2/Server/SSLServer.py b/src/lib/Bcfg2/Server/SSLServer.py index 5e6846a44..6ad5b5635 100644 --- a/src/lib/Bcfg2/Server/SSLServer.py +++ b/src/lib/Bcfg2/Server/SSLServer.py @@ -72,7 +72,7 @@ class SSLServer(SocketServer.TCPServer, object): def __init__(self, listen_all, server_address, RequestHandlerClass, keyfile=None, certfile=None, reqCert=False, ca=None, - timeout=None, protocol='xmlrpc/ssl'): + timeout=None, protocol='xmlrpc/tlsv1'): """ :param listen_all: Listen on all interfaces :type listen_all: bool @@ -333,7 +333,7 @@ class XMLRPCServer(SocketServer.ThreadingMixIn, SSLServer, """ Component XMLRPCServer. """ def __init__(self, listen_all, server_address, RequestHandlerClass=None, - keyfile=None, certfile=None, ca=None, protocol='xmlrpc/ssl', + keyfile=None, certfile=None, ca=None, protocol='xmlrpc/tlsv1', timeout=10, logRequests=False, register=True, allow_none=True, encoding=None): """ |