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" self.module_args = module_args = self.get_module_args(args, kwargs) loader = DataLoader() inventory_manager = SourcelessInventoryManager(loader=loader) for server, port in self.api.servers: inventory_manager._inventory.add_host(server, 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': self.api.servers.hosts, '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) 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() try: 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.info(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" self.module_args = module_args = self.get_module_args(args, kwargs) loader = DataLoader() variable_manager = VariableManager() # Ansible has some support for host lists, but it assumes at times # that these host lists are not in fact lists but a string pointing # to a host list file. The easiest way to make sure that Ansible gets # what we want is to pass a host list as a string which always contains # at least one comma so that ansible knows it's a string of hosts. host_list = ','.join(self.api.servers) + ',' inventory = UncachedInventory(loader=loader, variable_manager=variable_manager, host_list=host_list) variable_manager.set_inventory(inventory) play_source = { 'name': "Suitable Play", 'hosts': self.api.servers, 'gather_facts': 'no', 'tasks': [{ 'action': { 'module': self.module_name, 'args': module_args } }] } play = Play.load(play_source, variable_manager=variable_manager, loader=loader) 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() try: task_queue_manager = TaskQueueManager( inventory=inventory, 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.info(u'took {} to complete'.format(datetime.utcnow() - start)) return self.evaluate_results(callback)