func/commonconfig.py | 2 - func/overlord/client.py | 70 +++++++++++++++++++++++++------------- func/overlord/delegation_tools.py | 13 ++++--- func/utils.py | 7 +++ 4 files changed, 63 insertions(+), 29 deletions(-) New commits: commit 82c08a57832a7a7bc057c655af49f1392e8b1568 Author: S.Ã?aÄ?lar Onur <caglar@xxxxxxxxxxxxxxxx> Date: Tue Aug 10 15:36:23 2010 -0400 * 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 diff --git a/func/commonconfig.py b/func/commonconfig.py index ab2ce04..224c156 100644 --- a/func/commonconfig.py +++ b/func/commonconfig.py @@ -48,5 +48,5 @@ class OverlordConfig(BaseConfig): puppet_signed_certs_dir = Option('/var/lib/puppet/ssl/ca/signed') 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/overlord/client.py b/func/overlord/client.py index 4ccd98e..0931172 100644 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -22,7 +22,6 @@ import shlex import subprocess import re import fnmatch -import socket import func.yaml as yaml from certmaster.commonconfig import CMConfig @@ -149,6 +148,16 @@ class Minions(object): tmp_certs = set() tmp_hosts = set() + # if call is delegated find the shortest path to the minion and use the sub-overlord's certificate + if self.delegate: + try: + each_gloob = func_utils.get_all_host_aliases(each_gloob)[0] + shortest_path = dtools.get_shortest_path(each_gloob, self.minionmap) + except IndexError: + return tmp_hosts,tmp_certs + 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) @@ -161,19 +170,19 @@ 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) + aliases = func_utils.get_all_host_aliases(each_gloob) - for name in [fqdn] + aliases: + for name in 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: + + if self.overlord_config.allow_unknown_minions and not certs: tmp_hosts.add(each_gloob) - + for cert in certs: tmp_certs.add(cert) # use basename to trim off any excess /'s, fix @@ -330,7 +339,17 @@ class PuppetMinions(Minions): host_inv[hn] = serial fo.close() self._host_inv = host_inv # store ours - + + # if call is delegated find the shortest path to the minion and use the sub-overlord's certificate + if self.delegate: + try: + each_gloob = func_utils.get_all_host_aliases(each_gloob)[0] + shortest_path = dtools.get_shortest_path(each_gloob, self.minionmap) + except IndexError: + return tmp_hosts,tmp_certs + else: + each_gloob = shortest_path[0] + # revoked certs self._return_revoked_serials(self.overlord_config.puppet_crl) for hostname in self._host_inv.keys(): @@ -349,17 +368,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: + aliases = func_utils.get_all_host_aliases(each_gloob) + for name in 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: + + if self.overlord_config.allow_unknown_minions and not found_by_alias: tmp_hosts.add(each_gloob) - + # don't return certs path - just hosts return tmp_hosts,tmp_certs @@ -460,7 +479,10 @@ class Overlord(object): self.delegate = delegate self.mapfile = mapfile - + self.minionmap = {} + + self.allow_unknown_minions = self.config.allow_unknown_minions + #overlord_query stuff self.overlord_query = OverlordQuery() if self.config.puppet_minions: @@ -468,14 +490,6 @@ class Overlord(object): else: self._mc = Minions - self.minions_class = self._mc(self.server_spec, port=self.port, - noglobs=self.noglobs, verbose=self.verbose, - exclude_spec=self.exclude_spec) - self.minions = self.minions_class.get_urls() - - if len(self.minions) == 0: - raise Func_Client_Exception, 'Can\'t find any minions matching \"%s\". ' % self.server_spec - if self.delegate: try: mapstream = file(self.mapfile, 'r').read() @@ -483,7 +497,16 @@ class Overlord(object): except e: sys.stderr.write("mapfile load failed, switching delegation off") self.delegate = False - + + self.minions_class = self._mc(self.server_spec, port=self.port, + noglobs=self.noglobs, verbose=self.verbose, + delegate=self.delegate,minionmap=self.minionmap, + exclude_spec=self.exclude_spec) + self.minions = self.minions_class.get_urls() + + if len(self.minions) == 0: + raise Func_Client_Exception, 'Can\'t find any minions matching \"%s\". ' % self.server_spec + if init_ssl: self.setup_ssl() @@ -730,7 +753,8 @@ class Overlord(object): #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... - directhash.update(self.run_direct(module,method,args,nforks)) + if single_paths != []: + directhash.update(self.run_direct(module,method,args,nforks)) #poll async results if we've async turned on if self.async: diff --git a/func/overlord/delegation_tools.py b/func/overlord/delegation_tools.py index 0f3b43e..eb192b4 100644 --- a/func/overlord/delegation_tools.py +++ b/func/overlord/delegation_tools.py @@ -15,6 +15,7 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ## +from func import utils as func_utils import fnmatch class groupby(object): @@ -60,17 +61,19 @@ def group_paths(ungrouped_list): return (single_paths,path_group) -def get_paths_for_glob(glob, minionmap): +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 elem in match_glob_in_tree(glob,minionmap): - result = get_shortest_path(elem,minionmap) - if result not in pathlist: #prevents duplicates - pathlist.append(result) + for glob in glob_list.split(";"): + glob = func_utils.get_all_host_aliases(glob)[0] + for elem in match_glob_in_tree(glob,minionmap): + result = get_shortest_path(elem,minionmap) + if result not in pathlist: #prevents duplicates + pathlist.append(result) return pathlist def list_all_minions(minionmap): diff --git a/func/utils.py b/func/utils.py index 632d727..fcc5cdc 100644 --- a/func/utils.py +++ b/func/utils.py @@ -141,6 +141,13 @@ def get_hostname_by_route(): # an ip address return socket.gethostbyname(socket.gethostname()) +def get_all_host_aliases(hostname): + try: + (fqdn, aliases, ips) = socket.gethostbyname_ex(hostname) + except socket.gaierror, e: + return [hostname] + else: + return [fqdn] + aliases def get_fresh_method_instance(function_ref): """
_______________________________________________ Func-list mailing list Func-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/func-list