func/minion/acls.py | 56 +++++++++++++++++++++++++++++++++++------------- func/overlord/client.py | 20 +++++++++++++++-- func/utils.py | 18 ++++++++++++--- 3 files changed, 74 insertions(+), 20 deletions(-) New commits: commit 69234d02f3e047ea7e2a38ea3ae4a83971ed2828 Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Mon May 10 14:26:04 2010 -0400 - make Acls.acls a property - make acls reload if any .acl file is added, removed or changed during runtimes - log slightly better than before diff --git a/func/minion/acls.py b/func/minion/acls.py index fec3be0..5b80159 100644 --- a/func/minion/acls.py +++ b/func/minion/acls.py @@ -14,7 +14,8 @@ import fnmatch import glob import os import sys - +import time +import stat from func import logger @@ -25,25 +26,49 @@ class Acls(object): self.config = config self.acldir = self.config.acl_dir - self.acls = {} + self._acl_glob = '%s/*.acl' % self.acldir + self._acls = {} self.logger = logger.Logger().logger self.certmaster_overrides_acls = self.config.certmaster_overrides_acls + self.last_load_time = 0 self.load() + def _reload_acls(self): + """ + 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): """ 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 + 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 - acl_glob = '%s/*.acl' % self.acldir - files = glob.glob(acl_glob) + files = glob.glob(self._acl_glob) for acl_file in files: self.logger.debug("acl_file %s", acl_file) @@ -62,30 +87,31 @@ class Acls(object): methods = methods.strip() methods = methods.replace(',',' ') methods = methods.split() - if not self.acls.has_key(host): - self.acls[host] = [] - self.acls[host].extend(methods) + if not self._acls.has_key(host): + self._acls[host] = [] + self._acls[host].extend(methods) - self.logger.debug("acls %s" % self.acls) + self.logger.debug("acls %s" % self._acls) + + self.last_load_time = time.time() + return self._acls - return self.acls + acls = property(load) def check(self, cm_cert, cert, ip, method, params): # certmaster always gets to run things # unless we are testing, and need to turn it off.. -al; - - if self.config.certmaster_overrides_acls: ca_cn = cm_cert.get_subject().CN ca_hash = cm_cert.subject_name_hash() ca_key = '%s-%s' % (ca_cn, ca_hash) - self.acls[ca_key] = ['*'] + self._acls[ca_key] = ['*', 'foo'] cn = cert.get_subject().CN sub_hash = cert.subject_name_hash() self.logger.debug("cn: %s sub_hash: %s" % (cn, sub_hash)) - self.logger.debug("acls %s" % self.acls) + self.logger.debug("current acls %s" % self.acls) if self.acls: allow_list = [] hostkey = '%s-%s' % (cn, sub_hash) commit c722244b8f7d3be7f0fff06db23457ddfb0d61cc Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Mon May 10 14:25:39 2010 -0400 move around the imports of sys and re so chasing them down isn't as annoying diff --git a/func/utils.py b/func/utils.py index a9f302b..a3fb18c 100644 --- a/func/utils.py +++ b/func/utils.py @@ -14,6 +14,8 @@ import inspect import os import socket import string +import sys +import re from certmaster.config import read_config from certmaster.commonconfig import MinionConfig @@ -225,7 +227,7 @@ def re_glob(s): #it is a combination of http://code.activestate.com/recipes/168639/ and #http://code.activestate.com/recipes/475116/ and recipes for usage #you can look at places we use it ! -import sys, re + class TerminalController: """ commit a56e9df910740c9f5718919b1eec58d0218b8604 Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Fri May 7 14:23:50 2010 -0400 if we do not find a match in the minions list, then if the glob we're passed is NOT a glob, assume it's a hostname - and just allow it. add re_glob function from yum to utils. diff --git a/func/overlord/client.py b/func/overlord/client.py index 4e924c6..64622c4 100644 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -155,7 +155,12 @@ class Minions(object): if self.cm_config.peering: peer_gloob = "%s/%s.%s" % (self.cm_config.peerroot, each_gloob, self.cm_config.cert_extension) certs += glob.glob(peer_gloob) - + + # 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): + tmp_hosts.add(each_gloob) + for cert in certs: tmp_certs.add(cert) # use basename to trim off any excess /'s, fix @@ -290,7 +295,10 @@ class PuppetMinions(Minions): for line in fo.readlines(): if re.match('\s*(#|$)', line): continue - (serial, before, after, cn) = line.split() + try: + (serial, before, after, cn) = line.split() + except ValueError: + continue before = time.strftime('%s', time.strptime(before, time_format)) if now < int(before): continue @@ -314,8 +322,15 @@ class PuppetMinions(Minions): pempath = '%s/%s.pem' % (self.overlord_config.puppet_signed_certs_dir, hostname) if not os.path.exists(pempath): continue + matched_gloob = False 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 + # let the gloob be the hostname we try to connect to. + if not matched_gloob and not func_utils.re_glob(each_gloob): + tmp_hosts.add(each_gloob) # don't return certs path - just hosts return tmp_hosts,tmp_certs @@ -345,6 +360,7 @@ class PuppetMinions(Minions): return serials + # does the hostnamegoo actually expand to anything? def is_minion(minion_string): minions = Minions(minion_string) diff --git a/func/utils.py b/func/utils.py index 1c4d94c..a9f302b 100644 --- a/func/utils.py +++ b/func/utils.py @@ -165,9 +165,9 @@ def get_fresh_method_instance(function_ref): except Exception,e: #something went wrong so we return the normal reference value return function_ref - try: + try: return getattr(fresh_instance,function_ref.__name__) - except AttributeError: + except AttributeError: return getattr(fresh_instance,function_ref._name_) def should_log(args): @@ -210,6 +210,16 @@ def deep_base64(ds, mode = 0): return ds +_re_compiled_glob_match = None +def re_glob(s): + """ Tests if a string is a shell wildcard. """ + # TODO/FIXME maybe consider checking if it is a stringsType before going on - otherwise + # returning None + global _re_compiled_glob_match + if _re_compiled_glob_match is None: + _re_compiled_glob_match = re.compile('[*?]|\[.+\]').search + return _re_compiled_glob_match(s) + #################### PROGRESS BAR ################################## # The code below can be used for progress bar purposes as we will do #it is a combination of http://code.activestate.com/recipes/168639/ and _______________________________________________ Func-list mailing list Func-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/func-list