def on_task_start(self, name, is_conditional): msg = "TASK: [%s]" % name if is_conditional: msg = "NOTIFIED: [%s]" % name if hasattr(self, 'start_at'): if name == self.start_at or fnmatch.fnmatch(name, self.start_at): # we found out match, we can get rid of this now del self.start_at elif self.task.role_name: # handle tasks prefixed with rolenames actual_name = name.split('|', 1)[1].lstrip() if actual_name == self.start_at or fnmatch.fnmatch(actual_name, self.start_at): del self.start_at if hasattr(self, 'start_at'): # we still have start_at so skip the task self.skip_task = True elif hasattr(self, 'step') and self.step: msg = ('Perform task: %s (y/n/c): ' % name).encode(sys.stdout.encoding) resp = raw_input(msg) if resp.lower() in ['y','yes']: self.skip_task = False display(banner(msg), self.sqs_response_queue, self.sqs_request_message) elif resp.lower() in ['c', 'continue']: self.skip_task = False self.step = False display(banner(msg), self.sqs_response_queue, self.sqs_request_message) else: self.skip_task = True else: self.skip_task = False display(banner(msg), self.sqs_response_queue, self.sqs_request_message)
def run(self): stats = callbacks.AggregateStats() runner_cb = callbacks.PlaybookRunnerCallbacks( stats, verbose=utils.VERBOSITY) playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) pb = ansible.playbook.PlayBook( playbook=self.tmp, inventory=self.conf["inventory"], remote_user=self.conf["remote_user"], callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats ) pb.run() hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("‽")) for h in hosts: t = pb.stats.summarize(h) display( "%s : %s %s %s %s" % ( h, t['ok'], t['changed'], t['unreachable'], t['failures'],), screen_only=True )
def run(self): stats = callbacks.AggregateStats() runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) pb = ansible.playbook.PlayBook(playbook=self.tmp, inventory=self.conf["inventory"], remote_user=self.conf["remote_user"], callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats) pb.run() hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("‽")) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % ( h, t['ok'], t['changed'], t['unreachable'], t['failures'], ), screen_only=True)
def on_task_start(self, name, is_conditional): name = utils.unicode.to_bytes(name) msg = "TASK: [%s]" % name if is_conditional: msg = "NOTIFIED: [%s]" % name if hasattr(self, 'start_at'): self.start_at = utils.unicode.to_bytes(self.start_at) if name == self.start_at or fnmatch.fnmatch(name, self.start_at): # we found out match, we can get rid of this now del self.start_at elif self.task.role_name: # handle tasks prefixed with rolenames actual_name = name.split('|', 1)[1].lstrip() if actual_name == self.start_at or fnmatch.fnmatch( actual_name, self.start_at): del self.start_at if hasattr(self, 'start_at'): # we still have start_at so skip the task self.skip_task = True elif hasattr(self, 'step') and self.step: if isinstance(name, str): name = utils.unicode.to_unicode(name) msg = u'Perform task: %s (y/n/c): ' % name if sys.stdout.encoding: msg = to_bytes(msg, sys.stdout.encoding) else: msg = to_bytes(msg) resp = raw_input(msg) if resp.lower() in ['y', 'yes']: self.skip_task = False display(banner(msg), task_id=self.task_id) elif resp.lower() in ['c', 'continue']: self.skip_task = False self.step = False display(banner(msg), task_id=self.task_id) else: self.skip_task = True else: self.skip_task = False display(banner(msg), task_id=self.task_id) call_callback_module('playbook_on_task_start', name, is_conditional)
def on_task_start(self, name, is_conditional): name = utils.unicode.to_bytes(name) msg = "TASK: [%s]" % name if is_conditional: msg = "NOTIFIED: [%s]" % name if hasattr(self, 'start_at'): self.start_at = utils.unicode.to_bytes(self.start_at) if name == self.start_at or fnmatch.fnmatch(name, self.start_at): # we found out match, we can get rid of this now del self.start_at elif self.task.role_name: # handle tasks prefixed with rolenames actual_name = name.split('|', 1)[1].lstrip() if actual_name == self.start_at or fnmatch.fnmatch(actual_name, self.start_at): del self.start_at if hasattr(self, 'start_at'): # we still have start_at so skip the task self.skip_task = True elif hasattr(self, 'step') and self.step: if isinstance(name, str): name = utils.unicode.to_unicode(name) msg = u'Perform task: %s (y/n/c): ' % name if sys.stdout.encoding: msg = to_bytes(msg, sys.stdout.encoding) else: msg = to_bytes(msg) resp = raw_input(msg) if resp.lower() in ['y', 'yes']: self.skip_task = False display(banner(msg), task_id=self.task_id) elif resp.lower() in ['c', 'continue']: self.skip_task = False self.step = False display(banner(msg), task_id=self.task_id) else: self.skip_task = True else: self.skip_task = False display(banner(msg), task_id=self.task_id) call_callback_module('playbook_on_task_start', name, is_conditional)
continue if options.syntax: # if we've not exited by now then we are fine. print 'Playbook Syntax is fine' return 0 failed_hosts = [] unreachable_hosts = [] try: pb.run() hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: display(" to retry, use: --limit @%s\n" % filename)
def playbook_on_stats(self, stats): """ Prints the timings """ display(callbacks.banner("PLAY TIMINGS")) # Record the timing of the very last task if self.current is not None: self.stats[self.current] = time.time() - self.stats[self.current] # the raw results results = self.stats.items() # Sort the tasks by their running time sortedResults = sorted( self.stats.items(), key=lambda value: value[1], reverse=True, ) # Just keep the top 10 sortedResults = sortedResults[:10] # the total time for all of the roles/tasks totalTime = 0; # the timings for the role roleTimings = {} # Print the timings for name, elapsed in results: # build up the role timings # first thing to do is to figure out whether it is a role strippedName = "" if (name.find("|") == -1): strippedName = "<NO_DEFINED_ROLE>" else: strippedName = name[:name.find("|")] if(strippedName in roleTimings): roleTimings[strippedName] = roleTimings[strippedName] + elapsed else: roleTimings[strippedName] = elapsed print( "{0:-<70}{1:->9}".format( '{0} '.format(name), ' {0:.02f}s'.format(elapsed), ) ) totalTime = totalTime + elapsed # diaply the top 10 slowest tasks display(callbacks.banner("TOP 10 SLOWEST TASKS")) for name, elapsed in sortedResults: print( "{0:-<70}{1:->9}".format( '{0} '.format(name), ' {0:.02f}s'.format(elapsed), ) ) # Display the times per role display(callbacks.banner("ROLE TIMES")) for role, timing in sorted(roleTimings.iteritems(), key=lambda (k,v): (v,k), reverse=True): print( "{0:-<70}{1:->9}".format( '{0} '.format(role), ' {0:.02f}s'.format(timing), ) ) # display the total time taken for the ansible job display(callbacks.banner("TOTAL TIME")) print( "{0:-<70}{1:>9}".format( '{0}'.format(""), ' {0:.02f}s'.format(totalTime), ) )
def main(args): ''' run ansible-playbook operations ''' # create parser for CLI options usage = "%prog playbook.yml" parser = utils.base_parser(constants=C, usage=usage, connect_opts=True, runas_opts=True, subset_opts=True, check_opts=True, diff_opts=True) parser.add_option('-e', '--extra-vars', dest="extra_vars", default=None, help="set additional key=value variables from the CLI") parser.add_option('-t', '--tags', dest='tags', default='all', help="only run plays and tasks tagged with these values") # FIXME: list hosts is a common option and can be moved to utils/__init__.py parser.add_option( '--list-hosts', dest='listhosts', action='store_true', help= "dump out a list of hosts, each play will run against, does not run playbook!" ) parser.add_option( '--syntax-check', dest='syntax', action='store_true', help= "do a playbook syntax check on the playbook, do not execute the playbook" ) parser.add_option('--list-tasks', dest='listtasks', action='store_true', help="do list all tasks that would be executed") options, args = parser.parse_args(args) if len(args) == 0: parser.print_help(file=sys.stderr) return 1 inventory = ansible.inventory.Inventory(options.inventory) inventory.subset(options.subset) if len(inventory.list_hosts()) == 0: raise errors.AnsibleError("provided hosts list is empty") sshpass = None sudopass = None if not options.listhosts and not options.syntax and not options.listtasks: options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS if options.ask_pass: sshpass = getpass.getpass(prompt="SSH password: "******"sudo password: "******",") for playbook in args: if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % playbook) if not os.path.isfile(playbook): raise errors.AnsibleError( "the playbook: %s does not appear to be a file" % playbook) # run all playbooks specified on the command line for playbook in args: (playbook_path, playbook_file) = os.path.split(playbook) os.chdir(playbook_path) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) pb = ansible.playbook.PlayBook( playbook=playbook_file, module_path=options.module_path, inventory=inventory, forks=options.forks, remote_user=options.remote_user, remote_pass=sshpass, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=options.timeout, transport=options.connection, sudo=options.sudo, sudo_user=options.sudo_user, sudo_pass=sudopass, extra_vars=extra_vars, private_key_file=options.private_key_file, only_tags=only_tags, check=options.check, diff=options.diff) if options.listhosts or options.listtasks: print '' print 'playbook: %s' % playbook print '' playnum = 0 for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs): playnum += 1 play = ansible.playbook.Play(pb, play_ds, play_basedir) label = play.name if options.listhosts: hosts = pb.inventory.list_hosts(play.hosts) print ' play #%d (%s): host count=%d' % (playnum, label, len(hosts)) for host in hosts: print ' %s' % host if options.listtasks: matched_tags, unmatched_tags = play.compare_tags( pb.only_tags) unmatched_tags.discard('all') unknown_tags = set( pb.only_tags) - (matched_tags | unmatched_tags) if unknown_tags: msg = 'tag(s) not found in playbook: %s. possible values: %s' unknown = ','.join(sorted(unknown_tags)) unmatched = ','.join(sorted(unmatched_tags)) raise errors.AnsibleError(msg % (unknown, unmatched)) print ' play #%d (%s): task count=%d' % ( playnum, label, len(play.tasks())) for task in play.tasks(): if set(task.tags).intersection(pb.only_tags): print ' %s' % task.name print '' continue if options.syntax: # if we've not exited by now then we are fine. print 'Playbook Syntax is fine' return 0 try: pb.run() hosts = sorted(pb.stats.processed.keys()) print callbacks.banner("PLAY RECAP") playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) print "%-30s : %s %s %s %s " % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')) print "\n" for h in hosts: stats = pb.stats.summarize(h) if stats['failures'] != 0 or stats['unreachable'] != 0: return 2 print "\n" print "PLAYBOOK_OUT" print "\n" playbook_out = {} for h in hosts: if "playbook_out" in pb.SETUP_CACHE[h]: playbook_out[h] = pb.SETUP_CACHE[h]["playbook_out"] print json.dumps(playbook_out) except errors.AnsibleError, e: print >> sys.stderr, "ERROR: %s" % e return 1
def playbook_on_stats(self, stats): """ Prints the timings """ if self.enabled is None or not self.enabled: return display(callbacks.banner("PLAY TIMINGS")) # Record the timing of the very last task if self.current is not None: self.stats[self.current] = time.time() - self.stats[self.current] self.role_stats[self.current_role] += self.stats[self.current] self.total_time += self.stats[self.current] # the raw results results = self.stats.items() # Sort the tasks by their running time sortedResults = sorted( self.stats.items(), key=lambda value: value[1], reverse=True, ) # Just keep the top 10 sortedResults = sortedResults[:10] # Print the timings for name, elapsed in results: print( "{0:-<70}{1:->9}".format( '{0} '.format(name), ' {0:.02f}s'.format(elapsed), ) ) # display the top 10 slowest tasks display(callbacks.banner("TOP 10 SLOWEST TASKS")) for name, elapsed in sortedResults: print( "{0:-<70}{1:->9}".format( '{0} '.format(name), ' {0:.02f}s'.format(elapsed), ) ) # Display the times per role display(callbacks.banner("ROLE TIMES")) sortedRoleTimings = sorted( self.role_stats.items(), key=lambda value: value[1], reverse=True, ) for role, timing in sortedRoleTimings: print( "{0:-<70}{1:->9}".format( '{0} '.format(role), ' {0:.02f}s'.format(timing), ) ) # display the total time taken for the ansible job display(callbacks.banner("TOTAL TIME")) print( "{0:-<70}{1:>9}".format( '{0}'.format(""), ' {0:.02f}s'.format(self.total_time), ) )
def on_play_start(self, name): display(banner("PLAY [%s]" % name), self.sqs_response_queue, self.sqs_request_message)
def run(self): """ This is a modified version of the function used within ansible-playbook. playbooks. See top of file. """ tstart = time.time() # get the absolute path for the playbooks self.playbooks = [ '{}/playbooks/{}'.format(config['install_path'], pb) for pb in self.playbooks] # Ansible defaults carried over from `ansible-playbook`. Changes these # shouldn't be necessary since all R/W is done within *this* users # directory. sshpass = None sudopass = None su_pass = None vault_pass = None for playbook in self.playbooks: if not os.path.exists(playbook): raise errors.AnsibleError( "the playbook: %s could not be found" % playbook) if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)): raise errors.AnsibleError( "the playbook: %s does not appear to be a file" % playbook) for playbook in self.playbooks: display("Running playbook: %s" % playbook, color='green', stderr=False) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks( stats, verbose=utils.VERBOSITY) inventory = ansible.inventory.Inventory( self.inventory_path, vault_password=vault_pass) if len(inventory.list_hosts()) == 0: raise errors.AnsibleError("provided hosts list is empty") pb = ansible.playbook.PlayBook( playbook=playbook, module_path=self.options.module_path, inventory=inventory, forks=self.options.forks, remote_user=self.options.remote_user, remote_pass=sshpass, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=self.options.timeout, transport=self.options.connection, sudo=self.options.sudo, sudo_user=self.options.sudo_user, sudo_pass=sudopass, extra_vars=self.extra_vars, check=self.options.check, diff=self.options.diff, su=self.options.su, su_pass=su_pass, su_user=self.options.su_user, vault_password=vault_pass, force_handlers=self.options.force_handlers ) failed_hosts = [] unreachable_hosts = [] try: pb.run() hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: display( " to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" tend=time.time() self.runtime = tend-tstart if len(failed_hosts) > 0: self.statuscode = 2 return if len(unreachable_hosts) > 0: self.statuscode = 3 return self.statuscode = 0 except errors.AnsibleError, e: display("ERROR: %s" % e, color='red') self.statuscode = 1 return
def __call__(self, argv, help): inject_ansible_paths() import ansible.playbook import ansible.constants as C from ansible import errors from ansible import callbacks from ploy_ansible.inventory import Inventory from ansible import utils from ansible.color import ANSIBLE_COLOR, stringc try: from ansible.utils.vault import VaultLib except ImportError: VaultLib = None ansible_version = get_ansible_version() parser = utils.base_parser( constants=C, connect_opts=True, runas_opts=True, subset_opts=True, check_opts=True, diff_opts=True, usage='%s playbook playbook.yml' % self.ctrl.progname ) parser.remove_option('-i') parser.remove_option('-k') if not parser.has_option('--extra-vars'): parser.add_option( '-e', '--extra-vars', dest="extra_vars", action="append", help="set additional variables as key=value or YAML/JSON", default=[]) parser.add_option( '-t', '--tags', dest='tags', default='all', help="only run plays and tasks tagged with these values") parser.add_option( '--skip-tags', dest='skip_tags', help="only run plays and tasks whose tags do not match these values") parser.add_option( '--syntax-check', dest='syntax', action='store_true', help="perform a syntax check on the playbook, but do not execute it") parser.add_option( '--list-tasks', dest='listtasks', action='store_true', help="list all tasks that would be executed") parser.add_option( '--step', dest='step', action='store_true', help="one-step-at-a-time: confirm each task before running") parser.add_option( '--start-at-task', dest='start_at', help="start the playbook at the task matching this name") if ansible_version >= (1, 6): parser.add_option( '--force-handlers', dest='force_handlers', action='store_true', help="run handlers even if a task fails") options, args = parser.parse_args(argv) cbs = callbacks.CliRunnerCallbacks() cbs.options = options if len(args) == 0: parser.print_help(file=sys.stderr) sys.exit(1) if hasattr(options, 'become_ask_pass'): # privlege escalation command line arguments need to be mutually exclusive utils.check_mutually_exclusive_privilege(options, parser) else: # su and sudo command line arguments need to be mutually exclusive if (hasattr(options, 'su') and (options.su or options.su_user or options.ask_su_pass) and (options.sudo or options.sudo_user or options.ask_sudo_pass)): parser.error("Sudo arguments ('--sudo', '--sudo-user', and '--ask-sudo-pass') " "and su arguments ('-su', '--su-user', and '--ask-su-pass') are " "mutually exclusive") if hasattr(options, 'ask_vault_pass') and (options.ask_vault_pass and options.vault_password_file): parser.error("--ask-vault-pass and --vault-password-file are mutually exclusive") def colorize(lead, num, color): """ Print 'lead' = 'num' in 'color' """ if num != 0 and ANSIBLE_COLOR and color is not None: return "%s%s%-15s" % (stringc(lead, color), stringc("=", color), stringc(str(num), color)) else: return "%s=%-4s" % (lead, str(num)) def hostcolor(host, stats, color=True): if ANSIBLE_COLOR and color: if stats['failures'] != 0 or stats['unreachable'] != 0: return "%-37s" % stringc(host, 'red') elif stats['changed'] != 0: return "%-37s" % stringc(host, 'yellow') else: return "%-37s" % stringc(host, 'green') return "%-26s" % host try: patch_connect(self.ctrl) if hasattr(options, 'become_ask_pass'): becomepass = None else: sudopass = None su_pass = None vault_pass = None if not options.listhosts and not options.syntax and not options.listtasks: kw = {} if hasattr(options, 'become_ask_pass'): utils.normalize_become_options(options) become_method = utils.choose_pass_prompt(options) kw['become_ask_pass'] = options.become_ask_pass kw['become_method'] = become_method else: options.ask_sudo_pass = options.ask_sudo_pass or C.DEFAULT_ASK_SUDO_PASS kw['ask_sudo_pass'] = options.ask_sudo_pass if hasattr(options, 'ask_su_pass'): options.ask_su_pass = options.ask_su_pass or C.DEFAULT_ASK_SU_PASS kw['ask_su_pass'] = options.ask_sudo_pass if hasattr(options, 'ask_vault_pass'): options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_PASS kw['ask_vault_pass'] = options.ask_vault_pass passwds = utils.ask_passwords(**kw) if hasattr(options, 'become_ask_pass'): (sshpass, becomepass, vault_pass) = passwds else: if len(passwds) == 2: (sshpass, sudopass) = passwds elif len(passwds) == 3: (sshpass, sudopass, su_pass) = passwds else: (sshpass, sudopass, su_pass, vault_pass) = passwds if VaultLib is not None and vault_pass is None: vault_pass = get_vault_password_source(self.ctrl.config).get() if options.sudo_user or options.ask_sudo_pass: options.sudo = True options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER if hasattr(options, 'su'): if options.su_user or options.ask_su_pass: options.su = True options.su_user = options.su_user or C.DEFAULT_SU_USER if getattr(options, 'vault_password_file', None): this_path = os.path.expanduser(options.vault_password_file) try: f = open(this_path, "rb") tmp_vault_pass = f.read().strip() f.close() except (OSError, IOError), e: raise errors.AnsibleError("Could not read %s: %s" % (this_path, e)) if not options.ask_vault_pass: vault_pass = tmp_vault_pass inventory = Inventory(self.ctrl, vault_password=vault_pass) extra_vars = parse_extra_vars(options.extra_vars, vault_pass=vault_pass) only_tags = options.tags.split(",") skip_tags = options.skip_tags if options.skip_tags is not None: skip_tags = options.skip_tags.split(",") for playbook in args: if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % playbook) # run all playbooks specified on the command line for playbook in args: playbook = os.path.abspath(playbook) # let inventory know which playbooks are using so it can know the basedirs inventory.set_playbook_basedir(os.path.dirname(playbook)) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) if options.step: playbook_cb.step = options.step if options.start_at: playbook_cb.start_at = options.start_at runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) kw = {} if hasattr(options, 'become_ask_pass'): kw['become'] = options.become kw['become_method'] = options.become_method kw['become_pass'] = becomepass kw['become_user'] = options.become_user else: if hasattr(options, 'su'): kw['su'] = options.su kw['su_user'] = options.su_user if hasattr(options, 'su_pass'): kw['su_pass'] = options.su_pass kw['sudo'] = options.sudo kw['sudo_user'] = options.sudo_user kw['sudo_pass'] = sudopass if vault_pass: kw['vault_password'] = vault_pass if hasattr(options, 'force_handlers'): kw['force_handlers'] = options.force_handlers pb = ansible.playbook.PlayBook( playbook=playbook, module_path=options.module_path, inventory=inventory, forks=options.forks, remote_user=options.remote_user, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=options.timeout, transport=options.connection, extra_vars=extra_vars, private_key_file=options.private_key_file, only_tags=only_tags, skip_tags=skip_tags, check=options.check, diff=options.diff, **kw) if options.listhosts or options.listtasks or options.syntax: print '' print 'playbook: %s' % playbook print '' playnum = 0 for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs): playnum += 1 play = ansible.playbook.Play(pb, play_ds, play_basedir) label = play.name hosts = pb.inventory.list_hosts(play.hosts) # Filter all tasks by given tags if pb.only_tags != 'all': if options.subset and not hosts: continue matched_tags, unmatched_tags = play.compare_tags(pb.only_tags) # Remove skipped tasks matched_tags = matched_tags - set(pb.skip_tags) unmatched_tags.discard('all') unknown_tags = ((set(pb.only_tags) | set(pb.skip_tags)) - (matched_tags | unmatched_tags)) if unknown_tags: continue if options.listhosts: print ' play #%d (%s): host count=%d' % (playnum, label, len(hosts)) for host in hosts: print ' %s' % host if options.listtasks: print ' play #%d (%s):' % (playnum, label) for task in play.tasks(): _only_tags = set(task.tags).intersection(pb.only_tags) _skip_tags = set(task.tags).intersection(pb.skip_tags) if (_only_tags and not _skip_tags): if getattr(task, 'name', None) is not None: # meta tasks have no names print ' %s' % task.name print '' continue if options.syntax: # if we've not exited by now then we are fine. print 'Playbook Syntax is fine' sys.exit(0) failed_hosts = [] unreachable_hosts = [] pb.run() hosts = sorted(pb.stats.processed.keys()) callbacks.display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: callbacks.display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) callbacks.display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) callbacks.display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" if len(failed_hosts) > 0: sys.exit(2) if len(unreachable_hosts) > 0: sys.exit(3)
def on_setup(self): display(banner("GATHERING FACTS"), task_id=self.task_id) call_callback_module('playbook_on_setup')
def execute_ansible(playbook, settings): hosts = LOCAL_HOSTS if playbook == PROVISION else HOSTS_FILE playbook += ".yml" path_to_playbook = os.path.join(PATH_TO_PLAYBOOKS, playbook) # From ansible-playbook: stats = ansible.callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=VERBOSITY) # if options.step: # # execute step by step # playbook_cb.step = options.step # if options.start_at: # # start execution at a specific task # playbook_cb.start_at = options.start_at runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) pb = ansible.playbook.PlayBook( # From ansible-playbook: playbook=path_to_playbook, inventory=ansible.inventory.Inventory(hosts), extra_vars=utils.parse_yaml_from_file(settings), callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, ) failed_hosts = [] unreachable_hosts = [] pb.run() hosts = sorted(pb.stats.processed.keys()) callbacks.display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: callbacks.display( " to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) callbacks.display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) callbacks.display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" if len(failed_hosts) > 0: return 2 if len(unreachable_hosts) > 0: return 3
def main(args): ''' run ansible-playbook operations ''' ## truiz: here I add options that will become parameters in the function ## truiz: extra vars is dict with the vars and values extra_vars = {'host': 'testing', 'vars_file': 'the_vars.yml'} print extra_vars ## truiz: this is just a list of playbooks playbooks = ['ansible/the_work.yml'] ## truiz: The file with hosts and their vars inventory_file = 'ansible/inventory' ## truiz: this could be an usefull parameter timeout = 10 # create parser for CLI options parser = utils.base_parser( constants=C, usage = "%prog playbook.yml", connect_opts=True, runas_opts=True, subset_opts=True, check_opts=True, diff_opts=True ) parser.add_option('--vault-password', dest="vault_password", help="password for vault encrypted files") parser.add_option('--syntax-check', dest='syntax', action='store_true', help="perform a syntax check on the playbook, but do not execute it") parser.add_option('--list-tasks', dest='listtasks', action='store_true', help="list all tasks that would be executed") parser.add_option('--list-tags', dest='listtags', action='store_true', help="list all available tags") parser.add_option('--start-at-task', dest='start_at', help="start the playbook at the task matching this name") parser.add_option('--force-handlers', dest='force_handlers', default=C.DEFAULT_FORCE_HANDLERS, action='store_true', help="run handlers even if a task fails") parser.add_option('--flush-cache', dest='flush_cache', action='store_true', help="clear the fact cache") options, args = parser.parse_args(args) if len(args) == 0: parser.print_help(file=sys.stderr) return 1 # privlege escalation command line arguments need to be mutually exclusive # utils.check_mutually_exclusive_privilege(options, parser) # if (options.ask_vault_pass and options.vault_password_file): # parser.error("--ask-vault-pass and --vault-password-file are mutually exclusive") sshpass = None becomepass = None vault_pass = None # options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_PASS # if options.listhosts or options.syntax or options.listtasks or options.listtags: # (_, _, vault_pass) = utils.ask_passwords(ask_vault_pass=options.ask_vault_pass) # else: # options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS # # Never ask for an SSH password when we run with local connection # if options.connection == "local": # options.ask_pass = False # # set pe options # utils.normalize_become_options(options) # prompt_method = utils.choose_pass_prompt(options) # (sshpass, becomepass, vault_pass) = utils.ask_passwords(ask_pass=options.ask_pass, # become_ask_pass=options.become_ask_pass, # ask_vault_pass=options.ask_vault_pass, # become_method=prompt_method) # read vault_pass from a file # if not options.ask_vault_pass and options.vault_password_file: # vault_pass = utils.read_vault_file(options.vault_password_file) for playbook in playbooks: print playbook if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % playbook) if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)): raise errors.AnsibleError("the playbook: %s does not appear to be a file" % playbook) ## truiz: is better to pass the inventory file inventory = ansible.inventory.Inventory(inventory_file, vault_password=vault_pass) print options.inventory print inventory # Note: slightly wrong, this is written so that implicit localhost # (which is not returned in list_hosts()) is taken into account for # warning if inventory is empty. But it can't be taken into account for # checking if limit doesn't match any hosts. Instead we don't worry about # limit if only implicit localhost was in inventory to start with. # # Fix this in v2 no_hosts = False if len(inventory.list_hosts()) == 0: # Empty inventory utils.warning("provided hosts list is empty, only localhost is available") no_hosts = True #print options.subset #inventory.subset(options.subset) if len(inventory.list_hosts()) == 0 and no_hosts is False: # Invalid limit raise errors.AnsibleError("Specified --limit does not match any hosts") print options.become print options.become_user print options.remote_user print options.timeout print becomepass for playbook in playbooks: stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) print runner_cb pb = ansible.playbook.PlayBook( playbook=playbook, # module_path=options.module_path, inventory=inventory, # forks=options.forks, # remote_user=options.remote_user, # remote_pass=sshpass, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=timeout, # transport=options.connection, #become=options.become, become_method='sudo', become_user=options.become_user, # become_pass=becomepass, extra_vars=extra_vars, private_key_file=options.private_key_file, # only_tags=only_tags, # skip_tags=skip_tags, check=options.check, diff=options.diff, # vault_password=vault_pass, force_handlers=options.force_handlers, ) # if options.flush_cache: # display(callbacks.banner("FLUSHING FACT CACHE")) # pb.SETUP_CACHE.flush() # if options.listhosts or options.listtasks or options.syntax or options.listtags: # print '' # print 'playbook: %s' % playbook # print '' # playnum = 0 # for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs): # playnum += 1 # play = ansible.playbook.Play(pb, play_ds, play_basedir, # vault_password=pb.vault_password) # label = play.name # hosts = pb.inventory.list_hosts(play.hosts) # if options.listhosts: # print ' play #%d (%s): host count=%d' % (playnum, label, len(hosts)) # for host in hosts: # print ' %s' % host # if options.listtags or options.listtasks: # print ' play #%d (%s):\tTAGS: [%s]' % (playnum, label,','.join(sorted(set(play.tags)))) # if options.listtags: # tags = [] # for task in pb.tasks_to_run_in_play(play): # tags.extend(task.tags) # print ' TASK TAGS: [%s]' % (', '.join(sorted(set(tags).difference(['untagged'])))) # if options.listtasks: # for task in pb.tasks_to_run_in_play(play): # if getattr(task, 'name', None) is not None: # # meta tasks have no names # print ' %s\tTAGS: [%s]' % (task.name, ', '.join(sorted(set(task.tags).difference(['untagged'])))) # if options.listhosts or options.listtasks or options.listtags: # print '' # continue # if options.syntax: # # if we've not exited by now then we are fine. # print 'Playbook Syntax is fine' # return 0 failed_hosts = [] unreachable_hosts = [] try: print "Before run" res = pb.run() print "After run" ## truiz: returns a resume of all work done print res hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if C.RETRY_FILES_ENABLED and len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" if len(failed_hosts) > 0: return 2 if len(unreachable_hosts) > 0: return 3 except errors.AnsibleError, e: display("ERROR: %s" % e, color='red') return 1
def job(ymlfile,adict,rsfile): #data_dict playbook_path = get_playbook(ymlfile) # 设置playbook目录 inventory = get_inventory(adict )#,data_dict) inventory.set_playbook_basedir(os.path.dirname(playbook_path)) ''' print 'remote_user:'******'str'> print 'remote_pass:'******'str'> print 'sudo:',type(options.sudo),repr(options.sudo) #是否使用sudo <type 'bool'> print 'sudo_user:'******'str'> print 'sudo_pass:'******'NoneType'> print 'su:',type(options.su),repr(options.su) #是否使用su <type 'bool'> print 'su_pass:'******'NoneType'> print 'su_user:'******'str'> ''' pb = YunweiPlayBook( playbook=playbook_path, inventory=inventory, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, sudo=get_sudo(), #yunwei_task=yunwei_task, rsfile=rsfile, # remote_user='******', # remote_pass='******', # sudo_user='******', # sudo_pass=None ) failed_hosts = [] unreachable_hosts = [] # 运行pb,然后使用返回的数据 # try: # pb.run()直接写结果到console ansible_res=pb.run() # print ansible_res hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts # if len(retries) > 0: # filename = pb.generate_retry_inventory(retries) # if filename: # display(" to retry, use: --limit @%s\n" % filename) # raise RuntimeError('ansible error') for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" # if len(failed_hosts) > 0: # return ansible_res # if len(unreachable_hosts) > 0: # return ansible_res # except errors.AnsibleError, e: # # errinfo # display("ERROR: %s" % e, color='red') # return ansible_res # else: return ansible_res
def execute_ansible(playbook, args): ansible.utils.VERBOSITY = args.verbose hosts = args.inventory or (LOCAL_HOSTS if playbook == PROVISION else HOSTS_FILE) playbook = playbook.replace("-", "_") + ".yml" path_to_playbook = path.join(core.PATH_TO_PLAYBOOKS, playbook) # From ansible-playbook: stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=ansible.utils.VERBOSITY) # if options.step: # # execute step by step # playbook_cb.step = options.step # if options.start_at: # # start execution at a specific task # playbook_cb.start_at = options.start_at runner_cb = callbacks.PlaybookRunnerCallbacks( stats, verbose=ansible.utils.VERBOSITY ) pb = ansible.playbook.PlayBook( # From ansible-playbook: playbook=path_to_playbook, inventory=ansible.inventory.Inventory(hosts), extra_vars=ansible.utils.parse_yaml_from_file(args.settings), callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, ) failed_hosts = [] unreachable_hosts = [] if args.verbose: ansible_cmd = ["ansible-playbook"] ansible_cmd.append("-" + "v" * args.verbose) ansible_cmd.append("-i " + hosts) ansible_cmd.append("--extra-vars @" + args.settings) ansible_cmd.append(path_to_playbook) print "ANSIBLE COMMAND: " + " ".join(ansible_cmd) pb.run() hosts = sorted(pb.stats.processed.keys()) callbacks.display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: callbacks.display( " to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) callbacks.display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) callbacks.display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" if len(failed_hosts) > 0: raise Exception(2) if len(unreachable_hosts) > 0: raise Exception(3)
def on_play_start(self, name): display(banner("PLAY [%s]" % name), task_id=self.task_id) call_callback_module('playbook_on_play_start', name)
def deploy(args): # create parser for CLI options parser = utils.base_parser(constants=C, usage="%prog playbook.yml", connect_opts=True, runas_opts=True, subset_opts=True, check_opts=True, diff_opts=True) parser.add_option( '-e', '--extra-vars', dest="extra_vars", action="append", help="set additional variables as key=value or YAML/JSON", default=[]) options, args = parser.parse_args(args) if len(args) == 0: parser.print_help(file=sys.stderr) return 1 inventory = ansible.inventory.Inventory(options.inventory) inventory.subset(options.subset) print "number of hosts: %s" % str(len(inventory.list_hosts())) if len(inventory.list_hosts()) == 0: raise errors.AnsibleError("provided hosts list is empty") sshpass = None sudopass = None su_pass = None vault_pass = None options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS if options.connection == "local": options.ask_pass = False options.ask_sudo_pass = options.ask_sudo_pass or C.DEFAULT_ASK_SUDO_PASS (sshpass, sudopass, su_pass, vault_pass) = \ utils.ask_passwords(ask_pass=options.ask_pass, ask_sudo_pass=options.ask_sudo_pass, ask_su_pass=options.ask_su_pass, ask_vault_pass=options.ask_vault_pass) options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER options.su_user = options.su_user or C.DEFAULT_SU_USER extra_vars = {} for extra_vars_opt in options.extra_vars: if extra_vars_opt.startswith("@"): # Argument is a YAML file (JSON is a subset of YAML) extra_vars = utils.combine_vars( extra_vars, utils.parse_yaml_from_file(extra_vars_opt[1:])) elif extra_vars_opt and extra_vars_opt[0] in '[{': # Arguments as YAML extra_vars = utils.combine_vars(extra_vars, utils.parse_yaml(extra_vars_opt)) else: # Arguments as Key-value extra_vars = utils.combine_vars(extra_vars, utils.parse_kv(extra_vars_opt)) playbook = underwear.__path__[0] + '/django-stack.yml' inventory.set_playbook_basedir(os.path.dirname(playbook)) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % \ playbook) if not (os.path.isfile(playbook) or \ stat.S_ISFIFO(os.stat(playbook).st_mode)): raise errors.AnsibleError( \ "the playbook: %s does not appear to be a file" % playbook) pb = ansible.playbook.PlayBook(playbook=playbook, module_path=options.module_path, inventory=inventory, forks=options.forks, remote_user=options.remote_user, remote_pass=sshpass, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=options.timeout, transport=options.connection, sudo=options.sudo, sudo_user=options.sudo_user, sudo_pass=sudopass, extra_vars=extra_vars, private_key_file=options.private_key_file, only_tags=[ 'all', ], skip_tags=None, check=options.check, diff=options.diff) failed_hosts = [] unreachable_hosts = [] try: pb.run() hosts = sorted(pb.stats.processed.keys()) print hosts display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % (hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True) display("%s : %s %s %s %s" % (hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True) print "" if len(failed_hosts) > 0: return 2 if len(unreachable_hosts) > 0: return 3 except errors.AnsibleError, e: display("ERROR: %s" % e, color='red') return 1
def deploy(args): # create parser for CLI options parser = utils.base_parser( constants=C, usage = "%prog playbook.yml", connect_opts=True, runas_opts=True, subset_opts=True, check_opts=True, diff_opts=True ) parser.add_option('-e', '--extra-vars', dest="extra_vars", action="append", help="set additional variables as key=value or YAML/JSON", default=[]) options, args = parser.parse_args(args) if len(args) == 0: parser.print_help(file=sys.stderr) return 1 inventory = ansible.inventory.Inventory(options.inventory) inventory.subset(options.subset) print "number of hosts: %s" % str(len(inventory.list_hosts())) if len(inventory.list_hosts()) == 0: raise errors.AnsibleError("provided hosts list is empty") sshpass = None sudopass = None su_pass = None vault_pass = None options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS if options.connection == "local": options.ask_pass = False options.ask_sudo_pass = options.ask_sudo_pass or C.DEFAULT_ASK_SUDO_PASS (sshpass, sudopass, su_pass, vault_pass) = \ utils.ask_passwords(ask_pass=options.ask_pass, ask_sudo_pass=options.ask_sudo_pass, ask_su_pass=options.ask_su_pass, ask_vault_pass=options.ask_vault_pass) options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER options.su_user = options.su_user or C.DEFAULT_SU_USER extra_vars={} for extra_vars_opt in options.extra_vars: if extra_vars_opt.startswith("@"): # Argument is a YAML file (JSON is a subset of YAML) extra_vars = utils.combine_vars(extra_vars, utils.parse_yaml_from_file(extra_vars_opt[1:])) elif extra_vars_opt and extra_vars_opt[0] in '[{': # Arguments as YAML extra_vars = utils.combine_vars(extra_vars, utils.parse_yaml(extra_vars_opt)) else: # Arguments as Key-value extra_vars = utils.combine_vars(extra_vars, utils.parse_kv(extra_vars_opt)) playbook = underwear.__path__[0] + '/django-stack.yml' inventory.set_playbook_basedir(os.path.dirname(playbook)) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % \ playbook) if not (os.path.isfile(playbook) or \ stat.S_ISFIFO(os.stat(playbook).st_mode)): raise errors.AnsibleError( \ "the playbook: %s does not appear to be a file" % playbook) pb = ansible.playbook.PlayBook( playbook=playbook, module_path=options.module_path, inventory=inventory, forks=options.forks, remote_user=options.remote_user, remote_pass=sshpass, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=options.timeout, transport=options.connection, sudo=options.sudo, sudo_user=options.sudo_user, sudo_pass=sudopass, extra_vars=extra_vars, private_key_file=options.private_key_file, only_tags=['all',], skip_tags=None, check=options.check, diff=options.diff ) failed_hosts = [] unreachable_hosts = [] try: pb.run() hosts = sorted(pb.stats.processed.keys()) print hosts display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" if len(failed_hosts) > 0: return 2 if len(unreachable_hosts) > 0: return 3 except errors.AnsibleError, e: display("ERROR: %s" % e, color='red') return 1
def run(self): """ This is a modified version of the function used within ansible-playbook. """ tstart = time.time() # get the absolute path for the playbooks self.playbooks = [ "{}/playbooks/{}".format(config["install_path"], pb) for pb in self.playbooks ] # Ansible defaults carried over from `ansible-playbook`. sshpass = None sudopass = None su_pass = None vault_pass = None for playbook in self.playbooks: if not os.path.exists(playbook): raise errors.AnsibleError( "the playbook: %s could not be found" % playbook) if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)): raise errors.AnsibleError( "the playbook: %s does not appear to be a file" % playbook) for playbook in self.playbooks: display("Running playbook: %s" % playbook, color="green", stderr=False) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks( stats, verbose=utils.VERBOSITY) inventory = ansible.inventory.Inventory(self.inventory_path, vault_password=vault_pass) if len(inventory.list_hosts()) == 0: raise errors.AnsibleError("provided hosts list is empty") pb = ansible.playbook.PlayBook( playbook=playbook, module_path=self.options.module_path, inventory=inventory, forks=self.options.forks, remote_user=self.options.remote_user, remote_pass=sshpass, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=self.options.timeout, transport=self.options.connection, sudo=self.options.sudo, sudo_user=self.options.sudo_user, sudo_pass=sudopass, extra_vars=self.extra_vars, check=self.options.check, diff=self.options.diff, su=self.options.su, su_pass=su_pass, su_user=self.options.su_user, vault_password=vault_pass, force_handlers=self.options.force_handlers) failed_hosts = [] unreachable_hosts = [] try: pb.run() hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t["failures"] > 0: failed_hosts.append(h) if t["unreachable"] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % (hostcolor(h, t), colorize("ok", t["ok"], "green"), colorize("changed", t["changed"], "yellow"), colorize("unreachable", t["unreachable"], "red"), colorize("failed", t["failures"], "red")), screen_only=True) display( "%s : %s %s %s %s" % (hostcolor(h, t, False), colorize("ok", t["ok"], None), colorize("changed", t["changed"], None), colorize("unreachable", t["unreachable"], None), colorize("failed", t["failures"], None)), log_only=True) print "" tend = time.time() self.runtime = tend - tstart if len(failed_hosts) > 0: self.statuscode = 2 return if len(unreachable_hosts) > 0: self.statuscode = 3 return self.statuscode = 0 except errors.AnsibleError, e: display("ERROR: %s" % e, color="red") self.statuscode = 1 return
def on_setup(self): display(banner("GATHERING FACTS"), self.sqs_response_queue, self.sqs_request_message)
def execute_ansible(playbook, args): ansible.utils.VERBOSITY = args.verbose hosts = args.inventory or (LOCAL_HOSTS if playbook == PROVISION else HOSTS_FILE) playbook = playbook.replace("-", "_") + ".yml" path_to_playbook = path.join(core.PATH_TO_PLAYBOOKS, playbook) # From ansible-playbook: stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=ansible.utils.VERBOSITY) # if options.step: # # execute step by step # playbook_cb.step = options.step # if options.start_at: # # start execution at a specific task # playbook_cb.start_at = options.start_at runner_cb = callbacks.PlaybookRunnerCallbacks( stats, verbose=ansible.utils.VERBOSITY) pb = ansible.playbook.PlayBook( # From ansible-playbook: playbook=path_to_playbook, inventory=ansible.inventory.Inventory(hosts), extra_vars=ansible.utils.parse_yaml_from_file(args.settings), callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, ) failed_hosts = [] unreachable_hosts = [] if args.verbose: ansible_cmd = ["ansible-playbook"] ansible_cmd.append("-" + "v" * args.verbose) ansible_cmd.append("-i " + hosts) ansible_cmd.append("--extra-vars @" + args.settings) ansible_cmd.append(path_to_playbook) print "ANSIBLE COMMAND: " + " ".join(ansible_cmd) pb.run() hosts = sorted(pb.stats.processed.keys()) callbacks.display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: callbacks.display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) callbacks.display("%s : %s %s %s %s" % (hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True) callbacks.display( "%s : %s %s %s %s" % (hostcolor(h, t, False), colorize( 'ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True) print "" if len(failed_hosts) > 0: raise Exception(2) if len(unreachable_hosts) > 0: raise Exception(3)
def _run_playbook(directory, playbook, remote_user): # import late so that the os.environ[] line above gets # called before importing the main ansible modules. import ansible.playbook from ansible import utils from ansible import errors from ansible import callbacks from ansible.callbacks import display # add the local libraries to the global python path. local_module_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) os.environ['PYTHONPATH'] = local_module_path playbook = os.path.join(directory, playbook) if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % playbook) if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)): raise errors.AnsibleError("the playbook: %s does not appear to be a file" % playbook) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) hosts = os.path.join(directory, 'inventory', 'hosts') inventory = ansible.inventory.Inventory(host_list=hosts) pb = ansible.playbook.PlayBook(forks=1, playbook=playbook, inventory=inventory, remote_user=remote_user, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats ) failed_hosts = [] unreachable_hosts = [] try: pb.run() hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % ( "%-26s" % h, "%s=%-4s" % ('ok', str(t['ok'])), "%s=%-4s" % ('changed', str(t['changed'])), "%s=%-4s" % ('unreachable', str(t['unreachable'])), "%s=%-4s" % ('failed', str(t['failures']))) ) if len(failed_hosts) > 0: return 2 if len(unreachable_hosts) > 0: return 3 except errors.AnsibleError, e: display(u"ERROR: %s" % utils.unicode.to_unicode(e, nonstring='simplerepr')) return 1
def __call__(self, argv, help): import ansible.playbook import ansible.constants as C from ansible import errors from ansible import callbacks from mr.awsome.ansible.inventory import Inventory from ansible import utils from ansible.color import ANSIBLE_COLOR, stringc parser = utils.base_parser( constants=C, connect_opts=True, runas_opts=True, subset_opts=True, check_opts=True, diff_opts=True, usage='aws playbook playbook.yml' ) parser.remove_option('-i') parser.remove_option('-k') parser.add_option('-e', '--extra-vars', dest="extra_vars", action="append", help="set additional variables as key=value or YAML/JSON", default=[]) parser.add_option('-t', '--tags', dest='tags', default='all', help="only run plays and tasks tagged with these values") parser.add_option('--skip-tags', dest='skip_tags', help="only run plays and tasks whose tags do not match these values") parser.add_option('--syntax-check', dest='syntax', action='store_true', help="perform a syntax check on the playbook, but do not execute it") parser.add_option('--list-tasks', dest='listtasks', action='store_true', help="list all tasks that would be executed") parser.add_option('--step', dest='step', action='store_true', help="one-step-at-a-time: confirm each task before running") parser.add_option('--start-at-task', dest='start_at', help="start the playbook at the task matching this name") options, args = parser.parse_args(argv) cbs = callbacks.CliRunnerCallbacks() cbs.options = options if len(args) == 0: parser.print_help(file=sys.stderr) sys.exit(1) def colorize(lead, num, color): """ Print 'lead' = 'num' in 'color' """ if num != 0 and ANSIBLE_COLOR and color is not None: return "%s%s%-15s" % (stringc(lead, color), stringc("=", color), stringc(str(num), color)) else: return "%s=%-4s" % (lead, str(num)) def hostcolor(host, stats, color=True): if ANSIBLE_COLOR and color: if stats['failures'] != 0 or stats['unreachable'] != 0: return "%-37s" % stringc(host, 'red') elif stats['changed'] != 0: return "%-37s" % stringc(host, 'yellow') else: return "%-37s" % stringc(host, 'green') return "%-26s" % host try: patch_connect(self.aws) inventory = Inventory(self.aws) sudopass = None if not options.listhosts and not options.syntax and not options.listtasks: options.ask_sudo_pass = options.ask_sudo_pass or C.DEFAULT_ASK_SUDO_PASS sudopass = utils.ask_passwords(ask_sudo_pass=options.ask_sudo_pass) if options.sudo_user or options.ask_sudo_pass: options.sudo = True options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER extra_vars = {} for extra_vars_opt in options.extra_vars: if extra_vars_opt.startswith("@"): # Argument is a YAML file (JSON is a subset of YAML) extra_vars = utils.combine_vars(extra_vars, utils.parse_yaml_from_file(extra_vars_opt[1:])) elif extra_vars_opt and extra_vars_opt[0] in '[{': # Arguments as YAML extra_vars = utils.combine_vars(extra_vars, utils.parse_yaml(extra_vars_opt)) else: # Arguments as Key-value extra_vars = utils.combine_vars(extra_vars, utils.parse_kv(extra_vars_opt)) only_tags = options.tags.split(",") skip_tags = options.skip_tags if options.skip_tags is not None: skip_tags = options.skip_tags.split(",") for playbook in args: if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % playbook) # run all playbooks specified on the command line for playbook in args: # let inventory know which playbooks are using so it can know the basedirs inventory.set_playbook_basedir(os.path.dirname(playbook)) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) if options.step: playbook_cb.step = options.step if options.start_at: playbook_cb.start_at = options.start_at runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) pb = ansible.playbook.PlayBook( playbook=playbook, module_path=options.module_path, inventory=inventory, forks=options.forks, remote_user=options.remote_user, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=options.timeout, transport=options.connection, sudo=options.sudo, sudo_user=options.sudo_user, sudo_pass=sudopass, extra_vars=extra_vars, private_key_file=options.private_key_file, only_tags=only_tags, skip_tags=skip_tags, check=options.check, diff=options.diff ) if options.listhosts or options.listtasks or options.syntax: print '' print 'playbook: %s' % playbook print '' playnum = 0 for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs): playnum += 1 play = ansible.playbook.Play(pb, play_ds, play_basedir) label = play.name if options.listhosts: hosts = pb.inventory.list_hosts(play.hosts) print ' play #%d (%s): host count=%d' % (playnum, label, len(hosts)) for host in hosts: print ' %s' % host if options.listtasks: matched_tags, unmatched_tags = play.compare_tags(pb.only_tags) # Remove skipped tasks matched_tags = matched_tags - set(pb.skip_tags) unmatched_tags.discard('all') unknown_tags = ((set(pb.only_tags) | set(pb.skip_tags)) - (matched_tags | unmatched_tags)) if unknown_tags: continue print ' play #%d (%s):' % (playnum, label) for task in play.tasks(): if (set(task.tags).intersection(pb.only_tags) and not set(task.tags).intersection(pb.skip_tags)): if getattr(task, 'name', None) is not None: # meta tasks have no names print ' %s' % task.name print '' continue if options.syntax: # if we've not exited by now then we are fine. print 'Playbook Syntax is fine' sys.exit(0) failed_hosts = [] unreachable_hosts = [] pb.run() hosts = sorted(pb.stats.processed.keys()) callbacks.display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: callbacks.display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) callbacks.display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) callbacks.display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" if len(failed_hosts) > 0: sys.exit(2) if len(unreachable_hosts) > 0: sys.exit(3) except errors.AnsibleError, e: callbacks.display("ERROR: %s" % e, color='red', stderr=True) sys.exit(1)
def main(args): ''' run ansible-playbook operations ''' ## truiz: here I add options that will become parameters in the function ## truiz: extra vars is dict with the vars and values extra_vars = {'host': 'testing', 'vars_file': 'the_vars.yml'} print extra_vars ## truiz: this is just a list of playbooks playbooks = ['ansible/the_work.yml'] ## truiz: The file with hosts and their vars inventory_file = 'ansible/inventory' ## truiz: this could be an usefull parameter timeout = 10 # create parser for CLI options parser = utils.base_parser(constants=C, usage="%prog playbook.yml", connect_opts=True, runas_opts=True, subset_opts=True, check_opts=True, diff_opts=True) parser.add_option('--vault-password', dest="vault_password", help="password for vault encrypted files") parser.add_option( '--syntax-check', dest='syntax', action='store_true', help="perform a syntax check on the playbook, but do not execute it") parser.add_option('--list-tasks', dest='listtasks', action='store_true', help="list all tasks that would be executed") parser.add_option('--list-tags', dest='listtags', action='store_true', help="list all available tags") parser.add_option('--start-at-task', dest='start_at', help="start the playbook at the task matching this name") parser.add_option('--force-handlers', dest='force_handlers', default=C.DEFAULT_FORCE_HANDLERS, action='store_true', help="run handlers even if a task fails") parser.add_option('--flush-cache', dest='flush_cache', action='store_true', help="clear the fact cache") options, args = parser.parse_args(args) if len(args) == 0: parser.print_help(file=sys.stderr) return 1 # privlege escalation command line arguments need to be mutually exclusive # utils.check_mutually_exclusive_privilege(options, parser) # if (options.ask_vault_pass and options.vault_password_file): # parser.error("--ask-vault-pass and --vault-password-file are mutually exclusive") sshpass = None becomepass = None vault_pass = None # options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_PASS # if options.listhosts or options.syntax or options.listtasks or options.listtags: # (_, _, vault_pass) = utils.ask_passwords(ask_vault_pass=options.ask_vault_pass) # else: # options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS # # Never ask for an SSH password when we run with local connection # if options.connection == "local": # options.ask_pass = False # # set pe options # utils.normalize_become_options(options) # prompt_method = utils.choose_pass_prompt(options) # (sshpass, becomepass, vault_pass) = utils.ask_passwords(ask_pass=options.ask_pass, # become_ask_pass=options.become_ask_pass, # ask_vault_pass=options.ask_vault_pass, # become_method=prompt_method) # read vault_pass from a file # if not options.ask_vault_pass and options.vault_password_file: # vault_pass = utils.read_vault_file(options.vault_password_file) for playbook in playbooks: print playbook if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % playbook) if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)): raise errors.AnsibleError( "the playbook: %s does not appear to be a file" % playbook) ## truiz: is better to pass the inventory file inventory = ansible.inventory.Inventory(inventory_file, vault_password=vault_pass) print options.inventory print inventory # Note: slightly wrong, this is written so that implicit localhost # (which is not returned in list_hosts()) is taken into account for # warning if inventory is empty. But it can't be taken into account for # checking if limit doesn't match any hosts. Instead we don't worry about # limit if only implicit localhost was in inventory to start with. # # Fix this in v2 no_hosts = False if len(inventory.list_hosts()) == 0: # Empty inventory utils.warning( "provided hosts list is empty, only localhost is available") no_hosts = True #print options.subset #inventory.subset(options.subset) if len(inventory.list_hosts()) == 0 and no_hosts is False: # Invalid limit raise errors.AnsibleError("Specified --limit does not match any hosts") print options.become print options.become_user print options.remote_user print options.timeout print becomepass for playbook in playbooks: stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) print runner_cb pb = ansible.playbook.PlayBook( playbook=playbook, # module_path=options.module_path, inventory=inventory, # forks=options.forks, # remote_user=options.remote_user, # remote_pass=sshpass, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=timeout, # transport=options.connection, #become=options.become, become_method='sudo', become_user=options.become_user, # become_pass=becomepass, extra_vars=extra_vars, private_key_file=options.private_key_file, # only_tags=only_tags, # skip_tags=skip_tags, check=options.check, diff=options.diff, # vault_password=vault_pass, force_handlers=options.force_handlers, ) # if options.flush_cache: # display(callbacks.banner("FLUSHING FACT CACHE")) # pb.SETUP_CACHE.flush() # if options.listhosts or options.listtasks or options.syntax or options.listtags: # print '' # print 'playbook: %s' % playbook # print '' # playnum = 0 # for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs): # playnum += 1 # play = ansible.playbook.Play(pb, play_ds, play_basedir, # vault_password=pb.vault_password) # label = play.name # hosts = pb.inventory.list_hosts(play.hosts) # if options.listhosts: # print ' play #%d (%s): host count=%d' % (playnum, label, len(hosts)) # for host in hosts: # print ' %s' % host # if options.listtags or options.listtasks: # print ' play #%d (%s):\tTAGS: [%s]' % (playnum, label,','.join(sorted(set(play.tags)))) # if options.listtags: # tags = [] # for task in pb.tasks_to_run_in_play(play): # tags.extend(task.tags) # print ' TASK TAGS: [%s]' % (', '.join(sorted(set(tags).difference(['untagged'])))) # if options.listtasks: # for task in pb.tasks_to_run_in_play(play): # if getattr(task, 'name', None) is not None: # # meta tasks have no names # print ' %s\tTAGS: [%s]' % (task.name, ', '.join(sorted(set(task.tags).difference(['untagged'])))) # if options.listhosts or options.listtasks or options.listtags: # print '' # continue # if options.syntax: # # if we've not exited by now then we are fine. # print 'Playbook Syntax is fine' # return 0 failed_hosts = [] unreachable_hosts = [] try: print "Before run" res = pb.run() print "After run" ## truiz: returns a resume of all work done print res hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if C.RETRY_FILES_ENABLED and len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % (hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True) display("%s : %s %s %s %s" % (hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True) print "" if len(failed_hosts) > 0: return 2 if len(unreachable_hosts) > 0: return 3 except errors.AnsibleError, e: display("ERROR: %s" % e, color='red') return 1
def ansible_playbook(playbook, args, inventory="local_hosts"): """ Wraps the 'ansible-playbook' CLI. :playbook: the playbook to invoke :args: all arguments passed for the playbook :inventory: the inventory file to use, default: local_hosts """ if not playbook: LOG.error("No playbook to execute (%s)" % PLAYBOOKS) # TODO: remove all IRexceptions and change to regular Python exceptions raise exceptions.IRFileNotFoundException print "Executing Playbook: %s" % playbook ansible.utils.VERBOSITY = args['verbose'] path_to_playbook = path.join(CONF.get('defaults', 'playbooks'), playbook) # From ansible-playbook: stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=ansible.utils.VERBOSITY) if args.get('step'): # execute step by step playbook_cb.step = args.step if args.get('start_at'): # start execution at a specific task playbook_cb.start_at = args.start_at runner_cb = callbacks.PlaybookRunnerCallbacks( stats, verbose=ansible.utils.VERBOSITY) module_path = CONF.get('defaults', 'modules') pb = ansible.playbook.PlayBook( # From ansible-playbook: playbook=path_to_playbook, inventory=ansible.inventory.Inventory(inventory), extra_vars=args['settings'], callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, module_path=module_path) failed_hosts = [] unreachable_hosts = [] if args['verbose']: ansible_cmd = ["ansible-playbook"] if module_path: ansible_cmd.append("-M " + module_path) ansible_cmd.append("-" + "v" * args['verbose']) ansible_cmd.append("-i " + inventory) extra_vars = args['output'] or "<path to settings file>" ansible_cmd.append("--extra-vars @" + extra_vars) ansible_cmd.append(path_to_playbook) print "ANSIBLE COMMAND: " + " ".join(ansible_cmd) pb.run() hosts = sorted(pb.stats.processed.keys()) callbacks.display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for host in hosts: status = pb.stats.summarize(host) if status['failures'] > 0: failed_hosts.append(host) if status['unreachable'] > 0: unreachable_hosts.append(host) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: callbacks.display(" to retry, use: --limit @%s\n" % filename) for host in hosts: status = pb.stats.summarize(host) callbacks.display( "%s : %s %s %s %s" % (hostcolor(host, status), colorize('ok', status['ok'], 'green'), colorize('changed', status['changed'], 'yellow'), colorize('unreachable', status['unreachable'], 'red'), colorize('failed', status['failures'], 'red')), screen_only=True) callbacks.display( "%s : %s %s %s %s" % (hostcolor(host, status, False), colorize( 'ok', status['ok'], None), colorize('changed', status['changed'], None), colorize('unreachable', status['unreachable'], None), colorize('failed', status['failures'], None)), log_only=True) print "" if len(failed_hosts) > 0: raise exceptions.IRPlaybookFailedException( playbook, "Failed hosts: %s" % failed_hosts) if len(unreachable_hosts) > 0: raise exceptions.IRPlaybookFailedException( playbook, "Unreachable hosts: %s" % unreachable_hosts)