Allow the /etc/ansible/hosts file to contain groups and those group names to be used in place

of pattern names.
This commit is contained in:
Michael DeHaan 2012-03-01 20:41:17 -05:00
parent 24d854e0bc
commit bed29b7e11
3 changed files with 44 additions and 18 deletions

View file

@ -23,7 +23,7 @@ DEFAULT_MODULE_NAME = 'ping'
DEFAULT_PATTERN = '*'
DEFAULT_FORKS = 3
DEFAULT_MODULE_ARGS = ''
DEFAULT_TIMEOUT = 60
DEFAULT_TIMEOUT = 10
DEFAULT_REMOTE_USER = 'root'
DEFAULT_REMOTE_PASS = None

View file

@ -106,7 +106,7 @@ class PlayBook(object):
# actions where not all hosts have changed
# though top-level tasks will pass in "None" here
host_list = self.host_list
host_list = ansible.runner.Runner.parse_hosts(host_list)
(host_list, groups) = ansible.runner.Runner.parse_hosts(host_list)
# do not continue to run tasks on hosts that have had failures
new_hosts = []
@ -132,9 +132,9 @@ class PlayBook(object):
if self.verbose:
if not conditional:
print "\nTASK [%s]" % (name)
print "\nTASK: %s" % (name)
else:
print "\nNOTIFIED [%s]" % (name)
print "\nNOTIFIED: %s" % (name)
# load up an appropriate ansible runner to
# run the task in parallel
@ -240,10 +240,12 @@ class PlayBook(object):
tasks = pg['tasks']
handlers = pg['handlers']
user = pg.get('user', C.DEFAULT_REMOTE_USER)
self.host_list = pg.get('hosts', '/etc/ansible/hosts')
host_file = pg.get('hosts', '/etc/ansible/hosts')
self.host_list, groups = ansible.runner.Runner.parse_hosts(host_file)
if self.verbose:
print "PLAY: [%s] from [%s] ********** " % (pattern, self.host_list)
print "PLAY: [%s] ********** " % (pattern)
# run all the top level tasks, these get run on every node
@ -252,7 +254,8 @@ class PlayBook(object):
pattern=pattern,
task=task,
handlers=handlers,
remote_user=user)
remote_user=user
)
# handlers only run on certain nodes, they are flagged by _flag_handlers
# above. They only run on nodes when things mark them as changed, and

View file

@ -68,7 +68,8 @@ class Runner(object):
'''
# save input values
self.host_list = self.parse_hosts(host_list)
self.host_list, self.groups = self.parse_hosts(host_list)
self.module_path = module_path
self.module_name = module_name
self.forks = forks
@ -78,19 +79,35 @@ class Runner(object):
self.verbose = verbose
self.remote_user = remote_user
self.remote_pass = remote_pass
self._tmp_paths = {}
# hosts in each group name in the inventory file
self._tmp_paths = {}
@classmethod
def parse_hosts(cls, host_list):
''' parse the host inventory file if not sent as an array '''
'''
parse the host inventory file, returns (hosts, groups)
[groupname]
host1
host2
'''
# if the host list is given as a string load the host list
# from a file, one host per line
if type(host_list) != list:
host_list = os.path.expanduser(host_list)
return file(host_list).read().split("\n")
if type(host_list) == list:
return (host_list, {})
return host_list
host_list = os.path.expanduser(host_list)
lines = file(host_list).read().split("\n")
groups = {}
group_name = 'ungrouped'
results = []
for item in lines:
if item.startswith("["):
group_name = item.replace("[","").replace("]","").lstrip().rstrip()
groups[group_name] = []
else:
groups[group_name].append(item)
results.append(item)
return (results, groups)
def _matches(self, host_name, pattern=None):
@ -98,12 +115,18 @@ class Runner(object):
# a pattern is in fnmatch format but more than one pattern
# can be strung together with semicolons. ex:
# atlanta-web*.example.com;dc-web*.example.com
if host_name == '':
return False
subpatterns = pattern.split(";")
for subpattern in subpatterns:
# the pattern could be a real glob
if fnmatch.fnmatch(host_name, subpattern):
return True
# or it could be a literal group name instead
if self.groups.has_key(subpattern):
if host_name in self.groups[subpattern]:
return True
return False
def _connect(self, host):
@ -117,7 +140,7 @@ class Runner(object):
try:
# try paramiko
ssh.connect(host, username=self.remote_user, allow_agent=True,
look_for_keys=True, password=self.remote_pass timeout=self.timeout)
look_for_keys=True, password=self.remote_pass, timeout=self.timeout)
return [ True, ssh ]
except Exception, e:
# it failed somehow, return the failure string
@ -303,7 +326,7 @@ class Runner(object):
# find hosts that match the pattern
hosts = self.match_hosts(self.pattern)
# attack pool of hosts in N forks
# _executor_hook does all of the work
hosts = [ (self,x) for x in hosts ]