From ebe7542db7217c2fac3d7111e80f94caedfb69e2 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 16 Jan 2013 13:28:06 -0500 Subject: added module-level OptionParser to avoid passing it as an argument or global all over --- src/lib/Bcfg2/Server/Core.py | 65 ++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 32 deletions(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 37da4a4b6..0ef20dfac 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -2,21 +2,22 @@ implementations inherit from. """ import os -import atexit -import logging -import select import sys -import threading import time +import select +import atexit +import logging import inspect +import threading import lxml.etree -import Bcfg2.settings import Bcfg2.Server import Bcfg2.Logger -import Bcfg2.Server.FileMonitor -from Bcfg2.Cache import Cache +import Bcfg2.settings import Bcfg2.Statistics +import Bcfg2.Server.FileMonitor from itertools import chain +from Bcfg2.Cache import Cache +from Bcfg2.Options import get_option_parser from Bcfg2.Compat import xmlrpclib # pylint: disable=W0622 from Bcfg2.Server.Plugin import PluginInitError, PluginExecutionError, \ track_statistics @@ -85,23 +86,23 @@ class BaseCore(object): and modules. All core implementations must inherit from ``BaseCore``. """ - def __init__(self, setup): # pylint: disable=R0912,R0915 + def __init__(self): # pylint: disable=R0912,R0915 """ - :param setup: A Bcfg2 options dict - :type setup: Bcfg2.Options.OptionParser - .. automethod:: _daemonize .. automethod:: _run .. automethod:: _block .. ----- .. automethod:: _file_monitor_thread """ + #: The Bcfg2 options dict + self.setup = get_option_parser() + #: The Bcfg2 repository directory - self.datastore = setup['repo'] + self.datastore = self.setup['repo'] - if setup['debug']: + if self.setup['debug']: level = logging.DEBUG - elif setup['verbose']: + elif self.setup['verbose']: level = logging.INFO else: level = logging.WARNING @@ -112,8 +113,8 @@ class BaseCore(object): # setup_logging and the console will get DEBUG output. Bcfg2.Logger.setup_logging('bcfg2-server', to_console=logging.INFO, - to_syslog=setup['syslog'], - to_file=setup['logging'], + to_syslog=self.setup['syslog'], + to_file=self.setup['logging'], level=level) #: A :class:`logging.Logger` object for use by the core @@ -121,16 +122,16 @@ class BaseCore(object): try: filemonitor = \ - Bcfg2.Server.FileMonitor.available[setup['filemonitor']] + Bcfg2.Server.FileMonitor.available[self.setup['filemonitor']] except KeyError: self.logger.error("File monitor driver %s not available; " - "forcing to default" % setup['filemonitor']) + "forcing to default" % self.setup['filemonitor']) filemonitor = Bcfg2.Server.FileMonitor.available['default'] famargs = dict(ignore=[], debug=False) - if 'ignore' in setup: - famargs['ignore'] = setup['ignore'] - if 'debug' in setup: - famargs['debug'] = setup['debug'] + if 'ignore' in self.setup: + famargs['ignore'] = self.setup['ignore'] + if 'debug' in self.setup: + famargs['debug'] = self.setup['debug'] try: #: The :class:`Bcfg2.Server.FileMonitor.FileMonitor` @@ -138,12 +139,13 @@ class BaseCore(object): #: changes. self.fam = filemonitor(**famargs) except IOError: - msg = "Failed to instantiate fam driver %s" % setup['filemonitor'] + msg = "Failed to instantiate fam driver %s" % \ + self.setup['filemonitor'] self.logger.error(msg, exc_info=1) raise CoreInitError(msg) #: Path to bcfg2.conf - self.cfile = setup['configfile'] + self.cfile = self.setup['configfile'] #: Dict of plugins that are enabled. Keys are the plugin #: names (just the plugin name, in the correct case; e.g., @@ -161,9 +163,6 @@ class BaseCore(object): #: :class:`Bcfg2.Server.Plugin.interfaces.Version` plugin. self.revision = '-1' - #: The Bcfg2 options dict - self.setup = setup - atexit.register(self.shutdown) #: Threading event to signal worker threads (e.g., @@ -217,10 +216,10 @@ class BaseCore(object): self.logger.error("Failed to set ownership of database " "at %s: %s" % (db_settings['NAME'], err)) - if '' in setup['plugins']: - setup['plugins'].remove('') + if '' in self.setup['plugins']: + self.setup['plugins'].remove('') - for plugin in setup['plugins']: + for plugin in self.setup['plugins']: if not plugin in self.plugins: self.init_plugin(plugin) # Remove blacklisted plugins @@ -283,12 +282,12 @@ class BaseCore(object): self.connectors = self.plugins_by_type(Bcfg2.Server.Plugin.Connector) #: The CA that signed the server cert - self.ca = setup['ca'] + self.ca = self.setup['ca'] #: The FAM :class:`threading.Thread`, #: :func:`_file_monitor_thread` self.fam_thread = \ - threading.Thread(name="%sFAMThread" % setup['filemonitor'], + threading.Thread(name="%sFAMThread" % self.setup['filemonitor'], target=self._file_monitor_thread) #: A :func:`threading.Lock` for use by @@ -393,8 +392,10 @@ class BaseCore(object): """ Get the client :attr:`metadata_cache` mode. Options are off, initial, cautious, aggressive, on (synonym for cautious). See :ref:`server-caching` for more details. """ + # pylint: disable=E1103 mode = self.setup.cfp.get("caching", "client_metadata", default="off").lower() + # pylint: enable=E1103 if mode == "on": return "cautious" else: -- cgit v1.2.3-1-g7c22 From 45c7bbf24ae3c6530f33ebb33c062818ad44816d Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 30 Oct 2012 11:35:46 -0400 Subject: added a module-level FAM object to avoid passing it as an argument a billion times --- src/lib/Bcfg2/Server/Core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 0ef20dfac..0bc77afff 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -137,7 +137,7 @@ class BaseCore(object): #: The :class:`Bcfg2.Server.FileMonitor.FileMonitor` #: object used by the core to monitor for Bcfg2 data #: changes. - self.fam = filemonitor(**famargs) + self.fam = Bcfg2.Server.FileMonitor.get_fam(**famargs) except IOError: msg = "Failed to instantiate fam driver %s" % \ self.setup['filemonitor'] -- cgit v1.2.3-1-g7c22 From 1a6ad2805f5b12ed111f7a3a6adb127f2cbcef8e Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Thu, 17 Jan 2013 11:01:41 -0500 Subject: FAM: split loading a new FileMonitor from fetching an existing one --- src/lib/Bcfg2/Server/Core.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 0bc77afff..c7797a711 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -17,7 +17,7 @@ import Bcfg2.Statistics import Bcfg2.Server.FileMonitor from itertools import chain from Bcfg2.Cache import Cache -from Bcfg2.Options import get_option_parser +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 @@ -120,18 +120,16 @@ class BaseCore(object): #: A :class:`logging.Logger` object for use by the core self.logger = logging.getLogger('bcfg2-server') - try: - filemonitor = \ - Bcfg2.Server.FileMonitor.available[self.setup['filemonitor']] - except KeyError: + if 'ignore' not in self.setup: + self.setup.add_option('ignore', SERVER_FAM_IGNORE) + self.setup.reparse() + famargs = dict(filemonitor=self.setup['filemonitor'], + debug=self.setup['debug'], + ignore=self.setup['ignore']) + if self.setup['filemonitor'] not in Bcfg2.Server.FileMonitor.available: self.logger.error("File monitor driver %s not available; " "forcing to default" % self.setup['filemonitor']) - filemonitor = Bcfg2.Server.FileMonitor.available['default'] - famargs = dict(ignore=[], debug=False) - if 'ignore' in self.setup: - famargs['ignore'] = self.setup['ignore'] - if 'debug' in self.setup: - famargs['debug'] = self.setup['debug'] + famargs['filemonitor'] = 'default' try: #: The :class:`Bcfg2.Server.FileMonitor.FileMonitor` -- cgit v1.2.3-1-g7c22 From 25cb6db5ccb0c8e8302c220a90344a95baf3909b Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 5 Feb 2013 14:04:09 -0500 Subject: moved some libraries in Bcfg2/ into more specific (Server/ or Client/) places --- src/lib/Bcfg2/Server/Core.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'src/lib/Bcfg2/Server/Core.py') 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): -- cgit v1.2.3-1-g7c22 From e5072626bc50865ca95e64fa0ca78262655d2164 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 6 Feb 2013 15:45:30 -0500 Subject: fixed loading FAM in core --- src/lib/Bcfg2/Server/Core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index a2c4ee1cb..90349ddf9 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -134,7 +134,7 @@ class BaseCore(object): #: The :class:`Bcfg2.Server.FileMonitor.FileMonitor` #: object used by the core to monitor for Bcfg2 data #: changes. - self.fam = Bcfg2.Server.FileMonitor.get_fam(**famargs) + self.fam = Bcfg2.Server.FileMonitor.load_fam(**famargs) except IOError: msg = "Failed to instantiate fam driver %s" % \ self.setup['filemonitor'] -- cgit v1.2.3-1-g7c22 From e8a5500535cb7c23ef3d687304033e50e80dbd3f Mon Sep 17 00:00:00 2001 From: Matt Schwager Date: Mon, 15 Oct 2012 12:34:07 -0400 Subject: IP based ACLs working for CherryPy Server. Still need to implement BuiltinServer and test. --- src/lib/Bcfg2/Server/Core.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 90349ddf9..9ca540127 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -1072,6 +1072,13 @@ class BaseCore(object): return self.metadata.AuthenticateConnection(acert, user, password, address) + def check_acls(self, client): + """ Check if client IP is in list of accepted IPs """ + try: + return client in self.plugins['Acl'].config.ips + except KeyError: + return True + @exposed def GetDecisionList(self, address, mode): """ Get the decision list for the client with :func:`GetDecisions`. -- cgit v1.2.3-1-g7c22 From 168aa5f9d31f310caa2d8fb87b5d46d6e23b5821 Mon Sep 17 00:00:00 2001 From: Matt Schwager Date: Wed, 17 Oct 2012 13:44:43 -0400 Subject: IP based ACLs working for CherryPy and Builtin Server. Rudimentary tests performed and passed. --- src/lib/Bcfg2/Server/Core.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 9ca540127..e931a7bc0 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -1075,8 +1075,10 @@ class BaseCore(object): def check_acls(self, client): """ Check if client IP is in list of accepted IPs """ try: - return client in self.plugins['Acl'].config.ips + return (client in self.plugins['Acl'].config.ips or + '*' in self.plugins['Acl'].config) except KeyError: + # No ACL means accept all incoming ips (wildcard) return True @exposed -- cgit v1.2.3-1-g7c22 From ead022433a759686db6de02b91811de7ca166ac7 Mon Sep 17 00:00:00 2001 From: Matt Schwager Date: Wed, 17 Oct 2012 14:02:19 -0400 Subject: Corrected acceptance of wildcard ('*') in ACL XML file. --- src/lib/Bcfg2/Server/Core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index e931a7bc0..c9fd76325 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -1076,7 +1076,7 @@ class BaseCore(object): """ Check if client IP is in list of accepted IPs """ try: return (client in self.plugins['Acl'].config.ips or - '*' in self.plugins['Acl'].config) + '*' in self.plugins['Acl'].config.ips) except KeyError: # No ACL means accept all incoming ips (wildcard) return True -- cgit v1.2.3-1-g7c22 From 0253b04b9ba7c3e4ef139bf352b7a57de823daaa Mon Sep 17 00:00:00 2001 From: Matt Schwager Date: Fri, 19 Oct 2012 13:37:49 -0400 Subject: Added CIDR notation to IP ACLs. Still need to test. --- src/lib/Bcfg2/Server/Core.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index c9fd76325..c01b493de 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -1072,13 +1072,12 @@ class BaseCore(object): return self.metadata.AuthenticateConnection(acert, user, password, address) - def check_acls(self, client): + def check_acls(self, client_ip): """ Check if client IP is in list of accepted IPs """ try: - return (client in self.plugins['Acl'].config.ips or - '*' in self.plugins['Acl'].config.ips) + return self.plugins['Acl'].config.check_acl(client_ip) except KeyError: - # No ACL means accept all incoming ips (wildcard) + # No ACL means accept all incoming ips return True @exposed -- cgit v1.2.3-1-g7c22 From 5363e6d9a53146333da0d109aae170befc1b9481 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 12 Feb 2013 07:48:33 -0500 Subject: Added client ACLs: * IP and CIDR-based ACLs * Metadata (group/hostname)-based ACLs * Documentation * Unit tests --- src/lib/Bcfg2/Server/Core.py | 72 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index c01b493de..f93ca0a7b 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -743,6 +743,48 @@ class BaseCore(object): % plugin.name, exc_info=1) return result + @Bcfg2.Server.Statistics.track_statistics() + def check_acls(self, address, rmi): + """ Check client IP address and metadata object against all + :class:`Bcfg2.Server.Plugin.interfaces.ClientACLs` plugins. + If any ACL plugin denies access, then access is denied. ACLs + are checked in two phases: First, with the client IP address; + and second, with the client metadata object. This lets an ACL + interface do a quick rejection based on IP before metadata is + ever built. + + :param address: The address pair of the client to check ACLs for + :type address: tuple of (, ) + :param rmi: The fully-qualified name of the RPC call + :param rmi: string + :returns: bool + """ + plugins = self.plugins_by_type(Bcfg2.Server.Plugin.ClientACLs) + try: + ip_checks = [p.check_acl_ip(address, rmi) for p in plugins] + except: + self.logger.error("Unexpected error checking ACLs for %s for %s: " + "%s" % (address[0], rmi, sys.exc_info()[1])) + return False # failsafe + + if all(ip_checks): + # if all ACL plugins return True (allow), then allow + return True + elif False in ip_checks: + # if any ACL plugin returned False (deny), then deny + return False + # else, no plugins returned False, but not all plugins + # returned True, so some plugin returned None (defer), so + # defer. + + client, metadata = self.resolve_client(address) + try: + return all(p.check_acl_metadata(metadata, rmi) for p in plugins) + except: + self.logger.error("Unexpected error checking ACLs for %s for %s: " + "%s" % (client, rmi, sys.exc_info()[1])) + return False # failsafe + @Bcfg2.Server.Statistics.track_statistics() def build_metadata(self, client_name): """ Build initial client metadata for a client @@ -804,7 +846,7 @@ class BaseCore(object): :param address: The address pair of the client to get the canonical hostname for. - :type address: tuple of (, ) + :type address: tuple of (, ) :param cleanup_cache: Tell the :class:`Bcfg2.Server.Plugin.interfaces.Metadata` plugin in :attr:`metadata` to clean up @@ -881,21 +923,23 @@ class BaseCore(object): def listMethods(self, address): # pylint: disable=W0613 """ List all exposed methods, including plugin RMI. - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :returns: list of exposed method names """ methods = [name for name, func in inspect.getmembers(self, callable) - if getattr(func, "exposed", False)] - methods.extend(self._get_rmi().keys()) + if (getattr(func, "exposed", False) and + self.check_acls(address, name))] + methods.extend([m for m in self._get_rmi().keys() + if self.check_acls(address, m)]) return methods @exposed def methodHelp(self, address, method_name): # pylint: disable=W0613 """ Get help from the docstring of an exposed method - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :param method_name: The name of the method to get help on :type method_name: string @@ -911,7 +955,7 @@ class BaseCore(object): def DeclareVersion(self, address, version): """ Declare the client version. - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :param version: The client's declared version :type version: string @@ -932,7 +976,7 @@ class BaseCore(object): def GetProbes(self, address): """ Fetch probes for the client. - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :returns: lxml.etree._Element - XML tree describing probes for this client @@ -955,7 +999,7 @@ class BaseCore(object): def RecvProbeData(self, address, probedata): """ Receive probe data from clients. - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :returns: bool - True on success :raises: :exc:`xmlrpclib.Fault` @@ -1001,7 +1045,7 @@ class BaseCore(object): def AssertProfile(self, address, profile): """ Set profile for a client. - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :returns: bool - True on success :raises: :exc:`xmlrpclib.Fault` @@ -1021,7 +1065,7 @@ class BaseCore(object): """ Build config for a client by calling :func:`BuildConfiguration`. - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :returns: lxml.etree._Element - The full configuration document for the client @@ -1039,7 +1083,7 @@ class BaseCore(object): def RecvStats(self, address, stats): """ Act on statistics upload with :func:`process_statistics`. - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :returns: bool - True on success :raises: :exc:`xmlrpclib.Fault` @@ -1060,7 +1104,7 @@ class BaseCore(object): :type user: string :param password: The password supplied by the client :type password: string - :param address: An address pair of ``(, )`` + :param address: An address pair of ``(, )`` :type address: tuple :return: bool - True if the authenticate succeeds, False otherwise """ @@ -1084,7 +1128,7 @@ class BaseCore(object): def GetDecisionList(self, address, mode): """ Get the decision list for the client with :func:`GetDecisions`. - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :returns: list of decision tuples :raises: :exc:`xmlrpclib.Fault` @@ -1111,7 +1155,7 @@ class BaseCore(object): def toggle_debug(self, address): """ Toggle debug status of the FAM and all plugins - :param address: Client (address, hostname) pair + :param address: Client (address, port) pair :type address: tuple :returns: bool - The new debug state of the FAM """ -- cgit v1.2.3-1-g7c22 From 4b339bf61244714661fc73a192296ca37b12ab9f Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 20 Feb 2013 10:38:57 -0500 Subject: fixed unit tests for merge --- src/lib/Bcfg2/Server/Core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Server/Core.py') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 1b0ecadf5..07f9e0588 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -334,7 +334,7 @@ class BaseCore(object): continue self._update_vcs_revision() - @track_statistics() + @Bcfg2.Server.Statistics.track_statistics() def _update_vcs_revision(self): """ Update the revision of the current configuration on-disk from the VCS plugin """ -- cgit v1.2.3-1-g7c22