func/minion/server.py | 19 ++++++++++--------- func/overlord/client.py | 18 +++++++++--------- func/overlord/group/conf_backend.py | 16 ++++++++++++---- func/utils.py | 29 +++++++++++++++++++++++++---- 4 files changed, 56 insertions(+), 26 deletions(-) New commits: commit 042aca6e6acfe6462a8b33c497be848607ba31dc Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Fri Aug 13 15:50:40 2010 -0400 make the group matching lower() all the things we pass in and all groups instantiated are lower() cased diff --git a/func/overlord/group/conf_backend.py b/func/overlord/group/conf_backend.py index 04968d8..70ad56c 100644 --- a/func/overlord/group/conf_backend.py +++ b/func/overlord/group/conf_backend.py @@ -67,6 +67,9 @@ class ConfBackend(BaseBackend): """ Adds a host to a group """ + host = host.lower() + group = group.lower() + if not self.__groups.has_key(group): self.__groups[group] = [] @@ -85,6 +88,7 @@ class ConfBackend(BaseBackend): """ Adds a group """ + group = group.lower() if self.__groups.has_key(group): return (False,"Group name : %s already exists"%group) #create with an empty list @@ -117,6 +121,9 @@ class ConfBackend(BaseBackend): """ Remove a host from groups """ + 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") @@ -155,6 +162,7 @@ class ConfBackend(BaseBackend): @param exclude : A list to be excluded from final set """ + if not pattern: #return all of them if not exclude: @@ -168,7 +176,7 @@ class ConfBackend(BaseBackend): #there is no mean to check here for #exclude list ... for g in self.__groups.keys(): - if g == pattern: + if g == pattern.lower(): return [g] return [] @@ -182,7 +190,7 @@ class ConfBackend(BaseBackend): else: tmp_l = set() for g in self.__groups.keys(): - if pattern.lower() in g.lower(): + if pattern.lower() in g: tmp_l.add(g) #get the difference of 2 sets return list(tmp_l.difference(set(exclude))) @@ -225,13 +233,13 @@ class ConfBackend(BaseBackend): #there is no mean to check here for exclude list ... if type(pattern)==str: for g in hosts: - if g == pattern: + if g.lower() == pattern.lower(): return [g] else: #sometimes we pass all list to compare em tmp = [] for p in pattern: - if p in hosts: + if p.lower() in hosts: tmp.append(p) return tmp return [] commit c6abd0bdd5af060c1476cf4ce8e78f44c9daa154 Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Fri Aug 13 15:50:30 2010 -0400 fix up typo on peerroot diff --git a/func/overlord/client.py b/func/overlord/client.py index 12deb49..6d73712 100644 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -163,7 +163,7 @@ class Minions(object): # 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.peeroot, 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 @@ -177,7 +177,7 @@ class Minions(object): 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.peeroot, self.cm_config.cert_extension) + certs += func_utils.find_files_by_hostname(name, self.cm_config.peerroot, self.cm_config.cert_extension) break if self.overlord_config.allow_unknown_minions and not certs: commit e1ba882019e5629df6dc56509b704491711629f5 Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Tue Aug 10 16:48:06 2010 -0400 b/c dns names can be cased but b/c we didn't handle this to begin with by lower()ing everything I've added a function to return items from our directories case-insensitively with limited globbing support diff --git a/func/minion/server.py b/func/minion/server.py index 5f217d7..28d6fa1 100644 --- a/func/minion/server.py +++ b/func/minion/server.py @@ -29,14 +29,13 @@ from certmaster.commonconfig import CMConfig from func import logger from certmaster import certs import func.jobthing as jobthing -from func import utils as func_utils # our modules import AuthedXMLRPCServer import codes import func.module_loader as module_loader import func.minion.acls as acls_mod -from func import utils as futils +from func import utils as func_utils from certmaster import utils @@ -89,6 +88,8 @@ class XmlRpcInterface(object): self.handlers["system.list_modules"] = self.list_modules self.handlers["system.inventory"] = self.inventory self.handlers["system.grep"] = self.grep + # ultimately need to add a method here to force the server to reload itself so all NEW connections + # get a new RequestHandler def list_modules(self): modules = self.modules.keys() @@ -100,9 +101,6 @@ class XmlRpcInterface(object): methods.sort() return methods - def load_module(self, name): - """FIXME load a module and set it up on the running xmlrpc instance""" - pass import func.minion.modules.func_module as fm def grep(self,word): @@ -192,7 +190,7 @@ class FuncApiMethod: self.logger.debug("(X) -------------------------------------------") try: - self.__method = futils.get_fresh_method_instance(self.__method) + self.__method = func_utils.get_fresh_method_instance(self.__method) rc = self.__method(*args) except codes.FuncException, e: self.__log_exc() @@ -250,12 +248,15 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, if self.config.key_file != '': self.key = self.config.key_file else: - self.key = "%s/%s.pem" % (self.cm_config.cert_dir, hn) + # 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: - self.cert = "%s/%s.cert" % (self.cm_config.cert_dir, hn) + self.cert = func_utils.find_files_by_hostname(hn, self.cm_config.cert_dir, '.cert')[0] + if self.config.ca_file != '': self.ca = self.config.ca_file else: @@ -373,7 +374,7 @@ def main(argv): try: config = read_config("/etc/func/minion.conf", FuncdConfig) if config.use_certmaster: - hn = futils.get_hostname_by_route() + hn = func_utils.get_hostname_by_route() requester.request_cert(hn) serve() except codes.FuncException, e: diff --git a/func/overlord/client.py b/func/overlord/client.py index 0931172..12deb49 100644 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -15,7 +15,6 @@ from func.jobthing import RETAIN_INTERVAL import sys -import glob import os import time import shlex @@ -158,13 +157,14 @@ class Minions(object): else: each_gloob = shortest_path[0] - actual_gloob = "%s/%s.%s" % (self.cm_config.certroot, each_gloob, self.cm_config.cert_extension) - certs = glob.glob(actual_gloob) + #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 += glob.glob(peer_gloob) + #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.peeroot, 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. @@ -173,11 +173,11 @@ class Minions(object): aliases = func_utils.get_all_host_aliases(each_gloob) for name in aliases: - actual_gloob = "%s/%s.%s" % (self.cm_config.certroot, name, self.cm_config.cert_extension) - certs += glob.glob(actual_gloob) + #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) if self.cm_config.peering: - peer_gloob = "%s/%s.%s" % (self.cm_config.peerroot, name, self.cm_config.cert_extension) - certs += glob.glob(peer_gloob) + #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.peeroot, self.cm_config.cert_extension) break if self.overlord_config.allow_unknown_minions and not certs: diff --git a/func/utils.py b/func/utils.py index fcc5cdc..fe0c9da 100644 --- a/func/utils.py +++ b/func/utils.py @@ -16,6 +16,7 @@ import socket import string import sys import re +import fnmatch from certmaster.config import read_config from certmaster.commonconfig import MinionConfig @@ -86,7 +87,7 @@ def get_hostname_by_route(): # don't bother guessing a hostname if they specify it in the config file if minion_config.minion_name: - return minion_config.minion_name + return minion_config.minion_name.lower() # try to find the hostname attached to the ip of the interface that we use # to talk to the certmaster @@ -107,7 +108,7 @@ def get_hostname_by_route(): # not talking via localhost? good enough... if ip != '127.0.0.1': s.close() - return intf_hostname + return intf_hostname.lower() except: s.close() # something failed, reverse dns, etc @@ -133,13 +134,33 @@ 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 + return hostname.lower() # all else has failed to get a good hostname, so just return # an ip address - return socket.gethostbyname(socket.gethostname()) + return socket.gethostbyname(socket.gethostname()).lower() # yes I know it's an ip but I don't trust anything + +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 + craziness that is dns names that have mixed case :(""" + + # 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)) + 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] + def get_all_host_aliases(hostname): try: commit 1f0a0108393125a067789349500855c140e01cee Merge: 4e3773a... 82c08a5... Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Tue Aug 10 16:05:06 2010 -0400 Merge branch 'master' of ssh://git.fedorahosted.org/git/func * 'master' of ssh://git.fedorahosted.org/git/func: * Add globbing support to delegation mode, * Invoke the sub-overlord only if it is really required, * Incorporate Seth Vidal's "make sure we catch unresolveable hostname errors and behave accordingly" patch so that non-fqdn hostnames can be used with delegation as well, * Introduce allow_unknown_minions (False by default) Overlord config option to onditionalize the unknown-host behavior Conflicts: func/overlord/client.py commit 4e3773a3f107a253e29c90c954bf76d44221b1dd Merge: 293a98a... 7f3f0dd... Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Thu Aug 5 17:14:57 2010 -0400 Merge branch 'master' of ssh://git.fedorahosted.org/git/func * 'master' of ssh://git.fedorahosted.org/git/func: add dropped part of the commit c7ea92da476ffbe5bd926c84c620be0683a26e45 certmaster returns None for minion only setups with commit f6ee54c2457bec39c869d9526d47e977e87c702c. So use that return value to determine minion only setups to solve following exception; commit 2fb87602b573b6e6dd21ab000da79804b3ea10f5 replaced mktemp with mkstemp but mkstemp returns a tuple containing an OS-level handle to an open file and the absolute pathname of that file, in that order. Use the latter. fix delegated async calls commit 293a98ac098b728794fd783abffbbe5ee9cafebe Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Tue Aug 3 16:41:44 2010 -0400 make sure we catch unresolveable hostname errors and behave accordingly diff --git a/func/overlord/client.py b/func/overlord/client.py index 4ccd98e..4d07abc 100644 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -161,15 +161,18 @@ class Minions(object): # let the gloob be the hostname we try to connect to. if not certs and not func_utils.re_glob(each_gloob): found_by_alias = False - (fqdn, aliases, ips) = socket.gethostbyname_ex(each_gloob) - - for name in [fqdn] + aliases: - actual_gloob = "%s/%s.%s" % (self.cm_config.certroot, name, self.cm_config.cert_extension) - certs += glob.glob(actual_gloob) - if self.cm_config.peering: - peer_gloob = "%s/%s.%s" % (self.cm_config.peerroot, name, self.cm_config.cert_extension) - certs += glob.glob(peer_gloob) - break + try: + (fqdn, aliases, ips) = socket.gethostbyname_ex(each_gloob) + except socket.gaierror, e: + pass + else: + for name in [fqdn] + aliases: + actual_gloob = "%s/%s.%s" % (self.cm_config.certroot, name, self.cm_config.cert_extension) + certs += glob.glob(actual_gloob) + if self.cm_config.peering: + peer_gloob = "%s/%s.%s" % (self.cm_config.peerroot, name, self.cm_config.cert_extension) + certs += glob.glob(peer_gloob) + break if not certs: tmp_hosts.add(each_gloob) @@ -349,13 +352,17 @@ class PuppetMinions(Minions): # or aliases matches _something_ we know about if not matched_gloob and not func_utils.re_glob(each_gloob): found_by_alias = False - (fqdn, aliases, ips) = socket.gethostbyname_ex(each_gloob) - for name in [fqdn] + aliases: - if name in self._host_inv and int(self._host_inv[name], 16) not in self._revoked_serials: - if os.path.exists(self.overlord_config.puppet_signed_certs_dir + '/' + name + '.pem'): - tmp_hosts.add(name) - found_by_alias = True - break + try: + (fqdn, aliases, ips) = socket.gethostbyname_ex(each_gloob) + except socket.gaierror, e: + pass + else: + for name in [fqdn] + aliases: + if name in self._host_inv and int(self._host_inv[name], 16) not in self._revoked_serials: + if os.path.exists(self.overlord_config.puppet_signed_certs_dir + '/' + name + '.pem'): + tmp_hosts.add(name) + found_by_alias = True + break if not found_by_alias: tmp_hosts.add(each_gloob) _______________________________________________ Func-list mailing list Func-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/func-list