contrib/find_resources.py | 8 contrib/packagekit.py | 6 examples/drive_checker.py | 3 examples/find_recalled_parts.py | 4 examples/service_checker.py | 2 func/CommonErrors.py | 1 func/commonconfig.py | 3 func/forkbomb.py | 16 func/index_db.py | 13 func/jobthing.py | 48 func/logger.py | 15 func/minion/acls.py | 28 func/minion/codes.py | 2 func/minion/facts/minion_query.py | 94 func/minion/facts/modules/fact_module.py | 11 func/minion/facts/modules/hardware.py | 17 func/minion/facts/overlord_query.py | 19 func/minion/facts/query.py | 48 func/minion/facts/query_utils.py | 2 func/minion/facts/tree.py | 2 func/minion/func_arg.py | 42 func/minion/modules/bridge.py | 11 func/minion/modules/certmastermod.py | 8 func/minion/modules/command.py | 2 func/minion/modules/confmgt_augeas.py | 23 func/minion/modules/copyfile.py | 2 func/minion/modules/delegation.py | 22 func/minion/modules/echo.py | 20 func/minion/modules/fact.py | 21 func/minion/modules/filetracker.py | 24 func/minion/modules/func_getargs.py | 15 func/minion/modules/func_module.py | 23 func/minion/modules/hardware.py | 11 func/minion/modules/httpd.py | 2 func/minion/modules/iptables/common.py | 2 func/minion/modules/iptables/port.py | 18 func/minion/modules/jboss.py | 44 func/minion/modules/jobs.py | 23 func/minion/modules/mount.py | 14 func/minion/modules/nagios-check.py | 2 func/minion/modules/netapp/common.py | 3 func/minion/modules/netapp/options.py | 3 func/minion/modules/netapp/snap.py | 5 func/minion/modules/netapp/vol/__init__.py | 10 func/minion/modules/netapp/vol/clone.py | 10 func/minion/modules/networktest.py | 12 func/minion/modules/overlord.py | 2 func/minion/modules/process.py | 30 func/minion/modules/pullfile.py | 1 func/minion/modules/reboot.py | 1 func/minion/modules/rpms.py | 10 func/minion/modules/service.py | 12 func/minion/modules/smart.py | 2 func/minion/modules/snmp.py | 4 func/minion/modules/sysctl.py | 8 func/minion/modules/test.py | 2 func/minion/modules/users.py | 3292 ++++++++++++------------ func/minion/modules/virt.py | 2 func/minion/modules/vlan.py | 8 func/minion/modules/yumcmd.py | 26 func/minion/server.py | 40 func/overlord/base_command.py | 4 func/overlord/client.py | 210 - func/overlord/cmd_modules/call.py | 88 func/overlord/cmd_modules/check.py | 86 func/overlord/cmd_modules/copyfile.py | 2 func/overlord/cmd_modules/grep.py | 46 func/overlord/cmd_modules/group.py | 38 func/overlord/cmd_modules/listminions.py | 3 func/overlord/cmd_modules/show.py | 2 func/overlord/cmd_modules/show_hardware.py | 14 func/overlord/command.py | 3 func/overlord/delegation_tools.py | 60 func/overlord/func_command.py | 9 func/overlord/group/base.py | 6 func/overlord/group/conf_backend.py | 35 func/overlord/group/sqlite_backend.py | 43 func/overlord/groups.py | 58 func/overlord/inventory.py | 24 func/overlord/mapper.py | 35 func/overlord/modules/copyfile.py | 4 func/overlord/modules/netapp.py | 4 func/overlord/modules/utils.py | 4 func/overlord/scripts.py | 5 func/utils.py | 53 func/yaml/dump.py | 42 func/yaml/load.py | 2 func/yaml/ordered_dict.py | 4 func/yaml/redump.py | 1 func/yaml/stream.py | 8 func/yaml/timestamp.py | 52 func/yaml/ypath.py | 6 funcweb/funcweb/async_tools.py | 25 funcweb/funcweb/commands.py | 8 funcweb/funcweb/controllers.py | 102 funcweb/funcweb/identity/pam.py | 2 funcweb/funcweb/result_handler.py | 36 funcweb/funcweb/tests/bork.py | 2 funcweb/funcweb/tests/test_async_tools.py | 56 funcweb/funcweb/tests/test_client_rendering.py | 5 funcweb/funcweb/tests/test_model.py | 1 funcweb/funcweb/tests/test_result_handler.py | 9 funcweb/funcweb/tests/test_widget_automation.py | 57 funcweb/funcweb/tests/test_widget_validation.py | 79 funcweb/funcweb/widget_automation.py | 52 funcweb/funcweb/widget_validation.py | 74 pusher.py | 41 setup.py | 131 test/async_test.py | 95 test/test-confmgt_augeas.py | 106 test/test_func_db.py | 36 test/unittest/cover_to_html.py | 68 test/unittest/plugins/funccover.py | 17 test/unittest/test_client.py | 56 test/unittest/test_config.py | 38 test/unittest/test_facts_minion.py | 94 test/unittest/test_facts_overlord.py | 32 test/unittest/test_facts_tree.py | 28 test/unittest/test_func_arg.py | 27 test/unittest/test_func_transmit.py | 36 test/unittest/test_groups_api.py | 112 test/unittest/test_minion.py | 40 test/unittest/test_users.py | 722 ++--- 123 files changed, 3600 insertions(+), 3692 deletions(-) New commits: commit 565ec1d2efa942acbb39372f1590e2ae92baabf6 Author: S.Ã?aÄ?lar Onur <caglar@xxxxxxxxxxxxxxxx> Date: Fri Oct 15 14:46:35 2010 -0400 Huge whitespace cleanup which includes; * Change files to use 4-space indents and no hard tab characters. * Trim excess spaces and tabs from ends of lines. * Remove empty lines at the end of files and ensure the last line ends with a newline. Generated by http://svn.python.org/projects/python/trunk/Tools/scripts/reindent.py diff --git a/contrib/find_resources.py b/contrib/find_resources.py index e43bb85..28379b2 100755 --- a/contrib/find_resources.py +++ b/contrib/find_resources.py @@ -26,9 +26,9 @@ import func.utils as utils class FindResources(object): def __init__(self): - pass + pass - def run(self,args): + def run(self,args): p = optparse.OptionParser() p.add_option("-v", "--verbose", @@ -60,8 +60,8 @@ class FindResources(object): host_freemem = func_client.Client(options.server_spec).virt.freemem() for (host, freemem) in host_freemem.iteritems(): if utils.is_error(freemem): - print "-- connection refused: %s" % host - continue + print "-- connection refused: %s" % host + continue # Take an additional 256M off the freemem to keep # Domain-0 stable (shrinking it to 256M can cause diff --git a/contrib/packagekit.py b/contrib/packagekit.py index 221fc5c..3fcaf7e 100644 --- a/contrib/packagekit.py +++ b/contrib/packagekit.py @@ -26,13 +26,13 @@ class PackageKitInterface(PackageKit): def __init__(self): PackageKit.__init__(self) self.packages = [] - + def Percentage(self, progress): pass - + def JobStatus(self, type): pass - + def Package(self, package_name, package_summary): self.packages.append( { "name" : "%s" % package_name, diff --git a/examples/drive_checker.py b/examples/drive_checker.py index e51e378..b5361ba 100644 --- a/examples/drive_checker.py +++ b/examples/drive_checker.py @@ -22,6 +22,5 @@ for (host,details) in info.iteritems(): print "Host %s may have problems" % host print "\n".join(list_of_output[3:]) failures = failures + 1 - -print "\n%s systems reported problems" % failures +print "\n%s systems reported problems" % failures diff --git a/examples/find_recalled_parts.py b/examples/find_recalled_parts.py index 36c4a7c..7419f13 100644 --- a/examples/find_recalled_parts.py +++ b/examples/find_recalled_parts.py @@ -18,8 +18,6 @@ for (host,details) in info.iteritems(): for (device, full_output) in details.iteritems(): for bad_value in bad: - if full_output.find(bad_value) != -1: + if full_output.find(bad_value) != -1: print "%s has flagged part: %s, matched %s" % (host, device, bad_value) break - - diff --git a/examples/service_checker.py b/examples/service_checker.py index 3dc683f..d757a53 100644 --- a/examples/service_checker.py +++ b/examples/service_checker.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# Copyright (c) 2007 Red Hat, inc +# Copyright (c) 2007 Red Hat, inc import sys import func.overlord.client as fc diff --git a/func/CommonErrors.py b/func/CommonErrors.py index c76cb3d..765672c 100644 --- a/func/CommonErrors.py +++ b/func/CommonErrors.py @@ -66,4 +66,3 @@ class Func_Client_Exception(Exception): self.value = value def __str__(self): return "%s" %(self.value,) - diff --git a/func/commonconfig.py b/func/commonconfig.py index 224c156..42a2412 100644 --- a/func/commonconfig.py +++ b/func/commonconfig.py @@ -27,7 +27,7 @@ class FuncdConfig(BaseConfig): listen_addr = Option('') listen_port = IntOption('51234') minion_name = Option('') - + method_log_dir = Option("/var/log/func/methods/") use_certmaster = BoolOption(True) ca_file = Option('') @@ -49,4 +49,3 @@ class OverlordConfig(BaseConfig): puppet_crl = Option('/var/lib/puppet/ssl/ca/ca_crl.pem') host_down_list = Option('/var/lib/func/hosts_down.lst') allow_unknown_minions = BoolOption(False) - diff --git a/func/forkbomb.py b/func/forkbomb.py index fc64ead..d682300 100644 --- a/func/forkbomb.py +++ b/func/forkbomb.py @@ -52,7 +52,7 @@ def __access_buckets(filename,clear,new_key=None,new_value=None): if not storage.has_key("data"): storage["data"] = {} - else: + else: pass if new_key is not None: @@ -78,7 +78,7 @@ def __bucketize(pool, slots): slot = count % slots count = count + 1 if not buckets.has_key(slot): - buckets[slot] = [] + buckets[slot] = [] buckets[slot].append(key) return buckets @@ -111,11 +111,11 @@ def __forkbomb(mybucket,buckets,what_to_do,filename): else: raise ose else: - __with_my_bucket(mybucket,buckets,what_to_do,filename) + __with_my_bucket(mybucket,buckets,what_to_do,filename) os._exit(0) def __demo(bucket_number, buckets, my_item): - """ + """ This is a demo handler for test purposes. It just multiplies all numbers by 1000, but slowly. """ @@ -129,11 +129,11 @@ def batch_run(pool,callback,nforks=DEFAULT_FORKS,cachedir=DEFAULT_CACHE_DIR): """ Given an array of items (pool), call callback in each one, but divide the workload over nfork forks. Temporary files used during the - operation will be created in cachedir and subsequently deleted. + operation will be created in cachedir and subsequently deleted. """ if nforks < 1: - # modulus voodoo gets crazy otherwise and bad things happen - nforks = 1 + # modulus voodoo gets crazy otherwise and bad things happen + nforks = 1 shelf_file = __get_storage(cachedir) __access_buckets(shelf_file,True,None) buckets = __bucketize(pool, nforks) @@ -155,5 +155,3 @@ def __test(nforks=4,sample_size=20): if __name__ == "__main__": __test() - - diff --git a/func/index_db.py b/func/index_db.py index b4135d4..51d7c0d 100644 --- a/func/index_db.py +++ b/func/index_db.py @@ -73,10 +73,10 @@ class IndexDb(object): print e self.__storage = None return None - + self.__close_storage() return tmp - + def delete_from_index(self,delete_list): """ @@ -85,7 +85,7 @@ class IndexDb(object): self.__mode = self.WRITE_MODE if not self.__storage: self.__load_index() - + try: for to_delete in delete_list: if self.__storage.has_key(to_delete): @@ -94,7 +94,7 @@ class IndexDb(object): print e self.__storage = None return False - + self.__close_storage() return True @@ -124,7 +124,7 @@ def write_index_data(data,dir=None): A simple setter method for above structure """ db = IndexDb(dir) - result = db.write_to_index(data) + result = db.write_to_index(data) return result def delete_index_data(data,dir=None): @@ -137,11 +137,10 @@ def delete_index_data(data,dir=None): def key_exists(key,dir=None): """ - Checks for a key if is there + Checks for a key if is there """ dict = get_index_data(dir) return dict.has_key(key) if __name__ == "__main__": pass - diff --git a/func/jobthing.py b/func/jobthing.py index 59e494c..05f3fe2 100644 --- a/func/jobthing.py +++ b/func/jobthing.py @@ -34,7 +34,7 @@ JOB_ID_PARTIAL = 3 JOB_ID_REMOTE_ERROR = 4 # how long to retain old job records in the job id database -RETAIN_INTERVAL = 60 * 60 +RETAIN_INTERVAL = 60 * 60 # where to store the internal job id database CACHE_DIR = "/var/lib/func" @@ -53,7 +53,7 @@ def clear_db(): def __purge_old_jobs(storage): """ - Deletes jobs older than RETAIN_INTERVAL seconds. + Deletes jobs older than RETAIN_INTERVAL seconds. MINOR FIXME: this probably should be a more intelligent algorithm that only deletes jobs if the database is too big and then only the oldest jobs but this will work just as well. @@ -84,23 +84,23 @@ def get_open_ids(): def __get_open_ids(storage): """ - That method is needes from other language/API/UI/GUI parts that uses + That method is needes from other language/API/UI/GUI parts that uses func's async methods to know the status of the results. """ result_hash_pack = {} #print storage for job_id,result in storage.iteritems(): - #TOBE REMOVED that control is for old job_ids + #TOBE REMOVED that control is for old job_ids #some users who will upgrade to new version will have errors #if we dont have that control here :) - if len(job_id.split("-"))>=4: #ignore the old job_ids the overlord part + if len(job_id.split("-"))>=4: #ignore the old job_ids the overlord part result_hash_pack[job_id]=result[0] elif len(job_id.split("-"))==2: #it seems to be a minion side id and also ignores old ids result_hash_pack[job_id]=result[0] return result_hash_pack - + def __access_status(jobid=0, status=0, results=0, clear=False, write=False, purge=False,get_all=False): @@ -111,7 +111,7 @@ def __access_status(jobid=0, status=0, results=0, clear=False, write=False, purg except IOError: raise Func_Client_Exception, 'Cannot create directory for status files. '+\ 'Ensure you have permission to create %s directory' % dir - filename = os.path.join(dir,"status-%s" % os.getuid()) + filename = os.path.join(dir,"status-%s" % os.getuid()) try: handle = open(filename,"w") @@ -127,7 +127,7 @@ def __access_status(jobid=0, status=0, results=0, clear=False, write=False, purg storage.close() fcntl.flock(handle.fileno(), fcntl.LOCK_UN) return {} - + if purge or write: __purge_old_jobs(storage) @@ -158,11 +158,11 @@ def batch_run(pool, callback, nforks,**extra_args): Given an array of items (pool), call callback in each one, but divide the workload over nfork forks. Temporary files used during the - operation will be created in cachedir and subsequently deleted. + operation will be created in cachedir and subsequently deleted. """ - + job_id = utils.get_formated_jobid(**extra_args) - + __update_status(job_id, JOB_ID_RUNNING, -1) pid = os.fork() if pid != 0: @@ -170,8 +170,8 @@ def batch_run(pool, callback, nforks,**extra_args): else: # kick off the job results = forkbomb.batch_run(pool, callback, nforks) - - # write job IDs to the state file on overlord + + # write job IDs to the state file on overlord __update_status(job_id, JOB_ID_PARTIAL, results) # we now have a list of job id's for each minion, kill the task os._exit(0) @@ -182,7 +182,7 @@ def minion_async_run(retriever, method, args,minion_query=None): This is a simpler invocation for minion side async usage. """ # to avoid confusion of job id's (we use the same job database) - # minion jobs contain the string "minion". + # minion jobs contain the string "minion". job_id = "%s-minion" % pprint.pformat(time.time()) __update_status(job_id, JOB_ID_RUNNING, -1) pid = os.fork() @@ -198,7 +198,7 @@ def minion_async_run(retriever, method, args,minion_query=None): os._exit(0) try: - + fact_result = None if args and type(args[0]) == dict and args[0].has_key('__fact__'): fact_result = minion_query.exec_query(args[0]['__fact__'],True) @@ -214,7 +214,7 @@ def minion_async_run(retriever, method, args,minion_query=None): args.append({'__logger__':True,'job_id':job_id}) args = tuple(args) rc = function_ref(*args) - + if fact_result and fact_result[0]: #that means we have True from query so can go on function_ref = retriever(method) #here we will append the job_id at the end of the args list @@ -230,7 +230,7 @@ def minion_async_run(retriever, method, args,minion_query=None): rc = [{'__fact__':fact_result},rc] elif fact_result and not fact_result[0]: rc = [{'__fact__':fact_result}] - + except Exception, e: (t, v, tb) = sys.exc_info() rc = cm_utils.nice_exception(t,v,tb) @@ -244,14 +244,14 @@ from func.index_db import write_index_data from func.index_db import key_exists def job_status(jobid, client_class=None, client_class_config=None): - + # NOTE: client_class is here to get around some evil circular reference # type stuff. This is intended to be called by minions (who can leave it None) # or by the Client module code (which does not need to be worried about it). API # users should not be calling jobthing.py methods directly. # NOTE: class_config is here so we can pass in all of our settings from the # parent - otherwise async jobs with timeouts go straight to hell. - + got_status = __get_status(jobid) # if the status comes back as JOB_ID_PARTIAL what we have is actually a hash # of hostname/minion-jobid pairs. Instantiate a client handle for each and poll them @@ -297,15 +297,15 @@ def job_status(jobid, client_class=None, client_class_config=None): partial_results[host] = [ utils.REMOTE_ERROR, "lost job" ] else: partial_results[host] = minion_interim_result - else: + else: some_missing = True - + #write the match dictionary for {overlord_job_id:minion_job_id} write_index_data(match_dict) if some_missing or not interim_results: return (JOB_ID_PARTIAL, partial_results) - + else: # Save partial results in state file so next time we don't # call minions to get status. @@ -315,10 +315,8 @@ def job_status(jobid, client_class=None, client_class_config=None): else: return got_status - + # of job id's on the minion in results. if __name__ == "__main__": __test() - - diff --git a/func/logger.py b/func/logger.py index ad9438c..caa5bab 100644 --- a/func/logger.py +++ b/func/logger.py @@ -34,12 +34,12 @@ class Logger(Singleton): def __init__(self, logfilepath ="/var/log/func/func.log"): config_file = '/etc/func/minion.conf' - self.config = read_config(config_file, FuncdConfig) + self.config = read_config(config_file, FuncdConfig) self.loglevel = logging._levelNames[self.config.log_level] self._setup_logging() if self._no_handlers: self._setup_handlers(logfilepath=logfilepath) - + def _setup_logging(self): self.logger = logging.getLogger("svc") @@ -87,7 +87,7 @@ class AuditLogger(Singleton): #some more dynamic logger handlers here config_file = '/etc/func/minion.conf' config = read_config(config_file, FuncdConfig) -GLOBAL_LOG_DIR = config.method_log_dir +GLOBAL_LOG_DIR = config.method_log_dir class StandartLogger(object): """ It is just a proxy like object to the logging @@ -105,14 +105,14 @@ class StandartLogger(object): # a default case is to have a FileHandler for all that is what we want for handler in self.handlers: self.logger.addHandler(handler) - + def progress(self,current,all): """ - A method to log the progress of the + A method to log the progress of the running method ... """ self.logger.debug("Progress report %d/%d completed"%(current,all)) - + def debug(self,msg): self.logger.debug(msg) def info(self,msg): @@ -159,7 +159,7 @@ STANDART_LOGGER = 0 EXCEPTION_LOGGER = 1 class LogFactory(object): - + def get_instance(type=STANDART_LOGGER,app_name="direct_log",log_place=None): if type == STANDART_LOGGER: if not log_place: @@ -177,4 +177,3 @@ class LogFactory(object): else: return None get_instance = staticmethod(get_instance) - diff --git a/func/minion/acls.py b/func/minion/acls.py index 5b80159..5a5d9b0 100644 --- a/func/minion/acls.py +++ b/func/minion/acls.py @@ -24,7 +24,7 @@ from func import logger class Acls(object): def __init__(self, config=None): self.config = config - + self.acldir = self.config.acl_dir self._acl_glob = '%s/*.acl' % self.acldir self._acls = {} @@ -38,38 +38,38 @@ class Acls(object): return True if most recent timestamp of any of the acl files in the acl dir is more recent than the last_load_time """ - + # if we removed or added a file - this will trigger a reload if os.stat(self.acldir)[stat.ST_MTIME] > self.last_load_time: return True - + # if we modified or added a file - this will trigger a reload for fn in glob.glob(self._acl_glob): if os.stat(fn)[stat.ST_MTIME] > self.last_load_time: return True - + return False - - def load(self): + + def load(self): """ takes a dir of .acl files returns a dict of hostname+hash = [methods, to, run] - + """ if not os.path.exists(self.acldir): sys.stderr.write('acl dir does not exist: %s\n' % self.acldir) return self._acls - + if not self._reload_acls(): return self._acls - + self.logger.debug("acl [re]loading") self._acls = {} # nuking from orbit - just in case # get the set of files files = glob.glob(self._acl_glob) - + for acl_file in files: self.logger.debug("acl_file %s", acl_file) try: @@ -77,7 +77,7 @@ class Acls(object): except (IOError, OSError), e: sys.stderr.write('cannot open acl config file: %s - %s\n' % (acl_file, e)) continue - + for line in fo.readlines(): if line.startswith('#'): continue if line.strip() == '': continue @@ -92,7 +92,7 @@ class Acls(object): self._acls[host].extend(methods) self.logger.debug("acls %s" % self._acls) - + self.last_load_time = time.time() return self._acls @@ -124,7 +124,7 @@ class Acls(object): for methodmatch in allow_list: if fnmatch.fnmatch(method, methodmatch): return True - + return False def save(self): @@ -138,5 +138,3 @@ class Acls(object): def update(self, acl, host): pass - - diff --git a/func/minion/codes.py b/func/minion/codes.py index b8d3fd9..4c9653a 100644 --- a/func/minion/codes.py +++ b/func/minion/codes.py @@ -29,5 +29,5 @@ class AccessToMethodDenied(FuncException): class ModuleNotFoundException(FuncException): pass - + # FIXME: more sub-exceptions maybe diff --git a/func/minion/facts/minion_query.py b/func/minion/facts/minion_query.py index b91bd2a..4178293 100644 --- a/func/minion/facts/minion_query.py +++ b/func/minion/facts/minion_query.py @@ -6,14 +6,14 @@ class FactsMinion(object): That class wil be responsible for: 1. De-serialization of the query by converting it to a Q structure. - + 2. Calling the ( prewritten ) 'facts' modules """ VALID_QUERY_KEYS = ["AND","OR","NOT"] def __init__(self,fact_query=None,method_fact_list=None): """ - Constructor + Constructor @type fact_query : FuncLogicQuery @param fact_query : FuncLogicQuery that will be produced from that class if @@ -35,7 +35,7 @@ class FactsMinion(object): modules... @type q_list : list - @param q_list : Query list + @param q_list : Query list """ q_result = self.__traverse_deserialize(q_list) if not self.fact_query: @@ -57,7 +57,7 @@ class FactsMinion(object): @type q_list : list @param q_list : Query list @type include_results : boolean - @param include_results : As it is known the main purpose + @param include_results : As it is known the main purpose of facts is to return True or False but sometimes we need the real result also included. @@ -81,26 +81,26 @@ class FactsMinion(object): modules. If you need change in calling fact methods that is the place to go . - @type overlord_tuple : Tuple + @type overlord_tuple : Tuple @param overlord_tuple : A tuple in format of (factname__factoperation,compared_value) """ keyword_tuple = overlord_tuple[0].split("__") overlord_value = overlord_tuple[1] - + if len(keyword_tuple) > 1: keyword = keyword_tuple[1] else: keyword = "" fact_name = keyword_tuple[0] - + if not self.method_fact_list.has_key(fact_name): raise MinionQueryError("None existing Fact method or tag required %s "%fact_name) - + fact_value = self.method_fact_list[fact_name]() #we have the result with fact now it is time to resolve it logic_fact = self.keyword_query.resolve(keyword,overlord_value,fact_value) - + #the return part is a tuple (logic_Value which is True or False and fact_name and value dictionary ) return (logic_fact,{fact_name:fact_value}) @@ -109,21 +109,21 @@ class FactsMinion(object): The private recursive part that traverses the incoming overlord list (included with facts) and produces a Q object query object from it. - **(heavy recursive code)Caution any change here + **(heavy recursive code)Caution any change here can make facts not tobe deserialized correctly so that will break the facts API. @type : list @param : List of overlord incoming facts query something like :[NOT,[AND,[a,TRUE,b,FALSE]]] - + @return : Q object returned """ q_object = None #lets try divide and conquer :) #assume that it is [NOT,[AND,[a,TRUE,b,FALSE]]] - + #print "The traverse object at start is ",traverse_object tmp_negated = False tmp_connector ="AND" @@ -155,7 +155,7 @@ class FactsMinion(object): q_object = q_object & Q(tuple(traverse_object[ch:ch+2])) if tmp_negated: q_object = ~q_object - + #print "IN children Q object is ",q_object traverse_object = [] @@ -163,13 +163,13 @@ class FactsMinion(object): #raw_input() if traverse_object: - + #print "The traverse object at end is ",traverse_object #raw_input() for t_o in traverse_object: #print "The traverse object at end is ",t_o #raw_input() - + tmp_q = self.__traverse_deserialize(t_o) #print "I ADD THAT TO THE ALL ",tmp_q #print "WILL BE ADDED TO ",q_object @@ -187,7 +187,7 @@ class FactsMinion(object): return q_object - + FACTS_MODULES = "func/minion/facts/modules/" from func.module_loader import load_modules @@ -211,13 +211,13 @@ def load_fact_methods(abort_on_conflict = False): if res: return {'__conflict__':res} - #get the fact methods + #get the fact methods return fact_methods class QueryKeyword(object): """ - That class is for resolving incoming keywords and + That class is for resolving incoming keywords and doing comparison stuff (the core part of the facts) Ex: query_ob.filter(uname__contains="f9") the contains @@ -237,10 +237,10 @@ class QueryKeyword(object): @type keyword : string @param keyword : The name of the method that will be called Ex: contains,icontains ... - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -252,10 +252,10 @@ class QueryKeyword(object): """ If the overlord value that comes from client is not the same as facts we should do some convention .. - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -267,12 +267,12 @@ class QueryKeyword(object): def keyword_contains(self,overlord_value,fact_value): """ - A simple method for contains, which checks if the + A simple method for contains, which checks if the fact_value contains the overlord_value - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -282,15 +282,15 @@ class QueryKeyword(object): return False else: return True - + def keyword_icontains(self,overlord_value,fact_value): """ - A simple method for contains, which checks if the + A simple method for contains, which checks if the fact_value contains the overlord_value (case insensitive) - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -303,10 +303,10 @@ class QueryKeyword(object): def keyword_iexact(self,overlord_value,fact_value): """ Looks for an iexact match - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -318,10 +318,10 @@ class QueryKeyword(object): def keyword_startswith(self,overlord_value,fact_value): """ A typical python starts with keyword implementation - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -333,10 +333,10 @@ class QueryKeyword(object): def keyword_gt(self,overlord_value,fact_value): """ A greater keyword - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -345,14 +345,14 @@ class QueryKeyword(object): else: return False - + def keyword_gte(self,overlord_value,fact_value): """ A greater keyword - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -361,14 +361,14 @@ class QueryKeyword(object): return True else: return False - + def keyword_lt(self,overlord_value,fact_value): """ A less keyword - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -376,14 +376,14 @@ class QueryKeyword(object): return True else: return False - + def keyword_lte(self,overlord_value,fact_value): """ A less equal keyword - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ @@ -391,14 +391,14 @@ class QueryKeyword(object): return True else: return False - + def keyword_(self,overlord_value,fact_value): """ A == keyword the default behaviour - + @type overlord_value : string @param overlord_value : Users value that he compares with system - + @type fact_value : string @param fact_value : The system fact value """ diff --git a/func/minion/facts/modules/fact_module.py b/func/minion/facts/modules/fact_module.py index 02f9f82..2facb3d 100644 --- a/func/minion/facts/modules/fact_module.py +++ b/func/minion/facts/modules/fact_module.py @@ -5,7 +5,7 @@ class BaseFactModule(object): """ The base fact module which is clever enough to register the facts it is kind - of FuncModule but registers modules with + of FuncModule but registers modules with different convention and style .. Look into other modules to get the idea ... """ @@ -16,11 +16,11 @@ class BaseFactModule(object): def __init__(self): self.__init_log() - + def __init_log(self): log = logger.Logger() self.logger = log.logger - + def register_facts(self,fact_callers,module_name,abort_on_conflict=False): # a dictionary to catch the conflicts """ @@ -30,7 +30,7 @@ class BaseFactModule(object): So it maybe easy to get conflicts (having 2 facts) with tha same name so when that is True it will tell user that something is wrong. There is no need - to worry about the unittests will vcatch if sth bad + to worry about the unittests will vcatch if sth bad happens ... """ conflicts = {} @@ -54,7 +54,6 @@ class BaseFactModule(object): #if there is conflict show it if abort_on_conflict: return conflicts - + def __is_public_valid_method(self,attr): return is_public_valid_method(self, attr, blacklist=['register_facts']) - diff --git a/func/minion/facts/modules/hardware.py b/func/minion/facts/modules/hardware.py index 767278e..80f6505 100644 --- a/func/minion/facts/modules/hardware.py +++ b/func/minion/facts/modules/hardware.py @@ -18,8 +18,8 @@ class HardwareFacts(fact_module.BaseFactModule): errmsg = "Import error while loading smolt for the hardware facts module. Smolt is probably not installed. This module is useless without it." self.logger.warning(errmsg) self.logger.warning("%s" % traceback.format_exc()) - # hmm, what to return... - return + # hmm, what to return... + return hardware = smolt.Hardware() self.host = hardware.host @@ -38,11 +38,11 @@ class HardwareFacts(fact_module.BaseFactModule): Gives back the os name of the system """ return str(self.host.os) - + #for easier acces be creful should be unique os_name.tag = "os" - + def cpu_vendor(self): """ The cpu vendor easy one @@ -51,13 +51,13 @@ class HardwareFacts(fact_module.BaseFactModule): cpu_vendor.tag = "cpuvendor" - + def cpu_model(self): """ Cpu model """ return str(self.host.cpuModel) - + cpu_model.tag = "cpumodel" def kernel_version(self): @@ -65,8 +65,5 @@ class HardwareFacts(fact_module.BaseFactModule): Kernel version """ return str(self.host.kernelVersion) - - kernel_version.tag = "kernel" - - + kernel_version.tag = "kernel" diff --git a/func/minion/facts/overlord_query.py b/func/minion/facts/overlord_query.py index c44af21..d243279 100644 --- a/func/minion/facts/overlord_query.py +++ b/func/minion/facts/overlord_query.py @@ -13,10 +13,10 @@ def display_active_facts(result,with_facts=False): that should be True,but it may make sense for Python API only . """ - + if type(result) != dict: return result - + final_display = {} for minion_name,minion_result in result.iteritems(): @@ -49,7 +49,7 @@ class OverlordQuery(object): if kwargs.has_key('fact_query'): fact_query = kwargs['fact_query'] self.fact_query = fact_query or FuncLogicQuery() - + #print "These are : ",self.overlord #print "These are : ",self.fact_query @@ -69,10 +69,10 @@ class OverlordQuery(object): @type q_object : FuncLogicQuery @param q_object : FuncLogicQuery - + @return : list of fact logic """ - results=[] + results=[] for n in q_object.children: if not type(n) == tuple and not type(n) == list: if n.negated: @@ -85,18 +85,15 @@ class OverlordQuery(object): results.append(n[ch:ch+2]) return results - + def display_active(self,result,with_facts=False): """ Get active ones only - + @type with_facts : boolean @param with_facts : If you want to see the incoming fact values that should be True,but it may make sense for Python API only . """ - - return display_active_facts(result,with_facts) - - + return display_active_facts(result,with_facts) diff --git a/func/minion/facts/query.py b/func/minion/facts/query.py index c1eb08b..c587ef5 100644 --- a/func/minion/facts/query.py +++ b/func/minion/facts/query.py @@ -4,15 +4,15 @@ from copy import deepcopy class BaseFuncQuery(object): """ Is an object that u can pass Q objects to make it fetch - some results about some variables. FuncQuery is kind of + some results about some variables. FuncQuery is kind of orm but not exactly.The exec_query returns True of False that is what is all about. For example passing variables - to FuncQuery like temperature=21,uname="2.6.27.15" will + to FuncQuery like temperature=21,uname="2.6.27.15" will control on target machine if temperature is 21 and uname is the expected if 2 of them are true the result will be true and u will query the rest of the methods u requested """ - + def __init__(self,q_object=None,pull_result=None): self.q = q_object #pull result variable is kind of important @@ -23,7 +23,7 @@ class BaseFuncQuery(object): def __getattribute__(self,name): """ Making it kind of proxy object to the Q object - + @type name : Not specified @param name: Attribute requested """ @@ -31,7 +31,7 @@ class BaseFuncQuery(object): return object.__getattribute__(self, name) except AttributeError,e: return object.__getattribute__(self.q,name) - + def _clone(self,klass=None,q_object=None,pull_result=None): """ When querying filter and other cool methods @@ -47,18 +47,18 @@ class BaseFuncQuery(object): @type pull_result : Method @param pull_result : Copy the reference that actually pulls """ - + if klass is None: klass = self.__class__ c = klass(q_object,pull_result) return c - + def exec_query(self): """ The part that will say if it is True or it is False """ raise Exception("Not implemted method you should subclass and override that method") - + result = property(exec_query) @@ -75,10 +75,10 @@ class BaseFuncQuery(object): tmp_q = self.q & other.q fresh_query = self._clone(q_object=tmp_q,pull_result=self.pull_result) return fresh_query - + def __nonzero__(self): return bool(self.q) - + def __main_filter(self,outside_connector,inside_connector,*args,**kwargs): """ Common OR and AND operation we do. @@ -94,7 +94,7 @@ class BaseFuncQuery(object): current_q = deepcopy(self.q) else: current_q = None - + if not current_q: current_q = temp_q else: @@ -105,7 +105,7 @@ class BaseFuncQuery(object): fresh_query = self._clone(q_object=current_q,pull_result=self.pull_result) return fresh_query - + def filter(self,*args,**kwargs): @@ -114,14 +114,14 @@ class BaseFuncQuery(object): of the time by end user ANDs the args inside. """ return self.__main_filter("AND","AND",*args,**kwargs) - + def filter_or(self,*args,**kwargs): """ The filter method is the one that will be used most of the time by end user ORs the args inside. """ return self.__main_filter("OR","OR",*args,**kwargs) - + def and_and(self,*args,**kwargs): """ AND inside and connect with AND @@ -134,7 +134,7 @@ class BaseFuncQuery(object): """ return self.__main_filter("AND","OR",*args,**kwargs) - + def or_or(self,*args,**kwargs): """ OR inside and connect with OR @@ -156,19 +156,19 @@ class BaseFuncQuery(object): much ... """ temp_q = ~Q(*args,**kwargs) - + if self.q: current_q = deepcopy(self.q) else: current_q = None - + if not self.q: current_q = temp_q else: current_q.add(temp_q,"AND") fresh_query = self._clone(q_object=current_q,pull_result=self.pull_result) return fresh_query - + def set_compexq(self,q_object,connector=None): """ Sometimes we need some complex queries ORed @@ -182,7 +182,7 @@ class BaseFuncQuery(object): current_q.add(q_object,connector) fresh_query = self._clone(q_object=current_q,pull_result=self.pull_result) return fresh_query - + def __str__(self): return str(self.q) @@ -205,7 +205,7 @@ class FuncLogicQuery(BaseFuncQuery): self.fact_dict = {} if not self.q: raise Exception("You should set up some query object before executing it") - + return self.__main_traverse(self.q) result = property(exec_query) @@ -217,7 +217,7 @@ class FuncLogicQuery(BaseFuncQuery): @param node : Q node """ - logic_results=[] + logic_results=[] for n in node.children: if not type(n) == tuple and not type(n) == list: result = self.__traverse_query(n) @@ -227,7 +227,7 @@ class FuncLogicQuery(BaseFuncQuery): if not self.pull_result: logic_results.append(n[1]) else: - logic_pull = self.pull_result(n) + logic_pull = self.pull_result(n) #append the result if True or False #print "What i append for logic ? ",logic_pull[0] logic_results.append(logic_pull[0]) @@ -239,12 +239,12 @@ class FuncLogicQuery(BaseFuncQuery): def __main_traverse(self,q_ob): """ Collects the final stuff - + @param q_ob : Q node """ tmp_res = self.__traverse_query(q_ob) return self.logic_operation(q_ob,tmp_res) - + def logic_operation(self,node,logic_list): """ Just computes the logic of current list diff --git a/func/minion/facts/query_utils.py b/func/minion/facts/query_utils.py index 780d842..dadff38 100644 --- a/func/minion/facts/query_utils.py +++ b/func/minion/facts/query_utils.py @@ -38,5 +38,3 @@ class Q(tree.Node): obj = deepcopy(self) obj.negate() return obj - - diff --git a/func/minion/facts/tree.py b/func/minion/facts/tree.py index c02559e..1ac9e3a 100644 --- a/func/minion/facts/tree.py +++ b/func/minion/facts/tree.py @@ -116,4 +116,4 @@ class Node(object): """ self.children = [self._new_instance(self.children, self.connector, not self.negated)] - self.connector = self.default + self.connector = self.default diff --git a/func/minion/func_arg.py b/func/minion/func_arg.py index 3d78b5f..d304cf6 100644 --- a/func/minion/func_arg.py +++ b/func/minion/func_arg.py @@ -11,7 +11,7 @@ ## class ArgCompatibility(object): - """ + """ That class is going to test if the module that was created by module writer if he/she obeys to the rules we put here """ @@ -42,7 +42,7 @@ class ArgCompatibility(object): @param : get_args_result : The dict with all method related info """ self.__args_to_check = get_args_result - + #what options does each of the basic_types have : self.__valid_args={ 'int':('range','min','max',), @@ -58,7 +58,7 @@ class ArgCompatibility(object): def _is_type_options_compatible(self,argument_dict): """ Checks the method's argument_dict's options and looks inside - self.__valid_args to see if the used option is there + self.__valid_args to see if the used option is there @param : argument_dict : current argument to check @return : True of raises IncompatibleTypesException @@ -67,14 +67,14 @@ class ArgCompatibility(object): #did module writer add a key 'type' if not argument_dict.has_key('type') or not self.__valid_args.has_key(argument_dict['type']): raise IncompatibleTypesException("%s is not in valid options,possible ones are :%s"%(argument_dict['type'],str(self.__valid_args))) - + #we need some specialization about if user has defined options #there is no need for using validator,min_lenght,max_length if argument_dict.has_key('options'): for arg_option in argument_dict.keys(): if arg_option!='options' and arg_option in self.__valid_args['string']: raise IncompatibleTypesException('The options keyword should be used alone in a string cant be used with min_length,max_length,validator together') - + #if range keyword is used into a int argument the others shouldnt be there if argument_dict.has_key('range'): if len(argument_dict['range'])!=2: @@ -85,14 +85,14 @@ class ArgCompatibility(object): for arg_option in argument_dict.keys(): if arg_option!='range' and arg_option in self.__valid_args['int']: raise IncompatibleTypesException('The options range should be used alone into a int argument') - + # we will use it everytime so not make lookups the_type = argument_dict['type'] from itertools import chain #may i use chain ? for key,value in argument_dict.iteritems(): - + if key == "type": continue if key not in chain(self.__valid_args[the_type],self.__common_options): @@ -103,20 +103,20 @@ class ArgCompatibility(object): def _is_basic_types_compatible(self,type_dict): """ - Validates that if the types that were submitted with + Validates that if the types that were submitted with get_method_args were compatible with our format above in __basic_types - @param : type_dict : The type to examine + @param : type_dict : The type to examine @return : True or raise IncompatibleTypesException Exception """ #print "The structure we got is %s:"%(type_dict) for key,value in type_dict.iteritems(): - #do we have that type + #do we have that type if not self.__basic_types.has_key(key): raise IncompatibleTypesException("%s not in the basic_types"%key) - + #if type matches and dont match default #print "The key: %s its value %s and type %s"%(key,value,type(value)) if key!='default' and type(value)!=type(self.__basic_types[key]): @@ -128,19 +128,19 @@ class ArgCompatibility(object): """ Method inspects the method arguments and checks if the user has registered all the arguments succesfully and also adds a - 'order' keyword to method arguments to + 'order' keyword to method arguments to """ import inspect from itertools import chain #get the arguments from real object we have [args],*arg,**kwarg,[defaults] #tmp_arguments=inspect.getargspec(getattr(cls,method_name)) - + #overriden args is something i created it is a hack ! tmp_arguments = getattr(cls, method_name).overriden_args check_args=[arg for arg in chain(tmp_arguments[0],tmp_arguments[1:3]) if arg and arg!='self'] #raise Exception("The check_args are like %s"%str(check_args)) - #print "The arguments taken from the inspect are :",check_args - #the size may change of the hash so should a copy of it + #print "The arguments taken from the inspect are :",check_args + #the size may change of the hash so should a copy of it copy_arguments = arguments.copy() for compare_arg in copy_arguments.iterkeys(): if not compare_arg in check_args: @@ -155,18 +155,18 @@ class ArgCompatibility(object): """ Validates the output for minion module's get_method_args method - + The structure that is going to be validated is in that format : - + { method_name1 : {'args':{...}, 'description':"wowo"}, method_name12 : {...} } - + @return : True or raise IncompatibleTypesException Exception """ - + for method in self.__args_to_check.iterkeys(): #here we got args or description part #check if user did submit something not in the __method_options @@ -190,7 +190,7 @@ class ArgCompatibility(object): class IncompatibleTypesException(Exception): """ - Raised when we assign some values that breaksour rules + Raised when we assign some values that breaksour rules @see ArgCompatibility class for allowed situations """ def __init__(self, value=None): @@ -225,6 +225,6 @@ class NonExistingMethodRegistered(IncompatibleTypesException): class ArgumentRegistrationError(IncompatibleTypesException): """ When user forgets to register soem of the arguments in the list - or adds some argument that is not there + or adds some argument that is not there """ pass diff --git a/func/minion/modules/bridge.py b/func/minion/modules/bridge.py index fe35281..fc072e2 100644 --- a/func/minion/modules/bridge.py +++ b/func/minion/modules/bridge.py @@ -100,7 +100,7 @@ class Bridge(func_module.FuncModule): if vifpattern.match(elements[0]) and listvif == False: continue retlist[curbr].append(elements[0]) - + return retlist def list_permanent(self): @@ -163,7 +163,7 @@ class Bridge(func_module.FuncModule): # is orphaned. retlist[brname].append(ifname) return retlist - + def add_bridge(self, brname): """ Creates a bridge @@ -196,7 +196,7 @@ class Bridge(func_module.FuncModule): netmask -- Netmask for this bridge (string) gateway -- Gateway address for this bridge (string) """ - + if brname not in self.options.ignorebridges: filename = "/etc/sysconfig/network-scripts/ifcfg-%s" % brname fp = open(filename, "w") @@ -309,7 +309,7 @@ class Bridge(func_module.FuncModule): else: returncode = -1 return returncode - + def delete_interface(self, brname, ifname): """ Deletes an interface from a bridge @@ -389,7 +389,7 @@ class Bridge(func_module.FuncModule): def delete_all_interfaces_permanent(self, brname): """ Permanently deletes all interfaces from a bridge - + Keyword arguments: brname -- Bridge name (string, ex: "br0") """ @@ -556,4 +556,3 @@ class Bridge(func_module.FuncModule): """ return self.updown_bridge(brname, 0) - diff --git a/func/minion/modules/certmastermod.py b/func/minion/modules/certmastermod.py index 41f093c..a1f34f6 100644 --- a/func/minion/modules/certmastermod.py +++ b/func/minion/modules/certmastermod.py @@ -33,7 +33,7 @@ class CertMasterModule(func_module.FuncModule): """ cm = certmaster.CertMaster() return cm.get_csrs_waiting() - + def get_signed_certs(self): """ Returns a list of all signed certs on this minion @@ -48,7 +48,7 @@ class CertMasterModule(func_module.FuncModule): list_of_hosts = self.__listify(list_of_hosts) cm = certmaster.CertMaster() for x in list_of_hosts: - cm.sign_this_csr(x) + cm.sign_this_csr(x) return True def cleanup_hosts(self, list_of_hosts): @@ -58,7 +58,7 @@ class CertMasterModule(func_module.FuncModule): list_of_hosts = self.__listify(list_of_hosts) cm = certmaster.CertMaster() for x in list_of_hosts: - cm.remove_this_cert(x) + cm.remove_this_cert(x) return True def peering_enabled(self): @@ -121,7 +121,7 @@ class CertMasterModule(func_module.FuncModule): def register_method_args(self): """ - Export certmaster module + Export certmaster module """ list_of_hosts = { diff --git a/func/minion/modules/command.py b/func/minion/modules/command.py index f25b751..919a487 100644 --- a/func/minion/modules/command.py +++ b/func/minion/modules/command.py @@ -42,7 +42,7 @@ class Command(func_module.FuncModule): if os.access(command, os.X_OK): return True - return False + return False def register_method_args(self): """ diff --git a/func/minion/modules/confmgt_augeas.py b/func/minion/modules/confmgt_augeas.py index 3438fd9..669fd3c 100644 --- a/func/minion/modules/confmgt_augeas.py +++ b/func/minion/modules/confmgt_augeas.py @@ -12,7 +12,7 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import func_module -from os import path as ospath,getenv as osgetenv +from os import path as ospath,getenv as osgetenv from time import strftime def lstripstr(the_string,the_prefix): @@ -63,11 +63,11 @@ with the help of Augeas, a configuration API (cf http://augeas.net)""" # yes, entryPath.rstrip('/')+'/' is really needed (i.e. entryPath=/) path=(hierarchy+entryPath.rstrip('/')+'/'+param).rstrip('/') try: - matchtest=aug.match(path) + matchtest=aug.match(path) except Exception, e: return str(e) if matchtest: try: - pvalue=aug.get(path) + pvalue=aug.get(path) #aug.close() except Exception, e: return str(e) else: @@ -154,7 +154,7 @@ with the help of Augeas, a configuration API (cf http://augeas.net)""" pvalue='(none)' nodes.append([ospath.basename(match),pvalue]) except Exception, e: return str(e) - + #try: # aug.close() #except Exception, e: return str(e) @@ -165,7 +165,7 @@ with the help of Augeas, a configuration API (cf http://augeas.net)""" # print is a reserved word so we use printconf instead def printconf(self,entryPath,hierarchy='/files'): """Print all tree children nodes from the path provided, -with the help of Augeas, a configuration API (cf http://augeas.net)""" +with the help of Augeas, a configuration API (cf http://augeas.net)""" path=hierarchy+entryPath try: from augeas import Augeas @@ -186,13 +186,13 @@ with the help of Augeas, a configuration API (cf http://augeas.net)""" except Exception, e: return str(e) path=(hierarchy+entryPath.rstrip('/')+'/'+param).rstrip('/') - + try: result=aug.remove(path) #aug.close() except Exception, e: return str(e) # Here is a little workaround for a bug in save for augeas. - # In the future this should not be necessary anymore. + # In the future this should not be necessary anymore. try: aug.save() except: @@ -205,7 +205,7 @@ with the help of Augeas, a configuration API (cf http://augeas.net)""" msg = 'Invalid node' else: msg = repr(result)+' node(s) removed.' - return msg + return msg def getenv(self,varname): """Get an environment variable.""" @@ -217,7 +217,7 @@ with the help of Augeas, a configuration API (cf http://augeas.net)""" def backup(self,entryPath): """Backup a file with a timestamp. Cautious before applying modifications on a configuration file.""" try: - import shutil + import shutil except Exception, e: return str(e) backupPath=entryPath+'.'+strftime('%Y%m%d-%H%M') try: @@ -227,8 +227,8 @@ with the help of Augeas, a configuration API (cf http://augeas.net)""" else: msg='Backup file '+backupPath+' already exists' except (OSError, IOError), e: return str(e) - return msg - + return msg + def register_method_args(self): """ @@ -389,4 +389,3 @@ with the help of Augeas, a configuration API (cf http://augeas.net)""" 'description':"Backup a file with a timestamp." } } - diff --git a/func/minion/modules/copyfile.py b/func/minion/modules/copyfile.py index e9411ab..61c6a4f 100644 --- a/func/minion/modules/copyfile.py +++ b/func/minion/modules/copyfile.py @@ -38,7 +38,7 @@ class CopyFile(func_module.FuncModule): thissum = hashlib.new('sha1') thissum.update(blob) return thissum.hexdigest() - + def checksum(self, thing): CHUNK=2**16 diff --git a/func/minion/modules/delegation.py b/func/minion/modules/delegation.py index b8d6c8d..d77eaca 100644 --- a/func/minion/modules/delegation.py +++ b/func/minion/modules/delegation.py @@ -21,11 +21,11 @@ DIRECT = False DELEGATED = True class DelegationModule(func_module.FuncModule): - + version = "0.0.1" api_version = "0.0.1" description = "Minion-side module to support delegation on sub-Overlords." - + def run(self,module,method,args,delegation_list,async,nforks): """ Delegates commands down the path of delegation @@ -33,11 +33,11 @@ class DelegationModule(func_module.FuncModule): """ result_dict = {} job_id_list = [] - - #separate list passed to us into minions we can call directly and + + #separate list passed to us into minions we can call directly and #further delegation paths (single_paths, grouped_paths) = dtools.group_paths(delegation_list) - + #run delegated calls for group in grouped_paths.keys(): overlord = fc.Overlord(group, @@ -51,7 +51,7 @@ class DelegationModule(func_module.FuncModule): async, nforks) if async: - job_id_list.append([overlord, + job_id_list.append([overlord, delegation_results, group, True]) @@ -62,10 +62,10 @@ class DelegationModule(func_module.FuncModule): result_dict.update(delegation_results) else: result_dict.update(delegation_results[group]) - + #run direct calls for minion in single_paths: - overlord = fc.Overlord(minion, + overlord = fc.Overlord(minion, async=async, nforks=nforks) overlord_module = getattr(overlord,module) @@ -77,7 +77,7 @@ class DelegationModule(func_module.FuncModule): False]) else: result_dict.update(results) - + #poll async calls while len(job_id_list) > 0: for job in job_id_list: @@ -104,5 +104,5 @@ class DelegationModule(func_module.FuncModule): result_dict.update(results) job_id_list.remove(job) time.sleep(0.1) #pause a bit so that we don't flood our minions - - return result_dict + + return result_dict diff --git a/func/minion/modules/echo.py b/func/minion/modules/echo.py index b61a199..6238bbf 100644 --- a/func/minion/modules/echo.py +++ b/func/minion/modules/echo.py @@ -40,30 +40,30 @@ class EchoTest(func_module.FuncModule): Run a list """ return command - - + + def run_list_star(self,*command): """ Run a star list :) """ return command - + def run_hash(self,command): """ Run hash """ return command - - - + + + def run_boolean(self,command): """ Run boolean """ return command - + def run_str_log(self,command): import time @@ -74,7 +74,7 @@ class EchoTest(func_module.FuncModule): self.run_str_log.logger.info("Calling method with counter is %d"%i) #log the progress so other apps can poll for it self.run_str_log.logger.progress(i,50) - + return command def register_method_args(self): @@ -118,7 +118,7 @@ class EchoTest(func_module.FuncModule): 'type':'string', 'optional':False, 'options':['first_option','second_option','third_option'] - }, + }, }, 'description':'Getting the status of the service_name' }, @@ -153,7 +153,7 @@ class EchoTest(func_module.FuncModule): }, 'description':'Returns back a hash' }, - + 'run_boolean':{ 'args': diff --git a/func/minion/modules/fact.py b/func/minion/modules/fact.py index b2d87cf..469357a 100644 --- a/func/minion/modules/fact.py +++ b/func/minion/modules/fact.py @@ -9,13 +9,13 @@ class FactsModule(func_module.FuncModule): version = "0.0.1" api_version = "0.0.1" description = "Has some useful about Facts module" - + def list_fact_modules(self): """ List facts that are availible in that system """ return minion_query.load_facts_modules().keys() - + def list_fact_methods(self,abort_on_conflict=False): """ List facts that are availible in that system @@ -30,7 +30,7 @@ class FactsModule(func_module.FuncModule): """ Show some info about fact module """ - + for name,module in minion_query.load_facts_modules().iteritems(): if name == module_name: return { @@ -44,7 +44,7 @@ class FactsModule(func_module.FuncModule): """ Display info about fact method """ - + for name,method in minion_query.load_fact_methods().iteritems(): if name == method_name: return { @@ -55,13 +55,13 @@ class FactsModule(func_module.FuncModule): def call_fact(self,method_name): """ - Sometimes we may need to get some of the facts live + Sometimes we may need to get some of the facts live """ for name,method in minion_query.load_fact_methods().iteritems(): if name == method_name: - return method() + return method() return {} - + def grep(self, word): """ Get some info about facts @@ -70,20 +70,19 @@ class FactsModule(func_module.FuncModule): self.list_fact_modules:[], self.list_fact_methods:[] } - + #search in modules for m in self.list_fact_modules(): if m.lower().find(word)!=-1: result[self.list_fact_modules].append(m) - + #search in methods for m in self.list_fact_methods(): if m.lower().find(word)!=-1: val = self.call_fact(m) result[self.list_fact_methods].append("%s: %s" % (m,val)) - + #the final collected stuff here return result grep = func_module.findout(grep) - diff --git a/func/minion/modules/filetracker.py b/func/minion/modules/filetracker.py index bfa6208..d4f7f3a 100644 --- a/func/minion/modules/filetracker.py +++ b/func/minion/modules/filetracker.py @@ -62,7 +62,7 @@ class FileTracker(func_module.FuncModule): def __save(self, filehash): """ Write data structure to file. - """ + """ config = open(CONFIG_FILE, "w+") for (path, scan_mode) in filehash.iteritems(): @@ -70,7 +70,7 @@ class FileTracker(func_module.FuncModule): config.close() #========================================================== - + def track(self, file_name_globs, full_scan=0, recursive=0, files_only=0): """ Adds files to keep track of. @@ -138,7 +138,7 @@ class FileTracker(func_module.FuncModule): for use by func-inventory. If you are writting another software application, using flatten=False will prevent the need to parse the returns. """ - + # XMLRPC feeds us strings from the CLI when it shouldn't flatten = int(flatten) checksum_enabled = int(checksum_enabled) @@ -178,7 +178,7 @@ class FileTracker(func_module.FuncModule): # ------ what we return depends on flatten if flatten: - this_result = "%s: mode=%s mtime=%s uid=%s gid=%s md5sum=%s\n" % (file_name,mode,mtime,uid,gid,hash) + this_result = "%s: mode=%s mtime=%s uid=%s gid=%s md5sum=%s\n" % (file_name,mode,mtime,uid,gid,hash) else: this_result = [file_name,mode,mtime,uid,gid,hash] @@ -191,11 +191,11 @@ class FileTracker(func_module.FuncModule): else: this_result.append(data) tracked_file.close() - + if os.path.isdir(file_name): if not file_name.endswith("/"): file_name = file_name + "/" - files = glob.glob(file_name + "*") + files = glob.glob(file_name + "*") if flatten: this_result = this_result + "*** FILES ***\n" + "\n".join(files) + "\n*** END FILES ***\n\n" else: @@ -210,26 +210,26 @@ class FileTracker(func_module.FuncModule): return results #========================================================== - + def grep(self, word): """ Some search utility about tracked files """ results = {self.inventory:[]} tracked_files = self.inventory() - + if type(tracked_files) == str and tracked_files.lower().find(word)!=-1: results[self.inventory].append(tracked_files) - + else: for res in tracked_files: if res.lower().find(word)!=-1: results[self.inventory].append(res) - + return results grep = func_module.findout(grep) - - + + def __sumfile(self, fobj): """ Returns an md5 hash for an object with read() method. diff --git a/func/minion/modules/func_getargs.py b/func/minion/modules/func_getargs.py index e313c76..b3ff70e 100644 --- a/func/minion/modules/func_getargs.py +++ b/func/minion/modules/func_getargs.py @@ -14,21 +14,21 @@ import sys import inspect import func_module -class getArgs(func_module.FuncModule): - version = "0.0.1" - api_version = "0.0.1" +class getArgs(func_module.FuncModule): + version = "0.0.1" + api_version = "0.0.1" description = "Get args of methods of the class in a func module" - def get(self, modname, methodname): + def get(self, modname, methodname): """Returns a list of args for the specified method in the class of a func module. This is useful when register_method_args is not defined (or not properly) - """ + """ vtuple=pv() pyver=vtuple[0]+'.'+vtuple[1] - sys.path.append('/usr/lib/python'+pyver+'/site-packages/func/minion/modules/') + sys.path.append('/usr/lib/python'+pyver+'/site-packages/func/minion/modules/') the_mod=__import__(modname) - name,data=inspect.getmembers(the_mod, inspect.isclass)[0] + name,data=inspect.getmembers(the_mod, inspect.isclass)[0] the_class=modname+'.'+name c=getattr(the_mod, name) @@ -55,4 +55,3 @@ class getArgs(func_module.FuncModule): 'description':'Returns a list with the args of the method you checked' } } - diff --git a/func/minion/modules/func_module.py b/func/minion/modules/func_module.py index e02d4a6..5ea5eb7 100644 --- a/func/minion/modules/func_module.py +++ b/func/minion/modules/func_module.py @@ -25,14 +25,14 @@ from func import utils def log_all(fn): """ That decorator will set a logger to a method - which will be associated with its job_id so + which will be associated with its job_id so will log only during when it is running,cool:) """ def wrapper(*args): - + if utils.should_log(args): logger = LogFactory.get_instance(app_name=args[len(args)-1]['job_id']) - + #remove job_id from it args = list(args) args.pop() @@ -41,7 +41,7 @@ def log_all(fn): setattr(wrapper,"logger",logger) return fn(*args) - + #a hack for get_arg_methods wrapper.overriden_args = inspect.getargspec(fn) try: @@ -64,13 +64,13 @@ class DecorateLogMeta(type): if type(attribute) == FunctionType and not attributeName.startswith("_"): attribute = log_all(attribute) newClassDict[attributeName] = attribute - + return type.__new__(meta, classname, bases, newClassDict) class FuncModule(object): - + __metaclass__ = DecorateLogMeta # the version is meant to version = "0.0.0" @@ -162,7 +162,7 @@ class FuncModule(object): """ tmp_arg_dict = self.register_method_args() - #if it is not implemeted then return empty stuff + #if it is not implemeted then return empty stuff if not tmp_arg_dict: return {} @@ -170,7 +170,7 @@ class FuncModule(object): for method in tmp_arg_dict.iterkeys(): if not hasattr(self,method): raise NonExistingMethodRegistered("%s is not in %s "%(method,self.__class__.__name__)) - + #create argument validation instance self.arg_comp = ArgCompatibility(tmp_arg_dict) #see if all registered arguments are there @@ -179,7 +179,7 @@ class FuncModule(object): #see if the options that were used are OK.. self.arg_comp.validate_all() - return tmp_arg_dict + return tmp_arg_dict def register_method_args(self): """ @@ -193,7 +193,7 @@ class FuncModule(object): # to know they didnt implement it return {} - + def grep(self,word): """ An useful utility for searching a specified @@ -221,6 +221,3 @@ def findout(fn): return {} return _fn_arg - - - diff --git a/func/minion/modules/hardware.py b/func/minion/modules/hardware.py index 0937d56..8b7cce5 100644 --- a/func/minion/modules/hardware.py +++ b/func/minion/modules/hardware.py @@ -69,7 +69,7 @@ class HardwareModule(func_module.FuncModule): def grep(self,word): """ - Find something in hardware info + Find something in hardware info """ result = {self.info:[]} hw_info = self.info() @@ -80,11 +80,11 @@ class HardwareModule(func_module.FuncModule): for hw_k,hw_v in hw_info.iteritems(): if hw_k.lower().find(word)!=-1: result[self.info].append({hw_k:hw_v}) - #we should see if the value is + #we should see if the value is elif type(hw_v)==str and hw_v.lower().find(word)!=-1: result[self.info].append({hw_k:hw_v}) elif type(hw_v)==list: - #as it si known the hw_info has a devices + #as it si known the hw_info has a devices #in its final data and it is in format of: #[{key:val}] so should check it also for device in hw_v: @@ -93,7 +93,7 @@ class HardwareModule(func_module.FuncModule): result[self.info].append({d_k:d_v}) elif d_v.lower().find(word)!=-1: result[self.info].append({d_k:d_v}) - + #get the final result return result grep = func_module.findout(grep) @@ -118,7 +118,7 @@ class HardwareModule(func_module.FuncModule): errmsg = _("Import error while loading smolt module. Smolt is probably not installed. This method is useless without it.") self.logger.warning(errmsg) self.logger.warning("%s" % traceback.format_exc()) - # hmm, what to return... + # hmm, what to return... return [] hardware = smolt.Hardware() @@ -196,4 +196,3 @@ class HardwareModule(func_module.FuncModule): } # ================================= - diff --git a/func/minion/modules/httpd.py b/func/minion/modules/httpd.py index 84cbc2c..dc3f725 100644 --- a/func/minion/modules/httpd.py +++ b/func/minion/modules/httpd.py @@ -93,7 +93,7 @@ class Httpd(func_module.FuncModule): 'description':'True if the server is an ssl server' } }, - + 'description':'Check the httpd status on a server' } diff --git a/func/minion/modules/iptables/common.py b/func/minion/modules/iptables/common.py index ab65ae0..ff42a44 100644 --- a/func/minion/modules/iptables/common.py +++ b/func/minion/modules/iptables/common.py @@ -42,7 +42,7 @@ def check_policy(chain): return False except: return False - + def set_policy(chain, policy): return call_iptables("-P %s %s" % (chain, policy) ) diff --git a/func/minion/modules/iptables/port.py b/func/minion/modules/iptables/port.py index 3d3902b..7a6b917 100644 --- a/func/minion/modules/iptables/port.py +++ b/func/minion/modules/iptables/port.py @@ -31,7 +31,7 @@ class Port(func_module.FuncModule): * Drop all incoming traffic to local TCP port 80: > func '*' call iptables.port drop_from 80 * Drop all incomming traffic to local UDP port 53 from 192.168.0.0/24: - > func '*' call iptables.port drop_from 80 192.168.0.0/24 udp + > func '*' call iptables.port drop_from 80 192.168.0.0/24 udp """ dir=parse_dir(dir) clear_all("-D INPUT -p %s --%sport %s -s %s -j ACCEPT" % (prot, dir, port, ip) ) @@ -49,7 +49,7 @@ class Port(func_module.FuncModule): * Reject all incoming traffic to local TCP port 80: > func '*' call iptables.port reject_from 80 * Reject incomming traffic to local UDP port 53 from 192.168.0.0/24: - > func '*' call iptables.port reject_from 80 192.168.0.0/24 udp + > func '*' call iptables.port reject_from 80 192.168.0.0/24 udp """ dir=parse_dir(dir) clear_all("-D INPUT -p %s --%sport %s -s %s -j ACCEPT" % (prot, dir, port, ip) ) @@ -67,7 +67,7 @@ class Port(func_module.FuncModule): * Accept all incoming traffic to local TCP port 80: > func '*' call iptables.port accept_from 80 * Accept incomming traffic to local UDP port 53 from 192.168.0.0/24: - > func '*' call iptables.port accept_from 80 192.168.0.0/24 udp + > func '*' call iptables.port accept_from 80 192.168.0.0/24 udp """ dir=parse_dir(dir) clear_all("-D INPUT -p %s --%sport %s -s %s -j DROP" % (prot, dir, port, ip) ) @@ -171,7 +171,7 @@ class Port(func_module.FuncModule): 'prot':prot, 'dir':dir, 'port':port - + } }, 'accept_from':{'args': @@ -180,7 +180,7 @@ class Port(func_module.FuncModule): 'prot':prot, 'dir':dir, 'port':port - + } }, 'drop_to':{'args': @@ -189,7 +189,7 @@ class Port(func_module.FuncModule): 'prot':prot, 'dir':dir, 'port':port - + } }, 'reject_to':{'args': @@ -198,7 +198,7 @@ class Port(func_module.FuncModule): 'prot':prot, 'dir':dir, 'port':port - + } }, 'accept_to':{'args': @@ -207,10 +207,10 @@ class Port(func_module.FuncModule): 'prot':prot, 'dir':dir, 'port':port - + } }, - + } def parse_dir(dir): diff --git a/func/minion/modules/jboss.py b/func/minion/modules/jboss.py index e5d12c5..77f090a 100644 --- a/func/minion/modules/jboss.py +++ b/func/minion/modules/jboss.py @@ -1,5 +1,5 @@ # -# Copyright 2008 +# Copyright 2008 # Luca Foppiano <lfoppiano@xxxxxxxxxxxxx> # Simone Pucci <spucci@xxxxxxxxxxxxx> # Byte-code srl www.byte-code.com @@ -28,15 +28,15 @@ class JBoss(func_module.FuncModule): version = "0.0.3" api_version = "0.0.2" description = "JBoss monitoring and control module" - + def status(self): """ Get jboss information (instance name, ports, bind address, pid) - """ + """ processo = process.ProcessModule() - results = processo.info("ax") - + results = processo.info("ax") + logging = logger.Logger().logger output = [] for items in results: @@ -73,7 +73,7 @@ class JBoss(func_module.FuncModule): except: address_port = None pid_name = None - + if address_port != None: try: address = address_port.split(":")[0] @@ -87,7 +87,7 @@ class JBoss(func_module.FuncModule): pid = int(pid_name.split("/")[0]) except: pid = None - + if pid != None: for data in output: if data[0] == pid: @@ -106,8 +106,8 @@ class JBoss(func_module.FuncModule): Return values: - instance up but not listen = (-1, instances with problem) - - OK = (0, []) - """ + - OK = (0, []) + """ if(status == None): data = self.status() else: @@ -119,7 +119,7 @@ class JBoss(func_module.FuncModule): if len(item[3]) == 0: code = -1 result.append(item) - + return (code, result) @@ -139,7 +139,7 @@ class JBoss(func_module.FuncModule): for ports in item[3]: if port == ports: founded.append(item) - + return founded @@ -157,7 +157,7 @@ class JBoss(func_module.FuncModule): for item in data: if item[1] == instance: founded.append(item) - + return founded def search_by_address(self, address, status=None): @@ -174,7 +174,7 @@ class JBoss(func_module.FuncModule): for item in data: if item[2] == address: founded.append(item) - + return founded def static_configuration(self): @@ -183,10 +183,10 @@ class JBoss(func_module.FuncModule): configuration file. ''' return (self.options.jboss_home, self.options.jboss_address, self.options.jboss_instance) - + def start(self): ''' - Start a jboss instance + Start a jboss instance ''' logging = logger.Logger().logger @@ -196,7 +196,7 @@ class JBoss(func_module.FuncModule): jboss_run_path=self.options.jboss_home+"/bin/run.sh" status=self.status() - + if len(self.search_by_address(address=address, status=status)) != 0: return (-1,"Another instances listening on this address, ") @@ -208,14 +208,14 @@ class JBoss(func_module.FuncModule): comm = command.Command() comm.run(launcher) - + return "OK, instance "+ instance +" started on address "+address def stop(self): ''' - Stop a jboss instance, It suppose you are using - use standard JNDI port 1099. + Stop a jboss instance, It suppose you are using + use standard JNDI port 1099. ''' logging = logger.Logger().logger @@ -227,7 +227,7 @@ class JBoss(func_module.FuncModule): if len(data) == 0: return (-1, "Istance on "+ address +" not running") - + launcher ="sh "+str(jboss_sd_path)+" -s jnp://"+address+":1099 &" logging.info(launcher) @@ -240,6 +240,4 @@ class JBoss(func_module.FuncModule): class Config(BaseConfig): jboss_home=Option('/var/lib/jboss') jboss_instance=Option('default') - jboss_address=Option('127.0.0.1') - - + jboss_address=Option('127.0.0.1') diff --git a/func/minion/modules/jobs.py b/func/minion/modules/jobs.py index 1d91187..7dc2c98 100644 --- a/func/minion/modules/jobs.py +++ b/func/minion/modules/jobs.py @@ -26,12 +26,12 @@ class xreverse: def __init__(self, file_object, buf_size=1024*8): self.fo = fo = file_object fo.seek(0, 2) # go to the end of the file - self.pos = fo.tell() # where we are + self.pos = fo.tell() # where we are self.buffer = '' # data buffer self.lbuf = [] # buffer for parsed lines self.done = 0 # we've read the last line self.jump = -1 * buf_size - + while 1: try: fo.seek(self.jump, 1) except IOError: fo.seek(0) @@ -78,7 +78,7 @@ class xreverse: self.done = 1 return self.buffer + '\n' - + class JobsModule(func_module.FuncModule): @@ -93,13 +93,13 @@ class JobsModule(func_module.FuncModule): Wiki details on async invocation for more information. """ return jobthing.job_status(job_id) - + def tail_output(self,minion_job_id): """ A tail method which will tail the log files that will track their output .... """ - + from func.minion import sub_process from certmaster.config import read_config from func.commonconfig import FuncdConfig @@ -107,8 +107,8 @@ class JobsModule(func_module.FuncModule): import os import subprocess - - + + config = read_config(config_file, FuncdConfig) method_log_dir = config.method_log_dir method_log_file = os.path.join(method_log_dir,minion_job_id) @@ -118,13 +118,13 @@ class JobsModule(func_module.FuncModule): stderr=subprocess.PIPE, shell = False, ) - + return cmd.communicate() - + def get_progress(self,minion_job_id): """ - Get the log file and parse the progress part + Get the log file and parse the progress part to be polled on overlord """ from certmaster.config import read_config @@ -136,7 +136,7 @@ class JobsModule(func_module.FuncModule): config = read_config(config_file, FuncdConfig) method_log_dir = config.method_log_dir method_log_file = os.path.join(method_log_dir,minion_job_id) - + reco=re.compile("Progress report (\d+)/(\d+) completed") fo = file(method_log_file) for line in xreverse(fo): @@ -148,4 +148,3 @@ class JobsModule(func_module.FuncModule): #that tells that we couldnt found any report there return(0,0) - diff --git a/func/minion/modules/mount.py b/func/minion/modules/mount.py index f871b38..3e54769 100644 --- a/func/minion/modules/mount.py +++ b/func/minion/modules/mount.py @@ -26,7 +26,7 @@ class MountModule(func_module.FuncModule): def list(self): cmd = sub_process.Popen(["/bin/cat", "/proc/mounts"], executable="/bin/cat", stdout=sub_process.PIPE, shell=False, close_fds=True) data = cmd.communicate()[0] - + mounts = [] lines = [l for l in data.split("\n") if l] #why must you append blank crap? @@ -43,7 +43,7 @@ class MountModule(func_module.FuncModule): def mount(self, device, dir, type="auto", options=None, createdir=False): cmdline = ["/bin/mount", "-t", type] - if options: + if options: cmdline.append("-o") cmdline.append(options) cmdline.append(device) @@ -58,7 +58,7 @@ class MountModule(func_module.FuncModule): return True else: return False - + def umount(self, dir, killall=False, force=False, lazy=False): # succeed if its not mounted if not os.path.ismount(dir): @@ -84,14 +84,14 @@ class MountModule(func_module.FuncModule): def inventory(self, flatten=True): return self.list() - + def grep(self,word): """ Get some info about mounted devices """ results = {self.list:[]} list_res = self.list() - + if list_res: for list_dict in list_res: for m_k,m_v in list_dict.iteritems(): @@ -99,8 +99,8 @@ class MountModule(func_module.FuncModule): results[self.list].append({m_k:m_v}) return results grep = func_module.findout(grep) - - + + def register_method_args(self): """ diff --git a/func/minion/modules/nagios-check.py b/func/minion/modules/nagios-check.py index 3c5aa06..c080e56 100644 --- a/func/minion/modules/nagios-check.py +++ b/func/minion/modules/nagios-check.py @@ -28,7 +28,7 @@ class Nagios(func_module.FuncModule): """ nagios_path='/usr/lib/nagios/plugins' command = '%s/%s' % (nagios_path, check_command) - + cmdref = sub_process.Popen(command.split(),stdout=sub_process.PIPE,stderr=sub_process.PIPE, shell=False, close_fds=True) data = cmdref.communicate() return (cmdref.returncode, data[0], data[1]) diff --git a/func/minion/modules/netapp/common.py b/func/minion/modules/netapp/common.py index 9f664b0..cd1551f 100644 --- a/func/minion/modules/netapp/common.py +++ b/func/minion/modules/netapp/common.py @@ -28,7 +28,7 @@ def ssh(host, cmdargs, input=None, user=SSH_USER): cmd = sub_process.Popen(cmdline, executable=SSH, stdin=sub_process.PIPE, - stdout=sub_process.PIPE, + stdout=sub_process.PIPE, stderr=sub_process.PIPE, shell=False) @@ -46,4 +46,3 @@ def check_output(regex, output): return True else: raise NetappCommandError, output - diff --git a/func/minion/modules/netapp/options.py b/func/minion/modules/netapp/options.py index f1e28ed..f5c06de 100644 --- a/func/minion/modules/netapp/options.py +++ b/func/minion/modules/netapp/options.py @@ -50,6 +50,3 @@ class Options(func_module.FuncModule): output = ssh(filer, cmd_opts) # should return no output (maybe a space or newline) return check_output("^\s*$", output) - - - diff --git a/func/minion/modules/netapp/snap.py b/func/minion/modules/netapp/snap.py index ee113f7..45e0ca8 100644 --- a/func/minion/modules/netapp/snap.py +++ b/func/minion/modules/netapp/snap.py @@ -40,7 +40,7 @@ class Snap(func_module.FuncModule): cmd_opts = ['snap', 'delete', vol, snap] output = ssh(filer, cmd_opts) return check_output(regex, output) - + def list(self, filer, vol): """ TODO: Document me ... @@ -61,7 +61,7 @@ class Snap(func_module.FuncModule): 'optional':False, 'description':"The name of the snapshot" } - + filer = { 'type':'string', 'optional':False, @@ -93,4 +93,3 @@ class Snap(func_module.FuncModule): 'description':"" } } - diff --git a/func/minion/modules/netapp/vol/__init__.py b/func/minion/modules/netapp/vol/__init__.py index 5cd4898..728a276 100644 --- a/func/minion/modules/netapp/vol/__init__.py +++ b/func/minion/modules/netapp/vol/__init__.py @@ -31,7 +31,7 @@ class Vol(func_module.FuncModule): cmd_opts = ['vol', 'create', vol, aggr, size] output = ssh(filer, cmd_opts) return check_output(regex, output) - + def destroy(self, filer, vol): """ TODO: Document me ... @@ -75,7 +75,7 @@ class Vol(func_module.FuncModule): tokens = line.split() if len(tokens) >= 2 and tokens[1] in ('online', 'offline', 'restricted'): if current_vol: vols.append(current_vol) - current_vol = {'name': tokens[0], + current_vol = {'name': tokens[0], 'state': tokens[1], 'status': [foo for foo in tokens[2:] if '=' not in foo], 'options': [foo for foo in tokens[2:] if '=' in foo]} @@ -99,7 +99,7 @@ class Vol(func_module.FuncModule): stat_regex = """vol size: Flexible volume .* has size .*.""" resize_regex = """vol size: Flexible volume .* size set to .*.""" cmd_opts = ['vol', 'size', vol] - + if delta: cmd_opts.append(delta) output = ssh(filer, cmd_opts) @@ -136,7 +136,7 @@ class Vol(func_module.FuncModule): 'optional':False, 'description':"The name of the volume" } - + filer = { 'type':'string', 'optional':False, @@ -144,7 +144,7 @@ class Vol(func_module.FuncModule): } return { - + 'create':{ 'args':{ 'filer':filer, diff --git a/func/minion/modules/netapp/vol/clone.py b/func/minion/modules/netapp/vol/clone.py index ff924d0..ca53ce7 100644 --- a/func/minion/modules/netapp/vol/clone.py +++ b/func/minion/modules/netapp/vol/clone.py @@ -31,7 +31,7 @@ class Clone(func_module.FuncModule): cmd_opts = ['vol', 'clone', 'create', vol, '-b', parent, snap] output = ssh(filer, cmd_opts) return check_output(regex, output) - + def split(self, filer, vol): """ TODO: Document me ... @@ -42,7 +42,7 @@ class Clone(func_module.FuncModule): output = ssh(filer, cmd_opts) return check_output(regex, output) - + def register_method_args(self): """ Implementing netapp.clone export @@ -52,13 +52,13 @@ class Clone(func_module.FuncModule): 'optional':False, 'description':"The name of the volume" } - + filer = { 'type':'string', 'optional':False, 'description':"Resolvable name of the target filer" } - + snap = { 'type':'string', 'optional':False, @@ -85,5 +85,5 @@ class Clone(func_module.FuncModule): 'vol':vol }, 'description':"Split the vol" - } + } } diff --git a/func/minion/modules/networktest.py b/func/minion/modules/networktest.py index 4d1d20f..7b5446f 100644 --- a/func/minion/modules/networktest.py +++ b/func/minion/modules/networktest.py @@ -29,12 +29,12 @@ class NetworkTest(func_module.FuncModule): self.__args_to_list(args)) def traceroute(self, *args): - return self.__run_command('/bin/traceroute', - self.__args_to_list(args)) + return self.__run_command('/bin/traceroute', + self.__args_to_list(args)) def dig(self, *args): - return self.__run_command('/usr/bin/dig', - self.__args_to_list(args)) + return self.__run_command('/usr/bin/dig', + self.__args_to_list(args)) def isportopen(self, host, port): # FIXME: the return api here needs some work... -akl @@ -57,7 +57,7 @@ class NetworkTest(func_module.FuncModule): def grep(self, word): """ Grep some info from grep test - especially netstat is very suitable + especially netstat is very suitable for that purpose ... """ results = { @@ -67,7 +67,7 @@ class NetworkTest(func_module.FuncModule): for res in netstat_result: if res.lower().find(word)!=-1: results[self.netstat].append(res) - + return results grep = func_module.findout(grep) diff --git a/func/minion/modules/overlord.py b/func/minion/modules/overlord.py index 2681ebe..ba94966 100644 --- a/func/minion/modules/overlord.py +++ b/func/minion/modules/overlord.py @@ -66,5 +66,3 @@ class OverlordModule(func_module.FuncModule): 'description':"Builds a recursive map of the minions currently assigned to this minion overlord" } } - - diff --git a/func/minion/modules/process.py b/func/minion/modules/process.py index e1186c9..b97d27e 100644 --- a/func/minion/modules/process.py +++ b/func/minion/modules/process.py @@ -37,8 +37,8 @@ class ProcessModule(func_module.FuncModule): flags.replace(";", "") # prevent stupidity - cmd = sub_process.Popen(["/bin/ps", flags], executable="/bin/ps", - stdout=sub_process.PIPE, + cmd = sub_process.Popen(["/bin/ps", flags], executable="/bin/ps", + stdout=sub_process.PIPE, stderr=sub_process.PIPE, shell=False) @@ -157,9 +157,9 @@ class ProcessModule(func_module.FuncModule): shareds[cmd]=shared cmds[cmd]=cmds.setdefault(cmd,0)+private if count.has_key(cmd): - count[cmd] += 1 + count[cmd] += 1 else: - count[cmd] = 1 + count[cmd] = 1 #Add shared mem for each program total=0 @@ -181,9 +181,9 @@ class ProcessModule(func_module.FuncModule): def cmd_with_count(cmd, count): if count>1: - return "%s (%u)" % (cmd, count) + return "%s (%u)" % (cmd, count) else: - return cmd + return cmd for cmd in sort_list: results.append([ @@ -203,12 +203,12 @@ class ProcessModule(func_module.FuncModule): if pid == "0": raise codes.FuncException("Killing pid group 0 not permitted") if signal == "": - # this is default /bin/kill behaviour, + # this is default /bin/kill behaviour, # it claims, but enfore it anyway signal = "-TERM" if signal[0] != "-": signal = "-%s" % signal - rc = sub_process.call(["/bin/kill",signal, pid], + rc = sub_process.call(["/bin/kill",signal, pid], executable="/bin/kill", shell=False, close_fds=True) print rc @@ -216,7 +216,7 @@ class ProcessModule(func_module.FuncModule): def pkill(self,name,level=""): # example killall("thunderbird","-9") - rc = sub_process.call(["/usr/bin/pkill", name, level], + rc = sub_process.call(["/usr/bin/pkill", name, level], executable="/usr/bin/pkill", shell=False, close_fds=True) return rc @@ -234,24 +234,24 @@ class ProcessModule(func_module.FuncModule): self.info:[], self.mem:[] } - #info result comes here + #info result comes here info_result = self.info() for process_pack in info_result: tmp_str = " ".join(process_pack) if tmp_str.lower().find(word)!= -1 : results[self.info].append(tmp_str) - + #mem results will come here mem_result = self.mem() for m in mem_result: tmp_str = " ".join(m) if tmp_str.lower().find(word)!= -1 : results[self.mem].append(tmp_str) - - + + return results grep = func_module.findout(grep) - + def register_method_args(self): """ @@ -304,7 +304,7 @@ class ProcessModule(func_module.FuncModule): "description":"Kill an app with supplying a name and level" }, 'loadavg':{ - 'args':{}, + 'args':{}, 'description':"Returns a list of loadavg details." }, } diff --git a/func/minion/modules/pullfile.py b/func/minion/modules/pullfile.py index 61a6f32..6ef0304 100644 --- a/func/minion/modules/pullfile.py +++ b/func/minion/modules/pullfile.py @@ -61,4 +61,3 @@ class PullFile(func_module.FuncModule): f.close() webFile.close() return 0 - diff --git a/func/minion/modules/reboot.py b/func/minion/modules/reboot.py index 631cb24..d2830fd 100644 --- a/func/minion/modules/reboot.py +++ b/func/minion/modules/reboot.py @@ -43,4 +43,3 @@ class Reboot(func_module.FuncModule): 'description':"Rebooting the minions" } } - diff --git a/func/minion/modules/rpms.py b/func/minion/modules/rpms.py index 5c0f055..b3eb11e 100644 --- a/func/minion/modules/rpms.py +++ b/func/minion/modules/rpms.py @@ -23,7 +23,7 @@ class RpmModule(func_module.FuncModule): Returns information on all installed packages. By default, 'flatten' is passed in as True, which makes printouts very clean in diffs for use by func-inventory. If you are writting another - software application, using flatten=False will prevent the need to + software application, using flatten=False will prevent the need to parse the returns. """ return self.glob('', flatten) @@ -31,16 +31,16 @@ class RpmModule(func_module.FuncModule): def grep(self, word): """ Grep some info from packages we got from - inventory especially + inventory especially """ results = {self.inventory:[]} inventory_res = self.inventory() - + for res in inventory_res: if res.lower().find(word)!= -1: results[self.inventory].append(res) return results - + grep = func_module.findout(grep) def verify(self, pattern='', flatten=True): @@ -58,7 +58,7 @@ class RpmModule(func_module.FuncModule): for fn in errors.keys(): for prob in errors[fn]: if flatten: - results.append('%s %s %s' % (name, fn, prob.message)) + results.append('%s %s %s' % (name, fn, prob.message)) else: results.append([name, fn, prob.message]) return results diff --git a/func/minion/modules/service.py b/func/minion/modules/service.py index 3380a8e..38de51c 100644 --- a/func/minion/modules/service.py +++ b/func/minion/modules/service.py @@ -25,7 +25,7 @@ class Service(func_module.FuncModule): description = "Allows for service control via func." def __command(self, service_name, command): - + service_name = service_name.strip() # remove useless spaces filename = os.path.join("/etc/rc.d/init.d/",service_name) @@ -60,16 +60,16 @@ class Service(func_module.FuncModule): Dig for some useful info in that module ... """ final_dict = {self.get_running:[], - self.get_enabled:[] + self.get_enabled:[] } running = self.get_running() enabled = self.get_enabled() - + #get enabled ones for e in enabled: if e[0].lower().find(word)!=-1: final_dict[self.get_enabled].append(e) - + #get running ones for e in running: if e[0].lower().find(word)!=-1: @@ -77,7 +77,7 @@ class Service(func_module.FuncModule): return final_dict grep = func_module.findout(grep) - + @@ -132,7 +132,7 @@ class Service(func_module.FuncModule): 'get_enabled':{'args':{}}, 'inventory':{'args':{}}, 'status':{'args':{ - 'service_name':service_name, + 'service_name':service_name, }, 'description':'Getting the status of the service_name' }, diff --git a/func/minion/modules/smart.py b/func/minion/modules/smart.py index 7acccf9..1ef9a56 100644 --- a/func/minion/modules/smart.py +++ b/func/minion/modules/smart.py @@ -52,7 +52,7 @@ class SmartModule(func_module.FuncModule): """ results = {self.info:[]} info_res = self.info()[1] - + if info_res: for res in info_res: if res.lower().find(word)!=-1: diff --git a/func/minion/modules/snmp.py b/func/minion/modules/snmp.py index b8033ee..594d915 100644 --- a/func/minion/modules/snmp.py +++ b/func/minion/modules/snmp.py @@ -28,7 +28,7 @@ class Snmp(func_module.FuncModule): Runs an snmpget on a specific oid returns the output of the call. """ command = '%s -c %s %s %s' % (base_snmp_command, rocommunity, hostname, oid) - + cmdref = sub_process.Popen(command.split(), stdout=sub_process.PIPE, stderr=sub_process.PIPE, shell=False, close_fds=True) data = cmdref.communicate() return (cmdref.returncode, data[0], data[1]) @@ -37,7 +37,7 @@ class Snmp(func_module.FuncModule): """ Implementing the argument getter """ - + return { 'get':{ 'args':{ diff --git a/func/minion/modules/sysctl.py b/func/minion/modules/sysctl.py index 71ecb6c..d353bf5 100644 --- a/func/minion/modules/sysctl.py +++ b/func/minion/modules/sysctl.py @@ -37,15 +37,15 @@ class SysctlModule(func_module.FuncModule): """ results = {self.list:[]} sys_res = self.list()#the ist fo sysctl - + for res in sys_res: if res.lower().find(word)!=-1: results[self.list].append(res) - + return results grep = func_module.findout(grep) - + def register_method_args(self): """ Implementing the method argument getter @@ -78,7 +78,7 @@ class SysctlModule(func_module.FuncModule): 'optional':False, 'description':"The name value to be set." } - + }, 'description':"Use this option when you want to change a sysctl setting" } diff --git a/func/minion/modules/test.py b/func/minion/modules/test.py index 71315b7..f5de11a 100644 --- a/func/minion/modules/test.py +++ b/func/minion/modules/test.py @@ -15,7 +15,7 @@ class Test(func_module.FuncModule): bool_option = BoolOption(True) float_option = FloatOption(3.14159) testvalue = 'this is a test. It is only a test' - + def add(self, numb1, numb2): return numb1 + numb2 diff --git a/func/minion/modules/users.py b/func/minion/modules/users.py index ca84fa0..4dc1bf1 100644 --- a/func/minion/modules/users.py +++ b/func/minion/modules/users.py @@ -5,7 +5,7 @@ # ############################################################################### # -# Legal: +# Legal: # # This software may be freely redistributed under the terms of the GNU # general public license. @@ -33,11 +33,11 @@ # - (Feature) Manage the memberships of users within groups # # 0.2: -# - (Feature) Most informational methods are complete and working for both +# - (Feature) Most informational methods are complete and working for both # users and groups at this point. # # 0.1: -# - (Feature) Initial release, supporting only some informational query +# - (Feature) Initial release, supporting only some informational query # messages regarding user accounts on the target system. # ############################################################################### @@ -52,1682 +52,1682 @@ import grp from os import system class UsersModule(func_module.FuncModule): - version = "0,5" - api_version = "0,5" - description = "Nearly complete." + version = "0,5" + api_version = "0,5" + description = "Nearly complete." # INTERNALLY USED METHODS ##################################################### - def __command(self,*list): - """ - This method is used internally by this module when invoking external commands. It should remain private. - This method should probably be improved to check the elems for suspicious characters like ';','&&','||'. - """ - cmd = '' - for elem in list: - if elem == '': - pass - else: - cmd = cmd + " '" + str(elem.replace("'","") if (type(elem) == str) else elem) + "'" + def __command(self,*list): + """ + This method is used internally by this module when invoking external commands. It should remain private. + This method should probably be improved to check the elems for suspicious characters like ';','&&','||'. + """ + cmd = '' + for elem in list: + if elem == '': + pass + else: + cmd = cmd + " '" + str(elem.replace("'","") if (type(elem) == str) else elem) + "'" # print "\nCmd: [%s]"%cmd - return False if system(cmd+" 2>/dev/null 1>/dev/null") else True + return False if system(cmd+" 2>/dev/null 1>/dev/null") else True - def __plural(self,f): - return (lambda xs: map(f,xs)) + def __plural(self,f): + return (lambda xs: map(f,xs)) # GROUPADD METHODS ############################################################ - def __groupadd(self,group,*switches): - """Constructs the proper argument sequence for self.__command and returns it's result.""" - if self.group_exists(group): - return False - else: - return self.__command("/usr/sbin/groupadd",group,*switches) - - def group_add(self,group,*gid): - """Adds a group on the target system(s).""" - if gid: - if self.gid_exists(gid[0]): - return False - else: - print str(gid[0]) + "<-" - return self.__groupadd(group,"-g",gid[0]) - else: - return self.__groupadd(group) - - def groups_add(self,*groups): - """Adds a series of groups on the target system(s).""" - return self.__plural(self.group_add)(groups) - - def group_add_non_unique(self,group,*gid): - """Adds a group on the target system(s).""" - if gid: - if self.gid_exists(gid[0]): - return False - else: - return self.__groupadd(group,"-o","-g",gid[0]) - else: - return self.__groupadd(group,"-o") + def __groupadd(self,group,*switches): + """Constructs the proper argument sequence for self.__command and returns it's result.""" + if self.group_exists(group): + return False + else: + return self.__command("/usr/sbin/groupadd",group,*switches) + + def group_add(self,group,*gid): + """Adds a group on the target system(s).""" + if gid: + if self.gid_exists(gid[0]): + return False + else: + print str(gid[0]) + "<-" + return self.__groupadd(group,"-g",gid[0]) + else: + return self.__groupadd(group) + + def groups_add(self,*groups): + """Adds a series of groups on the target system(s).""" + return self.__plural(self.group_add)(groups) + + def group_add_non_unique(self,group,*gid): + """Adds a group on the target system(s).""" + if gid: + if self.gid_exists(gid[0]): + return False + else: + return self.__groupadd(group,"-o","-g",gid[0]) + else: + return self.__groupadd(group,"-o") # GROUPDEL METHODS ############################################################ - def __groupdel(self,group,*switches): - """Constructs the proper argument sequence for self.__command and returns it's result.""" - if self.group_exists(group): - return self.__command("/usr/sbin/groupdel",group,*switches) - else: - return False - - def group_del(self,group): - """Deletes a group on the target system(s).""" - return self.__groupdel(group) - - def groups_del(self,*groups): - """Adds a series of groups.""" - return self.__plural(self.group_del)(groups) + def __groupdel(self,group,*switches): + """Constructs the proper argument sequence for self.__command and returns it's result.""" + if self.group_exists(group): + return self.__command("/usr/sbin/groupdel",group,*switches) + else: + return False + + def group_del(self,group): + """Deletes a group on the target system(s).""" + return self.__groupdel(group) + + def groups_del(self,*groups): + """Adds a series of groups.""" + return self.__plural(self.group_del)(groups) # GROUPMOD METHODS ############################################################ - def __groupmod(self,group,*switches): - """Constructs the proper argument sequence for self.__command and returns it's result.""" - if self.group_exists(group): - if switches: - return self.__command("/usr/sbin/groupmod",group,*switches) - else: - return self.__command("/usr/sbin/groupmod",group) - else: - return False - - def group_set_gid_non_unique(self,group,gid): - """Changes the GID of the specified group on the target system(s), allowing non-unique GID.""" - return self.__groupmod(group,"-o","-g",gid) - - def group_set_gid(self,group,gid): - """Changes the GID of the specified group on the target system(s).""" - if self.gid_exists(gid): - return False - else: - return self.__groupmod(group,"-g",gid) - - def group_set_groupname(self,group,groupname): - """Changes the name of the specified group on the target system(s).""" - if self.group_exists(groupname): - return False - else: - return self.__groupmod(group,"-n",groupname) + def __groupmod(self,group,*switches): + """Constructs the proper argument sequence for self.__command and returns it's result.""" + if self.group_exists(group): + if switches: + return self.__command("/usr/sbin/groupmod",group,*switches) + else: + return self.__command("/usr/sbin/groupmod",group) + else: + return False + + def group_set_gid_non_unique(self,group,gid): + """Changes the GID of the specified group on the target system(s), allowing non-unique GID.""" + return self.__groupmod(group,"-o","-g",gid) + + def group_set_gid(self,group,gid): + """Changes the GID of the specified group on the target system(s).""" + if self.gid_exists(gid): + return False + else: + return self.__groupmod(group,"-g",gid) + + def group_set_groupname(self,group,groupname): + """Changes the name of the specified group on the target system(s).""" + if self.group_exists(groupname): + return False + else: + return self.__groupmod(group,"-n",groupname) # USERADD METHODS ############################################################# - def __useradd(self,user,*switches): - """Constructs the proper argument sequence for self.__command and returns it's result.""" - if self.user_exists(user): - return False - else: - return self.__command("/usr/sbin/useradd",user) + def __useradd(self,user,*switches): + """Constructs the proper argument sequence for self.__command and returns it's result.""" + if self.user_exists(user): + return False + else: + return self.__command("/usr/sbin/useradd",user) - def user_add(self,user): - """Adds a user on the target system(s).""" - return self.__useradd(user) + def user_add(self,user): + """Adds a user on the target system(s).""" + return self.__useradd(user) - def users_add(self,*users): - """Adds a series of users on the target system(s).""" - return self.__plural(self.user_add)(users) + def users_add(self,*users): + """Adds a series of users on the target system(s).""" + return self.__plural(self.user_add)(users) # USERDEL METHODS ############################################################# - def __userdel(self,user,*switches): - """Constructs the proper argument sequence for self.__command and returns it's result.""" - if self.user_exists(user): - return self.__command("/usr/sbin/userdel",user,*switches) - else: - return False - - def user_del(self,user,*options): - """Deletes a user on the target system(s).""" - switches=[] - if options: - for option in options: - if option == 'force': - switches.append('-f') - elif option == 'remove': - switches.append('-r') - else: - return False - return self.__userdel(user,*switches) - - def users_del(self,*users): - """Deletes a series of users on the target system(s).""" - return self.__plural(self.user_del)(users) + def __userdel(self,user,*switches): + """Constructs the proper argument sequence for self.__command and returns it's result.""" + if self.user_exists(user): + return self.__command("/usr/sbin/userdel",user,*switches) + else: + return False + + def user_del(self,user,*options): + """Deletes a user on the target system(s).""" + switches=[] + if options: + for option in options: + if option == 'force': + switches.append('-f') + elif option == 'remove': + switches.append('-r') + else: + return False + return self.__userdel(user,*switches) + + def users_del(self,*users): + """Deletes a series of users on the target system(s).""" + return self.__plural(self.user_del)(users) # USERMOD METHODS ############################################################# - def __usermod(self,user,*switches): - """Constructs the proper argument sequence for self.__command and returns it's result.""" - if self.user_exists(user): - command = [] - if switches: - command = list(switches) - command.append(user) - return self.__command("/usr/sbin/usermod",*command) - else: - return False - - def user_lock(self,user): - """Locks a user account on the target system(s).""" - return self.__usermod(user,"-L") - - def users_lock(self,*users): - """Locks a series of user accounts on the target system(s).""" - return self.__plural(self.user_lock)(users) - - def user_set_shell(self,user,shell): - """Set a specified user's shell on the target system(s).""" - return self.__usermod(user,"-s",shell) - - def users_set_shell(self,shell,*users): - """Set a specified list of users' shell on the target system(s).""" - return self.__plural(lambda u: self.user_set_shell(u,shell))(users) - - def user_set_home(self,user,home): - """Change (but don't move the contents of) a user's home folder on the target system(s).""" - return self.__usermod(user,"-d",home) - - def user_set_loginname(self,user,loginname): - """Change a user's login name on the target system(s).""" - return self.__usermod(user,"-l",loginname) - - def user_set_comment(self,user,comment): - """Change the value of a user's GECOS field -- maybe replace this with a field sensitive version?""" - return self.__usermod(user,"-c",comment) - - def user_set_expiredate(self,user,expiredate): - """Set the expity date for a specified user on the target system(s).""" - return self.__usermod(user,"-e",expiredate) - - def users_set_expiredate(self,expiredate,*users): - """Set a specified list of users' expiry date on the target system(s).""" - return self.__plural(lambda u: self.user_set_expiredate(u,expiredate))(users) - - def user_set_uid_non_unique(self,user,uid): - """Change a user's UID, allowing non-unique UIDs on the target system(s).""" - return self.__usermod(user,"-u",uid,"-o") - - def user_set_uid(self,user,uid): - """Change a user's UID on the target system(s).""" - return self.__usermod(user,"-u",uid) - - def user_set_inactive(self,user,inactive): - """Set the inactivity timer on a user on the target system(s).""" - return self.__usermod(user,"-f",inactive) - - def users_set_inactive(self,inactive,*users): - """Set the inactivity timer on a series of users on the target system(s).""" - return self.__plural(lambda u: self.user_set_inactive(u,inactive))(users) - - def user_set_gid(self,user,gid): - """Change a users primary group by GID on the target system(s).""" - if self.gid_exists(gid): - return self.__usermod(user,"-g",gid) - else: - return False - - def users_set_gid(self,gid,*users): - """Set a specified list of users' primary GID on the target system(s).""" - return self.__plural(lambda u: self.user_set_gid(u,gid))(users) - - def user_move_home(self,user,home): - """Changes and moves a users home folder on the target system(s).""" - return self.__usermod(user,"-d",home,"-m") - - def user_unlock(self,user): - """Unlocks a specified user account on the target system(s).""" - return self.__usermod(user,"-U") - - def users_unlock(self,*users): - """Unlocks a specified list of users' accounts on the target system(s).""" - return self.__plural(self.user_unlock)(users) - - def user_add_to_group(self,user,group): - """Appends the user to a specified group on the target system(s).""" - if self.group_exists(group): - return self.__usermod(user,"-aG",group) - else: - return False - - def users_add_to_group(self,group,*users): - """Appends the list of users to a specified group on the target system(s).""" - return self.__plural(lambda u: self.user_add_to_group(u,group))(users) - - def user_set_group(self,user,group): - """Changes a users primary group on the target system(s).""" - if self.group_exists(group): - gid = self.group_to_gid(group) - return self.__usermod(user,"-g",gid) - else: - return False - - def users_set_group(self,group,*users): - """Changes a series of users' primary group on the target system(s).""" - return self.__plural(lambda u: self.user_set_group(u,group))(users) + def __usermod(self,user,*switches): + """Constructs the proper argument sequence for self.__command and returns it's result.""" + if self.user_exists(user): + command = [] + if switches: + command = list(switches) + command.append(user) + return self.__command("/usr/sbin/usermod",*command) + else: + return False + + def user_lock(self,user): + """Locks a user account on the target system(s).""" + return self.__usermod(user,"-L") + + def users_lock(self,*users): + """Locks a series of user accounts on the target system(s).""" + return self.__plural(self.user_lock)(users) + + def user_set_shell(self,user,shell): + """Set a specified user's shell on the target system(s).""" + return self.__usermod(user,"-s",shell) + + def users_set_shell(self,shell,*users): + """Set a specified list of users' shell on the target system(s).""" + return self.__plural(lambda u: self.user_set_shell(u,shell))(users) + + def user_set_home(self,user,home): + """Change (but don't move the contents of) a user's home folder on the target system(s).""" + return self.__usermod(user,"-d",home) + + def user_set_loginname(self,user,loginname): + """Change a user's login name on the target system(s).""" + return self.__usermod(user,"-l",loginname) + + def user_set_comment(self,user,comment): + """Change the value of a user's GECOS field -- maybe replace this with a field sensitive version?""" + return self.__usermod(user,"-c",comment) + + def user_set_expiredate(self,user,expiredate): + """Set the expity date for a specified user on the target system(s).""" + return self.__usermod(user,"-e",expiredate) + + def users_set_expiredate(self,expiredate,*users): + """Set a specified list of users' expiry date on the target system(s).""" + return self.__plural(lambda u: self.user_set_expiredate(u,expiredate))(users) + + def user_set_uid_non_unique(self,user,uid): + """Change a user's UID, allowing non-unique UIDs on the target system(s).""" + return self.__usermod(user,"-u",uid,"-o") + + def user_set_uid(self,user,uid): + """Change a user's UID on the target system(s).""" + return self.__usermod(user,"-u",uid) + + def user_set_inactive(self,user,inactive): + """Set the inactivity timer on a user on the target system(s).""" + return self.__usermod(user,"-f",inactive) + + def users_set_inactive(self,inactive,*users): + """Set the inactivity timer on a series of users on the target system(s).""" + return self.__plural(lambda u: self.user_set_inactive(u,inactive))(users) + + def user_set_gid(self,user,gid): + """Change a users primary group by GID on the target system(s).""" + if self.gid_exists(gid): + return self.__usermod(user,"-g",gid) + else: + return False + + def users_set_gid(self,gid,*users): + """Set a specified list of users' primary GID on the target system(s).""" + return self.__plural(lambda u: self.user_set_gid(u,gid))(users) + + def user_move_home(self,user,home): + """Changes and moves a users home folder on the target system(s).""" + return self.__usermod(user,"-d",home,"-m") + + def user_unlock(self,user): + """Unlocks a specified user account on the target system(s).""" + return self.__usermod(user,"-U") + + def users_unlock(self,*users): + """Unlocks a specified list of users' accounts on the target system(s).""" + return self.__plural(self.user_unlock)(users) + + def user_add_to_group(self,user,group): + """Appends the user to a specified group on the target system(s).""" + if self.group_exists(group): + return self.__usermod(user,"-aG",group) + else: + return False + + def users_add_to_group(self,group,*users): + """Appends the list of users to a specified group on the target system(s).""" + return self.__plural(lambda u: self.user_add_to_group(u,group))(users) + + def user_set_group(self,user,group): + """Changes a users primary group on the target system(s).""" + if self.group_exists(group): + gid = self.group_to_gid(group) + return self.__usermod(user,"-g",gid) + else: + return False + + def users_set_group(self,group,*users): + """Changes a series of users' primary group on the target system(s).""" + return self.__plural(lambda u: self.user_set_group(u,group))(users) # PASSWD/CHPASWD METHODS ##################################################### - def passwd(self,user,passwd): - """Changes a user's password on the target system(s).""" - if self.user_exists(user): - if system("echo "+passwd+" | passwd --stdin "+user): - return False - else: - return True - else: - return False + def passwd(self,user,passwd): + """Changes a user's password on the target system(s).""" + if self.user_exists(user): + if system("echo "+passwd+" | passwd --stdin "+user): + return False + else: + return True + else: + return False # INFORMATIONAL METHODS ####################################################### # EXISTANCE TEST METHODS - def user_exists(self,user): - """Checks to see if a given user exists on the target system(s).""" - try: - if pwd.getpwnam(user): - return True - except KeyError: - return False - - def users_exist(self,*users): - """Checks to see if a series of users exists on the target system(s).""" - return self.__plural(self.user_exists)(users) - - def uid_exists(self,uid): - """Checks to see if a given UID exists on the target system(s).""" - try: - if pwd.getpwuid(int(uid)): - return True - except KeyError: - return False - - def uids_exist(self,*uids): - """Checks to see if a series of UIDs exists on the target system(s).""" - return self.__plural(self.uid_exists)(uids) - - def group_exists(self,group): - """Checks to see if a given group exists on the target system(s).""" - try: - if grp.getgrnam(group): - return True - except KeyError: - return False - - def groups_exist(self,*groups): - """Checks to see if a series of groups exist on the target system(s).""" - return self.__plural(self.group_exists)(groups) - - def gid_exists(self,gid): - """Checks to see if a given GID exists on the target system(s).""" - try: - if grp.getgrgid(int(gid)): - return True - except KeyError: - return False - - def gids_exist(self,*gids): - """Checks to see if a series of GIDs exist on the target system(s).""" - return self.__plural(self.gid_exists)(gids) + def user_exists(self,user): + """Checks to see if a given user exists on the target system(s).""" + try: + if pwd.getpwnam(user): + return True + except KeyError: + return False + + def users_exist(self,*users): + """Checks to see if a series of users exists on the target system(s).""" + return self.__plural(self.user_exists)(users) + + def uid_exists(self,uid): + """Checks to see if a given UID exists on the target system(s).""" + try: + if pwd.getpwuid(int(uid)): + return True + except KeyError: + return False + + def uids_exist(self,*uids): + """Checks to see if a series of UIDs exists on the target system(s).""" + return self.__plural(self.uid_exists)(uids) + + def group_exists(self,group): + """Checks to see if a given group exists on the target system(s).""" + try: + if grp.getgrnam(group): + return True + except KeyError: + return False + + def groups_exist(self,*groups): + """Checks to see if a series of groups exist on the target system(s).""" + return self.__plural(self.group_exists)(groups) + + def gid_exists(self,gid): + """Checks to see if a given GID exists on the target system(s).""" + try: + if grp.getgrgid(int(gid)): + return True + except KeyError: + return False + + def gids_exist(self,*gids): + """Checks to see if a series of GIDs exist on the target system(s).""" + return self.__plural(self.gid_exists)(gids) # LISTING METHODS - def user_list(self): - """Lists all users on the target system(s).""" - users = [] - for user in pwd.getpwall(): - users.append(user[0]) - return users - - def users_list(self): - """Lists all users on the target system(s).""" - return self.user_list() - - def uid_list(self): - """Lists all UIDs on the target system(s).""" - uids = [] - for user in pwd.getpwall(): - uids.append(user[2] if user[2] < 4294967294 else True) - return uids - - def uids_list(self): - """Lists all UIDs on the target system(s).""" - return self.uid_list() - - def group_list(self): - """Lists all groups on the target system(s).""" - groups = [] - for group in grp.getgrall(): - groups.append(group[0]) - return groups - - def groups_list(self): - """Lists all groups on the target system(s).""" - return self.group_list() - - def gid_list(self): - """Lists all GIDs on the target system(s).""" - gids = [] - for group in grp.getgrall(): - gids.append(group[2] if group[2] < 4294967294 else True) - return gids - - def gids_list(self): - """Lists all GIDs on the target system(s).""" - return self.gid_list() + def user_list(self): + """Lists all users on the target system(s).""" + users = [] + for user in pwd.getpwall(): + users.append(user[0]) + return users + + def users_list(self): + """Lists all users on the target system(s).""" + return self.user_list() + + def uid_list(self): + """Lists all UIDs on the target system(s).""" + uids = [] + for user in pwd.getpwall(): + uids.append(user[2] if user[2] < 4294967294 else True) + return uids + + def uids_list(self): + """Lists all UIDs on the target system(s).""" + return self.uid_list() + + def group_list(self): + """Lists all groups on the target system(s).""" + groups = [] + for group in grp.getgrall(): + groups.append(group[0]) + return groups + + def groups_list(self): + """Lists all groups on the target system(s).""" + return self.group_list() + + def gid_list(self): + """Lists all GIDs on the target system(s).""" + gids = [] + for group in grp.getgrall(): + gids.append(group[2] if group[2] < 4294967294 else True) + return gids + + def gids_list(self): + """Lists all GIDs on the target system(s).""" + return self.gid_list() # INFO METHODS - def user_info(self,user): - """Returns user info or false for a specified user on the target system(s).""" - try: - if pwd.getpwnam(user): - info = pwd.getpwnam(user) - return list(info) # I'm not sure why this has to be listed but the method fails to work if it isn't. - except KeyError: - return False - - def users_info(self,*users): - """Returns a list of (group info or False) for a series of users on the target system(s).""" - return self.__plural(self.user_info)(users) - - def uid_info(self,uid): - """Returns user info or false for a specified user (by UID) on the target system(s).""" - try: - if pwd.getpwuid(uid): - info = pwd.getpwuid(int(uid)) - return list(info) - except KeyError: - return False - - def uids_info(self,*uids): - """Returns a list (group info or False) for a series of users (by UID) on the target system(s).""" - return self.__plural(self.uid_info)(uids) - - def group_info(self,group): - """Returns group info or false for a specified group on the target system(s).""" - try: - if grp.getgrnam(group): - info = grp.getgrnam(group) - return list(info) #for some reason this needs to be list-ed - except KeyError: - return False - - def groups_info(self,*groups): - """Returns a list (group info or False) for a series of groups on the target system(s).""" - return self.__plural(self.group_info)(groups) - - def gid_info(self,gid): - """Returns group info or false for a specified group (by GID) on the target system(s).""" - try: - if grp.getgrgid(int(gid)): - info = grp.getgrgid(int(gid)) - return list(info) - except KeyError: - return False - - def gids_info(self,*gids): - """Returns a list (group info or False) for a series of groups (by GID) on the target system(s).""" - return self.__plural(self.gid_info)(gids) + def user_info(self,user): + """Returns user info or false for a specified user on the target system(s).""" + try: + if pwd.getpwnam(user): + info = pwd.getpwnam(user) + return list(info) # I'm not sure why this has to be listed but the method fails to work if it isn't. + except KeyError: + return False + + def users_info(self,*users): + """Returns a list of (group info or False) for a series of users on the target system(s).""" + return self.__plural(self.user_info)(users) + + def uid_info(self,uid): + """Returns user info or false for a specified user (by UID) on the target system(s).""" + try: + if pwd.getpwuid(uid): + info = pwd.getpwuid(int(uid)) + return list(info) + except KeyError: + return False + + def uids_info(self,*uids): + """Returns a list (group info or False) for a series of users (by UID) on the target system(s).""" + return self.__plural(self.uid_info)(uids) + + def group_info(self,group): + """Returns group info or false for a specified group on the target system(s).""" + try: + if grp.getgrnam(group): + info = grp.getgrnam(group) + return list(info) #for some reason this needs to be list-ed + except KeyError: + return False + + def groups_info(self,*groups): + """Returns a list (group info or False) for a series of groups on the target system(s).""" + return self.__plural(self.group_info)(groups) + + def gid_info(self,gid): + """Returns group info or false for a specified group (by GID) on the target system(s).""" + try: + if grp.getgrgid(int(gid)): + info = grp.getgrgid(int(gid)) + return list(info) + except KeyError: + return False + + def gids_info(self,*gids): + """Returns a list (group info or False) for a series of groups (by GID) on the target system(s).""" + return self.__plural(self.gid_info)(gids) # INVENTORY METHODS - def user_inventory(self): - """Returns user info for all users on the target system(s).""" - return pwd.getpwall() - - def users_inventory(self): - """Returns user info for all users on the target system(s).""" - return self.users_inventory() - - def group_inventory(self): - """Returns group info for all users on the target system(s).""" - return grp.getgrall() - - def groups_inventory(self): - """Returns group info for all users on the target system(s).""" - return self.groups_inventory() - - def grep(self, word): - """ - Grep some info from user_list and - group list - """ - results = { - self.user_list:[], - self.group_list:[] - } - - user_list = self.user_list() - group_list = self.group_list() - - results[self.user_list].extend([res for res in user_list if res.lower().find(word)!=-1]) - results[self.group_list].extend([res for res in group_list if res.lower().find(word)!=-1]) - return results - grep = func_module.findout(grep) + def user_inventory(self): + """Returns user info for all users on the target system(s).""" + return pwd.getpwall() + + def users_inventory(self): + """Returns user info for all users on the target system(s).""" + return self.users_inventory() + + def group_inventory(self): + """Returns group info for all users on the target system(s).""" + return grp.getgrall() + + def groups_inventory(self): + """Returns group info for all users on the target system(s).""" + return self.groups_inventory() + + def grep(self, word): + """ + Grep some info from user_list and + group list + """ + results = { + self.user_list:[], + self.group_list:[] + } + + user_list = self.user_list() + group_list = self.group_list() + + results[self.user_list].extend([res for res in user_list if res.lower().find(word)!=-1]) + results[self.group_list].extend([res for res in group_list if res.lower().find(word)!=-1]) + return results + grep = func_module.findout(grep) # CONVERSION METHODS - def user_to_uid(self,user): - """Takes a user name and converts it to the matching UID.""" - try: - username = pwd.getpwnam(user)[2] - return username - except KeyError: - return False - - def users_to_uids(self,*users): - """Takes a series of usernames and converts it to a list of matching UIDs.""" - return self.__plural(self.user_to_uid)(users) - - def uid_to_user(self,uid): - """Takes a UID and converts it to the matching user name.""" - try: - user = pwd.getpwuid(int(uid))[0] - return user - except KeyError: - return False - - def uids_to_users(self,*uids): - """Takes a series of UIDs and converts it to a list of matching user names.""" - return self.__plural(self.uid_to_user)(uids) - - def group_to_gid(self,group): - """Takes a group name and converts it to the matching GID.""" - try: - groupname = grp.getgrnam(group)[2] - return groupname - except KeyError: - return False - - def groups_to_gids(self,*groups): - """Takes a series of group names and converts it to a list of matching GIDs.""" - return self.__plural(self.group_to_gid)(groups) - - def gid_to_group(self,gid): - """Takes a GID and converts it to the matching group name.""" - try: - group = grp.getgrgid(int(gid))[0] - return group - except KeyError: - return False - - def gids_to_groups(self,*gids): - """Takes a series of GIDs and converts it to a list of matching group names.""" - return self.__plural(self.gid_to_groups)(gids) + def user_to_uid(self,user): + """Takes a user name and converts it to the matching UID.""" + try: + username = pwd.getpwnam(user)[2] + return username + except KeyError: + return False + + def users_to_uids(self,*users): + """Takes a series of usernames and converts it to a list of matching UIDs.""" + return self.__plural(self.user_to_uid)(users) + + def uid_to_user(self,uid): + """Takes a UID and converts it to the matching user name.""" + try: + user = pwd.getpwuid(int(uid))[0] + return user + except KeyError: + return False + + def uids_to_users(self,*uids): + """Takes a series of UIDs and converts it to a list of matching user names.""" + return self.__plural(self.uid_to_user)(uids) + + def group_to_gid(self,group): + """Takes a group name and converts it to the matching GID.""" + try: + groupname = grp.getgrnam(group)[2] + return groupname + except KeyError: + return False + + def groups_to_gids(self,*groups): + """Takes a series of group names and converts it to a list of matching GIDs.""" + return self.__plural(self.group_to_gid)(groups) + + def gid_to_group(self,gid): + """Takes a GID and converts it to the matching group name.""" + try: + group = grp.getgrgid(int(gid))[0] + return group + except KeyError: + return False + + def gids_to_groups(self,*gids): + """Takes a series of GIDs and converts it to a list of matching group names.""" + return self.__plural(self.gid_to_groups)(gids) ###### - def register_method_args(self): - password = { - 'type':'string', - 'optional':False, - 'description':'A password.' - } - cmdopt = { - 'type':'string', - 'optional':False, - 'description':'An option to the command.' - } - cmdopts = { - 'type':'list*', - 'optional':False, - 'description':'An series of options to the command.' - } - username = { - 'type':'string', - 'optional':False, - 'description':'A username.', - } - usernames = { - 'type':'list*', - 'optional':False, - 'description':'A series of usernames.', - } - group = { - 'type':'string', - 'optional':False, - 'description':'A group name.' - } - groups = { - 'type':'list*', - 'optional':False, - 'description':'A series of group names.' - } - gid = { - 'type':'int', - 'optional':False, - 'description':'A gid.' - } - gids = { - 'type':'list*', - 'optional':False, - 'description':'A series of gids.' - } - ogid = { - 'type':'list*', - 'optional':False, - 'description':'An optional gid.' - } - ouid = { - 'type':'list*', - 'optional':False, - 'description':'An optional uid.' - } - uid = { - 'type':'int', - 'optional':False, - 'description':'A uid.' - } - uids = { - 'type':'list*', - 'optional':False, - 'description':'A series of uids.' - } - - return { - #GROUPADD METHODS - 'group_add':{ - 'args':{ - 'group':group, - 'gid':ogid - }, - 'description':"Create a group." - }, - - 'groups_add':{ - 'args':{ - 'groups':groups - }, - 'description':"Create series of groups." - }, - - 'group_add_non_unique':{ - 'args':{ - 'group':group, - 'gid':ogid - }, - 'description':"Create a group." - }, - - #GROUPDEL METHODS - 'group_del':{ - 'args':{ - 'group':group - }, - 'description':"Delete a group." - }, - - 'groups_del':{ - 'args':{ - 'groups':groups - }, - 'description':"Delete a series of groups." - }, - - #GROUPMOD METHODS - 'group_set_gid_non_unique':{ - 'args':{ - 'group':group, - 'gid':gid - }, - 'description':"Allows a groups gid to be non-unique." - }, - - 'group_set_gid':{ - 'args':{ - 'group':group, - 'gid':gid - }, - 'description':"Set a group's gid." - }, - - 'group_set_groupname':{ - 'args':{ - 'group':group, - 'groupname':group - }, - 'description':"Set a group's groupname." - }, - - #USERADD METHODS - 'user_add':{ - 'args':{ - 'user':username - }, - 'description':"Create a user." - }, - - 'users_add':{ - 'args':{ - 'users':usernames - }, - 'description':"Create series of users." - }, - - #USERDEL METHODS - 'user_del':{ - 'args':{ - 'user':username, - 'options':cmdopts, - }, - 'description':"Delete a user's account." - }, - - 'users_del':{ - 'args':{ - 'users':usernames, - }, - 'description':"Delete a series of users' accounts." - }, - - #USERMOD METHODS - 'user_lock':{ - 'args':{ - 'user':username, - }, - 'description':"Lock a user's account." - }, - - 'users_lock':{ - 'args':{ - 'users':usernames, - }, - 'description':"Lock a series of users' accounts." - }, - - 'user_set_shell':{ - 'args':{ - 'user':username, - 'shell':{ - 'type':'string', - 'optional':False, - 'description':"A path to a shell." - } - }, - 'description':"Set a user's shell." - }, - - 'users_set_shell':{ - 'args':{ - 'users':usernames, - 'shell':{ - 'type':'string', - 'optional':False, - 'description':"A path to a shell." - } - }, - 'description':"Set a series of users' shell." - }, - - 'user_set_home':{ - 'args':{ - 'user':username, - 'home':{ - 'type':'string', - 'optional':False, - 'description':"A directory." - } - }, - 'description':"Set a user's home folder." - }, - - 'user_set_loginname':{ - 'args':{ - 'user':username, - 'loginname':username - }, - 'description':"Set a user's GECOS field." - }, - - 'user_set_comment':{ - 'args':{ - 'user':username, - 'comment':cmdopt - }, - 'description':"Set a user's GECOS field." - }, - - 'user_set_expiredate':{ - 'args':{ - 'user':username, - 'expiredate':cmdopt - }, - 'description':"Set a user's account's expiry date." - }, - - 'users_set_expiredate':{ - 'args':{ - 'expiredate':cmdopt, - 'users':usernames - }, - 'description':"Set a series of users' accounts' expiry date." - }, - - 'user_set_uid_non_unique':{ - 'args':{ - 'user':username, - 'uid':uid - }, - 'description':"Set a user's uid." - }, - - 'user_set_uid':{ - 'args':{ - 'user':username, - 'uid':uid - }, - 'description':"Set a user's uid." - }, - - 'user_set_inactive':{ - 'args':{ - 'user':username, - 'inactive':cmdopt - }, - 'description':"Set a user's inactivity timer." - }, - - 'users_set_inactive':{ - 'args':{ - 'inactive':cmdopt, - 'users':usernames - }, - 'description':"Set a series of users' inactivity timer." - }, - - 'user_set_gid':{ - 'args':{ - 'user':username, - 'gid':gid - }, - 'description':"Set a user's gid." - }, - - 'users_set_gid':{ - 'args':{ - 'gid':gid, - 'users':usernames - }, - 'description':"Set a series of users' gids." - }, - - 'user_move_home':{ - 'args':{ - 'user':username, - 'home':{ - 'type':'string', - 'optional':False, - 'description':"A directory." + def register_method_args(self): + password = { + 'type':'string', + 'optional':False, + 'description':'A password.' + } + cmdopt = { + 'type':'string', + 'optional':False, + 'description':'An option to the command.' + } + cmdopts = { + 'type':'list*', + 'optional':False, + 'description':'An series of options to the command.' + } + username = { + 'type':'string', + 'optional':False, + 'description':'A username.', + } + usernames = { + 'type':'list*', + 'optional':False, + 'description':'A series of usernames.', + } + group = { + 'type':'string', + 'optional':False, + 'description':'A group name.' + } + groups = { + 'type':'list*', + 'optional':False, + 'description':'A series of group names.' + } + gid = { + 'type':'int', + 'optional':False, + 'description':'A gid.' + } + gids = { + 'type':'list*', + 'optional':False, + 'description':'A series of gids.' + } + ogid = { + 'type':'list*', + 'optional':False, + 'description':'An optional gid.' + } + ouid = { + 'type':'list*', + 'optional':False, + 'description':'An optional uid.' + } + uid = { + 'type':'int', + 'optional':False, + 'description':'A uid.' + } + uids = { + 'type':'list*', + 'optional':False, + 'description':'A series of uids.' + } + + return { + #GROUPADD METHODS + 'group_add':{ + 'args':{ + 'group':group, + 'gid':ogid + }, + 'description':"Create a group." + }, + + 'groups_add':{ + 'args':{ + 'groups':groups + }, + 'description':"Create series of groups." + }, + + 'group_add_non_unique':{ + 'args':{ + 'group':group, + 'gid':ogid + }, + 'description':"Create a group." + }, + + #GROUPDEL METHODS + 'group_del':{ + 'args':{ + 'group':group + }, + 'description':"Delete a group." + }, + + 'groups_del':{ + 'args':{ + 'groups':groups + }, + 'description':"Delete a series of groups." + }, + + #GROUPMOD METHODS + 'group_set_gid_non_unique':{ + 'args':{ + 'group':group, + 'gid':gid + }, + 'description':"Allows a groups gid to be non-unique." + }, + + 'group_set_gid':{ + 'args':{ + 'group':group, + 'gid':gid + }, + 'description':"Set a group's gid." + }, + + 'group_set_groupname':{ + 'args':{ + 'group':group, + 'groupname':group + }, + 'description':"Set a group's groupname." + }, + + #USERADD METHODS + 'user_add':{ + 'args':{ + 'user':username + }, + 'description':"Create a user." + }, + + 'users_add':{ + 'args':{ + 'users':usernames + }, + 'description':"Create series of users." + }, + + #USERDEL METHODS + 'user_del':{ + 'args':{ + 'user':username, + 'options':cmdopts, + }, + 'description':"Delete a user's account." + }, + + 'users_del':{ + 'args':{ + 'users':usernames, + }, + 'description':"Delete a series of users' accounts." + }, + + #USERMOD METHODS + 'user_lock':{ + 'args':{ + 'user':username, + }, + 'description':"Lock a user's account." + }, + + 'users_lock':{ + 'args':{ + 'users':usernames, + }, + 'description':"Lock a series of users' accounts." + }, + + 'user_set_shell':{ + 'args':{ + 'user':username, + 'shell':{ + 'type':'string', + 'optional':False, + 'description':"A path to a shell." + } + }, + 'description':"Set a user's shell." + }, + + 'users_set_shell':{ + 'args':{ + 'users':usernames, + 'shell':{ + 'type':'string', + 'optional':False, + 'description':"A path to a shell." + } + }, + 'description':"Set a series of users' shell." + }, + + 'user_set_home':{ + 'args':{ + 'user':username, + 'home':{ + 'type':'string', + 'optional':False, + 'description':"A directory." + } + }, + 'description':"Set a user's home folder." + }, + + 'user_set_loginname':{ + 'args':{ + 'user':username, + 'loginname':username + }, + 'description':"Set a user's GECOS field." + }, + + 'user_set_comment':{ + 'args':{ + 'user':username, + 'comment':cmdopt + }, + 'description':"Set a user's GECOS field." + }, + + 'user_set_expiredate':{ + 'args':{ + 'user':username, + 'expiredate':cmdopt + }, + 'description':"Set a user's account's expiry date." + }, + + 'users_set_expiredate':{ + 'args':{ + 'expiredate':cmdopt, + 'users':usernames + }, + 'description':"Set a series of users' accounts' expiry date." + }, + + 'user_set_uid_non_unique':{ + 'args':{ + 'user':username, + 'uid':uid + }, + 'description':"Set a user's uid." + }, + + 'user_set_uid':{ + 'args':{ + 'user':username, + 'uid':uid + }, + 'description':"Set a user's uid." + }, + + 'user_set_inactive':{ + 'args':{ + 'user':username, + 'inactive':cmdopt + }, + 'description':"Set a user's inactivity timer." + }, + + 'users_set_inactive':{ + 'args':{ + 'inactive':cmdopt, + 'users':usernames + }, + 'description':"Set a series of users' inactivity timer." + }, + + 'user_set_gid':{ + 'args':{ + 'user':username, + 'gid':gid + }, + 'description':"Set a user's gid." + }, + + 'users_set_gid':{ + 'args':{ + 'gid':gid, + 'users':usernames + }, + 'description':"Set a series of users' gids." + }, + + 'user_move_home':{ + 'args':{ + 'user':username, + 'home':{ + 'type':'string', + 'optional':False, + 'description':"A directory." + } + }, + 'description':"Set a user's home folder and move the contents to the new folder." + }, + + 'user_unlock':{ + 'args':{ + 'user':username, + }, + 'description':"Unlock a user's account." + }, + + 'users_unlock':{ + 'args':{ + 'users':usernames, + }, + 'description':"Unlock a series of users' account." + }, + + 'user_add_to_group':{ + 'args':{ + 'group':group, + 'user':username, + }, + 'description':"Append a user to a group." + }, + + 'users_add_to_group':{ + 'args':{ + 'group':group, + 'users':usernames, + }, + 'description':"Append a series of users to a group." + }, + + 'user_set_group':{ + 'args':{ + 'group':group, + 'user':username, + }, + 'description':"Set a user's group." + }, + + 'users_set_group':{ + 'args':{ + 'group':group, + 'users':usernames, + }, + 'description':"Set a series of users' group." + }, + + #PASSWD METHODS + 'passwd':{ + 'args':{ + 'user':username, + 'passwd':password + }, + 'description':"Change a user's password." + }, + + #EXISTANCE TEST METHODS + 'uid_exists':{ + 'args':{ + 'uid':uid + }, + 'description':'Test the existance of a uids.' + }, + + 'uids_exist':{ + 'args':{ + 'uids':uids + }, + 'description':'Test the existance of a series of uids.' + }, + + 'gid_exists':{ + 'args':{ + 'gid':gid + }, + 'description':'Test the existance of a gids.' + }, + + 'gids_exist':{ + 'args':{ + 'gids':gids + }, + 'description':'Test the existance of a series of groups.' + }, + + 'user_exists':{ + 'args':{ + 'user':username + }, + 'description':'Test the existance of a users.' + }, + + 'users_exist':{ + 'args':{ + 'users':usernames + }, + 'description':'Test the existance of a series of users.' + }, + + 'group_exists':{ + 'args':{ + 'group':group + }, + 'description':'Test the existance of a groups.' + }, + + 'groups_exist':{ + 'args':{ + 'groups':groups + }, + 'description':'Test the existance of a series of groups.' + }, + + #LISTING METHODS + 'uid_list':{ + 'args':{}, + 'description':'Get a list of all uids.' + }, + + 'uids_list':{ + 'args':{}, + 'description':'Get a list of all uids.' + }, + + 'gid_list':{ + 'args':{}, + 'description':'Get a list of all gids.' + }, + + 'gids_list':{ + 'args':{}, + 'description':'Get a list of all groups.' + }, + + 'user_list':{ + 'args':{}, + 'description':'Get a list of all users.' + }, + + 'users_list':{ + 'args':{}, + 'description':'Get a list of all users.' + }, + + 'group_list':{ + 'args':{}, + 'description':'Get a list of all groups.' + }, + + 'groups_list':{ + 'args':{}, + 'description':'Get a list of all groups.' + }, + + #INFO METHODS + 'user_info':{ + 'args':{ + 'user':username + }, + 'description':'Fetch info for a specified user.' + }, + + 'users_info':{ + 'args':{ + 'users':usernames + }, + 'description':'Fetch info for a specified series of users.' + }, + + 'uid_info':{ + 'args':{ + 'uid':uid + }, + 'description':'Fetch info for a specified uid.' + }, + + 'uids_info':{ + 'args':{ + 'uids':uids + }, + 'description':'Fetch info for a specified series of uids.' + }, + + 'group_info':{ + 'args':{ + 'group':group + }, + 'description':'Fetch info for a specified group.' + }, + + 'groups_info':{ + 'args':{ + 'groups':groups + }, + 'description':'Fetch info for a specified series of groups.' + }, + + 'gid_info':{ + 'args':{ + 'gid':gid + }, + 'description':'Fetch info for a specified gid.' + }, + + 'gids_info':{ + 'args':{ + 'gids':gids + }, + 'description':'Fetch info for a specified series of gids.' + }, + + #INVENTORY METHODS + 'user_inventory':{ + 'args':{}, + 'description':'Get user info for all users.' + }, + + 'users_inventory':{ + 'args':{}, + 'description':'Get user info for all users.' + }, + + 'group_inventory':{ + 'args':{}, + 'description':'Get group info for all groups.' + }, + + 'groups_inventory':{ + 'args':{}, + 'description':'Get group info for all groups.' + }, + + #CONVERSION METHODS + 'user_to_uid':{ + 'args':{ + 'user':username + }, + 'description':'Convert a username to a matching uid.' + }, + + 'users_to_uids':{ + 'args':{ + 'users':usernames + }, + 'description':'Convert a series of usernames to a list of matching uids.' + }, + + 'uid_to_user':{ + 'args':{ + 'uid':uid + }, + 'description':'Convert a uid to a username.' + }, + + 'uids_to_users':{ + 'args':{ + 'uids':uids + }, + 'description':'Convert a series of uids to a list of matching usernames.' + }, + + 'group_to_gid':{ + 'args':{ + 'group':group + }, + 'description':'Convert a group to a matching gid.' + }, + + 'groups_to_gids':{ + 'args':{ + 'groups':groups + }, + 'description':'Converts a series of groups to a list of matching gids.' + }, + + 'gid_to_group':{ + 'args':{ + 'gid':gid + }, + 'description':'Converts a gids to a matching groupname.' + }, + + 'gids_to_groups':{ + 'args':{ + 'gids':gids + }, + 'description':'Converts a series of gids to a list of matching groupnames.' } - }, - 'description':"Set a user's home folder and move the contents to the new folder." - }, - - 'user_unlock':{ - 'args':{ - 'user':username, - }, - 'description':"Unlock a user's account." - }, - - 'users_unlock':{ - 'args':{ - 'users':usernames, - }, - 'description':"Unlock a series of users' account." - }, - - 'user_add_to_group':{ - 'args':{ - 'group':group, - 'user':username, - }, - 'description':"Append a user to a group." - }, - - 'users_add_to_group':{ - 'args':{ - 'group':group, - 'users':usernames, - }, - 'description':"Append a series of users to a group." - }, - - 'user_set_group':{ - 'args':{ - 'group':group, - 'user':username, - }, - 'description':"Set a user's group." - }, - - 'users_set_group':{ - 'args':{ - 'group':group, - 'users':usernames, - }, - 'description':"Set a series of users' group." - }, - - #PASSWD METHODS - 'passwd':{ - 'args':{ - 'user':username, - 'passwd':password - }, - 'description':"Change a user's password." - }, - - #EXISTANCE TEST METHODS - 'uid_exists':{ - 'args':{ - 'uid':uid - }, - 'description':'Test the existance of a uids.' - }, - - 'uids_exist':{ - 'args':{ - 'uids':uids - }, - 'description':'Test the existance of a series of uids.' - }, - - 'gid_exists':{ - 'args':{ - 'gid':gid - }, - 'description':'Test the existance of a gids.' - }, - - 'gids_exist':{ - 'args':{ - 'gids':gids - }, - 'description':'Test the existance of a series of groups.' - }, - - 'user_exists':{ - 'args':{ - 'user':username - }, - 'description':'Test the existance of a users.' - }, - - 'users_exist':{ - 'args':{ - 'users':usernames - }, - 'description':'Test the existance of a series of users.' - }, - - 'group_exists':{ - 'args':{ - 'group':group - }, - 'description':'Test the existance of a groups.' - }, - - 'groups_exist':{ - 'args':{ - 'groups':groups - }, - 'description':'Test the existance of a series of groups.' - }, - - #LISTING METHODS - 'uid_list':{ - 'args':{}, - 'description':'Get a list of all uids.' - }, - - 'uids_list':{ - 'args':{}, - 'description':'Get a list of all uids.' - }, - - 'gid_list':{ - 'args':{}, - 'description':'Get a list of all gids.' - }, - - 'gids_list':{ - 'args':{}, - 'description':'Get a list of all groups.' - }, - - 'user_list':{ - 'args':{}, - 'description':'Get a list of all users.' - }, - - 'users_list':{ - 'args':{}, - 'description':'Get a list of all users.' - }, - - 'group_list':{ - 'args':{}, - 'description':'Get a list of all groups.' - }, - - 'groups_list':{ - 'args':{}, - 'description':'Get a list of all groups.' - }, - - #INFO METHODS - 'user_info':{ - 'args':{ - 'user':username - }, - 'description':'Fetch info for a specified user.' - }, - - 'users_info':{ - 'args':{ - 'users':usernames - }, - 'description':'Fetch info for a specified series of users.' - }, - - 'uid_info':{ - 'args':{ - 'uid':uid - }, - 'description':'Fetch info for a specified uid.' - }, - - 'uids_info':{ - 'args':{ - 'uids':uids - }, - 'description':'Fetch info for a specified series of uids.' - }, - - 'group_info':{ - 'args':{ - 'group':group - }, - 'description':'Fetch info for a specified group.' - }, - - 'groups_info':{ - 'args':{ - 'groups':groups - }, - 'description':'Fetch info for a specified series of groups.' - }, - - 'gid_info':{ - 'args':{ - 'gid':gid - }, - 'description':'Fetch info for a specified gid.' - }, - - 'gids_info':{ - 'args':{ - 'gids':gids - }, - 'description':'Fetch info for a specified series of gids.' - }, - - #INVENTORY METHODS - 'user_inventory':{ - 'args':{}, - 'description':'Get user info for all users.' - }, - - 'users_inventory':{ - 'args':{}, - 'description':'Get user info for all users.' - }, - - 'group_inventory':{ - 'args':{}, - 'description':'Get group info for all groups.' - }, - - 'groups_inventory':{ - 'args':{}, - 'description':'Get group info for all groups.' - }, - - #CONVERSION METHODS - 'user_to_uid':{ - 'args':{ - 'user':username - }, - 'description':'Convert a username to a matching uid.' - }, - - 'users_to_uids':{ - 'args':{ - 'users':usernames - }, - 'description':'Convert a series of usernames to a list of matching uids.' - }, - - 'uid_to_user':{ - 'args':{ - 'uid':uid - }, - 'description':'Convert a uid to a username.' - }, - - 'uids_to_users':{ - 'args':{ - 'uids':uids - }, - 'description':'Convert a series of uids to a list of matching usernames.' - }, - - 'group_to_gid':{ - 'args':{ - 'group':group - }, - 'description':'Convert a group to a matching gid.' - }, - - 'groups_to_gids':{ - 'args':{ - 'groups':groups - }, - 'description':'Converts a series of groups to a list of matching gids.' - }, - - 'gid_to_group':{ - 'args':{ - 'gid':gid - }, - 'description':'Converts a gids to a matching groupname.' - }, - - 'gids_to_groups':{ - 'args':{ - 'gids':gids - }, - 'description':'Converts a series of gids to a list of matching groupnames.' - } - - } - - - def ree(self): - password = { - 'type':'string', - 'optional':False, - 'description':'A password.' - } - cmdopt = { - 'type':'string', - 'optional':False, - 'description':'An option to the command.' - } - cmdopts = { - 'type':'list*', - 'optional':False, - 'description':'An series of options to the command.' - } - username = { - 'type':'string', - 'optional':False, - 'description':'A username.', - } - usernames = { - 'type':'list*', - 'optional':False, - 'description':'A series of usernames.', - } - group = { - 'type':'string', - 'optional':False, - 'description':'A group name.' - } - groups = { - 'type':'list*', - 'optional':False, - 'description':'A series of group names.' - } - gid = { - 'type':'int', - 'optional':False, - 'description':'A gid.' - } - gids = { - 'type':'list*', - 'optional':False, - 'description':'A series of gids.' - } - ogid = { - 'type':'list*', - 'optional':False, - 'description':'An optional gid.' - } - ouid = { - 'type':'list*', - 'optional':False, - 'description':'An optional uid.' - } - uid = { - 'type':'int', - 'optional':False, - 'description':'A uid.' - } - uids = { - 'type':'list*', - 'optional':False, - 'description':'A series of uids.' - } - - return { - #GROUPADD METHODS - 'group_add':{ - 'args':{ - 'group':group, - 'gid':ogid - }, - 'description':"Create a group." - }, - - 'groups_add':{ - 'args':{ - 'groups':groups - }, - 'description':"Create series of groups." - }, - - 'group_add_non_unique':{ - 'args':{ - 'group':group, - 'gid':ogid - }, - 'description':"Create a group." - }, - - #GROUPDEL METHODS - 'group_del':{ - 'args':{ - 'group':group - }, - 'description':"Delete a group." - }, - - 'groups_del':{ - 'args':{ - 'groups':groups - }, - 'description':"Delete a series of groups." - }, - - #GROUPMOD METHODS - 'group_set_gid_non_unique':{ - 'args':{ - 'group':group, - 'gid':gid - }, - 'description':"Allows a groups gid to be non-unique." - }, - - 'group_set_gid':{ - 'args':{ - 'group':group, - 'gid':gid - }, - 'description':"Set a group's gid." - }, - - 'group_set_groupname':{ - 'args':{ - 'group':group, - 'groupname':group - }, - 'description':"Set a group's groupname." - }, - - #USERADD METHODS - 'user_add':{ - 'args':{ - 'user':username - }, - 'description':"Create a user." - }, - - 'users_add':{ - 'args':{ - 'users':usernames - }, - 'description':"Create series of users." - }, - - #USERDEL METHODS - 'user_del':{ - 'args':{ - 'user':username, - 'options':cmdopts, - }, - 'description':"Delete a user's account." - }, - - 'users_del':{ - 'args':{ - 'users':usernames, - 'options':cmdopts, - }, - 'description':"Delete a series of users' accounts." - }, - - #USERMOD METHODS - 'user_lock':{ - 'args':{ - 'user':username, - }, - 'description':"Lock a user's account." - }, - - 'users_lock':{ - 'args':{ - 'users':usernames, - }, - 'description':"Lock a series of users' accounts." - }, - - 'user_set_shell':{ - 'args':{ - 'user':username, - 'shell':{ - 'type':'string', - 'optional':False, - 'description':"A path to a shell." - } - }, - 'description':"Set a user's shell." - }, - - 'users_set_shell':{ - 'args':{ - 'users':usernames, - 'shell':{ - 'type':'string', - 'optional':False, - 'description':"A path to a shell." - } - }, - 'description':"Set a series of users' shell." - }, - - 'user_set_home':{ - 'args':{ - 'user':username, - 'home':{ - 'type':'string', - 'optional':False, - 'description':"A directory." - } - }, - 'description':"Set a user's home folder." - }, - - 'user_set_loginname':{ - 'args':{ - 'user':username, - 'loginname':username - }, - 'description':"Set a user's GECOS field." - }, - - 'user_set_comment':{ - 'args':{ - 'user':username, - 'comment':cmdopt - }, - 'description':"Set a user's GECOS field." - }, - - 'user_set_expiredate':{ - 'args':{ - 'user':username, - 'expiredate':cmdopt - }, - 'description':"Set a user's account's expiry date." - }, - - 'users_set_expiredate':{ - 'args':{ - 'expiredate':cmdopt, - 'users':usernames - }, - 'description':"Set a series of users' accounts' expiry date." - }, - - 'user_set_uid_non_unique':{ - 'args':{ - 'user':username - }, - 'description':"Set a user's uid." - }, - - 'user_set_uid':{ - 'args':{ - 'user':username, - 'uid':uid - }, - 'description':"Set a user's uid." - }, - - 'user_set_inactive':{ - 'args':{ - 'user':username, - 'inactive':cmdopt - }, - 'description':"Set a user's inactivity timer." - }, - - 'users_set_inactive':{ - 'args':{ - 'inactive':cmdopt, - 'users':usernames - }, - 'description':"Set a series of users' inactivity timer." - }, - - 'user_set_gid':{ - 'args':{ - 'user':username, - 'gid':gid - }, - 'description':"Set a user's gid." - }, - - 'users_set_gid':{ - 'args':{ - 'gid':gid, - 'users':usernames - }, - 'description':"Set a series of users' gids." - }, - - 'user_move_home':{ - 'args':{ - 'user':username, - 'home':{ - 'type':'string', - 'optional':False, - 'description':"A directory." + + } + + + def ree(self): + password = { + 'type':'string', + 'optional':False, + 'description':'A password.' + } + cmdopt = { + 'type':'string', + 'optional':False, + 'description':'An option to the command.' + } + cmdopts = { + 'type':'list*', + 'optional':False, + 'description':'An series of options to the command.' + } + username = { + 'type':'string', + 'optional':False, + 'description':'A username.', + } + usernames = { + 'type':'list*', + 'optional':False, + 'description':'A series of usernames.', + } + group = { + 'type':'string', + 'optional':False, + 'description':'A group name.' + } + groups = { + 'type':'list*', + 'optional':False, + 'description':'A series of group names.' + } + gid = { + 'type':'int', + 'optional':False, + 'description':'A gid.' + } + gids = { + 'type':'list*', + 'optional':False, + 'description':'A series of gids.' + } + ogid = { + 'type':'list*', + 'optional':False, + 'description':'An optional gid.' + } + ouid = { + 'type':'list*', + 'optional':False, + 'description':'An optional uid.' + } + uid = { + 'type':'int', + 'optional':False, + 'description':'A uid.' + } + uids = { + 'type':'list*', + 'optional':False, + 'description':'A series of uids.' + } + + return { + #GROUPADD METHODS + 'group_add':{ + 'args':{ + 'group':group, + 'gid':ogid + }, + 'description':"Create a group." + }, + + 'groups_add':{ + 'args':{ + 'groups':groups + }, + 'description':"Create series of groups." + }, + + 'group_add_non_unique':{ + 'args':{ + 'group':group, + 'gid':ogid + }, + 'description':"Create a group." + }, + + #GROUPDEL METHODS + 'group_del':{ + 'args':{ + 'group':group + }, + 'description':"Delete a group." + }, + + 'groups_del':{ + 'args':{ + 'groups':groups + }, + 'description':"Delete a series of groups." + }, + + #GROUPMOD METHODS + 'group_set_gid_non_unique':{ + 'args':{ + 'group':group, + 'gid':gid + }, + 'description':"Allows a groups gid to be non-unique." + }, + + 'group_set_gid':{ + 'args':{ + 'group':group, + 'gid':gid + }, + 'description':"Set a group's gid." + }, + + 'group_set_groupname':{ + 'args':{ + 'group':group, + 'groupname':group + }, + 'description':"Set a group's groupname." + }, + + #USERADD METHODS + 'user_add':{ + 'args':{ + 'user':username + }, + 'description':"Create a user." + }, + + 'users_add':{ + 'args':{ + 'users':usernames + }, + 'description':"Create series of users." + }, + + #USERDEL METHODS + 'user_del':{ + 'args':{ + 'user':username, + 'options':cmdopts, + }, + 'description':"Delete a user's account." + }, + + 'users_del':{ + 'args':{ + 'users':usernames, + 'options':cmdopts, + }, + 'description':"Delete a series of users' accounts." + }, + + #USERMOD METHODS + 'user_lock':{ + 'args':{ + 'user':username, + }, + 'description':"Lock a user's account." + }, + + 'users_lock':{ + 'args':{ + 'users':usernames, + }, + 'description':"Lock a series of users' accounts." + }, + + 'user_set_shell':{ + 'args':{ + 'user':username, + 'shell':{ + 'type':'string', + 'optional':False, + 'description':"A path to a shell." + } + }, + 'description':"Set a user's shell." + }, + + 'users_set_shell':{ + 'args':{ + 'users':usernames, + 'shell':{ + 'type':'string', + 'optional':False, + 'description':"A path to a shell." + } + }, + 'description':"Set a series of users' shell." + }, + + 'user_set_home':{ + 'args':{ + 'user':username, + 'home':{ + 'type':'string', + 'optional':False, + 'description':"A directory." + } + }, + 'description':"Set a user's home folder." + }, + + 'user_set_loginname':{ + 'args':{ + 'user':username, + 'loginname':username + }, + 'description':"Set a user's GECOS field." + }, + + 'user_set_comment':{ + 'args':{ + 'user':username, + 'comment':cmdopt + }, + 'description':"Set a user's GECOS field." + }, + + 'user_set_expiredate':{ + 'args':{ + 'user':username, + 'expiredate':cmdopt + }, + 'description':"Set a user's account's expiry date." + }, + + 'users_set_expiredate':{ + 'args':{ + 'expiredate':cmdopt, + 'users':usernames + }, + 'description':"Set a series of users' accounts' expiry date." + }, + + 'user_set_uid_non_unique':{ + 'args':{ + 'user':username + }, + 'description':"Set a user's uid." + }, + + 'user_set_uid':{ + 'args':{ + 'user':username, + 'uid':uid + }, + 'description':"Set a user's uid." + }, + + 'user_set_inactive':{ + 'args':{ + 'user':username, + 'inactive':cmdopt + }, + 'description':"Set a user's inactivity timer." + }, + + 'users_set_inactive':{ + 'args':{ + 'inactive':cmdopt, + 'users':usernames + }, + 'description':"Set a series of users' inactivity timer." + }, + + 'user_set_gid':{ + 'args':{ + 'user':username, + 'gid':gid + }, + 'description':"Set a user's gid." + }, + + 'users_set_gid':{ + 'args':{ + 'gid':gid, + 'users':usernames + }, + 'description':"Set a series of users' gids." + }, + + 'user_move_home':{ + 'args':{ + 'user':username, + 'home':{ + 'type':'string', + 'optional':False, + 'description':"A directory." + } + }, + 'description':"Set a user's home folder and move the contents to the new folder." + }, + + 'user_unlock':{ + 'args':{ + 'user':username, + }, + 'description':"Unlock a user's account." + }, + + 'users_unlock':{ + 'args':{ + 'users':usernames, + }, + 'description':"Unlock a series of users' account." + }, + + 'user_add_to_group':{ + 'args':{ + 'group':group, + 'user':username, + }, + 'description':"Append a user to a group." + }, + + 'users_add_to_group':{ + 'args':{ + 'group':group, + 'users':usernames, + }, + 'description':"Append a series of users to a group." + }, + + 'user_set_group':{ + 'args':{ + 'group':group, + 'user':username, + }, + 'description':"Set a user's group." + }, + + 'users_set_group':{ + 'args':{ + 'group':group, + 'users':usernames, + }, + 'description':"Set a series of users' group." + }, + + #EXISTANCE TEST METHODS + 'uid_exists':{ + 'args':{ + 'uid':uid + }, + 'description':'Test the existance of a uids.' + }, + + 'uids_exist':{ + 'args':{ + 'uids':uids + }, + 'description':'Test the existance of a series of uids.' + }, + + 'gid_exists':{ + 'args':{ + 'gid':gid + }, + 'description':'Test the existance of a gids.' + }, + + 'gids_exist':{ + 'args':{ + 'gids':gids + }, + 'description':'Test the existance of a series of groups.' + }, + + 'user_exists':{ + 'args':{ + 'user':username + }, + 'description':'Test the existance of a users.' + }, + + 'users_exist':{ + 'args':{ + 'users':usernames + }, + 'description':'Test the existance of a series of users.' + }, + + 'group_exists':{ + 'args':{ + 'group':group + }, + 'description':'Test the existance of a groups.' + }, + + 'groups_exist':{ + 'args':{ + 'groups':groups + }, + 'description':'Test the existance of a series of groups.' + }, + + #LISTING METHODS + 'uid_list':{ + 'args':{}, + 'description':'Get a list of all uids.' + }, + + 'uids_list':{ + 'args':{}, + 'description':'Get a list of all uids.' + }, + + 'gid_list':{ + 'args':{}, + 'description':'Get a list of all gids.' + }, + + 'gids_list':{ + 'args':{}, + 'description':'Get a list of all groups.' + }, + + 'user_list':{ + 'args':{}, + 'description':'Get a list of all users.' + }, + + 'users_list':{ + 'args':{}, + 'description':'Get a list of all users.' + }, + + 'group_list':{ + 'args':{}, + 'description':'Get a list of all groups.' + }, + + 'groups_list':{ + 'args':{}, + 'description':'Get a list of all groups.' + }, + + #INFO METHODS + 'user_info':{ + 'args':{ + 'user':username + }, + 'description':'Fetch info for a specified user.' + }, + + 'users_info':{ + 'args':{ + 'users':usernames + }, + 'description':'Fetch info for a specified series of users.' + }, + + 'uid_info':{ + 'args':{ + 'uid':uid + }, + 'description':'Fetch info for a specified uid.' + }, + + 'uids_info':{ + 'args':{ + 'uids':uids + }, + 'description':'Fetch info for a specified series of uids.' + }, + + 'group_info':{ + 'args':{ + 'group':group + }, + 'description':'Fetch info for a specified group.' + }, + + 'groups_info':{ + 'args':{ + 'groups':groups + }, + 'description':'Fetch info for a specified series of groups.' + }, + + 'gid_info':{ + 'args':{ + 'gid':gid + }, + 'description':'Fetch info for a specified gid.' + }, + + 'gids_info':{ + 'args':{ + 'gids':gids + }, + 'description':'Fetch info for a specified series of gids.' + }, + + #INVENTORY METHODS + 'user_inventory':{ + 'args':{}, + 'description':'Get user info for all users.' + }, + + 'users_inventory':{ + 'args':{}, + 'description':'Get user info for all users.' + }, + + 'group_inventory':{ + 'args':{}, + 'description':'Get group info for all groups.' + }, + + 'groups_inventory':{ + 'args':{}, + 'description':'Get group info for all groups.' + }, + + #CONVERSION METHODS + 'user_to_uid':{ + 'args':{ + 'user':username + }, + 'description':'Convert a username to a matching uid.' + }, + + 'users_to_uids':{ + 'args':{ + 'users':usernames + }, + 'description':'Convert a series of usernames to a list of matching uids.' + }, + + 'uid_to_user':{ + 'args':{ + 'uid':uid + }, + 'description':'Convert a uid to a username.' + }, + + 'uids_to_users':{ + 'args':{ + 'uids':uids + }, + 'description':'Convert a series of uids to a list of matching usernames.' + }, + + 'group_to_gid':{ + 'args':{ + 'groups':groups + }, + 'description':'Convert a group to a matching gid.' + }, + + 'groups_to_gids':{ + 'args':{ + 'groups':groups + }, + 'description':'Converts a series of groups to a list of matching gids.' + }, + + 'gid_to_group':{ + 'args':{ + 'gid':gid + }, + 'description':'Converts a gids to a matching groupname.' + }, + + 'gids_to_groups':{ + 'args':{ + 'gids':gids + }, + 'description':'Converts a series of gids to a list of matching groupnames.' } - }, - 'description':"Set a user's home folder and move the contents to the new folder." - }, - - 'user_unlock':{ - 'args':{ - 'user':username, - }, - 'description':"Unlock a user's account." - }, - - 'users_unlock':{ - 'args':{ - 'users':usernames, - }, - 'description':"Unlock a series of users' account." - }, - - 'user_add_to_group':{ - 'args':{ - 'group':group, - 'user':username, - }, - 'description':"Append a user to a group." - }, - - 'users_add_to_group':{ - 'args':{ - 'group':group, - 'users':usernames, - }, - 'description':"Append a series of users to a group." - }, - - 'user_set_group':{ - 'args':{ - 'group':group, - 'user':username, - }, - 'description':"Set a user's group." - }, - - 'users_set_group':{ - 'args':{ - 'group':group, - 'users':usernames, - }, - 'description':"Set a series of users' group." - }, - - #EXISTANCE TEST METHODS - 'uid_exists':{ - 'args':{ - 'uid':uid - }, - 'description':'Test the existance of a uids.' - }, - - 'uids_exist':{ - 'args':{ - 'uids':uids - }, - 'description':'Test the existance of a series of uids.' - }, - - 'gid_exists':{ - 'args':{ - 'gid':gid - }, - 'description':'Test the existance of a gids.' - }, - - 'gids_exist':{ - 'args':{ - 'gids':gids - }, - 'description':'Test the existance of a series of groups.' - }, - - 'user_exists':{ - 'args':{ - 'user':username - }, - 'description':'Test the existance of a users.' - }, - - 'users_exist':{ - 'args':{ - 'users':usernames - }, - 'description':'Test the existance of a series of users.' - }, - - 'group_exists':{ - 'args':{ - 'group':group - }, - 'description':'Test the existance of a groups.' - }, - - 'groups_exist':{ - 'args':{ - 'groups':groups - }, - 'description':'Test the existance of a series of groups.' - }, - - #LISTING METHODS - 'uid_list':{ - 'args':{}, - 'description':'Get a list of all uids.' - }, - - 'uids_list':{ - 'args':{}, - 'description':'Get a list of all uids.' - }, - - 'gid_list':{ - 'args':{}, - 'description':'Get a list of all gids.' - }, - - 'gids_list':{ - 'args':{}, - 'description':'Get a list of all groups.' - }, - - 'user_list':{ - 'args':{}, - 'description':'Get a list of all users.' - }, - - 'users_list':{ - 'args':{}, - 'description':'Get a list of all users.' - }, - - 'group_list':{ - 'args':{}, - 'description':'Get a list of all groups.' - }, - - 'groups_list':{ - 'args':{}, - 'description':'Get a list of all groups.' - }, - - #INFO METHODS - 'user_info':{ - 'args':{ - 'user':username - }, - 'description':'Fetch info for a specified user.' - }, - - 'users_info':{ - 'args':{ - 'users':usernames - }, - 'description':'Fetch info for a specified series of users.' - }, - - 'uid_info':{ - 'args':{ - 'uid':uid - }, - 'description':'Fetch info for a specified uid.' - }, - - 'uids_info':{ - 'args':{ - 'uids':uids - }, - 'description':'Fetch info for a specified series of uids.' - }, - - 'group_info':{ - 'args':{ - 'group':group - }, - 'description':'Fetch info for a specified group.' - }, - - 'groups_info':{ - 'args':{ - 'groups':groups - }, - 'description':'Fetch info for a specified series of groups.' - }, - - 'gid_info':{ - 'args':{ - 'gid':gid - }, - 'description':'Fetch info for a specified gid.' - }, - - 'gids_info':{ - 'args':{ - 'gids':gids - }, - 'description':'Fetch info for a specified series of gids.' - }, - - #INVENTORY METHODS - 'user_inventory':{ - 'args':{}, - 'description':'Get user info for all users.' - }, - - 'users_inventory':{ - 'args':{}, - 'description':'Get user info for all users.' - }, - - 'group_inventory':{ - 'args':{}, - 'description':'Get group info for all groups.' - }, - - 'groups_inventory':{ - 'args':{}, - 'description':'Get group info for all groups.' - }, - - #CONVERSION METHODS - 'user_to_uid':{ - 'args':{ - 'user':username - }, - 'description':'Convert a username to a matching uid.' - }, - - 'users_to_uids':{ - 'args':{ - 'users':usernames - }, - 'description':'Convert a series of usernames to a list of matching uids.' - }, - - 'uid_to_user':{ - 'args':{ - 'uid':uid - }, - 'description':'Convert a uid to a username.' - }, - - 'uids_to_users':{ - 'args':{ - 'uids':uids - }, - 'description':'Convert a series of uids to a list of matching usernames.' - }, - - 'group_to_gid':{ - 'args':{ - 'groups':groups - }, - 'description':'Convert a group to a matching gid.' - }, - - 'groups_to_gids':{ - 'args':{ - 'groups':groups - }, - 'description':'Converts a series of groups to a list of matching gids.' - }, - - 'gid_to_group':{ - 'args':{ - 'gid':gid - }, - 'description':'Converts a gids to a matching groupname.' - }, - - 'gids_to_groups':{ - 'args':{ - 'gids':gids - }, - 'description':'Converts a series of gids to a list of matching groupnames.' - } - - } + + } diff --git a/func/minion/modules/virt.py b/func/minion/modules/virt.py index a7a6161..3bba8ae 100644 --- a/func/minion/modules/virt.py +++ b/func/minion/modules/virt.py @@ -457,7 +457,7 @@ class Virt(func_module.FuncModule): for el in strxml: if(strxml[el] != 'None'): node2.setAttribute(el,strxml[el]) - + output_xml = open("/etc/libvirt/qemu/%s.xml" % vmid, 'w') output_xml.write(node.toxml()) return 0 diff --git a/func/minion/modules/vlan.py b/func/minion/modules/vlan.py index e9912e2..b022641 100644 --- a/func/minion/modules/vlan.py +++ b/func/minion/modules/vlan.py @@ -110,7 +110,7 @@ class Vlan(func_module.FuncModule): exitcode = os.spawnv(os.P_WAIT, self.options.vconfig, [ self.options.vconfig, "add", interface, str(vlanid)] ) else: exitcode = -1 - + return exitcode def add_permanent(self, interface, vlanid, ipaddr=None, netmask=None, gateway=None): @@ -160,7 +160,7 @@ class Vlan(func_module.FuncModule): def delete(self, interface, vlanid): """ Deletes a vlan from an interface. - + Keyword arguments: interface -- Interface to delete vlan from (string, example: "eth0") vlanid -- Vlan ID to remove (string, example: "1100") @@ -276,7 +276,7 @@ class Vlan(func_module.FuncModule): # Todo: Compare the current configuration to the supplied configuration return self.list() - + def write(self): """ Permantly applies configuration obtained through the list() method to the system. @@ -301,7 +301,7 @@ class Vlan(func_module.FuncModule): if interface not in currentconfig: for vlan in vlans: self.add_permanent(interface, vlan) - + else: for vlan in vlans: if vlan not in currentconfig[interface]: diff --git a/func/minion/modules/yumcmd.py b/func/minion/modules/yumcmd.py index b44a39f..1bc0930 100644 --- a/func/minion/modules/yumcmd.py +++ b/func/minion/modules/yumcmd.py @@ -19,7 +19,7 @@ import func_module from codes import FuncException - + # XXX Use internal yum callback or write a useful one. class DummyCallback(object): @@ -32,7 +32,7 @@ def _makeresults(tsInfo): # FIXME obviously much more should happen here :) if pkg.ts_state: results += '%s\n' % pkg - + return results def _singleAction(action, items=[], config_dict={}, **kwargs): @@ -50,10 +50,10 @@ def _singleAction(action, items=[], config_dict={}, **kwargs): pkglist = items.split(' ') else: pkglist = [] - + if len(pkglist) == 0 and action not in ('update', 'upgrade'): raise FuncException("%s requires at least one pkg" % action) - + results = 'command: %s %s\n' % (action, ' '.join(pkglist)) try: ayum.doLock() @@ -67,7 +67,7 @@ def _singleAction(action, items=[], config_dict={}, **kwargs): elif action in ('update', 'upgrade'): tx_mbrs = ayum.update(pattern=p) - + if not tx_mbrs: results += "No %s matched for %s\n" % (action, p) @@ -82,7 +82,7 @@ def _singleAction(action, items=[], config_dict={}, **kwargs): ayum.closeRpmDB() ayum.doUnlock() return results - + class Yum(func_module.FuncModule): version = "0.0.1" @@ -98,7 +98,7 @@ class Yum(func_module.FuncModule): versionlist = ayum.rpmdb.simpleVersion(main_only=True) version = versionlist[0] return versionlist - + def update(self, pkg=None, config_dict={}): return _singleAction('update', items=pkg, config_dict=config_dict) @@ -107,7 +107,7 @@ class Yum(func_module.FuncModule): def remove(self, pkg=None, config_dict={}): return _singleAction('remove', items=pkg, config_dict=config_dict) - + #def multiple(self, cmdlist=[]): # """take multiple commands as a single transaction - equiv of yum shell""" # raise FuncException("Not Implemented Yet!" @@ -127,9 +127,9 @@ class Yum(func_module.FuncModule): thislist = getattr(obj, pkgtype) output_list = sorted(map(str, thislist)) resultsdict[pkgtype] = output_list - + return resultsdict - + def check_update(self, filter=[], repo=None): """Returns a list of packages due to be updated You can specify a filter using the standard yum wildcards @@ -156,7 +156,7 @@ class Yum(func_module.FuncModule): pkg_list = exactmatch + matched return map(str, pkg_list) - + def grep(self, word): """ Grep info from module @@ -164,10 +164,10 @@ class Yum(func_module.FuncModule): results = {self.check_update:[]} update_res = self.check_update() results[self.check_update].extend([res for res in update_res if res.lower().find(word)!=-1]) - + return results grep = func_module.findout(grep) - + def register_method_args(self): """ Implementing the argument getter diff --git a/func/minion/server.py b/func/minion/server.py index 28d6fa1..e79109f 100644 --- a/func/minion/server.py +++ b/func/minion/server.py @@ -100,8 +100,8 @@ class XmlRpcInterface(object): methods = self.handlers.keys() methods.sort() return methods - - + + import func.minion.modules.func_module as fm def grep(self,word): """ @@ -111,9 +111,9 @@ class XmlRpcInterface(object): word = word.strip() modules = self.modules.keys() methods = self.handlers.keys() - + return_dict = {} - + #find modules for m in modules: if m.find(word)!=-1: @@ -138,7 +138,7 @@ class XmlRpcInterface(object): for module in self.modules.keys(): inventory[module] = [] for method in self.handlers.keys(): - # string match, ick. + # string match, ick. method_bits = method.split('.') method_module = string.join(method_bits[:-1], '.') method_name = method_bits[-1] @@ -237,21 +237,21 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, def __init__(self, args): self.allow_reuse_address = True self.modules = module_loader.load_modules() - + #load facts methods self.fact_methods = load_fact_methods() - self.minion_query = FactsMinion(method_fact_list=self.fact_methods) + self.minion_query = FactsMinion(method_fact_list=self.fact_methods) XmlRpcInterface.__init__(self) hn = func_utils.get_hostname_by_route() - + if self.config.key_file != '': self.key = self.config.key_file else: # search case-insensitively to find the right key - take the first one - if there are # more than one differing only by case then the user is going to get 'unique' behavior :) self.key = func_utils.find_files_by_hostname(hn, self.cm_config.cert_dir, '.pem')[0] - + if self.config.cert_file != '': self.cert = self.config.cert_file else: @@ -261,11 +261,11 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, self.ca = self.config.ca_file else: self.ca = "%s/ca.cert" % self.cm_config.cert_dir - - + + self._our_ca = certs.retrieve_cert_from_file(self.ca) self.acls = acls_mod.Acls(config=self.config) - + AuthedXMLRPCServer.AuthedSSLXMLRPCServer.__init__(self, args, self.key, self.cert, self.ca) @@ -278,14 +278,14 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, """ # take _this_request and hand it off to check out the acls of the method # being called vs the requesting host - + if not hasattr(self, '_this_request'): raise codes.InvalidMethodException - + r,a = self._this_request peer_cert = r.get_peer_certificate() ip = a[0] - + # generally calling conventions are: hardware.info # async convention is async.hardware.info @@ -298,7 +298,7 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, if not self.acls.check(self._our_ca, peer_cert, ip, method, params): raise codes.AccessToMethodDenied - + # Recognize ipython's tab completion calls if method == 'trait_names' or method == '_getAttributeNames': return self.handlers.keys() @@ -309,9 +309,9 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, try: if not async_dispatch: - #check if we send some queries + #check if we send some queries if len(params)>0 and type(params[0]) == dict and params[0].has_key('__fact__'): - fact_result = self.minion_query.exec_query(params[0]['__fact__'],True) + fact_result = self.minion_query.exec_query(params[0]['__fact__'],True) else: return self.get_dispatch_method(method)(*params) @@ -330,7 +330,7 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, def auth_cb(self, request, client_address): peer_cert = request.get_peer_certificate() return peer_cert.get_subject().CN - + def excepthook(exctype, value, tracebackobj): exctype_blurb = "Exception occured: %s" % exctype @@ -341,7 +341,7 @@ def excepthook(exctype, value, tracebackobj): print excvalue_blurb print exctb_blurb - log = logger.Logger().logger + log = logger.Logger().logger log.info(exctype_blurb) log.info(excvalue_blurb) log.info(exctb_blurb) diff --git a/func/overlord/base_command.py b/func/overlord/base_command.py index 275bd95..b32b8a5 100644 --- a/func/overlord/base_command.py +++ b/func/overlord/base_command.py @@ -34,7 +34,7 @@ class BaseCommand(command.Command): delegate=False mapfile=DEFAULT_MAPLOC - # temporary work around FIXME + # temporary work around FIXME # we really need a way to store what port each minion is # listening on, though this is probably workable for most # cases. Though it should probably be a different config @@ -53,5 +53,3 @@ class BaseCommand(command.Command): timeout=self.parentCommand.socket_timeout, exclude_spec=self.parentCommand.exclude_spec, config=ol_config) - - diff --git a/func/overlord/client.py b/func/overlord/client.py index 20c70a4..f649421 100644 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -92,7 +92,7 @@ class CommandAutomagic(object): # other modules with a Overlord class class Minions(object): - def __init__(self, spec, port=51234, + def __init__(self, spec, port=51234, noglobs=None, verbose=None, just_fqdns=False, groups_backend="conf", delegate=False, minionmap={},exclude_spec=None,**kwargs): @@ -107,17 +107,17 @@ class Minions(object): self.exclude_spec = exclude_spec self.cm_config = read_config(CONFIG_FILE, CMConfig) - self.overlord_config = read_config(OVERLORD_CONFIG_FILE, OverlordConfig) + self.overlord_config = read_config(OVERLORD_CONFIG_FILE, OverlordConfig) self.group_class = groups.Groups(backend=groups_backend, get_hosts_for_spec=self.get_hosts_for_spec, **kwargs) - + #lets make them sets so we dont loop again and again self.all_hosts = set() self.all_certs = set() self.all_urls = [] self._downed_hosts = [] - + def _get_new_hosts(self): self.new_hosts = self._get_group_hosts(self.spec) return self.new_hosts @@ -160,13 +160,13 @@ class Minions(object): #actual_gloob = "%s/%s.%s" % (self.cm_config.certroot, each_gloob, self.cm_config.cert_extension) certs = func_utils.find_files_by_hostname(each_gloob, self.cm_config.certroot, self.cm_config.cert_extension) - + # pull in peers if enabled for minion-to-minion if self.cm_config.peering: #peer_gloob = "%s/%s.%s" % (self.cm_config.peerroot, each_gloob, self.cm_config.cert_extension) - certs += func_utils.find_files_by_hostname(each_gloob, self.cm_config.peerroot, self.cm_config.cert_extension) - - + certs += func_utils.find_files_by_hostname(each_gloob, self.cm_config.peerroot, self.cm_config.cert_extension) + + # if we can't match this gloob and the gloob is not REALLY a glob # let the gloob be the hostname we try to connect to. if not certs and not func_utils.re_glob(each_gloob): @@ -175,7 +175,7 @@ class Minions(object): for name in aliases: #actual_gloob = "%s/%s.%s" % (self.cm_config.certroot, name, self.cm_config.cert_extension) - certs += func_utils.find_files_by_hostname(name, self.cm_config.certroot, self.cm_config.cert_extension) + certs += func_utils.find_files_by_hostname(name, self.cm_config.certroot, self.cm_config.cert_extension) if self.cm_config.peering: #peer_gloob = "%s/%s.%s" % (self.cm_config.peerroot, name, self.cm_config.cert_extension) certs += func_utils.find_files_by_hostname(name, self.cm_config.peerroot, self.cm_config.cert_extension) @@ -209,7 +209,7 @@ class Minions(object): def _get_all_hosts(self): """ Gets hosts that are included and excluded by user - a better orm like spec so user may say + a better orm like spec so user may say func "*" --exclude "www.*;@mygroup" ... """ included_part = self._get_hosts_for_specs(self.spec.split(";")+self.new_hosts) @@ -232,7 +232,7 @@ class Minions(object): self._get_new_hosts() self._get_all_hosts() - #we keep it all the time as a set so + #we keep it all the time as a set so return list(self.all_hosts) def get_urls(self, hosts=[]): @@ -240,9 +240,9 @@ class Minions(object): self._get_new_hosts() self._get_all_hosts() hosts = self.all_hosts - + results = [] - + for host in hosts: if host in self.downed_hosts: if self.verbose: @@ -255,7 +255,7 @@ class Minions(object): if not host_res in results: # this might get slow if there are thousands of hosts results.append(host_res) - + if self.verbose and len(results) == 0: sys.stderr.write("no hosts matched\n") @@ -272,7 +272,7 @@ class Minions(object): """returns a list of minions which are known to not be up""" if self._downed_hosts: return self._downed_hosts - + hosts = [] if self.overlord_config.host_down_list and \ os.path.exists(self.overlord_config.host_down_list): @@ -284,11 +284,11 @@ class Minions(object): if hn not in hosts: hosts.append(hn) fo.close() - + self._downed_hosts = hosts - + return self._downed_hosts - + downed_hosts = property(fget=lambda self: self._get_downed_hosts()) class PuppetMinions(Minions): @@ -302,7 +302,7 @@ class PuppetMinions(Minions): Minions.__init__(self, spec, port=port, noglobs=noglobs, verbose=verbose, just_fqdns=just_fqdns, groups_backend=groups_backend, - delegate=delegate, minionmap=minionmap, + delegate=delegate, minionmap=minionmap, exclude_spec=exclude_spec,**kwargs) def _get_hosts_for_spec(self,each_gloob): @@ -364,9 +364,9 @@ class PuppetMinions(Minions): if fnmatch.fnmatch(hostname, each_gloob): matched_gloob = True tmp_hosts.add(hostname) - + # if we can't match this gloob and the gloob is not REALLY a glob - # then toss this at gethostbyname_ex() and see if any of the cname + # then toss this at gethostbyname_ex() and see if any of the cname # or aliases matches _something_ we know about if not matched_gloob and not func_utils.re_glob(each_gloob): found_by_alias = False @@ -408,11 +408,11 @@ class PuppetMinions(Minions): (crap, serial) = line.split(':') serial = serial.strip() serial = int(serial, 16) - serials.append(serial) - + serials.append(serial) + self._revoked_serials = serials - - + + # does the hostnamegoo actually expand to anything? @@ -451,7 +451,7 @@ class Overlord(object): if config: self.config = config - self.overlord_config = self.config # for backward compat + self.overlord_config = self.config # for backward compat self.server_spec = server_spec @@ -463,7 +463,7 @@ class Overlord(object): self.verbose = verbose self.interactive = interactive self.noglobs = noglobs - + # the default self.timeout = DEFAULT_TIMEOUT # the config file @@ -491,7 +491,7 @@ class Overlord(object): self._mc = PuppetMinions else: self._mc = Minions - + if self.delegate: try: mapstream = file(self.mapfile, 'r').read() @@ -513,20 +513,20 @@ class Overlord(object): self.setup_ssl() self.methods = module_loader.load_methods('func/overlord/modules/', overlord_module.BaseModule, self) - + def setup_ssl(self, client_key=None, client_cert=None, ca=None): # defaults go: # certmaster key, cert, ca # funcd key, cert, ca # raise FuncClientError - + if not client_key and self.config.key_file != '': client_key = self.config.key_file if not client_cert and self.config.cert_file != '': client_cert = self.config.cert_file if not ca and self.config.ca_file != '': ca = self.config.ca_file - + ol_key = '%s/certmaster.key' % self.cm_config.cadir ol_crt = '%s/certmaster.crt' % self.cm_config.cadir myname = func_utils.get_hostname_by_route() @@ -538,7 +538,7 @@ class Overlord(object): self.ca = '%s/certmaster.crt' % self.cm_config.cadir if not os.access(self.ca, os.R_OK): self.ca = '%s/ca.cert' % self.cm_config.cert_dir - if client_key and client_cert and ca: + if client_key and client_cert and ca: if (os.access(client_key, os.R_OK) and os.access(client_cert, os.R_OK) and os.access(ca, os.R_OK)): self.key = client_key @@ -554,10 +554,10 @@ class Overlord(object): else: raise Func_Client_Exception, 'Cannot read ssl credentials: ssl, cert, ca. '+\ 'Ensure you have permission to read files in /etc/pki/certmaster/ directory.' - - - + + + def __getattr__(self, name): """ This getattr allows manipulation of the object as if it were @@ -579,7 +579,7 @@ class Overlord(object): """ Use this to acquire status from jobs when using run with async client handles """ - status,async_result = jobthing.job_status(jobid, client_class=Overlord, + status,async_result = jobthing.job_status(jobid, client_class=Overlord, client_class_config=self.config) if not self.overlord_query.fact_query: #that will use the default overlord job_status @@ -595,8 +595,8 @@ class Overlord(object): to get current ids with their short results in the database """ return jobthing.get_open_ids() - - + + def tail_log(self,job_id,host=None,remove_old=None): """ Method will read from minion the log file @@ -604,15 +604,15 @@ class Overlord(object): output of it ,pretty easy ... """ from func.index_db import get_index_data,delete_index_data - from func.jobthing import JOB_ID_FINISHED,JOB_ID_LOST_IN_SPACE,JOB_ID_REMOTE_ERROR,JOB_ID_RUNNING - RETAIN_INTERVAL = 60 * 60 + from func.jobthing import JOB_ID_FINISHED,JOB_ID_LOST_IN_SPACE,JOB_ID_REMOTE_ERROR,JOB_ID_RUNNING + RETAIN_INTERVAL = 60 * 60 import time - + code,result = Overlord(self.server_spec).job_status(job_id) if code == JOB_ID_RUNNING: return (None,False) index_data = get_index_data() - + #if we should remove old ones if remove_old: rm_list = [] @@ -625,7 +625,7 @@ class Overlord(object): #deleting the old ones print "I will delete those : ",rm_list delete_index_data(rm_list) - + host_output = {} if index_data.has_key(job_id): host_tuple = index_data[job_id] @@ -644,7 +644,7 @@ class Overlord(object): return (None,True) else: return (None,True) - + if code in [JOB_ID_FINISHED,JOB_ID_LOST_IN_SPACE,JOB_ID_REMOTE_ERROR]: #means that job isfinished there is no need to wait for more return (host_output,True) @@ -660,13 +660,13 @@ class Overlord(object): """ from func.index_db import get_index_data - from func.jobthing import JOB_ID_FINISHED,JOB_ID_LOST_IN_SPACE,JOB_ID_REMOTE_ERROR,JOB_ID_RUNNING - + from func.jobthing import JOB_ID_FINISHED,JOB_ID_LOST_IN_SPACE,JOB_ID_REMOTE_ERROR,JOB_ID_RUNNING + code,result = Overlord(self.server_spec).job_status(job_id) if code == JOB_ID_RUNNING: return (None,False) index_data = get_index_data() - + host_output = {} if index_data.has_key(job_id): host_tuple = index_data[job_id] @@ -680,7 +680,7 @@ class Overlord(object): return (None,True) else: return (None,True) - + if code in [JOB_ID_FINISHED,JOB_ID_LOST_IN_SPACE,JOB_ID_REMOTE_ERROR]: #means that job isfinished there is no need to wait for more if host_output[host] == [0,0]: @@ -708,7 +708,7 @@ class Overlord(object): if minion not in minionlist: #ugh, brute force :( minionlist.append(minion) return minionlist - + # ----------------------------------------------- def run(self, module, method, args, nforks=1): @@ -734,17 +734,17 @@ class Overlord(object): return self.overlord_query.display_active(minion_result) else: return minion_result - + delegatedhash = {} directhash = {} completedhash = {} - + #First we get all call paths for minions not directly beneath this overlord dele_paths = dtools.get_paths_for_glob(self.server_spec, self.minionmap) - + #Then we group them together in a dictionary by a common next hop (single_paths,grouped_paths) = dtools.group_paths(dele_paths) - + for group in grouped_paths.keys(): delegatedhash.update(self.run_direct(module, method, @@ -752,13 +752,13 @@ class Overlord(object): nforks, call_path=grouped_paths[group], suboverlord=group)) - + #Next, we run everything that can be run directly beneath this overlord #Why do we do this after delegation calls? Imagine what happens when #reboot is called... if single_paths != []: directhash.update(self.run_direct(module,method,args,nforks)) - + #poll async results if we've async turned on if self.async: while (len(delegatedhash) + len(directhash)) > 0: @@ -772,7 +772,7 @@ class Overlord(object): else: completedhash.update(async_results[minion]) del delegatedhash[minion] - + for minion in directhash.keys(): results = directhash[minion] (return_code, async_results) = self.job_status(results) @@ -788,20 +788,20 @@ class Overlord(object): return self.overlord_query.display_active(completedhash) else: return completedhash - - + + #we didn't instantiate this Overlord in async mode, so we just return the #result hash completedhash.update(delegatedhash) completedhash.update(directhash) - + if self.overlord_query.fact_query: return self.overlord_query.display_active(completedhash) else: return completedhash - - + + # ----------------------------------------------- def run_direct(self, module, method, args, nforks=1, *extraargs, **kwargs): @@ -822,7 +822,7 @@ class Overlord(object): use_delegate = False delegation_path = [] - + def process_server(bucketnumber, buckets, server): conn = sslclient.FuncServer(server, self.key, self.cert, self.ca, self.timeout) # conn = xmlrpclib.ServerProxy(server) @@ -852,7 +852,7 @@ class Overlord(object): # this is the point at which we make the remote call. if use_delegate: retval = getattr(conn, meth)(module, - method, + method, args, delegation_path, self.async, @@ -862,7 +862,7 @@ class Overlord(object): if self.interactive: print retval - + except Exception, e: (t, v, tb) = sys.exc_info() retval = utils.nice_exception(t,v,tb) @@ -877,7 +877,7 @@ class Overlord(object): right = server.rfind(":") server_name = server[left:right] return (server_name, retval) - + if kwargs.has_key('call_path'): #we're delegating if this key exists delegation_path = kwargs['call_path'] spec = kwargs['suboverlord'] #the sub-overlord directly beneath this one @@ -891,7 +891,7 @@ class Overlord(object): #print "Minion_url is :",minionurls #print "Process server is :",process_server - + if not self.noglobs: if self.nforks > 1 or self.async: # using forkbomb module to distribute job over multiple threads @@ -905,25 +905,25 @@ class Overlord(object): results = {} for x in minionurls: (nkey,nvalue) = process_server(0, 0, x) - results[nkey] = nvalue + results[nkey] = nvalue else: - + # globbing is not being used, but still need to make sure # URI is well formed. # expanded = expand_servers(self.server_spec, port=self.port, noglobs=True, verbose=self.verbose)[0] expanded_minions = self._mc(spec, port=self.port, noglobs=True, verbose=self.verbose) minions = expanded_minions.get_urls()[0] results = process_server(0, 0, minions) - + if self.delegate and self.async: return {spec:results} - + if use_delegate: if utils.is_error(results[spec]): print results return results return results[spec] - + return results # ----------------------------------------------- @@ -954,108 +954,108 @@ class Overlord(object): if x > max: max = x return max - + def filter(self,*args,**kwargs): """ Filter The facts and doesnt call - the minion directly just gives back a + the minion directly just gives back a reference to the same object ANDED """ - #create a fresh overlord + #create a fresh overlord fresh_overlord = self._clone() fresh_overlord.overlord_query.fact_query = self.overlord_query.fact_query.filter(*args,**kwargs) - - #give back the fresh reference + + #give back the fresh reference return fresh_overlord - + def filter_or(self,*args,**kwargs): """ Filter The facts and doesnt call - the minion directly just gives back a + the minion directly just gives back a reference to the same object ORED """ - #create a fresh overlord + #create a fresh overlord fresh_overlord = self._clone() fresh_overlord.overlord_query.fact_query = self.overlord_query.fact_query.filter_or(*args,**kwargs) - #give back the fresh reference + #give back the fresh reference return fresh_overlord - + def and_and(self,*args,**kwargs): """ Filter The facts and doesnt call - the minion directly just gives back a + the minion directly just gives back a reference to the same object ORED """ - #create a fresh overlord + #create a fresh overlord fresh_overlord = self._clone() fresh_overlord.overlord_query.fact_query = self.overlord_query.fact_query.and_and(*args,**kwargs) - - #give back the fresh reference + + #give back the fresh reference return fresh_overlord - - + + def and_or(self,*args,**kwargs): """ Filter The facts and doesnt call - the minion directly just gives back a + the minion directly just gives back a reference to the same object ORED """ - #create a fresh overlord + #create a fresh overlord fresh_overlord = self._clone() fresh_overlord.overlord_query.fact_query = self.overlord_query.fact_query.and_or(*args,**kwargs) - #give back the fresh reference + #give back the fresh reference return fresh_overlord - + def or_or(self,*args,**kwargs): """ Filter The facts and doesnt call - the minion directly just gives back a + the minion directly just gives back a reference to the same object ORED """ - #create a fresh overlord + #create a fresh overlord fresh_overlord = self._clone() fresh_overlord.overlord_query.fact_query = self.overlord_query.fact_query.or_or(*args,**kwargs) - #give back the fresh reference + #give back the fresh reference return fresh_overlord - + def or_and(self,*args,**kwargs): """ Filter The facts and doesnt call - the minion directly just gives back a + the minion directly just gives back a reference to the same object ORED """ - #create a fresh overlord + #create a fresh overlord fresh_overlord = self._clone() fresh_overlord.overlord_query.fact_query = self.overlord_query.fact_query.or_and(*args,**kwargs) - #give back the fresh reference + #give back the fresh reference return fresh_overlord def set_complexq(self,q_object,connector=None): - #create a fresh overlord + #create a fresh overlord fresh_overlord = self._clone() fresh_overlord.overlord_query.fact_query = self.overlord_query.fact_query.set_compexq(q_object,connector) - #give back the fresh reference + #give back the fresh reference return fresh_overlord - + def _clone(self,klass=None): """ That method is for situations where we use query stuff - when querying it is important to return a fresh object of - Overlord instead of working on the same oone,so we can + when querying it is important to return a fresh object of + Overlord instead of working on the same oone,so we can work on one instance which reproduces many temporary ones """ from copy import copy if klass is None: klass = self.__class__ - + #create a fresh copy c = klass(copy(self.server_spec), port=copy(self.port), @@ -1075,4 +1075,4 @@ class Overlord(object): class Client(Overlord): def __init__(self, *args, **kwargs): Overlord.__init__(self, *args, **kwargs) - # provided for backward compatibility only + # provided for backward compatibility only diff --git a/func/overlord/cmd_modules/call.py b/func/overlord/cmd_modules/call.py index a351219..e674dec 100644 --- a/func/overlord/cmd_modules/call.py +++ b/func/overlord/cmd_modules/call.py @@ -42,9 +42,9 @@ class FactsCommand(object): "=":"", "<":"lt", ">":"gt", - } + } __valid_c_operators={ - + "<=":"lte", ">=":"gte" } @@ -62,7 +62,7 @@ class FactsCommand(object): return False elif filter and filteror: return False - + tmp_arg = filter or filteror parse_result = self.__parse_fact_args(tmp_arg) if not parse_result: @@ -72,13 +72,13 @@ class FactsCommand(object): def __parse_fact_args(self,args): """ - Parses the format of the arguments which is like + Parses the format of the arguments which is like keyword=value,keyword<value,value in keyword """ comma_separated = args.split(",") if not self.__is_coma_ok(comma_separated): return False - + final_dict = {} for com_key in comma_separated: @@ -88,7 +88,7 @@ class FactsCommand(object): return False final_dict[res[0]]=res[1] - + return final_dict @@ -101,31 +101,31 @@ class FactsCommand(object): #self.outputUsage() return False return True - + def __convert_keyword(self,keyword): """ Convert keyword to a ready to use Overlord parameter """ keyword = keyword.strip() - + #check for space first if keyword.find(" ")!=-1: #do the keyword operations first tmp_kw = keyword.split() return self.__join_keyword(tmp_kw,self.__valid_keywords) - + else: for op in self.__valid_c_operators: if keyword.find(op)!=-1: tmp_kw = keyword.split(op) - return self.__join_keyword(tmp_kw,self.__valid_c_operators,op) + return self.__join_keyword(tmp_kw,self.__valid_c_operators,op) #do the operator things for op in self.__valid_operators: if keyword.find(op)!=-1: tmp_kw = keyword.split(op) - return self.__join_keyword(tmp_kw,self.__valid_operators,op) + return self.__join_keyword(tmp_kw,self.__valid_operators,op) return False - + def __join_keyword(self,tmp_kw,valid_set,operator=None): """ A common util operation we do @@ -142,12 +142,12 @@ class FactsCommand(object): return False else: value = tmp_kw[1] - + #doing that trick to not to loose some of the oprators when showing if not operator.strip() in valid_set.keys(): - return False - + return False + if operator in self.__valid_keywords.keys(): return "".join([value.strip(),"__",valid_set[operator.strip()]]),tmp_kw[0].strip() else: @@ -203,7 +203,7 @@ class Call(base_command.BaseCommand): self.parser.add_option('-o', '--logone', dest="logone", help="Polls for that call for minion side to get some useful output info,for only one host,must suply job_id;host as parameter", action="store") - + self.parser.add_option('-r', '--progress', dest="progress", help="Polls for that call for minion side to get the progress.", action="store") @@ -213,7 +213,7 @@ class Call(base_command.BaseCommand): self.parser.add_option("", "--filteror", dest="filteror", help="use filteror to or minion facts", action="store") - + def handleOptions(self, options): self.options = options self.verbose = options.verbose @@ -225,13 +225,13 @@ class Call(base_command.BaseCommand): self.argv = argv return base_command.BaseCommand.parse(self, argv) - + def format_return(self, data): """ The call module supports multiple output return types, the default is pprint. """ - + if self.options.xmlrpc: return xmlrpclib.dumps((data,"")) @@ -267,7 +267,7 @@ class Call(base_command.BaseCommand): if not args: self.outputUsage() return - + self.module = args[0] if len(args) > 1: self.method = args[1] @@ -292,13 +292,13 @@ class Call(base_command.BaseCommand): self.async = self.options.async self.forks = self.options.forks self.delegate = self.options.delegate - + self.server_spec = self.parentCommand.server_spec #do we have exclude option activated ? self.exclude_spec = self.parentCommand.exclude_spec - + self.getOverlord() - + #the facts part inserted here if self.options.filter or self.options.filteror: facts = FactsCommand() @@ -306,13 +306,13 @@ class Call(base_command.BaseCommand): if not result_fact: self.outputUsage() return - + if self.options.filter: #print "The result facts are : ",result_fact self.overlord_obj=self.overlord_obj.filter(**result_fact) elif self.options.filteror: self.overlord_obj=self.overlord_obj.filter_or(**result_fact) - + #end of the facts parsing @@ -328,11 +328,11 @@ class Call(base_command.BaseCommand): return async_results #log for only one machine which is more reasonable instead - #of doing it for thousands ... + #of doing it for thousands ... if self.options.logone: self._poll_logs(self.module,self.options.logone) return #terminate no need for more - + if self.options.progress: self._print_progress(self.module,self.options.progress) return #terminate no need for more @@ -366,7 +366,7 @@ class Call(base_command.BaseCommand): """ import time from func.minion.modules.jobs import NUM_OF_LINES - #a constant that will tell us from how many same + #a constant that will tell us from how many same # logs we will accept that the rest of logs is the #same we should stop somewhere ! print_result = {} @@ -378,13 +378,13 @@ class Call(base_command.BaseCommand): poll_res = self.overlord_obj.tail_log(job_id,host,True) else: poll_res = self.overlord_obj.tail_log(job_id,host) - + if not poll_res[0]: print "Logging data is initializing ..." time.sleep(0.5) poll_res = self.overlord_obj.tail_log(job_id,host) continue - + #print the stuff you collected for minion,log in poll_res[0].iteritems(): log = self._convert_log_to_list(log) @@ -397,46 +397,46 @@ class Call(base_command.BaseCommand): #print "---------------------------------------------" #print "PRINT_RESULT : ",print_result[minion] #print "LOG IS ",log - + to_print[minion]=list(set(log).difference(set(print_result[minion]))) print_result[minion]=list(set(print_result[minion]).union(set(to_print[minion]))) #should empty the buffer a little bit #think if you have a file which is 1 GB :) #print_result[minion] = print_result[minion][-NUM_OF_LINES:] #print "PRINT_RESULT : ",print_result[minion] - + #print "to_print ",to_print #print "---------------------------------------------" #raw_input() - + self._print_dict_result(to_print,print_first_time) if print_first_time and host: print_first_time = False - + time.sleep(0.5) - + def _print_progress(self,job_id,host): """ Gets the progress for job_id and host """ import time - from func.utils import ProgressBar,TerminalController - + from func.utils import ProgressBar,TerminalController + poll_res = (None,False)#initial state first_time = True while not poll_res[1]:#while the job_id is not finished poll_res = self.overlord_obj.check_progress(job_id,host) - #print poll_res + #print poll_res if not poll_res[0]: time.sleep(0.5) continue - + if first_time: - + term = TerminalController() progress = ProgressBar(term, 'Progress Status',minValue=poll_res[0][host][0],maxValue=poll_res[0][host][1]) first_time = False - + #update the progress bar progress.update(poll_res[0][host][0]) #sleep a little bit @@ -448,11 +448,11 @@ class Call(base_command.BaseCommand): #clear the progress bar and say it is done progress.clear() print "JOB FINISHED : ",job_id - + def _print_dict_result(self,result,print_host=True): """ - An util method that just prints info + An util method that just prints info in a result dictionary ... """ for minion,logs in result.iteritems(): @@ -460,7 +460,7 @@ class Call(base_command.BaseCommand): if print_host: print "------HOST : %s -------"%minion print "\n".join(logs) - + def _convert_log_to_list(self,log): res = [] diff --git a/func/overlord/cmd_modules/check.py b/func/overlord/cmd_modules/check.py index 0fc141d..422cd4f 100644 --- a/func/overlord/cmd_modules/check.py +++ b/func/overlord/cmd_modules/check.py @@ -49,58 +49,58 @@ class CheckAction(base_command.BaseCommand): self.minion_config = read_config('/etc/certmaster/minion.conf', MinionConfig) self.funcd_config = read_config('/etc/func/minion.conf', FuncdConfig) - + if not self.check_certmaster and not self.check_minion: - print "* specify --certmaster, --minion, or both" - return + print "* specify --certmaster, --minion, or both" + return else: - print "SCAN RESULTS:" + print "SCAN RESULTS:" hostname = func_utils.get_hostname_by_route() print "* FQDN is detected as %s, verify that is correct" % hostname self.check_iptables() if not os.getuid() == 0: - print "* root is required to run these setup tests" - return + print "* root is required to run these setup tests" + return if self.check_minion: - # check that funcd is running - self.check_service("funcd") + # check that funcd is running + self.check_service("funcd") + + # check that the configured certmaster is reachable + self.check_talk_to_certmaster() - # check that the configured certmaster is reachable - self.check_talk_to_certmaster() - if self.check_certmaster: - # check that certmasterd is running - self.check_service("certmasterd") - - # see if we have any waiting CSRs - # FIXME: TODO - - # see if we have signed any certs - # FIXME: TODO - - self.server_spec = self.parentCommand.server_spec - self.getOverlord() - - results = self.overlord_obj.test.add(1,2) - hosts = results.keys() - if len(hosts) == 0: - print "* no systems have signed certs" - else: - failed = 0 - for x in hosts: - if results[x] != 3: - failed = failed+1 - if failed != 0: - print "* unable to connect to %s registered minions from overlord" % failed - print "* run func '*' ping to check status" - - # see if any of our certs have expired + # check that certmasterd is running + self.check_service("certmasterd") + + # see if we have any waiting CSRs + # FIXME: TODO + + # see if we have signed any certs + # FIXME: TODO + + self.server_spec = self.parentCommand.server_spec + self.getOverlord() + + results = self.overlord_obj.test.add(1,2) + hosts = results.keys() + if len(hosts) == 0: + print "* no systems have signed certs" + else: + failed = 0 + for x in hosts: + if results[x] != 3: + failed = failed+1 + if failed != 0: + print "* unable to connect to %s registered minions from overlord" % failed + print "* run func '*' ping to check status" + + # see if any of our certs have expired # warn about iptables if running print "End of Report." @@ -114,18 +114,18 @@ class CheckAction(base_command.BaseCommand): def check_iptables(self): if os.path.exists("/etc/rc.d/init.d/iptables"): rc = sub_process.call("/sbin/service iptables status >/dev/null 2>/dev/null", shell=True) - + if rc == 0: - # FIXME: don't hardcode port - print "* iptables may be running" - print "Insure that port %s is open for minions to connect to certmaster" % self.minion_config.certmaster_port - print "Insure that port %s is open for overlord to connect to minions" % self.funcd_config.listen_port + # FIXME: don't hardcode port + print "* iptables may be running" + print "Insure that port %s is open for minions to connect to certmaster" % self.minion_config.certmaster_port + print "Insure that port %s is open for overlord to connect to minions" % self.funcd_config.listen_port def check_talk_to_certmaster(self): # FIXME: don't hardcode port master_uri = "http://%s:%s/" % (self.minion_config.certmaster, self.minion_config.certmaster_port) print "* this minion is configured in /etc/certmaster/minion.conf" - print " to talk to host '%s' on port %s for certs, verify that is correct" % (self.minion_config.certmaster, + print " to talk to host '%s' on port %s for certs, verify that is correct" % (self.minion_config.certmaster, self.minion_config.certmaster_port) # this will be a 501, unsupported GET, but we should be # able to tell if we can make contact diff --git a/func/overlord/cmd_modules/copyfile.py b/func/overlord/cmd_modules/copyfile.py index 711c4dd..3f2263d 100644 --- a/func/overlord/cmd_modules/copyfile.py +++ b/func/overlord/cmd_modules/copyfile.py @@ -46,7 +46,7 @@ class CopyFile(base_command.BaseCommand): if not self.options.filename or not self.options.remotepath: self.outputUsage() return - + self.server_spec = self.parentCommand.server_spec self.getOverlord() diff --git a/func/overlord/cmd_modules/grep.py b/func/overlord/cmd_modules/grep.py index db60cd6..acb97df 100644 --- a/func/overlord/cmd_modules/grep.py +++ b/func/overlord/cmd_modules/grep.py @@ -24,7 +24,7 @@ class Grep(base_command.BaseCommand): name = "grep" usage = "grep [--modules = 'module1,module2'] search_term" summary = "Greps for some keyword in modules useful for troubleshooting" - + def addOptions(self): """ Add options for grep utility ... @@ -44,49 +44,49 @@ class Grep(base_command.BaseCommand): help="modules to be searched", default=[], action="append") - - + + def handleOptions(self, options): self.options = options self.verbose = options.verbose - + # I'm not really a fan of the "module methodname" approach # but we'll keep it for now -akl def parse(self, argv): self.argv = argv return base_command.BaseCommand.parse(self, argv) - - + + def do(self, args): """ Grepping the stuf real part """ - + if not args: self.outputUsage() return - + #the search keyword self.word = args[0] - + self.async = self.options.async self.delegate = self.options.delegate - + self.server_spec = self.parentCommand.server_spec self.getOverlord() host_modules = self._get_host_grep_modules(self.server_spec) results = {} - + # We could do this across hosts or across modules. Not sure # which is better, this is across hosts (aka, walk across the # hosts, then ask all the module.grep methods to it, then on to # next host - + existent_minions_class = self.overlord_obj.minions_class # keep a copy - + for host in host_modules.keys(): host_only_mc = self.overlord_obj._mc(host, noglobs=True) host_only_mc.get_all_hosts() @@ -95,24 +95,24 @@ class Grep(base_command.BaseCommand): if self.options.modules and module in self.options.modules: if self.options.verbose: print "Scanning module: %s on host: %s" %(module, host) - + tmp_res = self.overlord_obj.run(module,"grep",[self.word]) - + if self.options.async: tmp_res = self.overlord_obj.local.utils.async_poll(tmp_res,None) #FIXME: I'm not sure what the best format for this is... if tmp_res[host]: print "%s: %s" % (host, pprint.pformat(tmp_res[host])) - + self.overlord_obj.minions_class = existent_minions_class # put it back - + def _get_host_grep_modules(self, server_spec): """ In cases when user doesnt supply the module list we have to consider that all of the modules are chosen so that method will return a list of them """ - + #insetad of getting all of the modules we consider #that all of machines has the same modules ... @@ -121,16 +121,16 @@ class Grep(base_command.BaseCommand): #FIXME: we need to change this to create a dict of hostname->modules # so we only call module.grep on systems that report it. things like # virt/hardware aren't available on all guests - + if not hasattr(self, 'overlord_obj'): self.getOverlord() - + hosts = self.overlord_obj.minions_class.get_all_hosts() - existent_minions_class = self.overlord_obj.minions_class # keep a copy + existent_minions_class = self.overlord_obj.minions_class # keep a copy if not hosts: raise Exception("No minions on system!") - + for host in hosts: host_only_mc = self.overlord_obj._mc(host, noglobs=True) self.overlord_obj.minions_class = host_only_mc @@ -147,6 +147,6 @@ class Grep(base_command.BaseCommand): if not host_modules.has_key(host): host_modules[host] = [] host_modules[host].append(module) - + self.overlord_obj.minions_class = existent_minions_class # put it back return host_modules diff --git a/func/overlord/cmd_modules/group.py b/func/overlord/cmd_modules/group.py index 4b263fe..331aff3 100644 --- a/func/overlord/cmd_modules/group.py +++ b/func/overlord/cmd_modules/group.py @@ -22,41 +22,41 @@ class Group(base_command.BaseCommand): usage = "group [--add_group] [--remove_group] [--list_group] [--list_all] [--add_host] [--remove_host] [--list_hosts] {--exclude}" summary = "allows a specific module and method to be called" def addOptions(self): - + self.parser.add_option("-v", "--verbose", dest="verbose", default=self.verbose, action="store_true") - - self.parser.add_option("--ag", "--add_group", + + self.parser.add_option("--ag", "--add_group", dest="add_group", action="store_true") - - self.parser.add_option("--lg", "--list_group", + + self.parser.add_option("--lg", "--list_group", dest="list_group", action="store_true") - - self.parser.add_option("--rg", "--remove_group", + + self.parser.add_option("--rg", "--remove_group", dest="remove_group", action="store_true") - - self.parser.add_option("--la", "--list_all", + + self.parser.add_option("--la", "--list_all", dest="list_all", action="store_true") - - self.parser.add_option("--ah", "--add_host", + + self.parser.add_option("--ah", "--add_host", dest="add_host", action="store_true") - self.parser.add_option("--rh", "--remove_host", + self.parser.add_option("--rh", "--remove_host", dest="remove_host", action="store_true") - self.parser.add_option("--lh", "--list_hosts", + self.parser.add_option("--lh", "--list_hosts", dest="list_hosts", action="store_true") - self.parser.add_option("--e", "--exclude", + self.parser.add_option("--e", "--exclude", dest="exclude", action="store", type="string") @@ -73,7 +73,7 @@ class Group(base_command.BaseCommand): self.argv = argv return base_command.BaseCommand.parse(self, argv) - + def do(self, args): @@ -144,7 +144,7 @@ class Group(base_command.BaseCommand): if self.options.exclude: exclude = self._parse_args_list(self.options.exclude) exclude = self._match_group_host(exclude) - + for g_i,g_e in zip(args.iteritems(),exclude.iteritems()): for host_include,host_exclude in zip(g_i[1],g_e[1]): self.group.add_hosts_to_group_glob(g_i[0][1:],host_include,exclude_string=host_exclude) @@ -189,7 +189,7 @@ class Group(base_command.BaseCommand): print self.group.get_hosts_glob(args,exclude_string=self.options.exclude) else: print self.group.get_hosts_glob(args) - + def _parse_args_list(self,args): """ Parsing the args sometimes we separate em @@ -203,7 +203,7 @@ class Group(base_command.BaseCommand): def _match_group_host(self,args): """ - Returns a dictionary for + Returns a dictionary for {group:hosts} """ groups = {} @@ -225,5 +225,3 @@ class Group(base_command.BaseCommand): groups[group]=[] groups[group].append("*") return groups - - diff --git a/func/overlord/cmd_modules/listminions.py b/func/overlord/cmd_modules/listminions.py index 8d36d15..23e84dd 100644 --- a/func/overlord/cmd_modules/listminions.py +++ b/func/overlord/cmd_modules/listminions.py @@ -33,7 +33,7 @@ class ListMinions(base_command.BaseCommand): if options.verbose: self.verbose = self.options.verbose - + def do(self, args): self.server_spec = self.parentCommand.server_spec @@ -43,4 +43,3 @@ class ListMinions(base_command.BaseCommand): servers.sort() for server in servers: print server - diff --git a/func/overlord/cmd_modules/show.py b/func/overlord/cmd_modules/show.py index 7495396..3716523 100644 --- a/func/overlord/cmd_modules/show.py +++ b/func/overlord/cmd_modules/show.py @@ -62,7 +62,7 @@ class Show(base_command.BaseCommand): self.argv = argv return base_command.BaseCommand.parse(self, argv) - + def do(self, args): pass diff --git a/func/overlord/cmd_modules/show_hardware.py b/func/overlord/cmd_modules/show_hardware.py index 233c76f..040c119 100644 --- a/func/overlord/cmd_modules/show_hardware.py +++ b/func/overlord/cmd_modules/show_hardware.py @@ -30,11 +30,11 @@ class ShowHardware(base_command.BaseCommand): def addOptions(self): self.parser.add_option("-v", "--verbose", dest="verbose", action="store_true") - + def handleOptions(self, options): pass - + def parse(self, argv): self.argv = argv return base_command.BaseCommand.parse(self,argv) @@ -43,12 +43,12 @@ class ShowHardware(base_command.BaseCommand): self.server_spec = self.parentCommand.parentCommand.server_spec self.getOverlord() - + results = self.overlord_obj.run("hardware", "info", []) - # if the user + # if the user top_options = ["port","verbose"] - + for minion in results: print "%s:" % minion minion_data = results[minion] @@ -56,9 +56,7 @@ class ShowHardware(base_command.BaseCommand): if not args: pprint.pprint(minion_data) continue - + for arg in args: if arg in minion_data: print minion_data[arg] - - diff --git a/func/overlord/command.py b/func/overlord/command.py index 1290728..05eec17 100644 --- a/func/overlord/command.py +++ b/func/overlord/command.py @@ -121,7 +121,7 @@ class Command: self.stdout = stdout self.stderr = stderr self.parentCommand = parentCommand - + # create subcommands if we have them self.subCommands = {} @@ -294,4 +294,3 @@ class Command: while c.parentCommand: c = c.parentCommand return c - diff --git a/func/overlord/delegation_tools.py b/func/overlord/delegation_tools.py index eb192b4..55f6dd2 100644 --- a/func/overlord/delegation_tools.py +++ b/func/overlord/delegation_tools.py @@ -20,10 +20,10 @@ import fnmatch class groupby(object): """ - Borrowing the groupby iterator class directly + Borrowing the groupby iterator class directly from the Python API as it does not exist in Pythons < 2.4 """ - + def __init__(self, iterable, key=None): if key is None: key = lambda x: x @@ -32,7 +32,7 @@ class groupby(object): self.tgtkey = self.currkey = self.currvalue = xrange(0) def __iter__(self): return self - def next(self): + def next(self): while self.currkey == self.tgtkey: self.currvalue = self.it.next() # Exit on StopIteration self.currkey = self.keyfunc(self.currvalue) @@ -46,27 +46,27 @@ class groupby(object): def group_paths(ungrouped_list): """ - Given a list of multi-element path lists, + Given a list of multi-element path lists, groups them together into a list of single-element paths (which exist directly under the current overlord) and a dictionary of paths to send to next hops in the delegation chain, containing a list of lists keyed by their common next hop. """ - + single_paths = [path[0] for path in ungrouped_list if len(path) == 1] non_single_paths = [path for path in ungrouped_list if len(path) > 1] - path_group = dict([(key,[path[1:len(path)] for path in list(gen)]) + path_group = dict([(key,[path[1:len(path)] for path in list(gen)]) for key, gen in groupby(non_single_paths, key=lambda x:x[0])]) - + return (single_paths,path_group) - + def get_paths_for_glob(glob_list, minionmap): """ Given a glob, returns shortest path to all minions matching it in the delegation dictionary tree """ - + pathlist = [] for glob in glob_list.split(";"): glob = func_utils.get_all_host_aliases(glob)[0] @@ -95,7 +95,7 @@ def flatten_list(bumpy_list): Flattens gnarly nested lists into much nicer, flat lists """ - + flat_list = [] for item in bumpy_list: if isinstance(item, list): @@ -111,20 +111,20 @@ def match_glob_on_toplevel(pattern, minionmap): for all keys (minion FQDNs) matching the given glob, returns matches """ - + matched = [] for k,v in minionmap.iteritems(): if fnmatch.fnmatch(k,pattern): matched.append(k) return matched - + def match_glob_in_tree(pattern, minionmap): """ Searches through given tree dictionary for all keys (minion FQDNs) matching the given glob, returns matches """ - + matched = [] for k,v in minionmap.iteritems(): for result in match_glob_in_tree(pattern, v): @@ -140,7 +140,7 @@ def minion_exists_under_node(minion, minionmap): result denoting minion existence under your current node """ - + return len(match_glob_on_toplevel(minion,minionmap)) > 0 def get_shortest_path(minion, minionmap): @@ -149,12 +149,12 @@ def get_shortest_path(minion, minionmap): this method returns all paths from the top node to the minion in the form of a flat list """ - + def lensort(a,b): if len(a) > len(b): return 1 return -1 - + results = get_all_paths(minion,minionmap) results.sort(lensort) return results[0] @@ -165,54 +165,54 @@ def get_all_paths(minion, minionmap): this method returns all paths that exist from the top node to the minion in the delegation dictionary tree """ - + #This is an ugly kludge of franken-code. If someone with #more knowledge of graph theory than myself can improve this #module, please, please do so. - ssalevan 7/2/08 seq_list = [] - + if minion_exists_under_node(minion, minionmap): return [[minion]] #minion found, terminate branch - + if minionmap == {}: return [[]] #no minion found, terminate branch - + for k,v in minionmap.iteritems(): branch_list = [] branch_list.append(k) - + for branchlet in get_all_paths(minion, v): branch_list.append(branchlet) - + single_branch = flatten_list(branch_list) if minion in single_branch: seq_list.append(single_branch) - + return seq_list -if __name__ == "__main__": +if __name__ == "__main__": mymap = {'anthony':{'longpath1':{'longpath2':{'longpath3':{}}}}, 'phil':{'steve':{'longpath3':{}}}, 'tony':{'mike':{'anthony':{}}}, 'just_a_minion':{} } - + print "- Testing an element that exists in multiple lists of varying length:" - for elem in match_glob_in_tree('*path3',mymap): + for elem in match_glob_in_tree('*path3',mymap): print "Element: %s, all paths: %s" % (elem, get_all_paths(elem,mymap)) print "best path: %s" % get_shortest_path(elem, mymap) - + print "- Testing an element that is simply a minion and has no sub-nodes:" for elem in match_glob_in_tree('*minion',mymap): print "Element: %s, best path: %s" % (elem, get_shortest_path(elem,mymap)) - + print "- OK, now the whole thing:" for elem in match_glob_in_tree('*',mymap): print "Element: %s, best path: %s" % (elem, get_shortest_path(elem,mymap)) - + print "- And finally, with all duplicates removed:" for elem in get_paths_for_glob('*',mymap): print "Valid Path: %s" % elem - + print "- And grouped together:" print group_paths(get_paths_for_glob('*',mymap)) diff --git a/func/overlord/func_command.py b/func/overlord/func_command.py index a443693..56564fd 100644 --- a/func/overlord/func_command.py +++ b/func/overlord/func_command.py @@ -27,11 +27,11 @@ class FuncCommandLine(command.Command): subCommandClasses = [] exclude_spec = None conffile = None - + def __init__(self): modules = module_loader.load_modules('func/overlord/cmd_modules/', base_command.BaseCommand) for x in modules.keys(): - self.subCommandClasses.append(modules[x].__class__) + self.subCommandClasses.append(modules[x].__class__) command.Command.__init__(self, parentCommand=FuncCommandLine) def do(self, args): @@ -44,7 +44,7 @@ class FuncCommandLine(command.Command): help="exclude some of minions", action="store", type="string") - self.parser.add_option('-c', '--conf', dest="conffile", + self.parser.add_option('-c', '--conf', dest="conffile", help="specify an overlord.conf file for func to use") # just some ugly goo to try to guess if arg[1] is hostnamegoo or @@ -53,7 +53,7 @@ class FuncCommandLine(command.Command): if str.find("*") or str.find("?") or str.find("[") or str.find("]"): return True return False - + def handleArguments(self, args): if len(args) < 2: sys.stderr.write("see the func manpage for usage\n") @@ -77,4 +77,3 @@ class FuncCommandLine(command.Command): if options.conffile: self.conffile = options.conffile - diff --git a/func/overlord/group/base.py b/func/overlord/group/base.py index 9d136cd..c51ae33 100644 --- a/func/overlord/group/base.py +++ b/func/overlord/group/base.py @@ -10,7 +10,7 @@ class BaseBackend(object): """ raise NotImplementedError - + def add_group(self,group,save=True): """ Adds a group @@ -29,7 +29,7 @@ class BaseBackend(object): """ raise NotImplementedError - + def save_changes(self): """ Push the stuff that is in memory @@ -48,7 +48,7 @@ class BaseBackend(object): Get a set of groups """ raise NotImplementedError - + from func.commonconfig import OVERLORD_CONFIG_FILE,OverlordConfig from certmaster.config import read_config CONF_FILE = OVERLORD_CONFIG_FILE diff --git a/func/overlord/group/conf_backend.py b/func/overlord/group/conf_backend.py index 6c2de21..7e6032d 100644 --- a/func/overlord/group/conf_backend.py +++ b/func/overlord/group/conf_backend.py @@ -31,7 +31,7 @@ from func.overlord.group.base import BaseBackend class ConfBackend(BaseBackend): """ - That backend uses a configuraton file for + That backend uses a configuraton file for keeping the stuff """ def __init__(self,conf_file = None,*args,**kwargs): @@ -46,7 +46,7 @@ class ConfBackend(BaseBackend): self.__parse() - + def __parse(self): self.cp = ConfigParser.SafeConfigParser() @@ -63,14 +63,14 @@ class ConfBackend(BaseBackend): for h in hosts: h = h.strip() self.add_host_to_group(section,h,save=False) - + def add_host_to_group(self,group,host,save=True): """ Adds a host to a group """ host = host.lower() group = group.lower() - + if not self.__groups.has_key(group): self.__groups[group] = [] @@ -84,7 +84,7 @@ class ConfBackend(BaseBackend): if save: self.save_changes() return (True,"") - + def add_group(self,group,save=True): """ Adds a group @@ -124,10 +124,10 @@ class ConfBackend(BaseBackend): """ host = host.lower() group = group.lower() - + if not self.__groups.has_key(group) or not host in self.__groups[group]: return (False,"Non existing group or name") - + #remove the machine from there self.__groups[group].remove(host) #save to config file @@ -136,7 +136,7 @@ class ConfBackend(BaseBackend): return (True,'') - + def save_changes(self): """ Write changes to disk @@ -151,25 +151,25 @@ class ConfBackend(BaseBackend): conf_file = open(self.config, "w") self.cp.write(conf_file) - + def get_groups(self,pattern=None,exact=True,exclude=None): """ Get a list of groups @param pattern : You may request to get an exact host or a one in proper pattern . - @param exact : Related to pattern if you should do exact + @param exact : Related to pattern if you should do exact matching or related one. @param exclude : A list to be excluded from final set """ - + if not pattern: #return all of them if not exclude: return self.__groups.keys() else: - #get the difference of 2 sets + #get the difference of 2 sets return list(set(self.__groups.keys()).difference(set(exclude))) else: #it seems there is a pattern @@ -204,10 +204,10 @@ class ConfBackend(BaseBackend): """ Get a set of hosts - + @param pattern : You may request to get an exact host or a one in proper pattern . - @param exact : Related to pattern if you should do exact + @param exact : Related to pattern if you should do exact matching or related one. @param exclude : A list to be excluded from final set """ @@ -218,7 +218,7 @@ class ConfBackend(BaseBackend): return [] hosts = self.__groups[group[0]] - #print "The hosts we got are ",hosts + #print "The hosts we got are ",hosts if not pattern: #return all of them @@ -226,7 +226,7 @@ class ConfBackend(BaseBackend): #print "Returning back the hosts ",hosts return hosts else: - #get the difference of 2 sets + #get the difference of 2 sets return list(set(hosts()).difference(set(exclude))) else: #it seems there is a pattern @@ -262,6 +262,3 @@ class ConfBackend(BaseBackend): #shouldnt come here actually return [] - - - diff --git a/func/overlord/group/sqlite_backend.py b/func/overlord/group/sqlite_backend.py index a3c1018..6ee606e 100644 --- a/func/overlord/group/sqlite_backend.py +++ b/func/overlord/group/sqlite_backend.py @@ -12,13 +12,13 @@ class Group(Base): Group Table """ __tablename__ = 'groups' - + id = Column(Integer, primary_key=True) name = Column(String(100),nullable=False,unique=True) - + def __init__(self,name): self.name = name - + def __repr__(self): return "<Group('%s')>" % (self.name) @@ -28,17 +28,17 @@ class Host(Base): """ __tablename__ = 'hosts' - + id = Column(Integer, primary_key=True) name = Column(String(100), nullable=False,unique=True) group_id = Column(Integer, ForeignKey('groups.id')) - + group = relation(Group, backref=backref('hosts', order_by=id)) - + def __init__(self, name,group_id): self.name = name self.group_id = group_id - + def __repr__(self): return "<Host('%s')>" % self.name @@ -81,7 +81,7 @@ class SqliteBackend(BaseBackend): Session = scoped_session(sessionmaker(bind=engine)) self.session = Session() - + def add_group(self,group,save=True): """ Adds a group @@ -90,12 +90,12 @@ class SqliteBackend(BaseBackend): gr = self._group_exists(group) if gr[0]: return (False,"Group already exists %s "%(gr[1])) - + #add the group self.session.add(Group(group)) self._check_commit(save) return (True,'') - + def add_host_to_group(self,group,host,save=True): """ Adds a host to a group @@ -106,9 +106,9 @@ class SqliteBackend(BaseBackend): except Exception,e: self._recreate_session() return (False,"The host is already in database %s : %s "%(host,e)) - + return (True,'') - + def remove_group(self,group,save=True): """ Removes a group @@ -119,7 +119,7 @@ class SqliteBackend(BaseBackend): return group else: group = group[1] - + self.session.delete(group) self._check_commit(save) return (True,'') @@ -142,25 +142,25 @@ class SqliteBackend(BaseBackend): except Exception,e: #we dont have it so we can add it return (False,str(e)) - + self.session.delete(host_db) self._check_commit(save) return (True,"") - + def save_changes(self): """ Save the stuff that is in memory """ self._check_commit() - + def get_groups(self,pattern=None,exact=True,exclude=None): """ Get a set of groups - + @param pattern : You may request to get an exact host or a one in proper pattern . - @param exact : Related to pattern if you should do exact + @param exact : Related to pattern if you should do exact matching or related one. @param exclude : A list to be excluded from final set """ @@ -180,7 +180,7 @@ class SqliteBackend(BaseBackend): else: return [g.name for g in self.session.query(Group).filter_by(name=pattern).all()] - + return [] def get_hosts(self,pattern=None,group=None,exact=True,exclude=None): @@ -189,7 +189,7 @@ class SqliteBackend(BaseBackend): @param pattern : You may request to get an exact host or a one in proper pattern . - @param exact : Related to pattern if you should do exact + @param exact : Related to pattern if you should do exact matching or related one. @param exclude : A list to be excluded from final set """ @@ -220,7 +220,7 @@ class SqliteBackend(BaseBackend): return [h.name for h in self.session.query(Host).filter(Host.name.like("".join(["%",pattern,"%"]))).filter_by(group_id=group.id).all()] else: return [h.name for h in self.session.query(Host).filter(Host.name.like("".join(["%",pattern,"%"]))).filter_by(group_id=group.id).filter(not_(Host.name.in_(exclude))).all()] - + return [] def _check_commit(self,commit=True): """ @@ -241,4 +241,3 @@ class SqliteBackend(BaseBackend): return (False,"Not existing group name") except Exception,e: return (False,str(e)) - diff --git a/func/overlord/groups.py b/func/overlord/groups.py index be769d1..f99942c 100644 --- a/func/overlord/groups.py +++ b/func/overlord/groups.py @@ -26,7 +26,7 @@ class Groups(object): else: # fallback/legacy only - won't work for puppet or other minion types self.get_hosts_for_spec = get_hosts_spec - + self.backend = choose_backend(**kwargs) @@ -41,22 +41,22 @@ class Groups(object): if hosts: for h in hosts: print "\t Host : %s "%h - - + + def __parse_strings(self, hoststring): """ the host string maybe in 2 forms the first one is i it can be comma separated into the - configuration file the second one + configuration file the second one is it can be ; separated and entered from commandline so should consider both situations @param hoststring : String to be parsed """ hosts = [] - + if hoststring.find(';') != -1: bits = hoststring.split(';') elif hoststring.find(',') != -1: @@ -70,7 +70,7 @@ class Groups(object): return list(set(bits)) - + def add_group(self,group_name,save=True): """ Adding a new group @@ -79,9 +79,9 @@ class Groups(object): @param save : Save now or keep in memory and save later """ - return self.backend.add_group(group_name,save) + return self.backend.add_group(group_name,save) + - def add_hosts_to_group_glob(self,group,hoststring,exclude_string=None): """ With that method we will be able add lots of machines by single @@ -105,11 +105,11 @@ class Groups(object): def add_hosts_to_group(self, group, hoststring): """ Here you can add more than one hosts to a given group - + @param group : Group name that will add the hosts @param hoststring : A string in form of "host1;host2" or comma separated one (will be parsed) ... - + """ hosts = self.__parse_strings(hoststring) for host in hosts: @@ -130,7 +130,7 @@ class Groups(object): """ Similar as other add methods but accepts a list of hosts instead of some strings - + @param group : Group name that will add the hosts @param host_list : Host list @@ -141,10 +141,10 @@ class Groups(object): for host in host_list: self.add_host_to_group(group, host) - + self.save_changes() - - + + def get_groups(self,pattern=None,exact=True,exclude=None): """ Get a list fo groups according to args @@ -175,13 +175,13 @@ class Groups(object): def get_hosts(self,pattern=None,group=None,exact=True,exclude=None): """ Getting the list of hosts according to args - + @param pattern : A string to match name of the host @param exact : When true pattern matching is exact else it gets the ones that are related @param exclude : A list of excluded hosts useful in globbing """ - + return self.backend.get_hosts(pattern,group,exact,exclude) def get_group_names(self): @@ -192,7 +192,7 @@ class Groups(object): """ return self.get_groups() - + def _get_host_list_from_glob(self,group_globs,include_host): """ A private util method that is responsible for @@ -211,7 +211,7 @@ class Groups(object): else: for host_str in self.get_hosts(group=group_glob): include_host = include_host.union(set(self.get_hosts_for_spec(host_str))) - + return include_host def get_hosts_glob(self,host_string,exclude_string=None): @@ -227,7 +227,7 @@ class Groups(object): group_globs = host_string.split(';') include_host = set() include_host = self._get_host_list_from_glob(group_globs,include_host) - + #if you have a list to exclude if exclude_string: exclude_globs = exclude_string.split(';') @@ -244,15 +244,15 @@ class Groups(object): use more advanced one get_hosts_glob() method """ return self.get_hosts_glob(group_glob_str) - + def remove_group(self,group,save=True): """ Removing a group if needed - + @param group : Group to be removed @param save : Save now or keep in memory and save later """ - + return self.backend.remove_group(group,save) def remove_group_glob(self,group_str): @@ -273,7 +273,7 @@ class Groups(object): if type(group_list) != list: sys.stderr.write("We accept only lists for for remove_group_list method") return False - + for g in group_list: self.remove_group(g,save=False) self.save_changes() @@ -284,8 +284,8 @@ class Groups(object): Removes a proper host from the conf file """ return self.backend.remove_host(group_name,host,save) - - + + def remove_host_glob(self,group_name,host_str,exclude_string=None): copy_host_str = host_str host_str = self.get_hosts_for_spec(host_str) @@ -294,11 +294,11 @@ class Groups(object): host_str = host_str.difference(e_s) #remove the list completely - if not host_str: #sometimes we may have some old entries into db so + if not host_str: #sometimes we may have some old entries into db so #that will not make a match in that case - self.remove_host_list(group_name,[copy_host_str]) + self.remove_host_list(group_name,[copy_host_str]) else: - self.remove_host_list(group_name,host_str) + self.remove_host_list(group_name,host_str) def remove_host_list(self,group,host_list): """ @@ -321,7 +321,7 @@ class Groups(object): """ self.backend.save_changes() - + if __name__ == "__main__": pass diff --git a/func/overlord/inventory.py b/func/overlord/inventory.py index fa5ad50..df2fcbf 100644 --- a/func/overlord/inventory.py +++ b/func/overlord/inventory.py @@ -31,9 +31,9 @@ DEFAULT_TREE = "/var/lib/func/inventory/" class FuncInventory(object): def __init__(self): - pass + pass - def run(self,args): + def run(self,args): p = FuncOptionParser(version=True) p.add_option("-v", "--verbose", @@ -78,7 +78,7 @@ class FuncInventory(object): # see what modules each host provides (as well as what hosts we have) host_methods = func_client.Overlord(options.server_spec).system.list_methods() - + # call all remote info methods and handle them if options.verbose: print "- scanning ..." @@ -87,8 +87,8 @@ class FuncInventory(object): for (host, methods) in host_methods.iteritems(): if utils.is_error(methods): - sys.stderr.write("-- connection refused: %s\n" % host) - break + sys.stderr.write("-- connection refused: %s\n" % host) + break for each_method in methods: @@ -106,7 +106,7 @@ class FuncInventory(object): if not "all" in filtered_function_list and not method_name in filtered_function_list: continue - + overlord = func_client.Overlord(host,noglobs=True) # ,noglobs=True) results = getattr(getattr(overlord,module_name),method_name)() if self.options.verbose: @@ -137,12 +137,12 @@ class FuncInventory(object): return pprint.pformat(data) - # FUTURE: skvidal points out that guest symlinking would be an interesting feature + # FUTURE: skvidal points out that guest symlinking would be an interesting feature def save_results(self, options, host_name, module_name, method_name, results): dirname = os.path.join(options.tree, host_name, module_name) if not os.path.exists(dirname): - os.makedirs(dirname) + os.makedirs(dirname) filename = os.path.join(dirname, method_name) results_file = open(filename,"w+") data = self.format_return(results) @@ -151,12 +151,12 @@ class FuncInventory(object): def git_setup(self,options): if options.nogit: - return + return if not os.path.exists("/usr/bin/git"): sys.stderr.write("git-core is not installed, so no change tracking is available.\n") sys.stderr.write("use --no-git or, better, just install it.\n") - sys.exit(411) - + sys.exit(411) + if not os.path.exists(options.tree): os.makedirs(options.tree) dirname = os.path.join(options.tree, ".git") @@ -177,7 +177,7 @@ class FuncInventory(object): return else: if options.verbose: - print "- updating git" + print "- updating git" mytime = time.asctime() cwd = os.getcwd() os.chdir(options.tree) diff --git a/func/overlord/mapper.py b/func/overlord/mapper.py index abbc0f3..6ccebc2 100644 --- a/func/overlord/mapper.py +++ b/func/overlord/mapper.py @@ -2,7 +2,7 @@ ## func topology map-building tool ## If you've got a giant, tangled, complex web of func overlords ## and minions, this tool will help you construct or augment a map -## of your func network topology so that delegating commands to +## of your func network topology so that delegating commands to ## minions and overlords becomes a simple matter. ## ## Copyright 2008, Red Hat, Inc. @@ -30,9 +30,9 @@ class MapperTool(object): def __init__(self): pass - + def run(self,args): - + p = FuncOptionParser(version=True) #currently not implemented p.add_option("-a", "--append", @@ -47,29 +47,29 @@ class MapperTool(object): dest="verbose", action="store_true", help="provide extra output") - + (options, args) = p.parse_args(args) self.options = options - + if options.verbose: print "- recursively calling map function" - + self.build_map() - + return 1 - + def build_map(self): - + minion_hash = func_client.Overlord("*").overlord.map_minions(self.options.only_alive==True) - + for minion in minion_hash.keys(): #clean hash of any top-level errors if utils.is_error(minion_hash[minion]): - minion_hash[minion] = {} + minion_hash[minion] = {} if self.options.verbose: print "- built the following map:" print minion_hash - + if self.options.append: try: oldmap = file(DEFAULT_TREE, 'r').read() @@ -78,23 +78,22 @@ class MapperTool(object): except e: sys.stderr.write("ERROR: old map could not be read, append failed\n") sys.exit(-1) - + merged_map = {} merged_map.update(old_hash) merged_map.update(minion_hash) - + if self.options.verbose: print "- appended new map to the following map:" print old_hash print " resulting in:" print merged_map - + minion_hash = merged_map - + if self.options.verbose: print "- writing to %s" % DEFAULT_TREE - + mapfile = file(DEFAULT_TREE, 'w') data = yaml.dump(minion_hash) mapfile.write(data) - diff --git a/func/overlord/modules/copyfile.py b/func/overlord/modules/copyfile.py index b25d43d..9f385a9 100644 --- a/func/overlord/modules/copyfile.py +++ b/func/overlord/modules/copyfile.py @@ -21,11 +21,11 @@ class copyfile(overlord_module.BaseModule): self.parent.run("copyfile", "open", [remotepath, mode, uid, gid]) - while True: + while True: data=f.read(bufsize) if data: self.parent.run("copyfile", "append", [remotepath, xmlrpclib.Binary(data)]) else: break - + return True diff --git a/func/overlord/modules/netapp.py b/func/overlord/modules/netapp.py index 987901e..bc61868 100644 --- a/func/overlord/modules/netapp.py +++ b/func/overlord/modules/netapp.py @@ -45,10 +45,10 @@ class Filer(Client): return _(self.netapp.vol.destroy(self.filer, vol)[self.admin_host]) def offline_volume(self, vol): - return _(self.netapp.vol.offline(self.filer, vol)[self.admin_host]) + return _(self.netapp.vol.offline(self.filer, vol)[self.admin_host]) def online_volume(self, vol): - return _(self.netapp.vol.online(self.filer, vol)[self.admin_host]) + return _(self.netapp.vol.online(self.filer, vol)[self.admin_host]) def get_volume_size(self, vol): return _(self.netapp.vol.size(self.filer, vol)[self.admin_host]) diff --git a/func/overlord/modules/utils.py b/func/overlord/modules/utils.py index f18fd50..aae42cb 100644 --- a/func/overlord/modules/utils.py +++ b/func/overlord/modules/utils.py @@ -6,7 +6,7 @@ import func.jobthing as jobthing class utils(overlord_module.BaseModule): def __diff_dicts(self, a, b): return dict([(k, v) for k, v in a.iteritems() if k not in b]) - + def async_poll(self, job_id, partial_func=None, interval=0.5): async_done = False @@ -37,4 +37,4 @@ class utils(overlord_module.BaseModule): time.sleep(interval) def list_minions(self): - return self.parent.minions + return self.parent.minions diff --git a/func/overlord/scripts.py b/func/overlord/scripts.py index 57a6255..7f2e0f2 100644 --- a/func/overlord/scripts.py +++ b/func/overlord/scripts.py @@ -33,13 +33,12 @@ def handle_base_func_options(parser, opts): hosts = sys.stdin.readlines() else: hosts = open(opts.hostfile, 'r').readlines() - + for hn in hosts: hn = hn.strip() if hn.startswith('#'): continue hn = hn.replace('\n', '') - opts.host.append(hn) + opts.host.append(hn) return opts - diff --git a/func/utils.py b/func/utils.py index 129e9ab..fd456c1 100644 --- a/func/utils.py +++ b/func/utils.py @@ -41,7 +41,7 @@ def remove_weird_chars(dirty_word): That method will be used to clean some glob adress expressions because async stuff depends on that part - + @param dirty_word : word to be cleaned """ from copy import copy @@ -76,10 +76,10 @@ def get_hostname_by_route(): "localhost" is a lame hostname to use for a key, so try to get a more meaningful hostname. We do this by connecting to the certmaster and seeing what interface/ip it uses to make that connection, and looking - up the hostname for that. + up the hostname for that. """ # FIXME: this code ignores http proxies (which granted, we don't - # support elsewhere either. + # support elsewhere either. hostname = None ip = None @@ -120,7 +120,7 @@ def get_hostname_by_route(): (hostname, aliases, ips) = socket.gethostbyaddr(minion_config.listen_addr) except: hostname = None - + # in an ideal world, this would return exactly what we want: the most meaningful hostname # for a system, but that is often not that case if hostname is None: @@ -136,8 +136,8 @@ def get_hostname_by_route(): # non loopback is about as good as we can do for a guess if ip != "127.0.0.1" and hostname is not None: return hostname.lower() - - + + # all else has failed to get a good hostname, so just return # an ip address @@ -145,21 +145,21 @@ def get_hostname_by_route(): def find_files_by_hostname(hostglob, filepath, fileext=''): """look for files in the given filepath with the given extension that - match our hostname, but case insensitively. This handles the + match our hostname, but case insensitively. This handles the craziness that is dns names that have mixed case :(""" - - # this is a little like a case insensitive glob, except it's just one + + # this is a little like a case insensitive glob, except it's just one # layer deep - not multiple layers - + if fileext and fileext[0] != '.': fileext = '.' + fileext - thisregex = fnmatch.translate('%s%s' % (hostglob, fileext)) + thisregex = fnmatch.translate('%s%s' % (hostglob, fileext)) recomp = re.compile(thisregex, re.I) # case insensitive match files = [] for potfile in os.listdir(filepath): if recomp.match(potfile): files.append(potfile) - + return [os.path.normpath(filepath + '/' + file) for file in files] @@ -179,11 +179,11 @@ def get_fresh_method_instance(function_ref): calls we have a pool of references with module methods and overlord call them. If we want to pass those methods different logger instances in order to have log call per - job_ids we shouldnt have the same method reference to be + job_ids we shouldnt have the same method reference to be called,we need fresh ones so that is how we solve that kind of hacky ... """ - + #CAUTION HACKY IF STATEMNETS AROUND :) # we dont want private methods and system #modules around ,we should change system @@ -226,8 +226,8 @@ def re_glob(s): class TerminalController: """ A class that can be used to portably generate formatted output to - a terminal. - + a terminal. + `TerminalController` defines a set of instance variables whose values are initialized to the control sequence necessary to perform a given action. These can be simply included in normal @@ -287,11 +287,11 @@ class TerminalController: # Foreground colors: BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = '' - + # Background colors: BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = '' BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = '' - + _STRING_CAPABILITIES = """ BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1 CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold @@ -323,7 +323,7 @@ class TerminalController: # Look up numeric capabilities. self.COLS = curses.tigetnum('cols') self.LINES = curses.tigetnum('lines') - + # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') @@ -375,7 +375,7 @@ class TerminalController: class ProgressBar: """ A 3-line progress bar, which looks like:: - + Header 20% [===========----------------------------------] progress message @@ -385,7 +385,7 @@ class ProgressBar: """ BAR = '%3d%% ${WHITE}[${BLUE}%s%s${NORMAL}${WHITE}]${NORMAL}\n' HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n' - + def __init__(self, term, header,minValue = 0, maxValue = 10): self.term = term if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL): @@ -395,12 +395,12 @@ class ProgressBar: self.bar = term.render(self.BAR) self.header = self.term.render(self.HEADER % header.center(self.width)) self.cleared = 1 #: true if we haven't drawn the bar yet. - + self.min = minValue self.max = maxValue self.span = maxValue - minValue - self.amount = 0 # When amount == max, we are 100% done - + self.amount = 0 # When amount == max, we are 100% done + #initially it is 0 self.update(0, '') @@ -408,7 +408,7 @@ class ProgressBar: if newAmount < self.min: newAmount = self.min if newAmount > self.max: newAmount = self.max self.amount = newAmount - + # Figure out the new percent done, round to an integer diffFromMin = float(self.amount - self.min) percentDone = (diffFromMin / float(self.span)) * 100.0 @@ -436,7 +436,7 @@ if __name__ == "__main__": term = TerminalController() progress = ProgressBar(term, 'Progress Status',minValue=0,maxValue=5) filenames = ['this', 'that', 'other', 'foo', 'bar'] - + for i, filename in zip(range(len(filenames)), filenames): progress.update(i+1) time.sleep(3) @@ -445,4 +445,3 @@ if __name__ == "__main__": #progress.clear() #################### PROGRESS BAR ################################## - diff --git a/func/yaml/dump.py b/func/yaml/dump.py index eb34955..d0064cd 100644 --- a/func/yaml/dump.py +++ b/func/yaml/dump.py @@ -164,7 +164,7 @@ class Dumper: self.output(line) def raiseToYamlSyntaxError(self): - raise """ + raise """ to_yaml should return tuple w/object to dump and optional YAML type. Example: ({'foo': 'bar'}, '!!foobar') @@ -193,25 +193,25 @@ def accumulate(obj,occur): occur[obid] = occur[obid] + 1 class YamlAnchors: - def __init__(self,data): - occur = {} - accumulate(data,occur) - anchorVisits = {} - for (obid, occur) in occur.items(): - if occur > 1: - anchorVisits[obid] = 0 - self._anchorVisits = anchorVisits - self._currentAliasIndex = 0 - def shouldAnchor(self,obj): - ret = self._anchorVisits.get(id(obj),None) - if 0 == ret: - self._currentAliasIndex = self._currentAliasIndex + 1 - ret = self._currentAliasIndex - self._anchorVisits[id(obj)] = ret - return ret - return 0 - def isAlias(self,obj): - return self._anchorVisits.get(id(obj),0) + def __init__(self,data): + occur = {} + accumulate(data,occur) + anchorVisits = {} + for (obid, occur) in occur.items(): + if occur > 1: + anchorVisits[obid] = 0 + self._anchorVisits = anchorVisits + self._currentAliasIndex = 0 + def shouldAnchor(self,obj): + ret = self._anchorVisits.get(id(obj),None) + if 0 == ret: + self._currentAliasIndex = self._currentAliasIndex + 1 + ret = self._currentAliasIndex + self._anchorVisits[id(obj)] = ret + return ret + return 0 + def isAlias(self,obj): + return self._anchorVisits.get(id(obj),0) ### SORTING METHODS @@ -295,7 +295,7 @@ def isUnicode(data): def sloppyIsUnicode(data): # XXX - hack to make tests pass for 2.1 - return repr(data)[:2] == "u'" and repr(data) != data + return repr(data)[:2] == "u'" and repr(data) != data import sys if sys.hexversion < 0x20200000: diff --git a/func/yaml/load.py b/func/yaml/load.py index 54931d6..5f353d9 100644 --- a/func/yaml/load.py +++ b/func/yaml/load.py @@ -20,7 +20,7 @@ except: self._docs = [] try: while 1: - self._docs.append(parser.next()) + self._docs.append(parser.next()) except StopIteration: pass self._idx = 0 def __len__(self): return len(self._docs) diff --git a/func/yaml/ordered_dict.py b/func/yaml/ordered_dict.py index 5bc2e3e..4d9a876 100644 --- a/func/yaml/ordered_dict.py +++ b/func/yaml/ordered_dict.py @@ -32,7 +32,3 @@ if __name__ == '__main__': for key in data.keys(): print "The value for %s is %s" % (key, data[key]) print data - - - - diff --git a/func/yaml/redump.py b/func/yaml/redump.py index eefd68e..f8640c2 100644 --- a/func/yaml/redump.py +++ b/func/yaml/redump.py @@ -19,4 +19,3 @@ def redump(stream): dumper = Dumper() dumper.alphaSort = 0 return dumper.dump(*docs) - diff --git a/func/yaml/stream.py b/func/yaml/stream.py index dcd65c3..eb63751 100644 --- a/func/yaml/stream.py +++ b/func/yaml/stream.py @@ -56,10 +56,10 @@ def split(text): def eatNewLines(stream): while 1: - line = stream.get() - if line is None or len(string.strip(line)): - return line - + line = stream.get() + if line is None or len(string.strip(line)): + return line + COMMENT_LINE_REGEX = re.compile(R"\s*#") def isComment(line): return line is not None and COMMENT_LINE_REGEX.match(line) diff --git a/func/yaml/timestamp.py b/func/yaml/timestamp.py index 5c522f6..443e686 100644 --- a/func/yaml/timestamp.py +++ b/func/yaml/timestamp.py @@ -29,28 +29,28 @@ def _parseTime(val): siz = len(tpl) sec = 0 if 3 == siz: - tpl += [0,0,0,0,0,-1] + tpl += [0,0,0,0,0,-1] elif 7 == siz: - tpl.append(0) - tpl.append(-1) + tpl.append(0) + tpl.append(-1) elif 8 == siz: - if len(tpl.pop()) > 0: raise ValueError(val) - tpl.append(0) - tpl.append(-1) + if len(tpl.pop()) > 0: raise ValueError(val) + tpl.append(0) + tpl.append(-1) elif 9 == siz or 10 == siz: - mn = int(tpl.pop()) - hr = int(tpl.pop()) - sec = (hr*60+mn)*60 - if val.find("+") > -1: sec = -sec - if 10 == siz: tpl.pop() - tpl.append(0) - tpl.append(-1) + mn = int(tpl.pop()) + hr = int(tpl.pop()) + sec = (hr*60+mn)*60 + if val.find("+") > -1: sec = -sec + if 10 == siz: tpl.pop() + tpl.append(0) + tpl.append(-1) else: - raise ValueError(val) + raise ValueError(val) idx = 0 while idx < 9: - tpl[idx] = int(tpl[idx]) - idx += 1 + tpl[idx] = int(tpl[idx]) + idx += 1 if tpl[1] < 1 or tpl[1] > 12: raise ValueError(val) if tpl[2] < 1 or tpl[2] > 31: raise ValueError(val) if tpl[3] > 24: raise ValueError(val) @@ -69,16 +69,16 @@ def _parseTime(val): class _timestamp: def __init__(self,val=None): if not val: - self.__tval = time.gmtime() + self.__tval = time.gmtime() else: - typ = type(val) - if ListType == typ: - self.__tval = tuple(val) - elif TupleType == typ: - self.__tval = val - else: - self.__tval = _parseTime(val) - if 9 != len(self.__tval): raise ValueError + typ = type(val) + if ListType == typ: + self.__tval = tuple(val) + elif TupleType == typ: + self.__tval = val + else: + self.__tval = _parseTime(val) + if 9 != len(self.__tval): raise ValueError def __getitem__(self,idx): return self.__tval[idx] def __len__(self): return 9 def strftime(self,format): return time.strftime(format,self.__tval) @@ -103,7 +103,7 @@ try: # inherit from mx.DateTime functionality if available _timestamp.__init__(self,val) self.__mxdt = DateTime.mktime(self.__tval) def __getattr__(self, name): - return getattr(self.__mxdt, name) + return getattr(self.__mxdt, name) except: class timestamp(_timestamp): pass diff --git a/func/yaml/ypath.py b/func/yaml/ypath.py index b183a23..169d9fa 100644 --- a/func/yaml/ypath.py +++ b/func/yaml/ypath.py @@ -64,7 +64,7 @@ class context: def __setattr__(self,attname,attval): if attname in ('parent','key','value'): if self.__dict__.get(attname): - raise ValueError("context is read-only") + raise ValueError("context is read-only") self.__dict__[attname] = attval def __hash__(self): return hash(self.path) def __cmp__(self,other): @@ -228,7 +228,7 @@ class match_seg(self_seg): def __init__(self,key): #TODO: Do better implicit typing try: - key = int(key) + key = int(key) except: pass self.key = key def bind(self,cntx): @@ -327,7 +327,7 @@ class equal_pred: while 1: cntx = self.rhs.next() if str(cntx.value) == self.lhs: #TODO: Remove type hack - return 1 + return 1 except StopIteration: pass return 0 def exists_segment(self,cntx): diff --git a/funcweb/funcweb/async_tools.py b/funcweb/funcweb/async_tools.py index 1d6e4ce..f857f46 100644 --- a/funcweb/funcweb/async_tools.py +++ b/funcweb/funcweb/async_tools.py @@ -15,7 +15,7 @@ class AsyncResultManager(object): def __init__(self): #we keep all the entries in memory it may seems - #that it will occuppy lots of space but all it has + #that it will occuppy lots of space but all it has #is job_id:code pairs with some status info : changed,new #and etc all other stuff is kept in DB #so if someone does 1000 async queries will occupy @@ -28,7 +28,7 @@ class AsyncResultManager(object): def __get_current_list(self,check_for_change=False): """ - Method returns back the current + Method returns back the current list of the job_ids : result_code pairs """ changed = [] @@ -41,7 +41,7 @@ class AsyncResultManager(object): #print "I have that code %s no change will be reported"%job_id self.__current_list[job_id][1] = self.JOB_CODE_SAME else: - #we have change i db + #we have change i db #print "That is a change from %d to %d for %s"%(self.__current_list[job_id][0],code,job_id) self.__current_list[job_id]=[code,self.JOB_CODE_CHANGED] if check_for_change: @@ -63,7 +63,7 @@ class AsyncResultManager(object): return None - + def __update_current_list(self,tmp_db_hash): """ Synch the memory and local db @@ -76,7 +76,7 @@ class AsyncResultManager(object): def check_for_changes(self): """ Method will be called by js on client side to check if something - interesting happened in db in "before defined" time interval + interesting happened in db in "before defined" time interval If have lots of methods running async that may take a while to finish but user will not be interrupted about that situation ... """ @@ -100,13 +100,13 @@ class AsyncResultManager(object): #if should_check_change: return self.__get_current_list(check_for_change=True) - - + + def select_from(self,pull_property): """ Gets only ones that matches to pull_property_options """ - #may have some concurency problems ??? + #may have some concurency problems ??? code = None status = None #get the list of the finished jobs @@ -130,21 +130,21 @@ class AsyncResultManager(object): else: #there is no case like that :) return None - #now pull the list and return it back + #now pull the list and return it back final_list = [] #print "The current list in the selct is :",self.__current_list for job_id,code_status_pack in self.__current_list.iteritems(): if code != None and code == code_status_pack[0]: tmp_hash = {} tmp_hash[job_id]=code_status_pack - + #print "To select %s with code %s"%(job_id,code) final_list.append(tmp_hash) elif status != None and code_status_pack[1] == status: tmp_hash = {} tmp_hash[job_id]=code_status_pack final_list.append(tmp_hash) - + #get the final list here return final_list @@ -180,7 +180,6 @@ class AsyncResultManager(object): """ self.__get_current_list() - + if __name__ == "__main__": pass - diff --git a/funcweb/funcweb/commands.py b/funcweb/funcweb/commands.py index aa74680..ee6aacd 100644 --- a/funcweb/funcweb/commands.py +++ b/funcweb/funcweb/commands.py @@ -18,7 +18,7 @@ cherrypy.lowercase_api = True class ConfigurationError(Exception): pass -#that variable will help us to see when we are in PRODUCTION +#that variable will help us to see when we are in PRODUCTION PRODUCTION_ENV = False def start(): @@ -38,7 +38,7 @@ def start(): #we work with production settings now ! PRODUCTION_ENV = True configfile = "/etc/funcweb/prod.cfg" - + elif len(sys.argv) > 1: configfile = sys.argv[1] elif exists(join(setupdir, "setup.py")): @@ -57,7 +57,7 @@ def start(): modulename="funcweb.config") from funcweb.controllers import Root - + if PRODUCTION_ENV: utils.daemonize("/var/run/funcwebd.pid") #then start the server @@ -65,4 +65,4 @@ def start(): turbogears.start_server(Root()) except Exception,e: print "Debug information from cherrypy server ...: ",e - #sys.exit(1) + #sys.exit(1) diff --git a/funcweb/funcweb/controllers.py b/funcweb/funcweb/controllers.py index 43f60e3..07dd1d6 100644 --- a/funcweb/funcweb/controllers.py +++ b/funcweb/funcweb/controllers.py @@ -8,16 +8,16 @@ from funcweb.widget_validation import WidgetSchemaFactory from funcweb.async_tools import AsyncResultManager from func.jobthing import purge_old_jobs,JOB_ID_RUNNING,JOB_ID_FINISHED,JOB_ID_PARTIAL from func.utils import is_error -# it is assigned into method_display on every request -global_form = None +# it is assigned into method_display on every request +global_form = None ####**NOTE : All flash messages are used for error and some weird sitaution's reporting be careful when using #that turbogears functionality ! def validate_decorator_updater(validator_value=None): """ - When we pass the global_form directly to - turbogears.validate it is not updated on + When we pass the global_form directly to + turbogears.validate it is not updated on every request we should pass a callable to trigger it ;) @@ -26,7 +26,7 @@ def validate_decorator_updater(validator_value=None): because we compute the global_form in the method_display @return : the current form and schema to validate the - current input in cherrypy's request + current input in cherrypy's request """ global global_form return global_form @@ -34,7 +34,7 @@ def validate_decorator_updater(validator_value=None): class Funcweb(object): #preventing the everytime polling and getting #func = Overlord("name") thing - func_cache={ + func_cache={ 'fc_object':None,#the fc = Overlord() thing, 'fc_async_obj':None, 'glob':None, @@ -51,12 +51,12 @@ class Funcweb(object): def get_current_minion_list(self,glob): """ - That method will not be reachable from web interface it just - a util method that gives back the current minion list back, + That method will not be reachable from web interface it just + a util method that gives back the current minion list back, we use that minion glob form in lots of places so it is a hack to avoid writing stupid code again and again :) """ - + if self.func_cache['glob'] == glob: minions = self.func_cache['minions'] else: @@ -68,7 +68,7 @@ class Funcweb(object): except Exception,e: #TODO log here minions = [] - + return minions @expose(allow_json=True) @@ -76,7 +76,7 @@ class Funcweb(object): def minions(self, glob='*',submit=None): """ Return a list of our minions that match a given glob """ #make the cache thing - minions = self.get_current_minion_list(glob) + minions = self.get_current_minion_list(glob) if not submit: return dict(minions=minions,submit_adress="/funcweb/minions",tg_template="funcweb.templates.index") else: @@ -108,7 +108,7 @@ class Funcweb(object): #should also reset the other fields or not ? - + if not module: if not self.func_cache['modules']: try : @@ -117,7 +117,7 @@ class Funcweb(object): #TODO put logger here! flash("Some exception while getting the module list for %s minion"%(name)) return dict() - + except Exception,e: flash("Some exception while getting the module list for %s minion"%(name)) #it is an error case @@ -137,15 +137,15 @@ class Funcweb(object): #put it into the cache to make that slow thing faster self.func_cache['modules']=display_modules - + else: #print "Im in the cache" #just list those who have get_method_args display_modules = self.func_cache['modules'] - + modules = {} modules[name]=display_modules - + return dict(modules=modules,tg_template = "funcweb.templates.modules") else: # a module is specified if not method: # return a list of methods for specified module @@ -171,7 +171,7 @@ class Funcweb(object): if not m in registered_methods: mods.remove(m) - #store into cache if we get it again + #store into cache if we get it again self.func_cache['methods'] = modules #display em return dict(modules=modules, module=module, @@ -186,7 +186,7 @@ class Funcweb(object): """ That method generates the input widget for givent method. """ - + global global_form if self.func_cache['minion_name'] == minion: fc = self.func_cache['fc_object'] @@ -276,9 +276,9 @@ class Funcweb(object): return dict(message=msg, previous_url=previous_url, logging_in=True, original_parameters=request.params, forward_url=forward_url) - - - @expose() + + + @expose() @identity.require(identity.not_anonymous()) def handle_minion_error(self,tg_errors=None): """ @@ -290,7 +290,7 @@ class Funcweb(object): if tg_errors: #print tg_errors return str(tg_errors) - + @expose(allow_json=True) @error_handler(handle_minion_error) @@ -336,9 +336,9 @@ class Funcweb(object): except Exception,e: flash("Encountered some error when trying to get method arguments for %s.%s.%s"%(minion,module,method)) return dict() - #so we know the order just allocate and put them there + #so we know the order just allocate and put them there cmd_args=[] - + #firstly create a better dict to lookup sorted_args = {} for arg in kw.keys(): @@ -362,7 +362,7 @@ class Funcweb(object): cmd_args.append(list_arg) else: cmd_args.append(current_argument) - + #print "The list to be send is : ",cmd_args #now execute the stuff #at the final execute it as a multiple if the glob suits for that @@ -371,25 +371,25 @@ class Funcweb(object): try: if self.func_cache['glob']: fc_async = Overlord(self.func_cache['glob'],async=True) - + result_id = getattr(getattr(fc_async,module),method)(*cmd_args) result = "".join(["The id for current job is :",str(result_id)," You will be notified when there is some change about that command !"]) - + except Exception,e: flash("We got some error while trying to send command for %s.%s.%s"%(module,minion,method)) return dict() - + #TODO reformat that returning string to be more elegant to display :) return str(result) else: return "Missing arguments sorry can not proceess the form" - + @expose(template="funcweb.templates.result") @identity.require(identity.not_anonymous()) def execute_link(self,minion=None,module=None,method=None): """ - Method is fot those minion methods that dont accept any + Method is fot those minion methods that dont accept any arguments so they provide only some information,executed by pressing only the link ! """ @@ -429,9 +429,9 @@ class Funcweb(object): if not check_change : msg = "Method invoked with False parameter which makes it useless" return dict(changed = False,changes = [],remote_error=msg) - + if not self.async_manager: - #cleanup tha database firstly + #cleanup tha database firstly purge_old_jobs() self.async_manager = AsyncResultManager() changes = self.async_manager.check_for_changes() @@ -440,10 +440,10 @@ class Funcweb(object): changed = True else: self.first_run = False - + return dict(changed = changed,changes = changes) - + @expose(format = "json") @identity.require(identity.not_anonymous()) def check_job_status(self,job_id): @@ -461,12 +461,12 @@ class Funcweb(object): #store also into the cache else: fc_async = Overlord("*",async=True) - + self.func_cache['fc_async_obj'] = fc_async else: fc_async = self.func_cache['fc_async_obj'] - + try: id_result = fc_async.job_status(job_id) #parse the comming data in a better looking way :) @@ -496,9 +496,9 @@ class Funcweb(object): else: #make a refresh of the memory copy self.async_manager.refresh_list() - #get the actual db + #get the actual db func_db = self.async_manager.current_db() - + for job_id,code_status_pack in func_db.iteritems(): parsed_job_id = job_id.split("-") func_db[job_id].extend(parsed_job_id) @@ -509,12 +509,12 @@ class Funcweb(object): @expose() def logout(self): """ - The logoout part + The logoout part """ identity.current.logout() raise redirect("/") - -################################ Groups API methods here ############################# + +################################ Groups API methods here ############################# @expose(template="funcweb.templates.groups_main") @identity.require(identity.not_anonymous()) def groups_main(self): @@ -563,7 +563,7 @@ class Funcweb(object): copy_group_name = copy(group_name) if not group_name.startswith('@'): group_name = "".join(["@",group_name.strip()]) - + try: minion_api = Minions("*") hosts = minion_api.group_class.get_hosts_by_group_glob(group_name) @@ -573,7 +573,7 @@ class Funcweb(object): flash("We encountered some error while getting host list for %s "%(copy_group_name)) return dict() - #store the current group_name in cache variable + #store the current group_name in cache variable self.group_name = copy_group_name return dict(hosts = hosts,all_minions = all_minions,group_name = copy_group_name,submit_adress="/funcweb/filter_group_minions") @@ -588,10 +588,10 @@ class Funcweb(object): hosts = [] if not kw.has_key('group_name') or not kw.has_key('action_name'): return dict(hosts =hosts,group_name = None) - + current_host_list = None - #if we are adding some hosts + #if we are adding some hosts if kw['action_name'] == "add": if not kw.has_key('checkminion'): return dict(hosts =hosts,group_name = kw['group_name']) @@ -605,7 +605,7 @@ class Funcweb(object): hosts.extend(current_host_list.split(",")) else: hosts.extend(current_host_list) - + if kw['action_name'] == "add": minion_api.group_class.add_host_list(kw['group_name'],hosts,save = True) else:#remove them @@ -616,17 +616,17 @@ class Funcweb(object): group_name = copy(kw['group_name']) if not group_name.startswith('@'): group_name = "".join(["@",group_name.strip()]) - + hosts = minion_api.group_class.get_hosts_by_group_glob(group_name) return dict(hosts =hosts,group_name = kw['group_name']) - + @expose(allow_json=True) @identity.require(identity.not_anonymous()) def filter_group_minions(self,glob='*',submit=None): """ Return a list of our minions that match a given glob """ #make the cache thing - minions = self.get_current_minion_list(glob) + minions = self.get_current_minion_list(glob) if submit: return dict(all_minions=minions,submit_adress="/funcweb/filter_group_minions",tg_template="funcweb.templates.minion_small",group_name= self.group_name) else: @@ -636,10 +636,10 @@ class Funcweb(object): ############################# END of GROUPS API METHODS ############################ class Root(controllers.RootController): - + @expose() def index(self): raise redirect("/funcweb") - + index = index # start with our minion view, for now funcweb = Funcweb() diff --git a/funcweb/funcweb/identity/pam.py b/funcweb/funcweb/identity/pam.py index 0e45353..2dee750 100644 --- a/funcweb/funcweb/identity/pam.py +++ b/funcweb/funcweb/identity/pam.py @@ -14,7 +14,7 @@ __all__ = ['authenticate'] from ctypes import CDLL, POINTER, Structure, CFUNCTYPE, cast, pointer, sizeof from ctypes import c_void_p, c_uint, c_char_p, c_char, c_int -#funcweb specific part +#funcweb specific part from funcweb.commands import PRODUCTION_ENV LIBPAM = CDLL("libpam.so.0") diff --git a/funcweb/funcweb/result_handler.py b/funcweb/funcweb/result_handler.py index afd62f1..6273490 100644 --- a/funcweb/funcweb/result_handler.py +++ b/funcweb/funcweb/result_handler.py @@ -12,7 +12,7 @@ def produce_res_rec(result_pack): if type(result_pack) != list and type(result_pack) != dict: global_max = global_max + 1 return {'id':global_max,'text':str(result_pack)} - + elif type(result_pack) == list : for result_list in result_pack: if type(result_list) == list: @@ -47,9 +47,9 @@ def produce_res_rec(result_pack): tmp_parent = {} tmp_parent ['id'] = global_max tmp_parent ['text'] = str(key_result) - + tmp_dict_res = produce_res_rec(value_result) - + if tmp_dict_res and type(tmp_dict_res) == list : tmp_parent ['item'] = [] tmp_parent['item'].extend(tmp_dict_res) @@ -58,7 +58,7 @@ def produce_res_rec(result_pack): tmp_parent['item'].append(tmp_dict_res) send_list.append(tmp_parent) - + else: #shouldnt come here ! return {} @@ -66,20 +66,20 @@ def produce_res_rec(result_pack): if __name__ == "__main__": """ - - + + main_pack = { 'minion':[["one","two"],["three","four"]] } - - - - - - - + + + + + + + main_pack = { - + 'minion':{ 'result1':True, 'result2':False @@ -93,10 +93,10 @@ if __name__ == "__main__": 'result6':False } - + } """ - + main_pack = { 'minion1':[ { @@ -114,12 +114,10 @@ if __name__ == "__main__": 'res4':['wums','dums'] } ] - + } final = produce_res_rec(main_pack) print "The final pack is like that : " print final - - diff --git a/funcweb/funcweb/tests/bork.py b/funcweb/funcweb/tests/bork.py index 45631f7..9772f31 100644 --- a/funcweb/funcweb/tests/bork.py +++ b/funcweb/funcweb/tests/bork.py @@ -33,5 +33,3 @@ while code_status != JOB_ID_FINISHED: code_status = fc.job_status(job_id)[0] time.sleep(2) print "The run_string was finished" - - diff --git a/funcweb/funcweb/tests/test_async_tools.py b/funcweb/funcweb/tests/test_async_tools.py index 7af53ba..1dd8bfb 100644 --- a/funcweb/funcweb/tests/test_async_tools.py +++ b/funcweb/funcweb/tests/test_async_tools.py @@ -15,12 +15,12 @@ class AsyncResultManagerTest(object): def update_current_list_test(self): pass - + def check_for_changes_test(self): - print "***** Testing check_for_changes *****" + print "***** Testing check_for_changes *****" self.reset_stuff() - #now make a new entry into database to have a only one + #now make a new entry into database to have a only one #new entry in the db ... #running a new command which is a short one new_fc = Overlord("*",async=True) @@ -30,21 +30,21 @@ class AsyncResultManagerTest(object): print "The latest Changes for add method are :",changes assert len(changes) == 1 assert changes[0] == new_job_id - + #check if that one is finished another_test = False while new_fc.job_status(new_job_id)[0] != JOB_ID_FINISHED: print "Waiting for add command to finish " time.sleep(2) another_test = True - + # that probably may happen so should add it here if another_test: changes = self.async_manager.check_for_changes() assert len(changes) == 1 assert changes[0] == new_job_id print "The changes are for add finish :",changes - + #now should run another command that is longer to see what happens new_job_id = new_fc.test.sleep(4) # we have now one entry in the db what to do ? @@ -53,34 +53,34 @@ class AsyncResultManagerTest(object): print "The changes for sleep are :",changes assert len(changes) == 1 assert changes[0] == new_job_id - + #if we already have the finished message we dont have to run the other test after that one another_test = False while new_fc.job_status(new_job_id)[0] != JOB_ID_FINISHED: print "Waiting for sleep command to finish " time.sleep(2) another_test = True - + if another_test: changes = self.async_manager.check_for_changes() assert len(changes) == 1 assert changes[0] == new_job_id print "The changes for sleep finish are :",changes - - + + def select_from_test(self): print "****Testing select_from**** " - #these tests are a little bit tricky so may not have + #these tests are a little bit tricky so may not have #the exact results all depends on remote machines :) self.reset_stuff() new_fc = Overlord("*",async=True) #new_job_id=new_fc.test.add(1,2) new_job_id = new_fc.test.sleep(6) - + #insert one running - #now we have one entry into async_manager + #now we have one entry into async_manager result_ids = new_fc.open_job_ids() - self.async_manager.refresh_list() + self.async_manager.refresh_list() if result_ids.has_key(new_job_id) and result_ids[new_job_id] == JOB_ID_RUNNING: print "Testing for SELECT RUNNING ..." select_list = self.async_manager.select_from('RUNNING') @@ -88,7 +88,7 @@ class AsyncResultManagerTest(object): assert len(select_list) == 1 assert select_list[0].has_key(new_job_id) assert select_list[0][new_job_id][0] == JOB_ID_RUNNING - + #pull_property_options = ('FINISHED','ERROR','NEW','CHANGED','RUNNING','PARTIAL') #insert one that finishes #get one NEW @@ -98,15 +98,15 @@ class AsyncResultManagerTest(object): assert len(select_list) == 1 assert select_list[0].has_key(new_job_id) assert select_list[0][new_job_id][1] == self.async_manager.JOB_CODE_NEW - + #test the ones that are changed :) another_test = False - current_job_status = new_fc.job_status(new_job_id)[0] + current_job_status = new_fc.job_status(new_job_id)[0] while current_job_status != JOB_ID_FINISHED: print "Waiting for sleep command to finish " time.sleep(1) another_test = True - + #test also for partial resultst status if current_job_status == JOB_ID_PARTIAL: #populate the list @@ -115,12 +115,12 @@ class AsyncResultManagerTest(object): select_list = self.async_manager.select_from('PARTIAL') assert select_list[0].has_key(new_job_id) assert select_list[0][new_job_id][0] == JOB_ID_PARTIAL - - current_job_status = new_fc.job_status(new_job_id)[0] - - + + current_job_status = new_fc.job_status(new_job_id)[0] + + if another_test: - + print "Testing for SELECT CHANGED ..." self.async_manager.refresh_list() select_list = self.async_manager.select_from('CHANGED') @@ -128,7 +128,7 @@ class AsyncResultManagerTest(object): assert len(select_list) == 1 assert select_list[0].has_key(new_job_id) assert select_list[0][new_job_id][1] == self.async_manager.JOB_CODE_CHANGED - + print "Testing for SELECT FINISHED ..." assert select_list[0][new_job_id][0] == JOB_ID_FINISHED @@ -150,14 +150,14 @@ class AsyncResultManagerTest(object): real_result =self.async_manager.current_db() #print real_result - assert manual_list ==real_result - + assert manual_list ==real_result + def reset_stuff(self): #first reset the database to see what is there self.remove_db() #all of them are new now self.async_manager.reset_current_list() - + def remove_db(self): import os @@ -168,7 +168,7 @@ class AsyncResultManagerTest(object): os.remove("".join([root_dir,"/",f])) print "The database is removed" -# we do it that way because when run it from nosetest we hae failings +# we do it that way because when run it from nosetest we hae failings tester = AsyncResultManagerTest() tester.setUp() #tester.current_db_test() diff --git a/funcweb/funcweb/tests/test_client_rendering.py b/funcweb/funcweb/tests/test_client_rendering.py index f457da3..ea0ea85 100644 --- a/funcweb/funcweb/tests/test_client_rendering.py +++ b/funcweb/funcweb/tests/test_client_rendering.py @@ -18,7 +18,7 @@ class TestClientWidgetRender(object): fc = Overlord(self.minion) modules = fc.system.list_modules() display_modules={} - + print "Getting the modules that has exported arguments" for module in modules.itervalues(): for mod in module: @@ -40,6 +40,3 @@ class TestClientWidgetRender(object): schema_man=wf.get_ready_schema() minion_form = RemoteFormAutomation(wlist_object,schema_man) print "%s.%s.%s rendered"%(self.minion,module,method_name) - - - diff --git a/funcweb/funcweb/tests/test_model.py b/funcweb/funcweb/tests/test_model.py index 903c2d8..752bff8 100644 --- a/funcweb/funcweb/tests/test_model.py +++ b/funcweb/funcweb/tests/test_model.py @@ -19,4 +19,3 @@ from turbogears import testutil, database # display_name = "Mr Creosote", # password = "Wafer-thin Mint") # assert obj.display_name == "Mr Creosote" - diff --git a/funcweb/funcweb/tests/test_result_handler.py b/funcweb/funcweb/tests/test_result_handler.py index 95dcf73..69e3a68 100644 --- a/funcweb/funcweb/tests/test_result_handler.py +++ b/funcweb/funcweb/tests/test_result_handler.py @@ -1,5 +1,5 @@ -#all the test cases which are 16 and handle 4 level -#list hash indentation are tested manually because +#all the test cases which are 16 and handle 4 level +#list hash indentation are tested manually because #couldnt find a way to automate that process :) #zeros stands for dict type 1 id for lists @@ -46,7 +46,7 @@ test_0001 = { 'result111':[1111,1111,1111] } }, - + 'result12':{ 'result12':{ 'result122':[1222,1222,1222] @@ -422,8 +422,7 @@ def test_result_handler(): result = produce_res_rec(test_case) #not a perfect one but it is just a poc #if sth is wrong can be seen here - #if someone wants to add more casess it is + #if someone wants to add more casess it is #just enough to add them to the list #print result assert type(result) == list - diff --git a/funcweb/funcweb/tests/test_widget_automation.py b/funcweb/funcweb/tests/test_widget_automation.py index 36fc387..ab8f14d 100644 --- a/funcweb/funcweb/tests/test_widget_automation.py +++ b/funcweb/funcweb/tests/test_widget_automation.py @@ -6,22 +6,22 @@ from funcweb.widget_automation import * from funcweb.widget_validation import * class TestWidgetListFactory(unittest.TestCase): - + def setUp(self): self.widget_factory = WidgetListFactory(self.get_test_default_args(),minion="myminion",module="mymodule",method="my_method") def test_default_args(self): """ - Test to check the default args if they were assigned + Test to check the default args if they were assigned """ compare_with = self.get_test_default_args() widget_list=self.widget_factory.get_widgetlist() - + #print "The widget list is like :",widget_list for argument_name,argument_options in compare_with.iteritems(): assert widget_list.has_key(argument_name) == True - #test the label + #test the label assert pretty_label(argument_name) == getattr(widget_list[argument_name],'label') #print getattr(widget_list[argument_name],'label') @@ -35,42 +35,42 @@ class TestWidgetListFactory(unittest.TestCase): if argument_options.has_key("options"): assert argument_options['options'] == getattr(widget_list[argument_name],"options") - + def test_add_specialized_list(self): """ - Testing the internals of the special list widget + Testing the internals of the special list widget """ test_list_data = self.get_test_default_args()['list_default'] widget_list_object = self.widget_factory.get_widgetlist_object() #not very efficient but works #hash_widget_object should be a widgets.RepeatingFieldSet list_widget_object = [h_obj for h_obj in widget_list_object if getattr(h_obj,'name')=='list_default'][0] - + assert isinstance(list_widget_object.fields[0],widgets.TextField) == True assert getattr(list_widget_object.fields[0],'name') == 'listfield' assert getattr(list_widget_object.fields[0],'label') == 'List Field' - + def test_add_specialized_hash(self): """ - Testing the internals of the special hash widget - """ + Testing the internals of the special hash widget + """ test_hash_data = self.get_test_default_args()['hash_default'] widget_list_object = self.widget_factory.get_widgetlist_object() #not very efficient but works #hash_widget_object should be a widgets.RepeatingFieldSet hash_widget_object = [h_obj for h_obj in widget_list_object if getattr(h_obj,'name')=='hash_default'][0] - + #print hash_widget_object.fields #check the key data assert isinstance(hash_widget_object.fields[0],widgets.TextField) == True assert getattr(hash_widget_object.fields[0],'name') == 'keyfield' assert getattr(hash_widget_object.fields[0],'label') == 'Key Field' - #check the value data + #check the value data assert isinstance(hash_widget_object.fields[1],widgets.TextField) == True assert getattr(hash_widget_object.fields[1],'name') == 'valuefield' assert getattr(hash_widget_object.fields[1],'label') == 'Value Field' - + def test_get_widgetlist_object(self): """ @@ -78,9 +78,9 @@ class TestWidgetListFactory(unittest.TestCase): """ compare_with = self.get_test_default_args() widget_list_object = self.widget_factory.get_widgetlist_object() - + #print widget_list_object - + all_fields = [getattr(field,"name") for field in widget_list_object] #print all_fields for argument_name in compare_with.keys(): @@ -99,10 +99,10 @@ class TestWidgetListFactory(unittest.TestCase): def test_remote_form_factory(self): from turbogears.view import load_engines load_engines() - + schema_factory = WidgetSchemaFactory(self.get_test_default_args()) schema_validator=schema_factory.get_ready_schema() - + # WidgetsList object widget_list_object = self.widget_factory.get_widgetlist_object() #print widget_list_object @@ -115,7 +115,7 @@ class TestWidgetListFactory(unittest.TestCase): #print all_fields #will check if the remote form object hass all the names in it for argument_name in widget_list.items(): - argument_name in all_fields + argument_name in all_fields #print remote_form.render() @@ -125,17 +125,17 @@ class TestWidgetListFactory(unittest.TestCase): Testing the label converter util method """ test_strings = ('service_name','some__other','cool-arg','somenormal','someweir*1*2*3*3') - #print pretty_label(test_strings[0]) + #print pretty_label(test_strings[0]) assert pretty_label(test_strings[0]) == 'Service Name' - #print pretty_label(test_strings[1]) + #print pretty_label(test_strings[1]) assert pretty_label(test_strings[1]) == 'Some Other' - #print pretty_label(test_strings[2]) + #print pretty_label(test_strings[2]) assert pretty_label(test_strings[2]) == 'Cool Arg' - #print pretty_label(test_strings[3]) + #print pretty_label(test_strings[3]) assert pretty_label(test_strings[3]) == 'Somenormal' - #print pretty_label(test_strings[4]) + #print pretty_label(test_strings[4]) assert pretty_label(test_strings[4]) == 'Someweir*1*2*3*3' - + def get_test_default_args(self): return { 'string_default':{ @@ -161,7 +161,7 @@ class TestWidgetListFactory(unittest.TestCase): 'default':'default float', 'optional':False, 'description':'default description' - + }, 'hash_default':{ 'type':'hash', @@ -169,7 +169,7 @@ class TestWidgetListFactory(unittest.TestCase): 'optional':False, 'description':'default description', 'validator':'^[0-9]*$' - + }, 'list_default':{ 'type':'list', @@ -177,7 +177,7 @@ class TestWidgetListFactory(unittest.TestCase): 'optional':False, 'description':'default description', 'validator':'^[0-9]*$' - + }, #will be converted to dropdown 'special_string':{ @@ -187,6 +187,5 @@ class TestWidgetListFactory(unittest.TestCase): 'optional':False, 'description':'default dropdown list' } - - } + } diff --git a/funcweb/funcweb/tests/test_widget_validation.py b/funcweb/funcweb/tests/test_widget_validation.py index 373ce0b..9ead98b 100644 --- a/funcweb/funcweb/tests/test_widget_validation.py +++ b/funcweb/funcweb/tests/test_widget_validation.py @@ -2,14 +2,14 @@ import unittest import turbogears from turbogears import testutil from funcweb.widget_validation import WidgetSchemaFactory,MinionIntValidator,MinionFloatValidator,MinionListValidator,MinionHashValidator -from turbogears import validators +from turbogears import validators class TestWidgetValidator(unittest.TestCase): def test_string_validator(self): wf = WidgetSchemaFactory(self.get_string_params()) schema_man=wf.get_ready_schema() - + conversion_schema = { 'max_length':'max', 'min_length':'min', @@ -33,19 +33,19 @@ class TestWidgetValidator(unittest.TestCase): if arg_options.has_key('optional'): #print " ",argument_name," : ",getattr(schema_man,argument_name) assert not getattr(current_schema_object,'not_empty') == arg_options['optional'] - + print "Happy tests !" def test_int_validator(self): wf = WidgetSchemaFactory(self.get_int_params()) schema_man=wf.get_ready_schema() - - for argument_name,arg_options in self.get_int_params().iteritems(): + + for argument_name,arg_options in self.get_int_params().iteritems(): #print argument_name assert getattr(schema_man,'fields').has_key(argument_name)==True current_schema_object = getattr(schema_man,'fields')[argument_name] #print " ",argument_name," : ",getattr(schema_man,argument_name) - + #if the argument includes some range if arg_options.has_key('range'): #print " ",argument_name," : ",getattr(schema_man,argument_name) @@ -54,32 +54,32 @@ class TestWidgetValidator(unittest.TestCase): if arg_options.has_key('min'): #print " ",argument_name," : ",getattr(schema_man,argument_name) assert getattr(current_schema_object,'min') == arg_options['min'] - + if arg_options.has_key('max'): #print " ",argument_name," : ",getattr(schema_man,argument_name) assert getattr(current_schema_object,'max') == arg_options['max'] - + if arg_options.has_key('optional'): #print " ",argument_name," : ",getattr(schema_man,argument_name) assert not getattr(current_schema_object,'not_empty') == arg_options['optional'] print "Happy test!" - + def test_float_validator(self): wf = WidgetSchemaFactory(self.get_float_params()) schema_man=wf.get_ready_schema() - - for argument_name,arg_options in self.get_float_params().iteritems(): + + for argument_name,arg_options in self.get_float_params().iteritems(): #print argument_name assert getattr(schema_man,'fields').has_key(argument_name)==True current_schema_object = getattr(schema_man,'fields')[argument_name] #print " ",argument_name," : ",getattr(schema_man,argument_name) - + if arg_options.has_key('min'): #print " ",argument_name," : ",getattr(schema_man,argument_name) assert getattr(current_schema_object,'min') == arg_options['min'] - + if arg_options.has_key('max'): #print " ",argument_name," : ",getattr(schema_man,argument_name) assert getattr(current_schema_object,'max') == arg_options['max'] @@ -90,24 +90,24 @@ class TestWidgetValidator(unittest.TestCase): print "Happy test!" - + def test_bool_validator(self): testing_data = self.get_bool_params() wf = WidgetSchemaFactory(testing_data) schema_man=wf.get_ready_schema() - - for argument_name,arg_options in testing_data.iteritems(): + + for argument_name,arg_options in testing_data.iteritems(): #print argument_name #should all the argument names really assert getattr(schema_man,'fields').has_key(argument_name)==True current_schema_object = getattr(schema_man,'fields')[argument_name] - + #print " ",argument_name," : ",getattr(schema_man,argument_name) if arg_options.has_key('optional'): #print " ",argument_name," : ",getattr(schema_man,argument_name) assert not getattr(current_schema_object,'not_empty') == arg_options['optional'] - + print "Happy test!" @@ -120,15 +120,15 @@ class TestWidgetValidator(unittest.TestCase): wf = WidgetSchemaFactory(testing_data) schema_man=wf.get_ready_schema() - - for argument_name,arg_options in testing_data.iteritems(): + + for argument_name,arg_options in testing_data.iteritems(): #print argument_name #should all the argument names really #print " ",argument_name," : ",getattr(schema_man,argument_name) assert getattr(schema_man,'fields').has_key(argument_name)==True current_schema_object = getattr(schema_man,'fields')[argument_name] - - + + if arg_options.has_key('validator'): #print " ",argument_name," : ",getattr(schema_man,argument_name) assert getattr(current_schema_object,'regex_string') == arg_options['validator'] @@ -150,20 +150,20 @@ class TestWidgetValidator(unittest.TestCase): self.assertRaises(validators.Invalid,mv.to_python,1) self.assertRaises(validators.Invalid,mv.to_python,'some_string') assert mv.to_python(21) == 21 - + #dont use the min mv=MinionIntValidator(max = 44) self.assertRaises(validators.Invalid,mv.to_python,100) assert mv.to_python(1)==1 self.assertRaises(validators.Invalid,mv.to_python,'some_string') assert mv.to_python(21) == 21 - + mv=MinionIntValidator(min=12) self.assertRaises(validators.Invalid,mv.to_python,10) assert mv.to_python(14)==14 self.assertRaises(validators.Invalid,mv.to_python,'some_string') assert mv.to_python(21) == 21 - + mv=MinionIntValidator() assert mv.to_python(14)==14 self.assertRaises(validators.Invalid,mv.to_python,'some_string') @@ -174,26 +174,26 @@ class TestWidgetValidator(unittest.TestCase): self.assertRaises(validators.Invalid,mv.to_python,1.0) self.assertRaises(validators.Invalid,mv.to_python,'some_string') assert mv.to_python(21.0) == 21.0 - + #dont use the min mv=MinionFloatValidator(max = 44.0) self.assertRaises(validators.Invalid,mv.to_python,100.0) assert mv.to_python(1.0)==1.0 self.assertRaises(validators.Invalid,mv.to_python,'some_string') assert mv.to_python(21.0) == 21.0 - + mv=MinionFloatValidator(min=12.0) self.assertRaises(validators.Invalid,mv.to_python,10.0) assert mv.to_python(14.0)==14.0 self.assertRaises(validators.Invalid,mv.to_python,'some_string') assert mv.to_python(21.0) == 21.0 - + mv=MinionFloatValidator() assert mv.to_python(14.0)==14.0 self.assertRaises(validators.Invalid,mv.to_python,'some_string') - + def test_minion_list_validator(self): - + #test default mv = MinionListValidator() [{'listfield': u'listone'}, {'listfield': u'listtwo'}] @@ -210,10 +210,10 @@ class TestWidgetValidator(unittest.TestCase): print "Happy testing !" - - + + def test_minion_hash_validator(self): - + #test default mv = MinionHashValidator() assert mv.to_python([{'keyfield':'keyvalue','valuefield':'valuehere'}]) == {'keyvalue':'valuehere'} @@ -228,7 +228,7 @@ class TestWidgetValidator(unittest.TestCase): del mv print "Happy testing !" - + def get_string_params(self): return { @@ -259,7 +259,7 @@ class TestWidgetValidator(unittest.TestCase): 'validator':'^[A-Z]+$' } } - + def get_int_params(self): return { 'int_default':{ @@ -281,7 +281,7 @@ class TestWidgetValidator(unittest.TestCase): 'range':[1,55] } } - + def get_float_params(self): return { 'float_default':{ @@ -298,7 +298,7 @@ class TestWidgetValidator(unittest.TestCase): 'min':5.0 }, } - + def get_list_params(self): return { 'list_default':{ @@ -330,7 +330,7 @@ class TestWidgetValidator(unittest.TestCase): 'validator':'^[A-Z]+$' }, } - + def get_bool_params(self): return { 'bool_default':{ @@ -340,6 +340,3 @@ class TestWidgetValidator(unittest.TestCase): 'optional':False, }, } - - - diff --git a/funcweb/funcweb/widget_automation.py b/funcweb/funcweb/widget_automation.py index 9769586..92e9a37 100644 --- a/funcweb/funcweb/widget_automation.py +++ b/funcweb/funcweb/widget_automation.py @@ -1,4 +1,4 @@ -#the purpose of that module is to make widget automation +#the purpose of that module is to make widget automation #for registered minion modules so we dont hace to write #that same boring stuff for every added module ! @@ -30,7 +30,7 @@ class WidgetListFactory(object): 'list':{ 'type':"RepeatingFieldSet"}, 'list*':{ - 'type':"RepeatingFieldSet"} + 'type':"RepeatingFieldSet"} } #will contain the input widget created in that class @@ -50,20 +50,20 @@ class WidgetListFactory(object): self.minion = minion self.module = module self.method = method - + def __add_general_widget(self): - # a mirror var to show that these are same things + # a mirror var to show that these are same things mirror_case = {'list*':'list'} #key is the argument_name and the argument are options for key,argument in self.__argument_dict.iteritems(): #get the type of the argument current_type = argument['type'] - + act_special = False #if it has some special parameters #it should be passed to its specialized method,if it has #for example options in its key it should be shown as a #SingleSelectField not a TextFiled - + for type_match in self.__convert_table[current_type].keys(): if type_match!='default_value' and argument.has_key(type_match): act_special = True @@ -108,16 +108,16 @@ class WidgetListFactory(object): @param : argument_name : the name of the argument also the name of the widget @return : Nothing """ - + #allittle bit difficult to follow but that structure does #temp_object = SingleSelectField() for example - + temp_object = getattr(widgets,self.__convert_table[argument['type']]['options'])(options = argument['options']) self.__add_commons_to_object(temp_object,argument,argument_name) #add a new entry to final list self.__widget_list[argument_name]=temp_object del temp_object - + def __add_specialized_hash(self,argument,argument_name): """ Specialized option adder for hash, we need it to be diffferent @@ -126,7 +126,7 @@ class WidgetListFactory(object): web UI. It uses the RepeatingFieldSet which is able to contain the other normal input widgets. It will have two fields (TextFields) one for key : keyfield and other for value : valuefield - Also the validator addition is a little bit different and should + Also the validator addition is a little bit different and should be done in that method also ... @param : argument : the argument options, @@ -140,7 +140,7 @@ class WidgetListFactory(object): widgets.TextField(name="valuefield",label="Value Field") ], } - + #create the RepeatingFieldSet object and add it to global list like you do for others temp_object = getattr(widgets,self.__convert_table[argument['type']]['type'])(**hash_repeat_data) #print temp_object.fields @@ -149,17 +149,17 @@ class WidgetListFactory(object): #add a new entry to final list self.__widget_list[argument_name]=temp_object del temp_object - + def __add_specialized_list(self,argument,argument_name): """ Very similar to __add_specialized_hash except it has one field - that is repeated so that provides a dynamic numbers of fields into + that is repeated so that provides a dynamic numbers of fields into the web UI. - - TODO : combine the 2 methods into a one generic they are very similar + + TODO : combine the 2 methods into a one generic they are very similar @param : argument : the argument options, @param : argument_name : the name of the argument also the name of the widget @return : Nothing @@ -170,7 +170,7 @@ class WidgetListFactory(object): widgets.TextField(name="listfield",label="List Field") ], } - + #create the RepeatingFieldSet object and add it to global list like you do for others temp_object = getattr(widgets,self.__convert_table[argument['type']]['type'])(**list_repeat_data) #add the commno options @@ -178,23 +178,23 @@ class WidgetListFactory(object): #add a new entry to final list self.__widget_list[argument_name]=temp_object del temp_object - + def __add_commons_to_object(self,object,argument,argument_name): """ As it was thought all input widgets have the same common parameters they take so that method will add - them to instantiated object for ex (TextField) if they + them to instantiated object for ex (TextField) if they occur into the argument ... @param object : instantiated inputwidget object @param method argument to lookup {type:'int','max':12 ...} @return :None """ - #firstly set the name of the argument + #firstly set the name of the argument setattr(object,"name",argument_name) setattr(object,"label",pretty_label(argument_name)) - + #print "The argument name is :",argument_name #print "The argument options are :",argument @@ -202,7 +202,7 @@ class WidgetListFactory(object): setattr(object,"default",argument["default"]) if argument.has_key('description'): setattr(object,'help_text',argument['description']) - + def get_widgetlist(self): """ Return back a dictionay with argument_name : input_widget @@ -222,7 +222,7 @@ class WidgetListFactory(object): #print self.__widget_list if len(self.__widget_list.keys())==0: self.__add_general_widget() #not very efficient - + widget_list_object = widgets.WidgetsList() for name,input_widget in self.__widget_list.iteritems(): #it is a list indeed @@ -244,7 +244,7 @@ class RemoteFormAutomation(CoreWD): name = "Ajaxian Minion Submit Form" - template = """ + template = """ <div> ${for_widget.display(action='/funcweb/post_form')} <div id="loading"></div> @@ -279,7 +279,7 @@ class RemoteFormFactory(object): and return back a RemoteForm the same as above just for testing """ - #some values that may want to change later + #some values that may want to change later name = "minion_form", update = "col5", before='getElement(\'loading\').innerHTML=toHTML(IMG({src:\'../funcweb/static/images/loading.gif\',width:\'100\',height:\'100\'}));', @@ -292,7 +292,7 @@ class RemoteFormFactory(object): self.validator_schema = validator_schema def get_remote_form(self): - + #print self.wlist_object return RemoteForm( @@ -310,7 +310,7 @@ class RemoteFormFactory(object): ############################################################################################# def pretty_label(name_to_label): """ - Simple util method to show the labels better + Simple util method to show the labels better without __ things and other ugly looking stuff """ tmp = None diff --git a/funcweb/funcweb/widget_validation.py b/funcweb/funcweb/widget_validation.py index b04572a..22fc8b2 100644 --- a/funcweb/funcweb/widget_validation.py +++ b/funcweb/funcweb/widget_validation.py @@ -9,7 +9,7 @@ class WidgetSchemaFactory(object): def __init__(self,method_argument_dict): """ - @param method_argument_dict : The dict that is + @param method_argument_dict : The dict that is from minion in format of {'arg':{'type':'string','options':[...]}} the format is defined in func/minion/func_arg.py """ @@ -21,9 +21,9 @@ class WidgetSchemaFactory(object): """ Method is an entry point of factory iters over the all arguments and according to their types it sends the process to more specialized - validator adders + validator adders """ - # a mirror var to show that these are same things + # a mirror var to show that these are same things mirror_case = {'list*':'list'} for argument_name,argument_values in self.method_argument_dict.iteritems(): #some lazy stuff :) @@ -36,22 +36,22 @@ class WidgetSchemaFactory(object): def _add_boolean_validator(self,argument_name): bool_data_set = {} - + #the optional keyword if self.method_argument_dict[argument_name].has_key('optional'): if self.method_argument_dict[argument_name]['optional']: bool_data_set['not_empty']=False else: bool_data_set['not_empty']=True - - + + if bool_data_set: self.validator_list[argument_name]=validators.Bool(**bool_data_set) else: self.validator_list[argument_name]=validators.Bool() - + def _add_int_validator(self,argument_name): """ @@ -60,14 +60,14 @@ class WidgetSchemaFactory(object): """ #the initializer for the int_validator int_data_set = {} - + #the optional keyword if self.method_argument_dict[argument_name].has_key('optional'): if self.method_argument_dict[argument_name]['optional']: int_data_set['not_empty']=False else: int_data_set['not_empty']=True - + if self.method_argument_dict[argument_name].has_key('range'): #because the range is [min,max] list the 0 is min 1 is the max int_data_set['min']=self.method_argument_dict[argument_name]['range'][0] @@ -85,7 +85,7 @@ class WidgetSchemaFactory(object): - + def _add_string_validator(self,argument_name): """ Gets the options of the string type and adds a @@ -94,7 +94,7 @@ class WidgetSchemaFactory(object): string_data_set={} str_validator_list =[] - + if self.method_argument_dict[argument_name].has_key('optional'): if self.method_argument_dict[argument_name]['optional']: string_data_set['not_empty']=False @@ -111,7 +111,7 @@ class WidgetSchemaFactory(object): #if we have set a string_data_set if string_data_set: str_validator_list.append(getattr(validators,'String')(**string_data_set)) - + #if true it should be a validator.All thing if len(str_validator_list)>1: self.validator_list[argument_name]=getattr(validators,'All')(*str_validator_list) @@ -131,14 +131,14 @@ class WidgetSchemaFactory(object): #the initializer for the float_validator float_data_set = {} - + #is it optional if self.method_argument_dict[argument_name].has_key('optional'): if self.method_argument_dict[argument_name]['optional']: float_data_set['not_empty']=False else: float_data_set['not_empty']=True - + if self.method_argument_dict[argument_name].has_key('min'): float_data_set['min']=self.method_argument_dict[argument_name]['min'] @@ -159,17 +159,17 @@ class WidgetSchemaFactory(object): new validator to validator_list """ list_data_set = {} - + #is it optional if self.method_argument_dict[argument_name].has_key('optional'): if self.method_argument_dict[argument_name]['optional']: list_data_set['not_empty']=False else: list_data_set['not_empty']=True - + if self.method_argument_dict[argument_name].has_key('validator'): list_data_set['regex_string'] = self.method_argument_dict[argument_name]['validator'] - + if list_data_set: if the_type == 'list': self.validator_list[argument_name]=MinionListValidator(**list_data_set) @@ -211,7 +211,7 @@ class MinionIntValidator(validators.FancyValidator): """ Confirms that the input/output is of the proper type of int. - + """ #automatically will be assigned min = None @@ -228,8 +228,8 @@ class MinionIntValidator(validators.FancyValidator): raise validators.Invalid('The field should be integer',value,state) return int(value) - - + + def validate_python(self,value,state): """ The actual validator @@ -238,15 +238,15 @@ class MinionIntValidator(validators.FancyValidator): if self.min and self.min: if value < self.min: raise validators.Invalid('The number you entered should be bigger that %d'%(self.min),value,state) - + if self.max and self.max: if value > self.max: raise validators.Invalid('The number you entered exceeds the %d'%(self.max),value,state) - + ################################################################## class MinionFloatValidator(MinionIntValidator): - + def _to_python(self,value,state): """ Will check just the type here and return @@ -258,10 +258,10 @@ class MinionFloatValidator(MinionIntValidator): raise validators.Invalid('The field should be a float',value,state) return float(value) - + ################################################################# class MinionListValidator(validators.FancyValidator): - + regex_string = None def _to_python(self,value,state): @@ -269,7 +269,7 @@ class MinionListValidator(validators.FancyValidator): Will check just the type here and return value to be validated in validate_python """ - #will add more beautiful validation here after + #will add more beautiful validation here after #integrate the complex widgets for lists and dicts #print "Im in the list validator the value i recieved is : ",value @@ -281,12 +281,12 @@ class MinionListValidator(validators.FancyValidator): tmp = [] if type(tmp) != type(value): value = list(value) - - #concert the data to proper format + + #concert the data to proper format final_list = [] for hash_data in value: final_list.extend(hash_data.values()) - + return final_list def validate_python(self,value,state): @@ -296,15 +296,15 @@ class MinionListValidator(validators.FancyValidator): compiled_regex = re.compile(self.regex_string) except Exception,e: raise validators.Invalid('The passed regex_string is not a valid expression'%self.regex_string,value,state) - + for list_value in value: if not re.match(compiled_regex,str(list_value)): raise validators.Invalid('The %s doesnt match to the regex expression that was supplied'%list_value,value,state) - #there is no else for now :) + #there is no else for now :) class MinionHashValidator(validators.FancyValidator): - + regex_string = None def _to_python(self,value,state): @@ -312,26 +312,26 @@ class MinionHashValidator(validators.FancyValidator): Will check just the type here and return value to be validated in validate_python """ - #will add more beautiful validation here after + #will add more beautiful validation here after #integrate the complex widgets for lists and dicts #print "Im in hash validator the value i recieved is ",value if self.not_empty: if len(value)==0: raise validators.Invalid('Empty hash passed when not_empty is set',value,state) - - #concert the data to proper format + + #concert the data to proper format final_hash = {} for hash_data in value: final_hash[hash_data['keyfield']] = hash_data['valuefield'] - + #check the type firstly tmp = {} if type(tmp) != type(final_hash): raise validators.Invalid('The value passed to MinionHashValidator should be a dict object',final_hash,state) - + #print value return final_hash diff --git a/pusher.py b/pusher.py index a9120fb..1df0b4d 100755 --- a/pusher.py +++ b/pusher.py @@ -34,22 +34,22 @@ import glob import subprocess def run(cmd,failok=False): - """ - Wrapper around subprocess - """ - print "running: %s" % cmd - rc = subprocess.call(cmd, shell=True) - print "rc: %s" % rc - if not failok and not rc == 0: - croak("aborting") + """ + Wrapper around subprocess + """ + print "running: %s" % cmd + rc = subprocess.call(cmd, shell=True) + print "rc: %s" % rc + if not failok and not rc == 0: + croak("aborting") def croak(msg): - """ - Print something and die. - """ - print msg - sys.exit(1) + """ + Print something and die. + """ + print msg + sys.exit(1) # process options, as described at the top of this file @@ -58,9 +58,9 @@ p.add_option("--cvs", dest="cvs", help="EX: ~/cvs/func") p.add_option("--proj", dest="proj", help="EX: /cg/func") (options,args) = p.parse_args() if options.cvs is None: - croak("--cvs is required, PEBKAC") + croak("--cvs is required, PEBKAC") if options.proj is None: - croak("--proj is required, PEBKAC") + croak("--proj is required, PEBKAC") cvsdir = os.path.expanduser(options.cvs) projdir = os.path.expanduser(options.proj) @@ -80,14 +80,14 @@ print " " # find the RPM build directory rpmbuild = os.path.join(projdir, "rpm-build") if not os.path.exists(rpmbuild): - croak("no directory: %s" % rpmbuild) + croak("no directory: %s" % rpmbuild) print "found rpm-build directory" # find the tarballs tarsearch = "%s/*.tar.gz" % rpmbuild tars = glob.glob(tarsearch) if len(tars) != 1: - croak("expected to find just one tar.gz in %s, no luck") % rpmbuild + croak("expected to find just one tar.gz in %s, no luck") % rpmbuild tarfile = tars[0] print "found tarball: %s" % tarfile @@ -103,13 +103,13 @@ versionfile = None specsearch = "%s/*.spec" % projdir specs = glob.glob(specsearch) if len(specs) != 1: - croak("need one and only one specfile in %s" % projdir) + croak("need one and only one specfile in %s" % projdir) specfile = specs[0] print "found specfile: %s" % specfile # verify cvsdir exists if not os.path.exists(cvsdir): - croak("can't find cvs directory: %s" % cvsdir) + croak("can't find cvs directory: %s" % cvsdir) # store current directory topdir = os.getcwd() @@ -144,5 +144,4 @@ for x in PROCESS_RELEASES: print "---------------------------------------------" print "all done, assuming you didn't see anything weird" print "don't forget to visit https://admin.fedoraproject.org/updates" -print " " - +print " " diff --git a/setup.py b/setup.py index a64f26b..29bddd4 100644 --- a/setup.py +++ b/setup.py @@ -12,70 +12,69 @@ A small pluggable xml-rpc daemon used by %s to implement various web services ho if __name__ == "__main__": - - manpath = "share/man/man1/" - etcpath = "/etc/%s" % NAME - etcmodpath = "/etc/%s/modules" % NAME - initpath = "/etc/init.d/" - logpath = "/var/log/%s/" % NAME - varpath = "/var/lib/%s/" % NAME - rotpath = "/etc/logrotate.d" - aclpath = "%s/minion-acl.d" % etcpath - setup( - name="%s" % NAME, - version = VERSION, - author = "Lots", - author_email = "func-list@xxxxxxxxxx", - url = "https://fedorahosted.org/func/", - license = "GPL", - scripts = [ - "scripts/funcd", - "scripts/func", - "scripts/func-group", - "scripts/func-inventory", - "scripts/func-create-module", - "scripts/func-transmit", - "scripts/func-build-map" - ], - package_dir = {"%s" % NAME: "%s" % NAME - }, - packages = ["%s" % NAME, - "%s/minion" % NAME, - "%s/overlord" % NAME, - "%s/overlord/cmd_modules" % NAME, - "%s/overlord/modules" % NAME, - "%s/overlord/group" % NAME, - "%s/minion/modules" % NAME, - "%s/minion/facts" % NAME, - "%s/minion/facts/modules/" % NAME, - "%s/yaml" % NAME, - # FIXME if there's a clean/easy way to recursively - # find modules then by all means do it, for now - # this will work. - "%s/minion/modules.netapp" % NAME, - "%s/minion/modules.netapp.vol" % NAME, - "%s/minion/modules.iptables" % NAME - ], - data_files = [(initpath, ["init-scripts/funcd"]), - (etcpath, ["etc/minion.conf", - "etc/overlord.conf", - "etc/async_methods.conf", - "etc/version"]), - (manpath, ["docs/func.1.gz", - "docs/func-inventory.1.gz", - "docs/funcd.1.gz", - "docs/func-transmit.1.gz", - "docs/func-create-module.1.gz", - "docs/func-build-map.1.gz"]), - (rotpath, ['etc/func_rotate']), - (logpath, []), - (etcmodpath, ['etc/Test.conf', - 'etc/Bridge.conf', - 'etc/Vlan.conf']), - (varpath, []), - (aclpath, []) - ], - description = SHORT_DESC, - long_description = LONG_DESC - ) + manpath = "share/man/man1/" + etcpath = "/etc/%s" % NAME + etcmodpath = "/etc/%s/modules" % NAME + initpath = "/etc/init.d/" + logpath = "/var/log/%s/" % NAME + varpath = "/var/lib/%s/" % NAME + rotpath = "/etc/logrotate.d" + aclpath = "%s/minion-acl.d" % etcpath + setup( + name="%s" % NAME, + version = VERSION, + author = "Lots", + author_email = "func-list@xxxxxxxxxx", + url = "https://fedorahosted.org/func/", + license = "GPL", + scripts = [ + "scripts/funcd", + "scripts/func", + "scripts/func-group", + "scripts/func-inventory", + "scripts/func-create-module", + "scripts/func-transmit", + "scripts/func-build-map" + ], + package_dir = {"%s" % NAME: "%s" % NAME + }, + packages = ["%s" % NAME, + "%s/minion" % NAME, + "%s/overlord" % NAME, + "%s/overlord/cmd_modules" % NAME, + "%s/overlord/modules" % NAME, + "%s/overlord/group" % NAME, + "%s/minion/modules" % NAME, + "%s/minion/facts" % NAME, + "%s/minion/facts/modules/" % NAME, + "%s/yaml" % NAME, + # FIXME if there's a clean/easy way to recursively + # find modules then by all means do it, for now + # this will work. + "%s/minion/modules.netapp" % NAME, + "%s/minion/modules.netapp.vol" % NAME, + "%s/minion/modules.iptables" % NAME + ], + data_files = [(initpath, ["init-scripts/funcd"]), + (etcpath, ["etc/minion.conf", + "etc/overlord.conf", + "etc/async_methods.conf", + "etc/version"]), + (manpath, ["docs/func.1.gz", + "docs/func-inventory.1.gz", + "docs/funcd.1.gz", + "docs/func-transmit.1.gz", + "docs/func-create-module.1.gz", + "docs/func-build-map.1.gz"]), + (rotpath, ['etc/func_rotate']), + (logpath, []), + (etcmodpath, ['etc/Test.conf', + 'etc/Bridge.conf', + 'etc/Vlan.conf']), + (varpath, []), + (aclpath, []) + ], + description = SHORT_DESC, + long_description = LONG_DESC + ) diff --git a/test/async_test.py b/test/async_test.py index 60c15ed..f8fdf4d 100755 --- a/test/async_test.py +++ b/test/async_test.py @@ -17,61 +17,60 @@ TESTS = [ SLOW_COMMAND, QUICK_COMMAND, RAISES_EXCEPTION_COMMAND, FAKE_COMMAND ] #TESTS = [ SLOW_COMMAND, QUICK_COMMAND, R ] def __tester(async,test, count): - if async: - overlord= Overlord("*",nforks=3,async=True) - oldtime = time.time() + if async: + overlord= Overlord("*",nforks=3,async=True) + oldtime = time.time() - job_id = -411 - print - # print "======================================================" - print "test iteration: %s" % count - if test == SLOW_COMMAND: - print "TESTING command that sleeps %s seconds" % TEST_SLEEP - job_id = overlord.test.sleep(TEST_SLEEP) - elif test == QUICK_COMMAND: - # print "TESTING a quick command" - job_id = overlord.test.ping() - # job_id = overlord.test.add(1,2) - elif test == RAISES_EXCEPTION_COMMAND: - print "TESTING a command that deliberately raises an exception" - job_id = overlord.test.explode() # doesn't work yet - elif test == FAKE_COMMAND: - print "TESTING a command that does not exist" - job_id = overlord.test.does_not_exist(1,2) # ditto + job_id = -411 + print + # print "======================================================" + print "test iteration: %s" % count + if test == SLOW_COMMAND: + print "TESTING command that sleeps %s seconds" % TEST_SLEEP + job_id = overlord.test.sleep(TEST_SLEEP) + elif test == QUICK_COMMAND: + # print "TESTING a quick command" + job_id = overlord.test.ping() + # job_id = overlord.test.add(1,2) + elif test == RAISES_EXCEPTION_COMMAND: + print "TESTING a command that deliberately raises an exception" + job_id = overlord.test.explode() # doesn't work yet + elif test == FAKE_COMMAND: + print "TESTING a command that does not exist" + job_id = overlord.test.does_not_exist(1,2) # ditto # print "======================================================" - print "job_id = %s" % job_id - while True: - status = overlord.job_status(job_id) - print "job_status: %s" % status[0] - (code, results) = status - nowtime = time.time() - delta = int(nowtime - oldtime) - if nowtime > oldtime + TEST_SLEEP + EXTRA_SLEEP: - print "time expired, test failed" - return - if code == jobthing.JOB_ID_RUNNING: - print "task is still running, %s elapsed ..." % delta - elif code == jobthing.JOB_ID_PARTIAL: - print "task reports partial status, %s elapsed, results = %s" % (delta, results) - elif code == jobthing.JOB_ID_FINISHED: - print "task complete, %s elapsed, results = %s" % (delta, results) - return - else: - print "job not found: %s, %s elapased" % (code, delta) - time.sleep(1) - else: - print Overlord("*",nforks=3,async=False).test.sleep(5) - print Overlord("*",nforks=3,async=False).test.bork(5) - print Overlord("*",nforks=1,async=False).test.bork(5) + print "job_id = %s" % job_id + while True: + status = overlord.job_status(job_id) + print "job_status: %s" % status[0] + (code, results) = status + nowtime = time.time() + delta = int(nowtime - oldtime) + if nowtime > oldtime + TEST_SLEEP + EXTRA_SLEEP: + print "time expired, test failed" + return + if code == jobthing.JOB_ID_RUNNING: + print "task is still running, %s elapsed ..." % delta + elif code == jobthing.JOB_ID_PARTIAL: + print "task reports partial status, %s elapsed, results = %s" % (delta, results) + elif code == jobthing.JOB_ID_FINISHED: + print "task complete, %s elapsed, results = %s" % (delta, results) + return + else: + print "job not found: %s, %s elapased" % (code, delta) + time.sleep(1) + else: + print Overlord("*",nforks=3,async=False).test.sleep(5) + print Overlord("*",nforks=3,async=False).test.bork(5) + print Overlord("*",nforks=1,async=False).test.bork(5) i = 1 while i < 3: - for t in TESTS: - __tester(True,t, i) - i = i + 1 + for t in TESTS: + __tester(True,t, i) + i = i + 1 #print "=======================================================" #print "Testing non-async call" #print __tester(False,-1) - diff --git a/test/test-confmgt_augeas.py b/test/test-confmgt_augeas.py index 6fe8dba..7a09248 100755 --- a/test/test-confmgt_augeas.py +++ b/test/test-confmgt_augeas.py @@ -10,7 +10,7 @@ print c.configmgt_augeas.getenv('AUGEAS_ROOT') def chroottest(): envdict={} print 'Get the env. variable AUGEAS_ROOT' - for host,envlist in c.confmgt_augeas.getenv('AUGEAS_ROOT').iteritems(): + for host,envlist in c.confmgt_augeas.getenv('AUGEAS_ROOT').iteritems(): print "Host: "+host augroot=envlist.get('AUGEAS_ROOT') print 'AUGEAS_ROOT: '+augroot @@ -21,7 +21,7 @@ def chroottest(): print "before launching this test." sys.exit() print - + print 'Prepare the test environment' for host in envdict: augroot=envdict[host] @@ -42,71 +42,71 @@ def basictest(): print 'Delete the Parameter PermitRootLogin in sshd_config' print c.confmgt_augeas.rm('/etc/ssh/sshd_config','PermitRootLogin') print - + print 'Delete the Parameter Port in sshd_config with an Augeas-style path' print c.confmgt_augeas.rm('/etc/ssh/sshd_config/Port') print - + print 'Get sshd_config Port value.' print c.confmgt_augeas.get('/etc/ssh/sshd_config','Port') print - + print 'Set Port to 22 in sshd_config' print c.confmgt_augeas.set('/etc/ssh/sshd_config','Port','22') print - + print 'Get sshd_config Port value.' print c.confmgt_augeas.get('/etc/ssh/sshd_config','Port') print - + print 'Try to delete a non existant parameter in sshd_config' print c.confmgt_augeas.rm('/etc/ssh/sshd_config','Nawak') print - + print 'Try to delete a parameter in a non existant file.' print c.confmgt_augeas.rm('/etc/ssh/nimp','Nawak') print - + print 'Get sshd_config PermitRootLogin value.' print c.confmgt_augeas.get('/etc/ssh/sshd_config','PermitRootLogin') print - + print 'Set PermitRootLogin to yes in sshd_config' print c.confmgt_augeas.set('/etc/ssh/sshd_config','PermitRootLogin','yes') print - + print 'Set PermitRootLogin to no in sshd_config with an Augeas-style path.' print c.confmgt_augeas.set('/etc/ssh/sshd_config/PermitRootLogin','','no') print - + print 'Set PermitRootLogin to yes in sshd_config with an Augeas-style path.' print c.confmgt_augeas.set('/etc/ssh/sshd_config/PermitRootLogin','','yes') print - + print 'Get sshd_config PermitRootLogin value.' print c.confmgt_augeas.get('/etc/ssh/sshd_config','PermitRootLogin') print - + print 'Get sshd_config PermitRootLogin value with an Augeas-style path.' print c.confmgt_augeas.get('/etc/ssh/sshd_config/PermitRootLogin') print - + print 'Attempt to get a value for a non existant param in sshd_config' print c.confmgt_augeas.get('/etc/ssh/sshd_config','Nawak') print - + print 'Attempt to get a value for an empty param in sshd_config' print c.confmgt_augeas.get('/etc/ssh/sshd_config','Subsystem') print - - print 'Search for conf. entry in hosts file with canonical hostname = localhost' + + print 'Search for conf. entry in hosts file with canonical hostname = localhost' print c.confmgt_augeas.match('/etc/hosts','canonical','localhost') print - + #print 'List all direct children of hosts (not very useful)' #print c.confmgt_augeas.ls('/etc/hosts/*') #print - + print 'List all direct children parameters of 1st hosts entry.' for host,paramlist in c.confmgt_augeas.ls('/etc/hosts/1').iteritems(): print "Host: "+host @@ -116,8 +116,8 @@ def basictest(): else: print paramlist print - - print 'List all children nodes of 1st hosts entry.' + + print 'List all children nodes of 1st hosts entry.' for host,paramlist in c.confmgt_augeas.printconf('/etc/hosts/1').iteritems(): print "Host: "+host if type(paramlist) == type({}): @@ -126,12 +126,12 @@ def basictest(): else: print paramlist print - + print 'Get values of 1st host entry.' print c.confmgt_augeas.get('/etc/hosts/','1') print - - print 'List all values for parameter of 1st fstab entry.' + + print 'List all values for parameter of 1st fstab entry.' minionDict=c.confmgt_augeas.ls('/etc/fstab/1') for host,entry in minionDict.iteritems(): print "Host: "+host @@ -142,12 +142,12 @@ def basictest(): else: print entry print - + print 'Get ipaddr of /etc/hosts 1st entry.' print c.confmgt_augeas.get('/etc/hosts/1','ipaddr') print # - #print 'List all direct children parameters of sshd_config' + #print 'List all direct children parameters of sshd_config' #for host,paramlist in c.confmgt_augeas.ls('/etc/ssh/sshd_config').iteritems(): # print "Host: "+host # for node in paramlist['nodes']: @@ -156,11 +156,11 @@ def basictest(): # print 'List all children nodes of sshd_config' for host,paramlist in c.confmgt_augeas.printconf('/etc/ssh/sshd_config').iteritems(): - print "Host: "+host - for node in paramlist['nodes']: - print node[0]+" = "+node[1] + print "Host: "+host + for node in paramlist['nodes']: + print node[0]+" = "+node[1] print - + print 'List all direct children of AcceptEnv entries in sshd_config' for host,paramlist in c.confmgt_augeas.ls('/etc/ssh/sshd_config/AcceptEnv').iteritems(): print "Host: "+host @@ -170,7 +170,7 @@ def basictest(): else: print paramlist print - + print 'See all AcceptEnv entries in sshd_config' for host,paramlist in c.confmgt_augeas.printconf('/etc/ssh/sshd_config/AcceptEnv').iteritems(): print "Host: "+host @@ -180,52 +180,52 @@ def basictest(): else: print paramlist print - + print 'Try to match PermitRootLogin yes in sshd_config' print c.confmgt_augeas.match('/etc/ssh/sshd_config','PermitRootLogin','yes') print - + print 'Try to match PermitRootLogin yes in sshd_config with an Augeas-style path' print c.confmgt_augeas.match('/etc/ssh/sshd_config/PermitRootLogin','','yes') print - + print 'Try to match PermitRootLogin yes in some config. files.' print c.confmgt_augeas.match('/etc/*/*','PermitRootLogin','yes') print - + print 'Try to match AcceptEnv in sshd_config' print c.confmgt_augeas.match('/etc/ssh/sshd_config','AcceptEnv') print - + print 'Try to match PermitRootLogin in sshd_config' print c.confmgt_augeas.match('/etc/ssh/sshd_config','PermitRootLogin') print - + print 'Try to match PermitRootLogin in sshd_config with an Augeas-style path.' print c.confmgt_augeas.match('/etc/ssh/sshd_config/PermitRootLogin') print - + print 'Try to match canonical entries in hosts file.' print c.confmgt_augeas.match('/etc/hosts','canonical') print - + print 'Try to match canonical entries in hosts file with an Augeas-style path.' print c.confmgt_augeas.match('/etc/hosts/*/canonical') print - + print 'Augeas metainformation.' print c.confmgt_augeas.ls('/','/augeas') print c.confmgt_augeas.get('/','save','/augeas') - + #Not supposed to work: print c.confmgt_augeas.set('/','save','backup','/augeas') print c.confmgt_augeas.set('/save','','backup','/augeas') - + print c.confmgt_augeas.get('/save','','/augeas') print c.confmgt_augeas.get('/files/etc/hosts/lens','info','/augeas') - - - + + + print 'Add a new variable FOO at the end of the last AcceptEnv line of sshd_config' print "And we don't want to do this twice." foomatch=c.confmgt_augeas.match('/etc/ssh/sshd_config','AcceptEnv/*','FOO') @@ -234,8 +234,8 @@ def basictest(): client = fc.Client(host) print client.confmgt_augeas.set('/etc/ssh/sshd_config/AcceptEnv[last()]','10000','FOO') print - - + + print 'Change the (canonical) hostname associated to a specific IP in hosts file.' hostfile='/etc/hosts' ip='1.2.3.4' @@ -243,9 +243,9 @@ def basictest(): #newCanonical='piggy' # We search which entry in /etc/hosts refers to the IP ipmatch = c.confmgt_augeas.match(hostfile,'ipaddr',ip) - # for each minion concerned + # for each minion concerned for host,entry in ipmatch.iteritems(): - # The first and unique entry in the list, entry[0], is what we searched for + # The first and unique entry in the list, entry[0], is what we searched for # We check that the target canonical hostname is not already set if (type(entry) == type([]) and entry): oldCanonical=c.confmgt_augeas.get(entry[0],'canonical')[host]['value'] @@ -264,8 +264,8 @@ def extendedtest(): print 'Tests on extended paths' # not working: print c.confmgt_augeas.match('//error/descendant-or-self::*','/augeas') - print - + print + print c.confmgt_augeas.get('/etc/hosts/*[ipaddr = "127.0.0.1"]/canonical') print c.confmgt_augeas.get('/etc/hosts/*[ipaddr = "127.0.0.1"]/','canonical') print @@ -281,7 +281,7 @@ def extendedtest(): #print print c.confmgt_augeas.match('/etc/pam.d/*[.//module="pam_limits.so"]') - print + print # not working (wrong): print c.confmgt_augeas.match('/etc//1') diff --git a/test/test_func_db.py b/test/test_func_db.py index 0e35730..d7191e0 100644 --- a/test/test_func_db.py +++ b/test/test_func_db.py @@ -3,7 +3,7 @@ from func.utils import remove_weird_chars,get_formated_jobid from func import jobthing import pprint import time - + def generate_word(type_word,how_many): """ generating some test fuzzy words @@ -15,10 +15,10 @@ def generate_word(type_word,how_many): #what you can choose ALLOWED_CHARS = ('*','-','_',';','@','.') - #may add more later + #may add more later ALLOWED_GLOB_WORDS = ("w-e-i-r-d","foo.com","zoom","@group1","g.r.o.u.p.2","some-hey-com","some_hack.org","1212-32323_blippy-zorg","interesting*;o*n*e") ALLOWED_MODULE_METHOD_W = ("some_service","s-o-m-e","s_u_m_m_er","FOOO","FoFo","real_stupid-w-e-i-r-d-naME") - + final_word = "" pickup = [] @@ -34,7 +34,7 @@ def generate_word(type_word,how_many): else: final_word = "".join([final_word,word]) - #return the final word back + #return the final word back return final_word @@ -114,13 +114,13 @@ class BaseFuncDB(object): def test_get_status(self): #__get_status(jobid) self.enter_some_data(self.new_jobids) - + for job in self.new_jobids: for job_id,job_pack in job.iteritems(): result = jobthing.__dict__['__get_status'](job_id) assert job_pack == result - + def enter_some_data(self,data): """ We need that one because every func here uses it at the initial stage @@ -136,11 +136,11 @@ class BaseFuncDB(object): def create_an_old_jobid(self): #will be overriden pass - + def create_new_jobid(self): #will be overriden pass - + class TestOverlordDB(BaseFuncDB): def __init__(self): @@ -181,16 +181,16 @@ class TestOverlordDB(BaseFuncDB): #the stres words :) gw=generate_word(choice,4) pack[choice] = gw - + return get_formated_jobid(**pack) - + def create_an_old_jobid(self,base_time): new_time = self.create_new_jobid().split("-") new_time[len(new_time)-1]=str(base_time) return "-".join(new_time) - + def test_old_new_upgrade(self): #that will do some control if some users has old_ids and @@ -203,7 +203,7 @@ class TestOverlordDB(BaseFuncDB): tmp_hash = {} tmp_hash[job_id] = (self.status_opt[randint(0,len(self.status_opt)-1)],{"some_old_type_new.com":self.test_result}) old_type_new.append(tmp_hash) - + #create 5 old type job ids with older time base_time = self.an_old_time for n in xrange(5): @@ -212,7 +212,7 @@ class TestOverlordDB(BaseFuncDB): tmp_hash[job_id] = (self.status_opt[randint(0,len(self.status_opt)-1)],{"some_old_type.com":self.test_result}) old_type_old.append(tmp_hash) base_time = base_time + 10 - + #print "The old type pack is : ",old_type_new #print "The old type pack is : ",old_type_old #enter also that ids into database @@ -223,7 +223,7 @@ class TestOverlordDB(BaseFuncDB): self.enter_some_data(self.new_jobids) self.enter_some_data(self.old_jobids) - + #db_results = jobthing.get_open_ids() #print "The current db results are : ",db_results @@ -236,7 +236,7 @@ class TestOverlordDB(BaseFuncDB): for job_id,job_pack in job.iteritems(): assert db_results.has_key(job_id) == True assert db_results[job_id] == job_pack[0] - + def access_update_stress(self): """ @@ -251,7 +251,7 @@ class TestOverlordDB(BaseFuncDB): print "Entering data test is over" def access_delete_stress(self): - + if not self.new_jobids or not self.old_jobids: self.create_lots_of_ids(how_many,self.new_jobids,"old") self.create_lots_of_ids(how_many,self.old_jobids,"new") @@ -260,7 +260,7 @@ class TestOverlordDB(BaseFuncDB): print "Old ids were removed succesfully " def create_lots_of_ids(self,how_many,to_object,type_id): - #generates lots of weird named + #generates lots of weird named import time base_time = self.an_old_time for new_id in xrange(how_many): @@ -282,7 +282,7 @@ class TestOverlordDB(BaseFuncDB): class TestMinionDB(BaseFuncDB): - + def __init__(self): super(TestMinionDB,self).__init__() self.status_opt = [jobthing.JOB_ID_RUNNING,jobthing.JOB_ID_FINISHED,jobthing.JOB_ID_PARTIAL,jobthing.JOB_ID_LOST_IN_SPACE,jobthing.JOB_ID_REMOTE_ERROR] diff --git a/test/unittest/cover_to_html.py b/test/unittest/cover_to_html.py index 2d69242..ce5a00e 100755 --- a/test/unittest/cover_to_html.py +++ b/test/unittest/cover_to_html.py @@ -2,22 +2,22 @@ #Copyright (c) 2005 Drew Smathers -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -# of the Software, and to permit persons to whom the Software is furnished to do +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do # so, subject to the following conditions: -# The above copyright notice and this permission notice shall be included in all +# The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. @@ -97,7 +97,7 @@ def _annotationToXML(annotation): aline.attrib['covered'] = str(line.covered).lower() aline.text = line.text return ET.ElementTree(root) - + def annotationToHTML(annotation, xml=None, xslt=None, tree=False): """Transform annotation object to HTML string or ElementTree instance @@ -200,31 +200,31 @@ def _reportToXML(report): relm.attrib['start'] = start relm.attrib['end'] = end return ET.ElementTree(root) - -def gen_html(path_to_cover, path_for_html): - cover_files = glob.glob("%s/*,cover" % path_to_cover) - # write out the css file - f = open("coverage.css", "w") - f.write(_CSS) +def gen_html(path_to_cover, path_for_html): + cover_files = glob.glob("%s/*,cover" % path_to_cover) + + # write out the css file + f = open("coverage.css", "w") + f.write(_CSS) + f.close() + + for cf in cover_files: + fd = open(cf, "r") + ann = AnnotationParser().parse(fd) + html = annotationToHTML(ann, xslt=_XSLT) + base_name = os.path.basename(cf) + source_name = base_name.split(',')[0] + html_name = "%s/%s.html" % (path_for_html, source_name) + f = open(html_name, "w") + f.write(html) f.close() - for cf in cover_files: - fd = open(cf, "r") - ann = AnnotationParser().parse(fd) - html = annotationToHTML(ann, xslt=_XSLT) - base_name = os.path.basename(cf) - source_name = base_name.split(',')[0] - html_name = "%s/%s.html" % (path_for_html, source_name) - f = open(html_name, "w") - f.write(html) - f.close() - # fd = open("%s/cover.report" % path_to_cover) # crp = CoverageReportParser().parse(fd) - - + + _CSS = """ body { margin: 0px; @@ -302,7 +302,7 @@ pre { float: bottom; width: 100%; margin-top: 20px; - font-size: 75%; + font-size: 75%; text-align: center; } @@ -350,6 +350,4 @@ _XSLT = '''<?xml version="1.0"?> if __name__ == "__main__": - gen_html(sys.argv[1], sys.argv[2]) - - + gen_html(sys.argv[1], sys.argv[2]) diff --git a/test/unittest/plugins/funccover.py b/test/unittest/plugins/funccover.py index a45d9e1..9af26ce 100644 --- a/test/unittest/plugins/funccover.py +++ b/test/unittest/plugins/funccover.py @@ -31,7 +31,7 @@ class FuncCoverage(Plugin): """ coverTests = False coverPackages = None - + def options(self, parser, env=os.environ): Plugin.options(self, parser, env) parser.add_option("--func-cover-package", action="append", @@ -66,7 +66,7 @@ class FuncCoverage(Plugin): "discovering holes in test coverage if not all " "files are imported by the test suite. " "[FUNC_NOSE_COVER_INCLUSIVE]") - + def configure(self, options, config): Plugin.configure(self, options, config) @@ -91,7 +91,7 @@ class FuncCoverage(Plugin): if self.coverPackages: log.info("Coverage report will include only packages: %s", self.coverPackages) - + def begin(self): log.debug("Coverage begin") import coverage @@ -101,7 +101,7 @@ class FuncCoverage(Plugin): coverage.erase() coverage.exclude('#pragma[: ]+[nN][oO] [cC][oO][vV][eE][rR]') coverage.start() - + def report(self, stream): log.debug("Coverage report") import coverage @@ -130,7 +130,7 @@ class FuncCoverage(Plugin): and (self.coverTests or not self.conf.testMatch.search(name))): log.debug("coverage for %s", name) - return True + return True if name in self.skipModules: log.debug("no coverage for %s: loaded before coverage start", name) @@ -143,12 +143,12 @@ class FuncCoverage(Plugin): # module, we would have already returned True return not self.coverPackages - def wantFile(self, file, package=None): - """If inclusive coverage enabled, return true for all source files + def wantFile(self, file, package=None): + """If inclusive coverage enabled, return true for all source files in wanted packages. """ if self.coverInclusive: - if file.endswith(".py"): + if file.endswith(".py"): if package and self.coverPackages: for want in self.coverPackages: if package.startswith(want): @@ -156,4 +156,3 @@ class FuncCoverage(Plugin): else: return True return None - diff --git a/test/unittest/test_client.py b/test/unittest/test_client.py index a603080..8ad1e5b 100644 --- a/test/unittest/test_client.py +++ b/test/unittest/test_client.py @@ -40,7 +40,7 @@ class BaseTest: def test_module_api_version(self): mod = getattr(self.overlord, self.module) - result = mod.module_api_version() + result = mod.module_api_version() self.assert_on_fault(result) def test_module_description(self): @@ -121,7 +121,7 @@ class TestTest(BaseTest): result = self.overlord.test.echo(data) self.assert_on_fault(result) assert result[self.th] == data - + # this tests are basically just to test the basic # marshalling/demarshaling bits def test_echo_int(self): @@ -188,11 +188,11 @@ class TestTest(BaseTest): self.assert_on_fault(result) def test_config_get_string(self): - result = self.overlord.test.config_get("string_option") + result = self.overlord.test.config_get("string_option") option = result[self.th] print option assert(type(option) == type("foo")) - self.assert_on_fault(result) + self.assert_on_fault(result) def test_config_get_int(self): result = self.overlord.test.config_get("int_option") @@ -213,8 +213,8 @@ class TestTest(BaseTest): self.assert_on_fault(result) def test_config_get_test(self): - result = self.overlord.test.config_get_test() - self.assert_on_fault(result) + result = self.overlord.test.config_get_test() + self.assert_on_fault(result) @@ -236,10 +236,10 @@ class TestCommand(BaseTest): def test_env(self): - result = self.overlord.command.run("env", - {'BLIPPYFOO':'awesome'}) - self.assert_on_fault(result) - assert result[self.th][1].find("BLIPPYFOO=awesome") != -1 + result = self.overlord.command.run("env", + {'BLIPPYFOO':'awesome'}) + self.assert_on_fault(result) + assert result[self.th][1].find("BLIPPYFOO=awesome") != -1 # def test_sleep_long(self): # result = self.overlord.command.run("sleep 256") @@ -273,7 +273,7 @@ class TestCopyfile(BaseTest): content = "this is a func test file" module = "copyfile" def create_a_file(self, size=1): - + f = open(self.fn, "w") f.write(self.content*size) f.close() @@ -291,12 +291,12 @@ class TestCopyfile(BaseTest): result = self.overlord.copyfile.copyfile(self.dest_fn, data) self.assert_on_fault(result) assert result[self.th] == 0 - + # def test_copyfile_big(self): # # make a file in the ~70 meg range # self.test_copyfile(size=100) - - + + def test_checksum(self): self.create_a_file() fb = open(self.fn,"r").read() @@ -307,7 +307,7 @@ class TestCopyfile(BaseTest): assert result[self.th] == "b36a8040e44c16605d7784cdf1b3d9ed04ea7f55" - + class TestHardware(BaseTest): module = "hardware" @@ -405,10 +405,10 @@ class TestNetworkTest(BaseTest): self.assert_on_fault(result) def test_ping_bad_arg(self): - result = self.overlord.networktest.ping(self.th) - # this should give us a FuncException - foo = func.utils.is_error(result[self.th]) - + result = self.overlord.networktest.ping(self.th) + # this should give us a FuncException + foo = func.utils.is_error(result[self.th]) + def test_netstat(self): result = self.overlord.networktest.netstat("-n") self.assert_on_fault(result) @@ -450,7 +450,7 @@ class TestService(BaseTest): def test_inventory(self): result = self.overlord.service.inventory() self.assert_on_fault(result) - + def test_get_enabled(self): result = self.overlord.service.get_enabled() self.assert_on_fault(result) @@ -516,7 +516,7 @@ class TestSmart(BaseTest): result = self.overlord.smart.info() self.assert_on_fault(result) - + class TestSysctl(BaseTest): module = "sysctl" @@ -585,22 +585,22 @@ class TestIptablesPort(BaseTest): # result = self.overlord.httpd.graceful() # self.assert_on_fault(result) - + class TestEchoTest(BaseTest): module = "echo" def test_run_string(self): result=self.overlord.echo.run_string("heyman") self.assert_on_fault(result) - + def test_run_int(self): result=self.overlord.echo.run_int(12) self.assert_on_fault(result) - + def test_run_float(self): result=self.overlord.echo.run_float(12.0) self.assert_on_fault(result) - + def test_run_options(self): result=self.overlord.echo.run_options("hehehh") self.assert_on_fault(result) @@ -642,7 +642,7 @@ class TestFactsModule(BaseTest): result = self.overlord.fact.show_fact_module(module) print result self.assert_on_fault(result) - + def test_show_fact_method(self): methods = self.overlord.fact.list_fact_methods().values() print "Methods to run for show fact method are ",methods @@ -666,11 +666,11 @@ class TestSystem(BaseTest): result = self.overlord.system.list_methods() self.assert_on_fault(result) - + def test_listMethods(self): result = self.overlord.system.listMethods() self.assert_on_fault(result) - + def test_list_modules(self): result = self.overlord.system.list_modules() self.assert_on_fault(result) diff --git a/test/unittest/test_config.py b/test/unittest/test_config.py index f7e8db8..b9dddad 100644 --- a/test/unittest/test_config.py +++ b/test/unittest/test_config.py @@ -17,29 +17,29 @@ from test_client import BaseTest config_file_1 = """ [main] option = this is an option from the file -#option_empty = +#option_empty = int_option = 2222 -#int_option_empty = +#int_option_empty = bool_option_true = True bool_option_false = False bool_option = False -#bool_option_empty = +#bool_option_empty = list_option = seven,eight,nine -#list_option_empty = +#list_option_empty = url_list_option = http://www.redhat.com, http://www.fedoraproject.org -#url_list_option_empty = +#url_list_option_empty = float_option = 2.7182 -#float_option_empty = +#float_option_empty = float_option_int = 5 bytes_option = 2001M -#bytes_option_empty = +#bytes_option_empty = """ @@ -98,11 +98,11 @@ class ConfigTest(config.BaseConfig): float_option = config.FloatOption(3.14159) float_option_empty = config.FloatOption() float_option_int = config.FloatOption(1.0) - + #selection_option bytes_option = config.BytesOption("123M") # bytes_option_empty = config.BytesOption() - + # FIXME: we need a test fixture for testing the config file parsing # since it's currently kind of all of nothing if an error occurs, so @@ -117,8 +117,8 @@ class TestConfig: def setUp(self): f = open(self.config_file, "w+") - if not os.access("/tmp/func-test", os.R_OK): - os.mkdir("/tmp/func-test") + if not os.access("/tmp/func-test", os.R_OK): + os.mkdir("/tmp/func-test") f.write(config_file_1) f.close() @@ -134,12 +134,12 @@ class TestConfig: print self.cfg.iteritems() for i in self.cfg.iteritems(): print i - - + + def test_config_option(self): assert type(self.cfg.option) == type('') assert self.exp.option == self.cfg.option - + def test_config_int_option(self): assert type(self.cfg.int_option) == type(4) assert self.exp.int_option == self.cfg.int_option @@ -180,7 +180,7 @@ class TestConfig: def test_config_float_option_int(self): print "blip" print self.cfg.float_option_int - + # FIXME: not sure why this is different, but we don't use this option type anyway # def test_config_bytes_option(self): @@ -204,7 +204,7 @@ class TestConfigSet(TestConfig): def setUp(self): TestConfig.setUp(self) - + self.cfg.option = self.exp.option self.cfg.bool_option = self.exp.bool_option self.cfg.int_option = self.exp.int_option @@ -217,19 +217,19 @@ class TestConfigSet(TestConfig): class TestConfigWrite(TestConfigSet): module = "config" exp = ConfigFileWriteValues() - + def setUp(self): TestConfigSet.setUp(self) filename = "/tmp/func-test/test2.conf" f = open(filename, "a+") - + self.cfg.write(f, "main") f.close() self.cfg = config.read_config(filename, ConfigTest) - + # test cases diff --git a/test/unittest/test_facts_minion.py b/test/unittest/test_facts_minion.py index a5c61e6..fbb5a94 100644 --- a/test/unittest/test_facts_minion.py +++ b/test/unittest/test_facts_minion.py @@ -1,7 +1,7 @@ from func.minion.facts.minion_query import * from func.minion.facts.overlord_query import OverlordQuery from func.minion.facts.query_utils import Q -from func.minion.facts.query import FuncLogicQuery +from func.minion.facts.query import FuncLogicQuery import func.overlord.client as fc from copy import copy import socket @@ -14,7 +14,7 @@ def test_load_fact_methods(): def generate_queries(how_many): """ - Generate some queries + Generate some queries """ import random @@ -23,7 +23,7 @@ def generate_queries(how_many): negated = [True,False] logic = ["OR","AND"] for now in xrange(0,how_many): - #pull 3 chars + #pull 3 chars ch_dict = {} first = char_list[random.randint(0,len(char_list)-1)] second = char_list[random.randint(0,len(char_list)-1)] @@ -38,7 +38,7 @@ def generate_queries(how_many): tmp_q.connector = logic[random.randint(0,1)] if negated[random.randint(0,1)]: tmp_q = ~tmp_q - + final_list.append(tmp_q) real_final = [final_list[0]] @@ -47,9 +47,9 @@ def generate_queries(how_many): tmp_q = q|real_final[len(real_final)-1] else: tmp_q = q&real_final[len(real_final)-1] - + real_final.append(tmp_q) - + return real_final @@ -60,7 +60,7 @@ class TestFactsMinion(object): """ # assume we are talking to localhost #th = "localhost.localdomain" - th = socket.getfqdn() + th = socket.getfqdn() #th = socket.getfqdn() nforks=1 async=False @@ -70,10 +70,10 @@ class TestFactsMinion(object): self.overlord = fc.Overlord(self.th, nforks=self.nforks, async=self.async) - + #load em self.fact_methods = load_fact_methods() - + def test_deserialize(self): """ Test deserialization @@ -86,20 +86,20 @@ class TestFactsMinion(object): self.tmp_proxy = OverlordQuery(fact_query=FuncLogicQuery(query)) serialized = self.tmp_proxy.serialize_query() cp_serialized = copy(serialized) - + min_q = FactsMinion() de_q = min_q.deserialize(serialized) #print "From REAL_Q object",self.query self.tmp_proxy = OverlordQuery(fact_query=FuncLogicQuery(de_q)) serialized_again = self.tmp_proxy.serialize_query() - + #print "BEFORE : ",cp_serialized #print "AFTER :",serialized_again if cp_serialized != serialized_again: print "We hve broken the stuff" print "BEFORE : ",cp_serialized print "AFTER :",serialized_again - + assert cp_serialized == serialized_again if counter%10 == 0: print "%d of %d completed "%(counter,HOW_MANY) @@ -110,17 +110,17 @@ class TestFactsMinion(object): query = Q(**q_d) self.tmp_proxy = OverlordQuery(fact_query=FuncLogicQuery(query)) serialized = self.tmp_proxy.serialize_query() - + min_q = FactsMinion(method_fact_list=self.fact_methods) final_query = min_q.exec_query(serialized) final_query_with_values = min_q.exec_query(serialized,True) #print "The result without values ",final_query #print "The result with values ",final_query_with_values - + #def test_longer_des(self): # """ - # Uncomment that method for longer tests + # Uncomment that method for longer tests # probably u wont need that sterss tessts # """ @@ -151,67 +151,67 @@ class TestQueryKeyword(object): def test_keyword_contains(self): """ - Test if it contains + Test if it contains """ fact_value = "os f9 2.16" overlord_tuple = ("os__contains","f9") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__contains","nonexisting") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - + def test_keyword_icontains(self): """ - Test if it contains + Test if it contains """ fact_value = "os f9 2.16" overlord_tuple = ("os__icontains","F9") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__icontains","nonexisting") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False def test_keyword_iexact(self): """ - Test if it contains + Test if it contains """ fact_value = "fedora9" overlord_tuple = ("os__iexact","FeDorA9") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__iexact","nonexisting") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False def test_keyword_startswith(self): """ - Test if it contains + Test if it contains """ fact_value = "fedora10" overlord_tuple = ("os__startswith","fed") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__startswith","nonexisting") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - + def test_keyword_gt(self): """ - Test if it contains + Test if it contains """ fact_value = "fedora10" overlord_tuple = ("os__gt","fedora101") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - + overlord_tuple = ("os__gt","fedora") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True @@ -221,11 +221,11 @@ class TestQueryKeyword(object): overlord_tuple = ("os__gt",101) self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - + overlord_tuple = ("os__gt","101") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - + overlord_tuple = ("os__gt","100") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False @@ -233,17 +233,17 @@ class TestQueryKeyword(object): overlord_tuple = ("os__gt",100) self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - - + + def test_keyword_gte(self): """ - Test if it contains + Test if it contains """ fact_value = "fedora10" overlord_tuple = ("os__gte","fedora10") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + #overlord_tuple = ("os__gte","fedora") #self.__prepare_overlord_word(overlord_tuple) #assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True @@ -253,24 +253,24 @@ class TestQueryKeyword(object): overlord_tuple = ("os__gte",100) self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__gte","101") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - + overlord_tuple = ("os__gte","100") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True def test_keyword_lte(self): """ - Test if it contains + Test if it contains """ fact_value = "fedora10" overlord_tuple = ("os__lte","fedora10") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__lte","fedora") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False @@ -280,24 +280,24 @@ class TestQueryKeyword(object): overlord_tuple = ("os__lte",100) self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__lte","101") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__lte","100") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True def test_keyword_lt(self): """ - Test if it contains + Test if it contains """ fact_value = "fedora10" overlord_tuple = ("os__lt","fedora10") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - + overlord_tuple = ("os__lt","fedora") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False @@ -307,24 +307,24 @@ class TestQueryKeyword(object): overlord_tuple = ("os__lt",100) self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - + overlord_tuple = ("os__lt","101") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os__lt","33") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False def test_keyword(self): """ - Test if it contains + Test if it contains """ fact_value = "fedora10" overlord_tuple = ("os","fedora10") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os","fedora") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False @@ -334,9 +334,7 @@ class TestQueryKeyword(object): overlord_tuple = ("os",100) self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == True - + overlord_tuple = ("os","101") self.__prepare_overlord_word(overlord_tuple) assert self.fact_keyword.resolve(self.keyword,self.overlord_value,fact_value) == False - - diff --git a/test/unittest/test_facts_overlord.py b/test/unittest/test_facts_overlord.py index ac89b4f..7dd0549 100644 --- a/test/unittest/test_facts_overlord.py +++ b/test/unittest/test_facts_overlord.py @@ -1,31 +1,31 @@ from func.minion.facts.overlord_query import OverlordQuery from func.minion.facts.query_utils import Q -from func.minion.facts.query import FuncLogicQuery +from func.minion.facts.query import FuncLogicQuery import func.overlord.client as fc import socket class TestOverlordQueryProxy(object): - + # assume we are talking to localhost #th = "localhost.localdomain" th = socket.getfqdn() nforks=1 async=False - + def __init__(self): self.query = FuncLogicQuery( Q(a=True,b=True)| Q(c=True,b=False) ) - - + + self.negated_q = FuncLogicQuery( (~Q(a=True,b=True)| Q(c=True,b=False))& Q(e=True,f=False) ) - + self.negated_q2 = FuncLogicQuery( ~Q(a=True,b=True)| Q(c=True,b=False) ) @@ -48,21 +48,21 @@ class TestOverlordQueryProxy(object): """ self.tmp_proxy = OverlordQuery(fact_query=self.query) self.tmp_proxy.serialize_query() - + self.tmp_proxy = OverlordQuery(fact_query=self.negated_q) self.tmp_proxy.serialize_query() - + self.tmp_proxy = OverlordQuery(fact_query=self.negated_q2) self.tmp_proxy.serialize_query() - + def test_chain_send(self): - query = Q(runlevel__lt=6,runlevel__gt=2) + query = Q(runlevel__lt=6,runlevel__gt=2) print self.overlord.set_complexq(query).hardware.info() def test_async_chain_send(self): - query = Q(runlevel__lt=6,runlevel__gt=2) + query = Q(runlevel__lt=6,runlevel__gt=2) res = self.async_overlord.set_complexq(query).hardware.info() print res import time @@ -79,7 +79,7 @@ class TestFactModule(object): only_int_keywords = ["","gt","gte","lt","lte"] rest_keywords = ['contains','icontains','iexact','startswith'] - + def __init__(self): self.overlord = fc.Overlord(self.th, nforks=self.nforks, @@ -95,7 +95,7 @@ class TestFactModule(object): self.overlord_query = fc.Overlord(self.th, nforks=self.nforks, async=self.async) - + def test_fact_module(self): @@ -132,7 +132,7 @@ class TestFactModule(object): #active_res = self.overlord_query.display_active(result,with_facts=True) #assert active_res[self.th][0]['__fact__'][0] == True - + def __make_it_less_or_greater(self,value,type_cmp): if type_cmp == "lt": if type(value) == int: @@ -144,8 +144,8 @@ class TestFactModule(object): return value-1 elif type(value)==str: return value[:len(value)-1] - + def assert_on_fault(self, result): - + import func.utils assert func.utils.is_error(result[self.th]) == False diff --git a/test/unittest/test_facts_tree.py b/test/unittest/test_facts_tree.py index df5df0e..3ea9002 100644 --- a/test/unittest/test_facts_tree.py +++ b/test/unittest/test_facts_tree.py @@ -1,8 +1,8 @@ -from func.minion.facts.query import FuncLogicQuery +from func.minion.facts.query import FuncLogicQuery from func.minion.facts.query_utils import Q class TestFactsTree(object): - + def setUp(self): self.q1 = FuncLogicQuery(Q(a=True,b=True)) self.q2 = FuncLogicQuery(Q(a=False,b=True)) @@ -22,29 +22,29 @@ class TestFactsTree(object): print self.q3 print self.q4 print self.q_negated - + def test_traverse_logic_tree(self): - + assert self.q1.result == True assert self.q2.result == False assert self.q3.result == False assert self.q4.result == False assert self.q_negated.result == True - + q1_q2_or = self.q3 | self.q1 q1_q2_and = self.q1 & self.q2 - + assert q1_q2_or.result == True assert q1_q2_and.result == False - + tmp = q1_q2_or | q1_q2_and tmp2 = q1_q2_or & q1_q2_and assert tmp.result == True assert tmp2.result == False - + #lets do sth more more complex :) very_tmp = tmp & tmp very_tmp2 = tmp2 | tmp2 & tmp @@ -55,7 +55,7 @@ class TestFactsTree(object): """ Do some testing on filtering the stuff """ - + tmp_q = self.q1.filter(c=False,e=True) assert tmp_q.result == False @@ -74,19 +74,19 @@ class TestFactsTree(object): tmp_q=self.q4.filter(c=False,e=True) assert tmp_q.result == False - + def test_exclude(self): """ Test the negated situations """ tmp_q = self.q1.exclude(c=False,e=True) assert tmp_q.result == True - + def test_complex(self): """ The complex thing """ - + #what it does is creates a Q on the #fly and ORs it with set_compexq @@ -96,12 +96,10 @@ class TestFactsTree(object): "OR" ) assert tmp_q.result == True - + tmp_q=self.q1.set_compexq( (Q(a=True,b=False)| Q(c=False,d=False)), "AND" ) assert tmp_q.result == False - - diff --git a/test/unittest/test_func_arg.py b/test/unittest/test_func_arg.py index f22861a..6de7c2e 100644 --- a/test/unittest/test_func_arg.py +++ b/test/unittest/test_func_arg.py @@ -14,9 +14,9 @@ from func.minion.func_arg import ArgCompatibility class TestArgCompatibility: - + def setUp(self): - #create the simple object + #create the simple object self.ac = ArgCompatibility(self.dummy_arg_getter()) def test_arg_compatibility(self): @@ -25,15 +25,15 @@ class TestArgCompatibility: """ result = self.ac.validate_all() assert result == True - + self.ac = ArgCompatibility(self.dummy_no_getter()) result = self.ac.validate_all() assert result == True - + self.ac = ArgCompatibility(self.dummy_empty_args()) result = self.ac.validate_all() assert result == True - + def test_is_all_arguments_registered(self): #create the dummy class tc = FooClass() @@ -41,7 +41,7 @@ class TestArgCompatibility: assert self.ac.is_all_arguments_registered(tc,'foomethod',arguments['foomethod']['args'])==True print arguments assert self.ac.validate_all()==True - + def dummy_no_getter(self): return {} @@ -55,13 +55,13 @@ class TestArgCompatibility: def dummy_arg_getter(self): """ - A simple method to test the stuff we have written for + A simple method to test the stuff we have written for arg compatiblity. I just return a dict with proper stuff Should more an more tests here to see if didnt miss something """ return { 'hifunc':{ - + 'args':{ 'app':{ 'type':'int', @@ -69,14 +69,14 @@ class TestArgCompatibility: 'optional':False, 'default' : 12 }, - + 'platform':{ 'type':'string', 'options':["fedora","redhat","ubuntu"], 'description':"Hey im a fedora fan", 'default':'fedora8', }, - + 'platform2':{ 'type':'string', 'min_length':4, @@ -84,7 +84,7 @@ class TestArgCompatibility: 'description':"Hey im a fedora fan", 'default':'fedora8', }, - + 'is_independent':{ 'type':'boolean', @@ -92,7 +92,7 @@ class TestArgCompatibility: 'description':'Are you independent ?', 'optional':False }, - + 'some_string':{ 'type':'string', 'validator': "^[a-zA-Z]$", @@ -119,7 +119,7 @@ class TestArgCompatibility: 'description':"Dummy desc here", 'optional':True, #of course it is, 'validator':"^[a-z]*$",#only for values not keys - + } }, 'description':"The dummy method description", @@ -148,4 +148,3 @@ class FooClass(object): } } } - diff --git a/test/unittest/test_func_transmit.py b/test/unittest/test_func_transmit.py index ada3160..03d7a7f 100644 --- a/test/unittest/test_func_transmit.py +++ b/test/unittest/test_func_transmit.py @@ -37,7 +37,7 @@ def structToYaml(data): def structToJSON(data): #Take data structure for the test #and serializes it using json - + serialized = simplejson.dumps(input) return serialized @@ -94,7 +94,7 @@ class BaseTest(object): if self.async: return self._call_async(data) return self._call(data) - + def __init__(self): pass @@ -128,12 +128,12 @@ class JSONBaseTest(BaseTest): return data class ListMinion(object): - + def test_list_minions(self): out = self.call({'clients': '*', 'module':'local', 'method':'utils.list_minions'}) - + def test_list_minions_no_match(self): out = self.call({'clients': 'somerandom-name-that-shouldnt-be-a_real_host_name', 'module':'local', @@ -149,8 +149,8 @@ class ListMinion(object): # def test_list_minions_no_clients(self): # out = self.call({'module':'local', # 'method': 'utils.list_minions'}) - - + + class ListMinionAsync(ListMinion): async = True @@ -180,7 +180,7 @@ class TestListMinionJSON(JSONBaseTest, ListMinion): # super(TestListMinionJSONAsync, self).__init__() - + class ClientGlob(object): def _test_add(self, client): result = self.call({'clients': client, @@ -189,7 +189,7 @@ class ClientGlob(object): 'parameters': [1,2]}) self.assert_on_fault(result) return result - + def test_single_client(self): result = self._test_add(self.th) @@ -204,7 +204,7 @@ class ClientGlob(object): # note, needs a /etc/func/group setup with the proper groups defined # need to figure out a good way to test this... -akl -# FIXME: +# FIXME: # def test_group(self): # result = self._test_add("@test") @@ -218,7 +218,7 @@ class ClientGlob(object): # result = self._test_add("@test;@test2") -# run all the same tests, but run then +# run all the same tests, but run then class ClientGlobAsync(ClientGlob): async = True @@ -252,7 +252,7 @@ class TestClientGlobJSONAsync(JSONBaseTest, ClientGlobAsync): # invoked as test classes themselves, only as bases for other tests class T_estTest(object): # __test__ = False - + def _echo_test(self, data): result = self.call({'clients':'*', 'method': 'echo', @@ -262,7 +262,7 @@ class T_estTest(object): self.assert_on_fault(result) assert result[self.th] == data - + def test_add(self): result = self.call({'clients':'*', 'method': 'add', @@ -281,7 +281,7 @@ class T_estTest(object): self._echo_test(37) def test_echo_array(self): - self._echo_test([1,2,"three", "fore", "V"]) + self._echo_test([1,2,"three", "fore", "V"]) def test_echo_hash(self): self._echo_test({'one':1, 'two':2, 'three': 3, 'four':"IV"}) @@ -290,7 +290,7 @@ class T_estTest(object): self._echo_test(1.0) - # NOTE/FIXME: the big float tests fail for yaml and json + # NOTE/FIXME: the big float tests fail for yaml and json # def test_echo_big_float(self): # self._echo_test(123121232.23) @@ -315,13 +315,13 @@ class T_estTestAsync(T_estTest): class T_estTestCommandRun(T_estTest): async = False def test_command_run(self): - result = self.call({'clients':'*', + result = self.call({'clients':'*', # 'async': False, # 'nforks': 1, 'method': 'run', 'module': 'command', 'parameters': 'ifconfig'}) - + class TestTestYamlCommandRun(YamlBaseTest, T_estTestCommandRun): yaml = True @@ -344,7 +344,7 @@ class TestTestAsyncJSON(JSONBaseTest, T_estTestAsync): async = True def __init__(self): super(JSONBaseTest,self).__init__() - + class TestTestAsyncYaml(YamlBaseTest, T_estTestAsync): yaml = True async = True @@ -356,5 +356,3 @@ class TestTestAsyncYaml(YamlBaseTest, T_estTestAsync): class TestTestYamlNforksOne(TestTestYaml): nforks = 1 async = False - - diff --git a/test/unittest/test_groups_api.py b/test/unittest/test_groups_api.py index a798e5f..6608d0e 100644 --- a/test/unittest/test_groups_api.py +++ b/test/unittest/test_groups_api.py @@ -6,14 +6,14 @@ import fnmatch from func.overlord.group.conf_backend import ConfBackend from func.overlord.group.sqlite_backend import SqliteBackend - + TEST_DB_FILE = "/tmp/test_sqlite.db" TEST_CONF_FILE = "/tmp/test_conf.conf" class BaseMinions(object): - + def create_dummy_minions(self,howmany=None): """ Creates a lots of minions so we can query @@ -22,7 +22,7 @@ class BaseMinions(object): cm_config = read_config(CONFIG_FILE, CMConfig) howmany = howmany or 100 #it is a good default number - + final_list = [] for m in xrange(howmany): tmp_f = open("%s/%s.%s" % (cm_config.certroot,str(m),cm_config.cert_extension),"w") @@ -48,19 +48,19 @@ class BaseMinions(object): class BaseGroupT(object): - + backends = [ {'backend':'sqlite','db_file':TEST_DB_FILE}, {'backend':'conf','conf_file':TEST_CONF_FILE} ] - + def refresh_backend(self,g_object): """ Here you should add your object in if statements """ from func.overlord.group.conf_backend import ConfBackend from func.overlord.group.sqlite_backend import SqliteBackend - + if isinstance(g_object.backend,ConfBackend): return Groups(**self.backends[1]) elif isinstance(g_object.backend,SqliteBackend): @@ -72,13 +72,13 @@ class BaseGroupT(object): """ Initializer """ - + gr_list = [] for b in self.backends: gr_list.append(Groups(**b)) return gr_list - + def clean_t_files(self,path): """ Clean the initialized stuff @@ -96,13 +96,13 @@ class TestGroupApi(BaseGroupT,BaseMinions): #clean current files self.clean_t_files(TEST_DB_FILE) self.clean_t_files(TEST_CONF_FILE) - + #destroy and create minions self.clean_dummy_minions() self.current_minions = self.create_dummy_minions() #get groups self.groups = self.get_group_objects() - + def teardown(self): """ Clean the stuff @@ -110,7 +110,7 @@ class TestGroupApi(BaseGroupT,BaseMinions): self.clean_dummy_minions() self.clean_t_files(TEST_DB_FILE) self.clean_t_files(TEST_CONF_FILE) - + def test_add_group(self): """ adds a single group item @@ -120,8 +120,8 @@ class TestGroupApi(BaseGroupT,BaseMinions): g = self.refresh_backend(g) assert g.add_group("group1")[0] == False - - + + def test_add_host_to_group(self): """ adds a host test @@ -133,8 +133,8 @@ class TestGroupApi(BaseGroupT,BaseMinions): assert g.add_host_to_group(g_name,"host1")[0] == True g = self.refresh_backend(g) assert g.add_host_to_group(g_name,"host1")[0] == False - - + + def test_add_hostst_to_group(self): """ Test adding hosts via string @@ -146,7 +146,7 @@ class TestGroupApi(BaseGroupT,BaseMinions): g.add_hosts_to_group(g_name,"host1,host2,host3") g = self.refresh_backend(g) g.add_hosts_to_group(g_name,"host5;host7;host8") - + def test_add_host_list(self): """ Test adding hosts via list @@ -172,7 +172,7 @@ class TestGroupApi(BaseGroupT,BaseMinions): g.add_hosts_to_group_glob(g_name,"*") #add all of them g = self.refresh_backend(g) - self.groups = self.get_group_objects() + self.groups = self.get_group_objects() for g in self.groups: for h in self.current_minions: if self.current_minions.index(h) %10 == 0: @@ -180,14 +180,14 @@ class TestGroupApi(BaseGroupT,BaseMinions): assert g.add_host_to_group(g_name,h)[0] == False #print "Let see IT ",g.add_host_to_group(g_name,h)[0] g = self.refresh_backend(g) - + #clear again so we can test exclude thing self.teardown() self.setUp() - + #print "Testing exclude string ...." - self.groups = self.get_group_objects() + self.groups = self.get_group_objects() for g in self.groups: g.add_group(g_name) g = self.refresh_backend(g) @@ -203,7 +203,7 @@ class TestGroupApi(BaseGroupT,BaseMinions): assert g.add_host_to_group(g_name,h)[0] == True g = self.refresh_backend(g) - + def test_get_groups(self): """ test get groups @@ -216,27 +216,27 @@ class TestGroupApi(BaseGroupT,BaseMinions): #get all groups grs = g.get_groups() assert self._t_compare_arrays(grs,["group1","group2"]) == True - + #get one tmg = g.get_groups(pattern="group1") assert tmg==["group1"] - + tmg = g.get_groups(pattern="gr",exact=False) assert self._t_compare_arrays(tmg,["group1","group2"])==True - + tmg = g.get_groups(pattern="gr",exact=False,exclude=["group2"]) assert tmg == ["group1"] - + #test also an empty one tmg = g.get_groups(pattern="group3") assert tmg == [] - - + + def test_get_groups_glob(self): - """ - Globbing in groups - """ - for g in self.groups: + """ + Globbing in groups + """ + for g in self.groups: g.add_group("group1") g = self.refresh_backend(g) g.add_group("group2") @@ -244,18 +244,18 @@ class TestGroupApi(BaseGroupT,BaseMinions): #get all groups grs = g.get_groups_glob("*") assert self._t_compare_arrays(grs,["group1","group2"]) == True - + #get one tmg = g.get_groups_glob("*[1]") assert tmg == ["group1"] - + tmg = g.get_groups_glob("*",exclude_string="*[2]") assert tmg == ["group1"] - + #test also an empty one tmg = g.get_groups_glob("*[3]") assert tmg == [] - + def test_get_hosts(self): """ Get hosts tests @@ -266,14 +266,14 @@ class TestGroupApi(BaseGroupT,BaseMinions): g = self.refresh_backend(g) g.add_host_list(g_name,["host1","host2","host3"]) g = self.refresh_backend(g) - + hosts = g.get_hosts(group=g_name) assert self._t_compare_arrays(hosts,["host1","host2","host3"]) == True #get only one host = g.get_hosts(pattern="host1",group=g_name) assert host == ["host1"] - + #get pattern host = g.get_hosts(pattern="ho",group=g_name,exact=False) assert self._t_compare_arrays(host,["host1","host2","host3"]) == True @@ -295,10 +295,10 @@ class TestGroupApi(BaseGroupT,BaseMinions): g = self.refresh_backend(g) g.add_hosts_to_group_glob(g_name,"*") #add all of them g = self.refresh_backend(g) - + hosts = g.get_hosts_glob("@group1") assert self._t_compare_arrays(hosts,self.current_minions) == True - + #try subgroupping thing on the fly hosts = g.get_hosts_glob("@group1:[0-9]") assert self._t_compare_arrays(hosts,list(range(10))) == True @@ -339,7 +339,7 @@ class TestGroupApi(BaseGroupT,BaseMinions): g = self.refresh_backend(g) grs = g.get_groups_glob("*") assert grs == [] - + def test_remove_group_glob(self): """ Remove groups by glob @@ -354,7 +354,7 @@ class TestGroupApi(BaseGroupT,BaseMinions): g = self.refresh_backend(g) grs = g.get_groups_glob("*") assert grs == [] - + def test_remove_host(self): """ remove host test @@ -365,10 +365,10 @@ class TestGroupApi(BaseGroupT,BaseMinions): g = self.refresh_backend(g) g.add_host_list(g_name,["host1","host2","host3"]) g = self.refresh_backend(g) - - assert g.remove_host(g_name,"host1")[0] == True + + assert g.remove_host(g_name,"host1")[0] == True g = self.refresh_backend(g) - assert g.remove_host(g_name,"host1")[0] == False + assert g.remove_host(g_name,"host1")[0] == False g = self.refresh_backend(g) hosts = g.get_hosts(group=g_name) assert self._t_compare_arrays(hosts,["host2","host3"]) @@ -377,7 +377,7 @@ class TestGroupApi(BaseGroupT,BaseMinions): hosts = g.get_hosts(group=g_name) assert self._t_compare_arrays(hosts,["host3"]) - + def test_remove_host_list(self): """ Remove the host list @@ -392,7 +392,7 @@ class TestGroupApi(BaseGroupT,BaseMinions): g = self.refresh_backend(g) hosts = g.get_hosts(group=g_name) assert hosts == ["host3"] - + def test_remove_host_glob(self): """ Remove hosts bu glob @@ -403,12 +403,12 @@ class TestGroupApi(BaseGroupT,BaseMinions): g = self.refresh_backend(g) g.add_hosts_to_group_glob(g_name,"*") #add all of them g = self.refresh_backend(g) - + g.remove_host_glob("group1","*") g = self.refresh_backend(g) hosts = g.get_hosts_glob("@group1") assert hosts==[] - + g.add_hosts_to_group_glob(g_name,"*") #add all of them g = self.refresh_backend(g) #try subgroupping thing on the fly @@ -444,19 +444,19 @@ class TestMinionGroups(BaseMinions): """ Test the minion methods that wraps the group classes """ - + backends = [ {'groups_backend':'sqlite','db_file':TEST_DB_FILE}, {'groups_backend':'conf','conf_file':TEST_CONF_FILE} ] - + def teardown(self): for path in [TEST_DB_FILE,TEST_CONF_FILE]: if os.path.exists(path): os.remove(path) - + self.clean_dummy_minions() - + def setUp(self): #destroy and create minions self.clean_dummy_minions() @@ -480,7 +480,7 @@ class TestMinionGroups(BaseMinions): minions = m.get_hosts_for_spec(spec) assert compare_arrays(minions,self.current_minions) == True - + def test_get_all_hosts(self): """ Getting all hosts @@ -491,10 +491,10 @@ class TestMinionGroups(BaseMinions): #create some groups and hosts into that Minion m.group_class.add_group("group1") m.group_class.add_hosts_to_group_glob("group1","[0-9]") - + hosts = m.get_all_hosts() assert compare_arrays(hosts,self.current_minions) == True - + #now test with grouping m = Minions("[1][0-9];@group1:*",**backend_dict) hosts = m.get_all_hosts() @@ -503,7 +503,7 @@ class TestMinionGroups(BaseMinions): m = Minions("[1][0-5];@group1:[5-9]",**backend_dict) hosts = m.get_all_hosts() assert compare_arrays(hosts,range(5,16)) == True - + #do some testing about exclude string m = Minions("*",exclude_spec="[1-9][0-9]",**backend_dict) hosts = m.get_all_hosts() diff --git a/test/unittest/test_minion.py b/test/unittest/test_minion.py index 895467e..b4a041e 100644 --- a/test/unittest/test_minion.py +++ b/test/unittest/test_minion.py @@ -4,7 +4,7 @@ NUMBER_OF_TEST_MINIONS = 10000 PICKLE_PLACE = "/tmp/minion.pkl" - + import pickle import fnmatch from func.overlord.client import Minions @@ -13,7 +13,7 @@ from certmaster.commonconfig import CMConfig import os class BaseMinions(object): - + def create_dummy_minions(self,howmany=NUMBER_OF_TEST_MINIONS): """ Creates a lots of minions so we can query @@ -22,7 +22,7 @@ class BaseMinions(object): cm_config = read_config(CONFIG_FILE, CMConfig) howmany = howmany or 100 #it is a good default number - + final_list = [] for m in xrange(howmany): tmp_f = open("%s/%s.%s" % (cm_config.certroot,str(m),cm_config.cert_extension),"w") @@ -59,16 +59,16 @@ class FromPickle(Minions): """ #these will be returned tmp_certs = set() - + all_minions = self.load_minions() hosts = fnmatch.filter(all_minions.keys(),each_gloob) - + for h in hosts: tmp_certs.add(all_minions[h]) - + print "ALL DONE" return set(hosts),tmp_certs - + def prepare_pickle(self): final_dict = {} for i in xrange(NUMBER_OF_TEST_MINIONS): @@ -96,15 +96,15 @@ class FromFile(Minions): """ #these will be returned tmp_certs = set() - + hosts = self.load_minions() hosts = fnmatch.filter(hosts,each_gloob) - + for h in hosts: tmp_certs.add("%s/%s.%s" % (self.cm_config.certroot,h, self.cm_config.cert_extension)) - + return set(hosts),tmp_certs - + def prepare_pickle(self): p_file = open(PICKLE_PLACE,"w") final_list = [] @@ -135,12 +135,12 @@ class FromDb(Minions): tmp_certs = set() all_minions = self.load_minions() hosts = fnmatch.filter(all_minions.keys(),each_gloob) - + for h in hosts: tmp_certs.add(all_minions[h]) - + return set(hosts),tmp_certs - + def prepare_pickle(self): p_file = open(PICKLE_PLACE,"w") @@ -149,7 +149,7 @@ class FromDb(Minions): for i in xrange(NUMBER_OF_TEST_MINIONS): storage[str(i)] = "%s/%s.%s" % (self.cm_config.certroot,str(i), self.cm_config.cert_extension) - + storage.close() def load_minions(self): @@ -166,7 +166,7 @@ def get_glob_list(): final_list.append("[5-9][0-9][0-9]") final_list.append("[1,3,5,8,9][0-9][0-9][0-9]") final_list.append("[2,4,6,8][0-9][0-9][0-9]") - + #tottal 10 000 + 5 :) return final_list @@ -177,19 +177,17 @@ if __name__ == "__main__": fi = FromDb("*") fi.prepare_pickle() for glob in get_glob_list(): - + f=FromDb(glob) print f.get_all_hosts() #f=FromFile(glob) #print f.get_all_hosts() - + b.clean_dummy_minions() - + #fi = FromPickle("*") #fi.prepare_pickle() #for glob in get_glob_list(): #f=FromPickle(glob) # print f.get_all_hosts() - - diff --git a/test/unittest/test_users.py b/test/unittest/test_users.py index da09faa..a4c2802 100644 --- a/test/unittest/test_users.py +++ b/test/unittest/test_users.py @@ -31,442 +31,442 @@ class TestUsers(BaseTest): testgroup2 = "func_users__testgroup2" def __unused_gid__(self): - potentialgid = self.r.randint(2,65535) - return potentialgid if self.overlord.users.gid_exists(potentialgid) else self.__unused_gid__() + potentialgid = self.r.randint(2,65535) + return potentialgid if self.overlord.users.gid_exists(potentialgid) else self.__unused_gid__() def __unused_uid__(self): - potentialuid = self.r.randint(2,65535) - return potentialuid if self.overlord.users.uid_exists(potentialuid) else self.__unused_uid__() + potentialuid = self.r.randint(2,65535) + return potentialuid if self.overlord.users.uid_exists(potentialuid) else self.__unused_uid__() def __make_test_user__(self): - return self.overlord.users.user_add(TestUsers.testuser1) + return self.overlord.users.user_add(TestUsers.testuser1) def __make_test_user2__(self): - return self.overlord.users.user_add(TestUsers.testuser2) + return self.overlord.users.user_add(TestUsers.testuser2) def __make_test_group__(self): - return self.overlord.users.group_add(TestUsers.testgroup1) + return self.overlord.users.group_add(TestUsers.testgroup1) def __make_test_group2__(self): - self.overlord.users.group_add(TestUsers.testgroup2) + self.overlord.users.group_add(TestUsers.testgroup2) def __cleanup__(self): - self.overlord.users.user_del(TestUsers.testuser1) if self.overlord.users.user_exists(TestUsers.testuser1) else True - self.overlord.users.user_del(TestUsers.testuser2) if self.overlord.users.user_exists(TestUsers.testuser2) else True - self.overlord.users.group_del(TestUsers.testgroup1) if self.overlord.users.group_exists(TestUsers.testgroup1) else True - self.overlord.users.group_del(TestUsers.testgroup2) if self.overlord.users.group_exists(TestUsers.testgroup2) else True + self.overlord.users.user_del(TestUsers.testuser1) if self.overlord.users.user_exists(TestUsers.testuser1) else True + self.overlord.users.user_del(TestUsers.testuser2) if self.overlord.users.user_exists(TestUsers.testuser2) else True + self.overlord.users.group_del(TestUsers.testgroup1) if self.overlord.users.group_exists(TestUsers.testgroup1) else True + self.overlord.users.group_del(TestUsers.testgroup2) if self.overlord.users.group_exists(TestUsers.testgroup2) else True def test_user_add(self): - try: - result = self.__make_test_user__() - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + result = self.__make_test_user__() + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_del(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_del(TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() - + try: + self.__make_test_user__() + result = self.overlord.users.user_del(TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() + def test_group_add(self): - try: - result = self.__make_test_group__() - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + result = self.__make_test_group__() + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_group_del(self): - try: - self.__make_test_group__() - result = self.overlord.users.group_del(TestUsers.testgroup1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_group__() + result = self.overlord.users.group_del(TestUsers.testgroup1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_groups_add(self): - try: - result = self.overlord.users.groups_add(TestUsers.testgroup1,TestUsers.testgroup2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + result = self.overlord.users.groups_add(TestUsers.testgroup1,TestUsers.testgroup2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_users_add(self): - try: - result = self.overlord.users.users_add(TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + result = self.overlord.users.users_add(TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_groups_del(self): - try: - self.__make_test_group__() - self.__make_test_group2__() - result = self.overlord.users.groups_del(TestUsers.testgroup1,TestUsers.testgroup2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_group__() + self.__make_test_group2__() + result = self.overlord.users.groups_del(TestUsers.testgroup1,TestUsers.testgroup2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_users_del(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - result = self.overlord.users.users_del(TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + result = self.overlord.users.users_del(TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_group_set_gid_non_unique(self): - try: - self.__make_test_group__() - result = self.overlord.users.group_set_gid_non_unique(TestUsers.testgroup1,self.__unused_gid__()) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_group__() + result = self.overlord.users.group_set_gid_non_unique(TestUsers.testgroup1,self.__unused_gid__()) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_group_set_gid(self): - try: - self.__make_test_group__() - result = self.overlord.users.group_set_gid(TestUsers.testgroup1,self.__unused_gid__()) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() - + try: + self.__make_test_group__() + result = self.overlord.users.group_set_gid(TestUsers.testgroup1,self.__unused_gid__()) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() + def test_group_set_groupname(self): - try: - self.__make_test_group__() - result = self.overlord.users.group_set_groupname(TestUsers.testgroup1,TestUsers.testgroup2) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() - + try: + self.__make_test_group__() + result = self.overlord.users.group_set_groupname(TestUsers.testgroup1,TestUsers.testgroup2) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() + def test_group_add_non_unique(self): - try: - result = self.overlord.users.group_add_non_unique(TestUsers.testgroup1,self.__unused_gid__()) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + result = self.overlord.users.group_add_non_unique(TestUsers.testgroup1,self.__unused_gid__()) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_lock(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_lock(TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_lock(TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_users_lock(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - result = self.overlord.users.users_lock(TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + result = self.overlord.users.users_lock(TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_user_set_shell(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_set_shell(TestUsers.testuser1,"/bin/false") - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_set_shell(TestUsers.testuser1,"/bin/false") + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_users_set_shell(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - result = self.overlord.users.users_set_shell("/bin/false",TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + result = self.overlord.users.users_set_shell("/bin/false",TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_user_set_home(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_set_home(TestUsers.testuser1,"/home/"+TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_set_home(TestUsers.testuser1,"/home/"+TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_set_loginname(self): - try: - self.__make_test_user__() - self.overlord.users.user_set_loginname(TestUsers.testuser1,TestUsers.testuser2) - result = self.overlord.users.user_set_loginname(TestUsers.testuser2,TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.overlord.users.user_set_loginname(TestUsers.testuser1,TestUsers.testuser2) + result = self.overlord.users.user_set_loginname(TestUsers.testuser2,TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_set_comment(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_set_comment(TestUsers.testuser1,"zyxxyz") - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_set_comment(TestUsers.testuser1,"zyxxyz") + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_set_expiredate(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_set_expiredate(TestUsers.testuser1,999999) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_set_expiredate(TestUsers.testuser1,999999) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_users_set_expiredate(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - result = self.overlord.users.users_set_expiredate(999999,TestUsers.testuser1,TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + result = self.overlord.users.users_set_expiredate(999999,TestUsers.testuser1,TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_user_set_uid_non_unique(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_set_uid_non_unique(TestUsers.testuser1,self.__unused_uid__()) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_set_uid_non_unique(TestUsers.testuser1,self.__unused_uid__()) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_set_uid(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_set_uid(TestUsers.testuser1,self.__unused_uid__()) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_set_uid(TestUsers.testuser1,self.__unused_uid__()) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_set_inactive(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_set_inactive(TestUsers.testuser1,999999) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_set_inactive(TestUsers.testuser1,999999) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_users_set_inactive(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - result = self.overlord.users.users_set_inactive(999999,TestUsers.testuser1,TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + result = self.overlord.users.users_set_inactive(999999,TestUsers.testuser1,TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_user_move_home(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_move_home(TestUsers.testuser1,"/home/"+TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_move_home(TestUsers.testuser1,"/home/"+TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_unlock(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_unlock(TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_unlock(TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_users_unlock(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - result = self.overlord.users.users_unlock(TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + result = self.overlord.users.users_unlock(TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_users_add_to_group(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - self.__make_test_group__() - result = self.overlord.users.users_add_to_group(TestUsers.testgroup1,TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + self.__make_test_group__() + result = self.overlord.users.users_add_to_group(TestUsers.testgroup1,TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_user_add_to_group(self): - try: - self.__make_test_user__() - self.__make_test_group__() - result = self.overlord.users.user_add_to_group(TestUsers.testuser1,TestUsers.testgroup1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_group__() + result = self.overlord.users.user_add_to_group(TestUsers.testuser1,TestUsers.testgroup1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_users_set_gid(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - self.__make_test_group__() - result = self.overlord.users.users_set_gid(self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th],TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + self.__make_test_group__() + result = self.overlord.users.users_set_gid(self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th],TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_user_set_gid(self): - try: - self.__make_test_user__() - self.__make_test_group__() - result = self.overlord.users.user_set_gid(TestUsers.testuser1,self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th]) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_group__() + result = self.overlord.users.user_set_gid(TestUsers.testuser1,self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th]) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_users_set_group(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - self.__make_test_group__() - result = self.overlord.users.users_set_group(TestUsers.testgroup1,TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + self.__make_test_group__() + result = self.overlord.users.users_set_group(TestUsers.testgroup1,TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_user_set_group(self): - try: - self.__make_test_user__() - self.__make_test_group__() - result = self.overlord.users.user_set_group(TestUsers.testuser1,TestUsers.testgroup1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_group__() + result = self.overlord.users.user_set_group(TestUsers.testuser1,TestUsers.testgroup1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_passwd(self): - try: - self.__make_test_user__() - self.__make_test_group__() - result = self.overlord.users.passwd(TestUsers.testuser1,"".join(self.r.sample([chr(x) for x in range(48,58)+range(65,91)+range(97,123)],8))) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_group__() + result = self.overlord.users.passwd(TestUsers.testuser1,"".join(self.r.sample([chr(x) for x in range(48,58)+range(65,91)+range(97,123)],8))) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_user_exists(self): - try: - self.__make_test_user__() - result = self.overlord.users.user_exists(TestUsers.testuser1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.user_exists(TestUsers.testuser1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_uid_exists(self): - try: - self.__make_test_user__() - result = self.overlord.users.uid_exists(self.overlord.users.user_to_uid(TestUsers.testuser1)[self.th]) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_user__() + result = self.overlord.users.uid_exists(self.overlord.users.user_to_uid(TestUsers.testuser1)[self.th]) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_group_exists(self): - try: - self.__make_test_group__() - result = self.overlord.users.group_exists(TestUsers.testgroup1) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_group__() + result = self.overlord.users.group_exists(TestUsers.testgroup1) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_gid_exists(self): - try: - self.__make_test_group__() - result = self.overlord.users.gid_exists(self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th]) - self.assert_on_fault(result) - assert result[self.th] == True - finally: - self.__cleanup__() + try: + self.__make_test_group__() + result = self.overlord.users.gid_exists(self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th]) + self.assert_on_fault(result) + assert result[self.th] == True + finally: + self.__cleanup__() def test_users_exist(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - result = self.overlord.users.users_exist(TestUsers.testuser1,TestUsers.testuser2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + result = self.overlord.users.users_exist(TestUsers.testuser1,TestUsers.testuser2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_uids_exist(self): - try: - self.__make_test_user__() - self.__make_test_user2__() - result = self.overlord.users.uids_exist(self.overlord.users.user_to_uid(TestUsers.testuser1)[self.th],self.overlord.users.user_to_uid(TestUsers.testuser2)[self.th]) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_user__() + self.__make_test_user2__() + result = self.overlord.users.uids_exist(self.overlord.users.user_to_uid(TestUsers.testuser1)[self.th],self.overlord.users.user_to_uid(TestUsers.testuser2)[self.th]) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_groups_exist(self): - try: - self.__make_test_group__() - self.__make_test_group2__() - result = self.overlord.users.groups_exist(TestUsers.testgroup1,TestUsers.testgroup2) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() + try: + self.__make_test_group__() + self.__make_test_group2__() + result = self.overlord.users.groups_exist(TestUsers.testgroup1,TestUsers.testgroup2) + self.assert_on_fault(result) + assert result[self.th] == [True,True] + finally: + self.__cleanup__() def test_gids_exist(self): - try: - self.__make_test_group__() - result = self.overlord.users.gids_exist(self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th],self.overlord.users.group_to_gid(TestUsers.testgroup2)[self.th]) - self.assert_on_fault(result) - assert result[self.th] == [True,True] - finally: - self.__cleanup__() - - def __trivial_test__(self,function): - def list_test(): try: - result = function() - self.assert_on_fault(result) + self.__make_test_group__() + result = self.overlord.users.gids_exist(self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th],self.overlord.users.group_to_gid(TestUsers.testgroup2)[self.th]) + self.assert_on_fault(result) + assert result[self.th] == [True,True] finally: - self.__cleanup__() - return list_test + self.__cleanup__() + + def __trivial_test__(self,function): + def list_test(): + try: + result = function() + self.assert_on_fault(result) + finally: + self.__cleanup__() + return list_test def test_user_list(self): self.__trivial_test__(self.overlord.users.user_list)() def test_users_list(self): self.__trivial_test__(self.overlord.users.users_list)() @@ -478,17 +478,17 @@ class TestUsers(BaseTest): def test_gids_list(self): self.__trivial_test__(self.overlord.users.gids_list)() def __info_test__(self,function): - def info_test(target): - try: - self.__make_test_user__() - self.__make_test_user2__() - self.__make_test_group__() - self.__make_test_group2__() - result = function(target) - self.assert_on_fault(result) - finally: - self.__cleanup__() - return info_test + def info_test(target): + try: + self.__make_test_user__() + self.__make_test_user2__() + self.__make_test_group__() + self.__make_test_group2__() + result = function(target) + self.assert_on_fault(result) + finally: + self.__cleanup__() + return info_test def test_user_info(self): self.__info_test__(self.overlord.users.user_info)(TestUsers.testuser1) def test_group_info(self): self.__info_test__(self.overlord.users.group_info)(TestUsers.testgroup1) @@ -496,17 +496,17 @@ class TestUsers(BaseTest): def test_gid_info(self): self.__info_test__(self.overlord.users.gid_info)(self.overlord.users.group_to_gid(TestUsers.testgroup1)[self.th]) def __plural_info_test__(self,function): - def plural_info_test(*targets): - try: - self.__make_test_user__() - self.__make_test_user2__() - self.__make_test_group__() - self.__make_test_group2__() - result = function(*targets) - self.assert_on_fault(result) - finally: - self.__cleanup__() - return plural_info_test + def plural_info_test(*targets): + try: + self.__make_test_user__() + self.__make_test_user2__() + self.__make_test_group__() + self.__make_test_group2__() + result = function(*targets) + self.assert_on_fault(result) + finally: + self.__cleanup__() + return plural_info_test def test_users_info(self): self.__plural_info_test__(self.overlord.users.users_info)(TestUsers.testuser1,TestUsers.testuser2) def test_groups_info(self): self.__plural_info_test__(self.overlord.users.groups_info)(TestUsers.testgroup1,TestUsers.testgroup2)
_______________________________________________ Func-list mailing list Func-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/func-list