def test_playbook_hash_merge(self): # save default hash behavior so we can restore it in the end of the test saved_hash_behavior = C.DEFAULT_HASH_BEHAVIOUR C.DEFAULT_HASH_BEHAVIOUR = "merge" test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'test_hash_behavior', 'playbook.yml'), host_list='test/ansible_hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks ) playbook.run() filename = '/tmp/ansible_test_messages.out' expected_lines = [ "goodbye: Goodbye World!", "hello: Hello World!" ] self._compare_file_output(filename, expected_lines) filename = '/tmp/ansible_test_role_messages.out' expected_lines = [ "goodbye: Goodbye World!", "hello: Hello World!", "inside_a_role: Indeed!" ] self._compare_file_output(filename, expected_lines) # restore default hash behavior C.DEFAULT_HASH_BEHAVIOUR = saved_hash_behavior
def test_playbook_hash_merge(self): # save default hash behavior so we can restore it in the end of the test saved_hash_behavior = C.DEFAULT_HASH_BEHAVIOUR C.DEFAULT_HASH_BEHAVIOUR = "merge" test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'test_hash_behavior', 'playbook.yml'), host_list='test/ansible_hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks) playbook.run() filename = '/tmp/ansible_test_messages.out' expected_lines = ["goodbye: Goodbye World!", "hello: Hello World!"] self._compare_file_output(filename, expected_lines) filename = '/tmp/ansible_test_role_messages.out' expected_lines = [ "goodbye: Goodbye World!", "hello: Hello World!", "inside_a_role: Indeed!" ] self._compare_file_output(filename, expected_lines) # restore default hash behavior C.DEFAULT_HASH_BEHAVIOUR = saved_hash_behavior
def test_playbook_vars(self): test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'test_playbook_vars', 'playbook.yml'), host_list='test/test_playbook_vars/hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks) playbook.run()
def test_playbook_vars(self): test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'test_playbook_vars', 'playbook.yml'), host_list='test/test_playbook_vars/hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks ) playbook.run()
def test_playbook_vars(self): test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'test_playbook_vars', 'playbook.yml'), host_list='test/test_playbook_vars/hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks) playbook.run() assert playbook.SETUP_CACHE['host1'] == {'attr2': 2, 'attr1': 1} assert playbook.SETUP_CACHE['host2'] == {'attr2': 2}
def test_playbook_vars(self): test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'test_playbook_vars', 'playbook.yml'), host_list='test/test_playbook_vars/hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks ) playbook.run() assert playbook.SETUP_CACHE['host1'] == {'attr2': 2, 'attr1': 1} assert playbook.SETUP_CACHE['host2'] == {'attr2': 2}
def run_playbook(self, playbook, host_list=None, use_sudo=True, local=False, extra_vars={}, ans_remote_user=AnsibleConstants.DEFAULT_REMOTE_USER, ans_remote_pass=AnsibleConstants.DEFAULT_REMOTE_PASS, only_tags=None, skip_tags=None): """Runs an ansible playbook From ansible doc: lib/ansible/__init__.py playbook: path to a playbook file host_list: path to a file like /etc/ansible/hosts module_path: path to ansible modules, like /usr/share/ansible/ forks: desired level of paralellism timeout: connection timeout remote_user: run as this user if not specified in a particular play remote_pass: use this remote password (for all plays) vs using SSH keys sudo_pass: if sudo==True, and a password is required, this is the sudo password remote_port: default remote port to use if not specified with the host or play transport: how to connect to hosts that don't specify a transport (local, paramiko, etc) callbacks output callbacks for the playbook runner_callbacks: more callbacks, this time for the runner API stats: holds aggregate data about events occuring to each host sudo: if not specified per play, requests all plays use sudo mode inventory: can be specified instead of host_list to use a pre-existing inventory object check: don't change anything, just try to detect some potential changes only_tags: List of tags to include. Only run task of tasks in the include list. skip_tags: List of tags to skip. Run all task but tagged in the skip list. """ use_transport = AnsibleConstants.DEFAULT_TRANSPORT if local: use_transport = "local" host_list = [] host_list.append("127.0.0.1") playbook = ansible.playbook.PlayBook( playbook=playbook, host_list=host_list if host_list != [] else self.__host_list, stats=ans_callbacks.AggregateStats(), callbacks=self.callbacks, runner_callbacks=self.callbacks, transport=use_transport, sudo=use_sudo, extra_vars=extra_vars, remote_user=ans_remote_user, remote_pass=ans_remote_pass, only_tags=only_tags, skip_tags=skip_tags) playbook.SETUP_CACHE.clear() result = playbook.run() # The result is a dict. I'm going to add # The "alienvault" key with our "internal" # values result['alienvault'] = {'lasterror': self.callbacks.lasterror} return result
def run(validation, cancel_event): C.HOST_KEY_CHECKING = False stats = callbacks.AggregateStats() playbook_callbacks = SilentPlaybookCallbacks(cancel_event) runner_callbacks = callbacks.DefaultRunnerCallbacks() playbook = ansible.playbook.PlayBook( playbook=validation['playbook'], host_list='tripleo-ansible-inventory.py', stats=stats, callbacks=playbook_callbacks, runner_callbacks=runner_callbacks) try: result = playbook.run() except ValidationCancelled: result = {} for host in playbook.inventory.list_hosts(): result[host] = { 'failures': 1, 'unreachable': 0, 'description': "Validation was cancelled.", } for host, status in result.items(): success = status['failures'] == 0 and status['unreachable'] == 0 result[host]['success'] = success return result
def test_playbook_always_run(self): test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'playbook-always-run.yml'), host_list='test/ansible_hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks, check=True ) actual = playbook.run() # if different, this will output to screen print "**ACTUAL**" print utils.jsonify(actual, format=True) expected = { "localhost": { "changed": 4, "failures": 0, "ok": 4, "skipped": 8, "unreachable": 0 } } print "**EXPECTED**" print utils.jsonify(expected, format=True) assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)
def _test_playbook_undefined_vars(self, playbook, fail_on_undefined): # save DEFAULT_UNDEFINED_VAR_BEHAVIOR so we can restore it in the end of the test saved_undefined_var_behavior = C.DEFAULT_UNDEFINED_VAR_BEHAVIOR C.DEFAULT_UNDEFINED_VAR_BEHAVIOR = fail_on_undefined test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'test_playbook_undefined_vars', playbook), host_list='test/test_playbook_undefined_vars/hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks ) actual = playbook.run() C.DEFAULT_UNDEFINED_VAR_BEHAVIOR = saved_undefined_var_behavior # if different, this will output to screen print "**ACTUAL**" print utils.jsonify(actual, format=True) expected = { "localhost": { "changed": 0, "failures": 0, "ok": int(not fail_on_undefined) + 1, "skipped": 0, "unreachable": int(fail_on_undefined) } } print "**EXPECTED**" print utils.jsonify(expected, format=True) assert utils.jsonify(expected, format=True) == utils.jsonify(actual, format=True)
def _test_playbook_undefined_vars(self, playbook, fail_on_undefined): # save DEFAULT_UNDEFINED_VAR_BEHAVIOR so we can restore it in the end of the test saved_undefined_var_behavior = C.DEFAULT_UNDEFINED_VAR_BEHAVIOR C.DEFAULT_UNDEFINED_VAR_BEHAVIOR = fail_on_undefined test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'test_playbook_undefined_vars', playbook), host_list='test/test_playbook_undefined_vars/hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks) actual = playbook.run() C.DEFAULT_UNDEFINED_VAR_BEHAVIOR = saved_undefined_var_behavior # if different, this will output to screen print "**ACTUAL**" print utils.jsonify(actual, format=True) expected = { "localhost": { "changed": 0, "failures": 0, "ok": int(not fail_on_undefined) + 1, "skipped": 0, "unreachable": int(fail_on_undefined) } } print "**EXPECTED**" print utils.jsonify(expected, format=True) assert utils.jsonify(expected, format=True) == utils.jsonify(actual, format=True)
def test_playbook_always_run(self): test_callbacks = TestCallbacks() playbook = ansible.playbook.PlayBook( playbook=os.path.join(self.test_dir, 'playbook-always-run.yml'), host_list='test/ansible_hosts', stats=ans_callbacks.AggregateStats(), callbacks=test_callbacks, runner_callbacks=test_callbacks, check=True) actual = playbook.run() # if different, this will output to screen print "**ACTUAL**" print utils.jsonify(actual, format=True) expected = { "localhost": { "changed": 4, "failures": 0, "ok": 4, "skipped": 8, "unreachable": 0 } } print "**EXPECTED**" print utils.jsonify(expected, format=True) assert utils.jsonify(expected, format=True) == utils.jsonify(actual, format=True)
def run_playbook(host, playbook, **kwargs): logger.info('running playbook {playbook} on host {hostname}'.format( playbook=playbook, hostname=host.hostname, )) inventory = ansible.inventory.Inventory(host_list=[host.hostname]) stats = ansible.callbacks.AggregateStats() callbacks = ansible.callbacks.PlaybookCallbacks(verbose=ansible.utils.VERBOSITY) runner_callbacks = ansible.callbacks.PlaybookRunnerCallbacks(stats=stats, verbose=ansible.utils.VERBOSITY) playbook = ansible.playbook.PlayBook( inventory=inventory, playbook=playbook, remote_user=host.login, callbacks=callbacks, runner_callbacks=runner_callbacks, stats=stats, **kwargs ) results = playbook.run() logger.info('results: {}'.format(results)) return results
def run(validation, cancel_event): C.HOST_KEY_CHECKING = False stats = callbacks.AggregateStats() playbook_callbacks = SilentPlaybookCallbacks(cancel_event) runner_callbacks = callbacks.DefaultRunnerCallbacks() playbook = ansible.playbook.PlayBook( playbook=validation['playbook'], # TODO we should use a dynamic inventory based on data coming from # tripleo-common/heat/ironic # http://docs.ansible.com/ansible/developing_api.html host_list='hosts', stats=stats, callbacks=playbook_callbacks, runner_callbacks=runner_callbacks) try: result = playbook.run() except ValidationCancelled: result = {} for host in playbook.inventory.list_hosts(): result[host] = { 'failures': 1, 'unreachable': 0, 'description': "Validation was cancelled.", } for host, status in result.items(): success = status['failures'] == 0 and status['unreachable'] == 0 result[host]['success'] = success return result
def run_playbook(self, playbook, host_list=None, use_sudo=True, local=False, extra_vars={}, ans_remote_user=AnsibleConstants.DEFAULT_REMOTE_USER, ans_remote_pass=AnsibleConstants.DEFAULT_REMOTE_PASS, only_tags=None, skip_tags=None): """Runs an ansible playbook From ansible doc: lib/ansible/__init__.py playbook: path to a playbook file host_list: path to a file like /etc/ansible/hosts module_path: path to ansible modules, like /usr/share/ansible/ forks: desired level of paralellism timeout: connection timeout remote_user: run as this user if not specified in a particular play remote_pass: use this remote password (for all plays) vs using SSH keys sudo_pass: if sudo==True, and a password is required, this is the sudo password remote_port: default remote port to use if not specified with the host or play transport: how to connect to hosts that don't specify a transport (local, paramiko, etc) callbacks output callbacks for the playbook runner_callbacks: more callbacks, this time for the runner API stats: holds aggregate data about events occuring to each host sudo: if not specified per play, requests all plays use sudo mode inventory: can be specified instead of host_list to use a pre-existing inventory object check: don't change anything, just try to detect some potential changes only_tags: List of tags to include. Only run task of tasks in the include list. skip_tags: List of tags to skip. Run all task but tagged in the skip list. """ use_transport = AnsibleConstants.DEFAULT_TRANSPORT if local: use_transport = "local" host_list = [] host_list.append("127.0.0.1") playbook = ansible.playbook.PlayBook(playbook=playbook, host_list=host_list if host_list != [] else self.__host_list, stats=ans_callbacks.AggregateStats(), callbacks=self.callbacks, runner_callbacks=self.callbacks, transport=use_transport, sudo=use_sudo, extra_vars=extra_vars, remote_user=ans_remote_user, remote_pass=ans_remote_pass, only_tags=only_tags, skip_tags=skip_tags) playbook.SETUP_CACHE.clear() result = playbook.run() # The result is a dict. I'm going to add # The "alienvault" key with our "internal" # values result['alienvault'] = {'lasterror': self.callbacks.lasterror} return result
def run_playbook(playbook_file=None, inventory=ansible.inventory.Inventory([]), verbose=psi_ops_config.ANSIBLE_VERBOSE_LEVEL, email_stats=True): ''' Runs a playbook file and returns the result playbook_file : Playbook file to open and run (String) inventory : Ansible inventory to run playbook against verbose : Output verbosity ''' try: start_time = datetime.datetime.now() playbook_callbacks = ansible.callbacks.PlaybookCallbacks( verbose=verbose) stats = ansible.callbacks.AggregateStats() runner_callbacks = ansible.callbacks.PlaybookRunnerCallbacks( stats, verbose=verbose) playbook = ansible.playbook.PlayBook(playbook=playbook_file, callbacks=playbook_callbacks, runner_callbacks=runner_callbacks, stats=stats, inventory=inventory) res = playbook.run() end_time = datetime.datetime.now() print "Run completed at: %s\nTotal run time: %s" % ( str(end_time), str(end_time - start_time)) if email_stats is True: # stats.dark : (dict) number of hosts that could not be contacted # stats.failures : (dict) number of hosts that failed to complete the tasks (host_output, host_errs) = process_playbook_vars_cache(playbook) setup_cache = process_playbook_setup_cache(playbook) if 'apt_update' in playbook_file: print playbook_file host_output = process_playbook_apt_update_cache( host_output, setup_cache) host_output = massage_responses(host_output) record = (str(start_time), str(end_time), playbook_file, stats.processed, stats.dark, stats.failures, stats.changed, stats.skipped, res, host_output, host_errs, setup_cache) send_mail(record) return (stats, res) except Exception as e: raise e
def ansible_book(pb, args, id): stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) playbook = ansible.playbook.PlayBook( playbook=pb, #要执行的剧本 extra_vars=args, #剧本中设置的变量传递 stats=stats, #必填参数 callbacks=playbook_cb, #必填参数 runner_callbacks=runner_cb, #必填参数 #check=True #测试执行,设置为这个True的时候只会输出执行结果 但是不会在真实服务器上执行 #inventory='/root/my_app/get_inventory.py' host_list='/root/my_app/app/host.py') result = playbook.run() result = json.dumps(result, indent=4) return result
def run(validation, cancel_event): C.HOST_KEY_CHECKING = False stats = callbacks.AggregateStats() playbook_callbacks = SilentPlaybookCallbacks(cancel_event) runner_callbacks = CustomRunnerHandler() playbook = ansible.playbook.PlayBook( playbook=validation['playbook'], host_list='tripleo-ansible-inventory.py', stats=stats, forks=1, callbacks=playbook_callbacks, runner_callbacks=runner_callbacks) try: result = playbook.run() except ValidationCancelled: result = {} for host in playbook.inventory.list_hosts(): result[host] = { 'failures': 1, 'unreachable': 0, 'description': "Validation was cancelled.", } for host, captures in runner_callbacks.captured_results().items(): result[host]['raw'] = captures result[host]['failure_messages'] = [] result[host]['warning_messages'] = [] for capture in captures: if capture.get('failed'): result[host]['failure_messages'].append( capture.get('msg', 'Unknown failure')) if capture.get('rc', 0) != 0: msg = "Command '{}' exited with code {}. STDERR: {}".format( capture.get('cmd'), capture.get('rc'), capture.get('stderr')) result[host]['failure_messages'].append(msg) warnings = capture.get('warnings', []) for warning in warnings: result[host]['warning_messages'].append(warning) for host, status in result.items(): success = status['failures'] == 0 and status['unreachable'] == 0 result[host]['success'] = success return result
def RunPlaybook( self, playbook, hostlist): #playbook,用来指定playbook的yaml文件, hostlist 指定hosts文件 stats = callbacks.AggregateStats() #收集playbook执行期间的状态信息,最后会进行汇总 playbook_cb = callbacks.PlaybookCallbacks( verbose=utils.VERBOSITY) #callbacks用来输出playbook执行的结果 runner_cb = callbacks.PlaybookRunnerCallbacks( stats, verbose=utils.VERBOSITY) #用来输出playbook执行期间的结果 playbook = ansible.playbook.PlayBook( playbook=playbook, stats=stats, callbacks=playbook_cb, runner_callbacks=runner_cb, inventory=self.webInventory, ) result = playbook.run() data = json.dumps(result, indent=4) return data
def run_playbook(playbook_file=None, inventory=ansible.inventory.Inventory([]), verbose=psi_ops_config.ANSIBLE_VERBOSE_LEVEL, email_stats=True): ''' Runs a playbook file and returns the result playbook_file : Playbook file to open and run (String) inventory : Ansible inventory to run playbook against verbose : Output verbosity ''' try: start_time = datetime.datetime.now() playbook_callbacks = ansible.callbacks.PlaybookCallbacks(verbose=verbose) stats = ansible.callbacks.AggregateStats() runner_callbacks = ansible.callbacks.PlaybookRunnerCallbacks(stats, verbose=verbose) playbook = ansible.playbook.PlayBook( playbook=playbook_file, callbacks=playbook_callbacks, runner_callbacks=runner_callbacks, stats=stats, inventory=inventory) res = playbook.run() end_time = datetime.datetime.now() print "Run completed at: %s\nTotal run time: %s" % (str(end_time), str(end_time-start_time)) if email_stats is True: # stats.dark : (dict) number of hosts that could not be contacted # stats.failures : (dict) number of hosts that failed to complete the tasks (host_output, host_errs) = process_playbook_vars_cache(playbook) setup_cache = process_playbook_setup_cache(playbook) if 'apt_update' in playbook_file: print playbook_file host_output = process_playbook_apt_update_cache(host_output, setup_cache) host_output = massage_responses(host_output) record = (str(start_time), str(end_time), playbook_file, stats.processed, stats.dark, stats.failures, stats.changed, stats.skipped, res, host_output, host_errs, setup_cache) send_mail(record) return (stats, res) except Exception as e: raise e
def run_playbook(owner, cloud_id, machine_id, playbook_path, extra_vars=None, force_handlers=False, debug=False): if not extra_vars: extra_vars = None ret_dict = { 'success': False, 'started_at': time(), 'finished_at': 0, 'stdout': '', 'error_msg': '', 'inventory': '', 'stats': {}, } inventory = mist.api.inventory.MistInventory(owner, [(cloud_id, machine_id)]) if len(inventory.hosts) != 1: log.error("Expected 1 host, found %s", inventory.hosts) ret_dict['error_msg'] = "Expected 1 host, found %s" % inventory.hosts ret_dict['finished_at'] = time() return ret_dict ret_dict['host'] = inventory.hosts.values()[0]['ansible_ssh_host'] machine_name = inventory.hosts.keys()[0] log_prefix = "Running playbook '%s' on machine '%s'" % (playbook_path, machine_name) files = inventory.export(include_localhost=False) ret_dict['inventory'] = files['inventory'] tmp_dir = tempfile.mkdtemp() old_dir = os.getcwd() os.chdir(tmp_dir) try: log.debug("%s: Saving inventory files", log_prefix) os.mkdir('id_rsa') for name, data in files.items(): with open(name, 'w') as f: f.write(data) for name in os.listdir('id_rsa'): os.chmod('id_rsa/%s' % name, 0600) log.debug("%s: Inventory files ready", log_prefix) playbook_path = '%s/%s' % (old_dir, playbook_path) ansible_hosts_path = 'inventory' # extra_vars['host_key_checking'] = False ansible.utils.VERBOSITY = 4 if debug else 0 ansible.constants.HOST_KEY_CHECKING = False ansible.constants.ANSIBLE_NOCOWS = True stats = ansible.callbacks.AggregateStats() playbook_cb = ansible.callbacks.PlaybookCallbacks( verbose=ansible.utils.VERBOSITY) runner_cb = ansible.callbacks.PlaybookRunnerCallbacks( stats, verbose=ansible.utils.VERBOSITY) log.error(old_dir) log.error(tmp_dir) log.error(extra_vars) log.error(playbook_path) capture = StdStreamCapture() try: playbook = ansible.playbook.PlayBook( playbook=playbook_path, host_list=ansible_hosts_path, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, extra_vars=extra_vars, force_handlers=force_handlers, ) result = playbook.run() except Exception as exc: log.error("%s: Error %r", log_prefix, exc) ret_dict['error_msg'] = repr(exc) finally: ret_dict['finished_at'] = time() ret_dict['stdout'] = capture.close() if ret_dict['error_msg']: return ret_dict log.debug("%s: Ansible result = %s", log_prefix, result) mresult = result[machine_name] ret_dict['stats'] = mresult if mresult['failures'] or mresult['unreachable']: log.error("%s: Ansible run failed: %s", log_prefix, mresult) return ret_dict log.info("%s: Ansible run succeeded: %s", log_prefix, mresult) ret_dict['success'] = True return ret_dict finally: os.chdir(old_dir) if not debug: shutil.rmtree(tmp_dir)