def evaluate_results(self, callback): """ prepare the result of runner call for use with RunnerResults. """ for server, result in callback.unreachable.items(): log.error(u'{} could not be reached'.format(server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_unreachable: continue self.trigger_event(server, 'on_unreachable_host', (self, server)) for server, answer in callback.contacted.items(): success = answer['success'] result = answer['result'] # none of the modules in our tests hit the 'failed' result # codepath (which seems to not be implemented by all modules) # seo we ignore this branch since it's rather trivial if result.get('failed'): # pragma: no cover success = False if 'rc' in result: if self.api.is_valid_return_code(result['rc']): success = True # Add success to result result['success'] = success if not success: log.error(u'{} failed on {}'.format(self, server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_errors: continue self.trigger_event(server, 'on_module_error', (self, server, result)) # XXX this is a weird structure because RunnerResults still works # like it did with Ansible 1.x, where the results where structured # like this return RunnerResults({ 'contacted': { server: answer['result'] for server, answer in callback.contacted.items() }, 'unreachable': { server: result for server, result in callback.unreachable.items() } })
def evaluate_results(self, callback): """ prepare the result of runner call for use with RunnerResults. """ for server, result in callback.unreachable.items(): log.error(u'{} could not be reached'.format(server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_unreachable: continue self.trigger_event(server, 'on_unreachable_host', ( self, server )) for server, answer in callback.contacted.items(): success = answer['success'] result = answer['result'] # none of the modules in our tests hit the 'failed' result # codepath (which seems to not be implemented by all modules) # seo we ignore this branch since it's rather trivial if result.get('failed'): # pragma: no cover success = False if 'rc' in result: if self.api.is_valid_return_code(result['rc']): success = True if not success: log.error(u'{} failed on {}'.format(self, server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_errors: continue self.trigger_event(server, 'on_module_error', ( self, server, result )) # XXX this is a weird structure because RunnerResults still works # like it did with Ansible 1.x, where the results where structured # like this return RunnerResults({ 'contacted': { server: answer['result'] for server, answer in callback.contacted.items() } })
def evaluate_results(self, callback): """ prepare the result of runner call for use with RunnerResults. """ for server, result in callback.unreachable.items(): log.error(u'{} could not be reached'.format(server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_unreachable: continue self.trigger_event(server, 'on_unreachable_host', ( self, server )) for server, answer in callback.contacted.items(): success = answer['success'] result = answer['result'] if 'failed' in result: success = False if 'rc' in result: if self.api.is_valid_return_code(result['rc']): success = True if not success: log.error(u'{} failed on {}'.format(self, server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_errors: continue self.trigger_event(server, 'on_module_error', ( self, server, result )) # XXX this is a weird structure because RunnerResults still works # like it did with Ansible 1.x, where the results where structured # like this return RunnerResults({ 'contacted': { server: answer['result'] for server, answer in callback.contacted.items() } })
def evaluate_results(self, callback): """ prepare the result of runner call for use with RunnerResults. """ for server, result in callback.unreachable.items(): log.error(u'{} could not be reached'.format(server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_unreachable: continue self.trigger_event(server, 'on_unreachable_host', (self, server)) for server, answer in callback.contacted.items(): success = answer['success'] result = answer['result'] if result.get('failed'): success = False if 'rc' in result: if self.api.is_valid_return_code(result['rc']): success = True if not success: log.error(u'{} failed on {}'.format(self, server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_errors: continue self.trigger_event(server, 'on_module_error', (self, server, result)) # XXX this is a weird structure because RunnerResults still works # like it did with Ansible 1.x, where the results where structured # like this return RunnerResults({ 'contacted': { server: answer['result'] for server, answer in callback.contacted.items() } })
def parse_results(self, results): """ Parses the result of runner call. """ unreachable_servers = results['dark'] for server, result in unreachable_servers.items(): log.error(u'{} could not be reached'.format(server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_unreachable: continue self.trigger_event(server, 'on_unreachable_host', ( self, server )) contacted_servers = results['contacted'] for server, result in contacted_servers.items(): failure = False if 'failed' in result: failure = True if 'rc' in result: if not self.api.is_valid_return_code(result['rc']): failure = True if failure: log.error(u'{} failed on {}'.format(self, server)) log.debug(u'ansible-output =>\n{}'.format(pformat(result))) if self.api.ignore_errors: continue self.trigger_event(server, 'on_module_error', ( self, server, result )) return results
def execute(self, *args, **kwargs): """ Puts args and kwargs in a way ansible can understand. Calls ansible and interprets the result. """ assert self.is_hooked_up, "the module should be hooked up to the api" if set_global_context: set_global_context(self.api.options) # legacy key=value pairs shorthand approach if args: self.module_args = module_args = self.get_module_args(args, kwargs) else: self.module_args = module_args = kwargs loader = DataLoader() inventory_manager = SourcelessInventoryManager(loader=loader) for host, port in self.api.hosts_with_ports: inventory_manager._inventory.add_host(host, group='all', port=port) for key, value in self.api.options.extra_vars.items(): inventory_manager._inventory.set_variable('all', key, value) variable_manager = VariableManager( loader=loader, inventory=inventory_manager) play_source = { 'name': "Suitable Play", 'hosts': 'all', 'gather_facts': 'no', 'tasks': [{ 'action': { 'module': self.module_name, 'args': module_args, }, 'environment': self.api.environment, }] } try: play = Play.load( play_source, variable_manager=variable_manager, loader=loader, ) if self.api.strategy: play.strategy = self.api.strategy log.info( u'running {}'.format(u'- {module_name}: {module_args}'.format( module_name=self.module_name, module_args=module_args )) ) start = datetime.utcnow() task_queue_manager = None callback = SilentCallbackModule() # ansible uses various levels of verbosity (from -v to -vvvvvv) # offering various amounts of debug information # # we keep it a bit simpler by activating all of it during debug, # and falling back to the default of 0 otherwise verbosity = self.api.options.verbosity == logging.DEBUG and 6 or 0 with ansible_verbosity(verbosity): # host_key_checking is special, since not each connection # plugin handles it the same way, we need to apply both # environment variable and Ansible constant when running a # command in the runner to be successful with host_key_checking(self.api.host_key_checking): kwargs = dict( inventory=inventory_manager, variable_manager=variable_manager, loader=loader, options=self.api.options, passwords=getattr(self.api.options, 'passwords', {}), stdout_callback=callback ) if set_global_context: del kwargs['options'] task_queue_manager = TaskQueueManager(**kwargs) try: task_queue_manager.run(play) except SystemExit: # Mitogen forks our process and exits it in one # instance before returning # # This is fine, but it does lead to a very messy exit # by py.test which will essentially return with a test # that is first successful and then failed as each # forked process dies. # # To avoid this we commit suicide if we are run inside # a pytest session. Normally this would just result # in a exit code of zero, which is good. if 'pytest' in sys.modules: try: atexit._run_exitfuncs() except Exception: pass os.kill(os.getpid(), signal.SIGKILL) raise finally: if task_queue_manager is not None: task_queue_manager.cleanup() if set_global_context: # Ansible 2.8 introduces a global context which persists # during the lifetime of the process - for Suitable this # singleton/cache needs to be cleared after each call # to make sure that API calls do not carry over state. # # The docs hint at a future inclusion of local contexts, which # would of course be preferable. from ansible.utils.context_objects import GlobalCLIArgs GlobalCLIArgs._Singleton__instance = None log.debug(u'took {} to complete'.format(datetime.utcnow() - start)) return self.evaluate_results(callback)
def execute(self, *args, **kwargs): """ Puts args and kwargs in a way ansible can understand. Calls ansible and interprets the result. """ assert self.is_hooked_up, "the module should be hooked up to the api" if set_global_context: set_global_context(self.api.options) # legacy key=value pairs shorthand approach if args: self.module_args = module_args = self.get_module_args(args, kwargs) else: self.module_args = module_args = kwargs loader = DataLoader() inventory_manager = SourcelessInventoryManager(loader=loader) for host, host_variables in self.api.inventory.items(): inventory_manager._inventory.add_host(host, group='all') for key, value in host_variables.items(): inventory_manager._inventory.set_variable(host, key, value) for key, value in self.api.options.extra_vars.items(): inventory_manager._inventory.set_variable('all', key, value) variable_manager = VariableManager(loader=loader, inventory=inventory_manager) play_source = { 'name': "Suitable Play", 'hosts': 'all', 'gather_facts': 'no', 'tasks': [{ 'action': { 'module': self.module_name, 'args': module_args, }, 'environment': self.api.environment, }] } try: play = Play.load( play_source, variable_manager=variable_manager, loader=loader, ) if self.api.strategy: play.strategy = self.api.strategy log.info(u'running {}'.format( u'- {module_name}: {module_args}'.format( module_name=self.module_name, module_args=module_args))) start = datetime.utcnow() task_queue_manager = None callback = SilentCallbackModule() # ansible uses various levels of verbosity (from -v to -vvvvvv) # offering various amounts of debug information # # we keep it a bit simpler by activating all of it during debug, # and falling back to the default of 0 otherwise verbosity = self.api.options.verbosity == logging.DEBUG and 6 or 0 with ansible_verbosity(verbosity): # host_key_checking is special, since not each connection # plugin handles it the same way, we need to apply both # environment variable and Ansible constant when running a # command in the runner to be successful with host_key_checking(self.api.host_key_checking): kwargs = dict(inventory=inventory_manager, variable_manager=variable_manager, loader=loader, options=self.api.options, passwords=getattr(self.api.options, 'passwords', {}), stdout_callback=callback) if set_global_context: del kwargs['options'] task_queue_manager = TaskQueueManager(**kwargs) try: task_queue_manager.run(play) except SystemExit: # Mitogen forks our process and exits it in one # instance before returning # # This is fine, but it does lead to a very messy exit # by py.test which will essentially return with a test # that is first successful and then failed as each # forked process dies. # # To avoid this we commit suicide if we are run inside # a pytest session. Normally this would just result # in a exit code of zero, which is good. if 'pytest' in sys.modules: try: atexit._run_exitfuncs() except Exception: pass os.kill(os.getpid(), signal.SIGKILL) raise finally: if task_queue_manager is not None: task_queue_manager.cleanup() if set_global_context: # Ansible 2.8 introduces a global context which persists # during the lifetime of the process - for Suitable this # singleton/cache needs to be cleared after each call # to make sure that API calls do not carry over state. # # The docs hint at a future inclusion of local contexts, which # would of course be preferable. from ansible.utils.context_objects import GlobalCLIArgs GlobalCLIArgs._Singleton__instance = None log.debug(u'took {} to complete'.format(datetime.utcnow() - start)) return self.evaluate_results(callback)
def execute(self, *args, **kwargs): """ Puts args and kwargs in a way ansible can understand. Calls ansible and interprets the result. """ assert self.is_hooked_up, "the module should be hooked up to the api" # legacy key=value pairs shorthand approach if args: self.module_args = module_args = self.get_module_args(args, kwargs) else: self.module_args = module_args = kwargs loader = DataLoader() inventory_manager = SourcelessInventoryManager(loader=loader) hosts_with_ports = tuple(self.api.hosts_with_ports) for host, port in hosts_with_ports: inventory_manager._inventory.add_host(host, group='all', port=port) for key, value in self.api.options.extra_vars.items(): inventory_manager._inventory.set_variable('all', key, value) variable_manager = VariableManager( loader=loader, inventory=inventory_manager) play_source = { 'name': "Suitable Play", 'hosts': [h for h, p in hosts_with_ports], # *must* be a list 'gather_facts': 'no', 'tasks': [{ 'action': { 'module': self.module_name, 'args': module_args, }, 'environment': self.api.environment }] } play = Play.load( play_source, variable_manager=variable_manager, loader=loader, ) if self.api.strategy: play.strategy = self.api.strategy log.info(u'running {}'.format(u'- {module_name}: {module_args}'.format( module_name=self.module_name, module_args=module_args ))) start = datetime.utcnow() task_queue_manager = None callback = SilentCallbackModule() # ansible uses various levels of verbosity (from -v to -vvvvvv) # offering various amounts of debug information # # we keep it a bit simpler by activating all of it during debug, and # falling back to the default of 0 otherwise verbosity = self.api.options.verbosity == logging.DEBUG and 6 or 0 try: with ansible_verbosity(verbosity): task_queue_manager = TaskQueueManager( inventory=inventory_manager, variable_manager=variable_manager, loader=loader, options=self.api.options, passwords=getattr(self.api.options, 'passwords', {}), stdout_callback=callback ) task_queue_manager.run(play) finally: if task_queue_manager is not None: task_queue_manager.cleanup() log.debug(u'took {} to complete'.format(datetime.utcnow() - start)) return self.evaluate_results(callback)
def execute(self, *args, **kwargs): """ Puts args and kwargs in a way ansible can understand. Calls ansible and interprets the result. """ assert self.is_hooked_up, "the module should be hooked up to the api" # legacy key=value pairs shorthand approach if args: self.module_args = module_args = self.get_module_args(args, kwargs) else: self.module_args = module_args = kwargs loader = DataLoader() inventory_manager = SourcelessInventoryManager(loader=loader) hosts_with_ports = tuple(self.api.hosts_with_ports) for host, port in hosts_with_ports: inventory_manager._inventory.add_host(host, group='all', port=port) for key, value in self.api.options.extra_vars.items(): inventory_manager._inventory.set_variable('all', key, value) variable_manager = VariableManager(loader=loader, inventory=inventory_manager) play_source = { 'name': "Suitable Play", 'hosts': [h for h, p in hosts_with_ports], # *must* be a list 'gather_facts': 'no', 'tasks': [{ 'action': { 'module': self.module_name, 'args': module_args, }, 'environment': self.api.environment }] } play = Play.load( play_source, variable_manager=variable_manager, loader=loader, ) if self.api.strategy: play.strategy = self.api.strategy log.info(u'running {}'.format(u'- {module_name}: {module_args}'.format( module_name=self.module_name, module_args=module_args))) start = datetime.utcnow() task_queue_manager = None callback = SilentCallbackModule() # ansible uses various levels of verbosity (from -v to -vvvvvv) # offering various amounts of debug information # # we keep it a bit simpler by activating all of it during debug, and # falling back to the default of 0 otherwise verbosity = self.api.options.verbosity == logging.DEBUG and 6 or 0 try: with ansible_verbosity(verbosity): task_queue_manager = TaskQueueManager( inventory=inventory_manager, variable_manager=variable_manager, loader=loader, options=self.api.options, passwords=getattr(self.api.options, 'passwords', {}), stdout_callback=callback) task_queue_manager.run(play) finally: if task_queue_manager is not None: task_queue_manager.cleanup() log.debug(u'took {} to complete'.format(datetime.utcnow() - start)) return self.evaluate_results(callback)