docs: 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)