def on_failed(self, host, results, ignore_errors=False):
        if self.runner.delegate_to:
            host = "%s -> %s" % (host, self.runner.delegate_to)

        results2 = results.copy()
        results2.pop("invocation", None)

        item = results2.get("item", None)
        parsed = results2.get("parsed", True)
        module_msg = ""

        if not parsed:
            module_msg = results2.pop("msg", None)

        stderr = results2.pop("stderr", None)
        stdout = results2.pop("stdout", None)
        returned_msg = results2.pop("msg", None)

        if item:
            msg = "failed: [%s] => (item=%s) => %s" % (host, item, utils.jsonify(results2))
        else:
            msg = "failed: [%s] => %s" % (host, utils.jsonify(results2))

        self.display(msg, color="red", runner=self.runner)

        if stderr:
            self.display("stderr: %s" % stderr, color="red", runner=self.runner)
        if stdout:
            self.display("stdout: %s" % stdout, color="red", runner=self.runner)
        if returned_msg:
            self.display("msg: %s" % returned_msg, color="red", runner=self.runner)
        if not parsed and module_msg:
            self.display(module_msg, color="red", runner=self.runner)
        if ignore_errors:
            self.display("...ignoring", color="cyan", runner=self.runner)
예제 #2
0
    def on_failed(self, host, results, ignore_errors=False):
        if self.runner.delegate_to:
            host = '%s -> %s' % (host, self.runner.delegate_to)

        results2 = results.copy()
        results2.pop('invocation', None)

        item = results2.get('item', None)
        parsed = results2.get('parsed', True)
        returned_msg = results2.pop('msg', None)
        module_msg = ''
        if not parsed:
            module_msg = results2.pop('msg', None)

        if item:
            msg = "failed: [%s] => (item=%s) => %s" % (host, item, utils.jsonify(results2))
        else:
            msg = "failed: [%s] => %s" % (host, utils.jsonify(results2))
        file_logger().error(msg)

        if returned_msg:
            file_logger().error(returned_msg)
        if not parsed and module_msg:
            file_logger().error(module_msg)
        if ignore_errors:
            file_logger().info("...ignoring")

        super(MyPlaybookRunnerCallbacks, self).on_failed(host, results, ignore_errors=ignore_errors)
예제 #3
0
파일: callbacks.py 프로젝트: Silaco/Plus
def regular_generic_msg(hostname, result, oneline, caption):
    ''' output on the result of a module run that is not command '''

    if not oneline:
        return "%s | %s >> %s\n" % (hostname, caption, utils.jsonify(result,format=True))
    else:
        return "%s | %s >> %s\n" % (hostname, caption, utils.jsonify(result))
예제 #4
0
    def on_failed(self, host, results, ignore_errors=False):
        delegate_to = self.runner.module_vars.get('delegate_to')
        if delegate_to:
            host = '%s -> %s' % (host, delegate_to)

        results2 = results.copy()
        results2.pop('invocation', None)

        item = results2.get('item', None)
        parsed = results2.get('parsed', True)
        module_msg = ''
        if not parsed:
            module_msg  = results2.pop('msg', None)
        stderr = results2.pop('stderr', None)
        stdout = results2.pop('stdout', None)
        returned_msg = results2.pop('msg', None)

        if item:
            msg = "failed: [%s] => (item=%s) => %s" % (host, item, utils.jsonify(results2))
        else:
            msg = "failed: [%s] => %s" % (host, utils.jsonify(results2))
        display(msg, self.sqs_response_queue, self.sqs_request_message)

        if stderr:
            display("stderr: %s" % stderr, self.sqs_response_queue, self.sqs_request_message)
        if stdout:
            display("stdout: %s" % stdout, self.sqs_response_queue, self.sqs_request_message)
        if returned_msg:
            display("msg: %s" % returned_msg, self.sqs_response_queue, self.sqs_request_message)
        if not parsed and module_msg:
            display("invalid output was: %s" % module_msg, self.sqs_response_queue, self.sqs_request_message)
        if ignore_errors:
            display("...ignoring", self.sqs_response_queue, self.sqs_request_message)
        super(PlaybookRunnerCallbacks, self).on_failed(host, results, ignore_errors=ignore_errors)
예제 #5
0
    def on_ok(self, host, host_result):
        item = host_result.get('item', None)

        host_result2 = host_result.copy()
        host_result2.pop('invocation', None)
        verbose_always = host_result2.pop('verbose_always', False)
        changed = host_result.get('changed', False)
        ok_or_changed = 'ok'
        if changed:
            ok_or_changed = 'changed'

        # show verbose output for non-setup module results if --verbose is used
        msg = ''
        if (not self.verbose or host_result2.get("verbose_override", None) is not
            None) and not verbose_always:
            if item:
                msg = "%s: [%s] => (item=%s)" % (ok_or_changed, host, item)
            else:
                if 'ansible_job_id' not in host_result or 'finished' in host_result:
                    msg = "%s: [%s]" % (ok_or_changed, host)
        else:
            # verbose ...
            if item:
                msg = "%s: [%s] => (item=%s) => %s" % (
                    ok_or_changed, host, item, utils.jsonify(host_result2, format=verbose_always))
            else:
                if 'ansible_job_id' not in host_result or 'finished' in host_result2:
                    msg = "%s: [%s] => %s" % (ok_or_changed, host, utils.jsonify(host_result2, format=verbose_always))

        if msg != '':
            file_logger().info(msg)
        if 'warnings' in host_result2 and host_result2['warnings']:
            for warning in host_result2['warnings']:
                file_logger().warn("warning: %s" % warning)
        super(MyPlaybookRunnerCallbacks, self).on_ok(host, host_result)
예제 #6
0
파일: callbacks.py 프로젝트: Silaco/Plus
    def on_failed(self, host, results, ignore_errors=False):
        if self.runner.delegate_to:
            host = '%s -> %s' % (host, self.runner.delegate_to)

        results2 = results.copy()
        results2.pop('invocation', None)

        item = results2.get('item', None)
        parsed = results2.get('parsed', True)
        module_msg = ''
        if not parsed:
            module_msg  = results2.pop('msg', None)
        stderr = results2.pop('stderr', None)
        stdout = results2.pop('stdout', None)
        returned_msg = results2.pop('msg', None)

        if item:
            msg = "failed: [%s] => (item=%s) => %s" % (host, item, utils.jsonify(results2))
        else:
            msg = "failed: [%s] => %s" % (host, utils.jsonify(results2))
        display(msg, color='red', runner=self.runner)

        if stderr:
            display("stderr: %s" % stderr, color='red', runner=self.runner)
        if stdout:
            display("stdout: %s" % stdout, color='red', runner=self.runner)
        if returned_msg:
            display("msg: %s" % returned_msg, color='red', runner=self.runner)
        if not parsed and module_msg:
            display(module_msg, color='red', runner=self.runner)
        if ignore_errors:
            display("...ignoring", color='cyan', runner=self.runner)
        super(PlaybookRunnerCallbacks, self).on_failed(host, results, ignore_errors=ignore_errors)
 def runner_on_failed(self, host, res, ignore_errors=False):
     results2 = res.copy()
     results2.pop('invocation', None)
     item = results2.get('item', None)
     if item:
         msg = 'failed: [%s] => (item=%s) => %s' % (host, item, utils.jsonify(results2))
     else:
         msg = 'failed: [%s] => %s' % (host, utils.jsonify(results2))
     append_to_log(msg)
     update_to_slack()
예제 #8
0
 def runner_on_failed(self, host, res, ignore_errors=False):
     results2 = res.copy()
     results2.pop('invocation', None)
     item = results2.get('item', None)
     if item:
         msg = "failed: [%s] => (item=%s) => %s" % (host, item, utils.jsonify(results2))
     else:
         msg = "failed: [%s] => %s" % (host, utils.jsonify(results2))
     if self._print_failed:
         self.append_report(msg)
예제 #9
0
   def test_recursive_copy(self):
       pb = 'test/playbook-recursive-copy.yml'
       actual = self._run(pb)

       expected =  {
            "localhost": {
                "changed": 65,
                "failures": 0,
                "ok": 73,
                "skipped": 0,
                "unreachable": 0
            }
       }

       assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)
예제 #10
0
파일: callbacks.py 프로젝트: Silaco/Plus
 def _on_any(self, host, result):
     result2 = result.copy()
     result2.pop('invocation', None)
     (msg, color) = host_report_msg(host, self.options.module_name, result2, self.options.one_line)
     display(msg, color=color, runner=self.runner)
     if self.options.tree:
         utils.write_tree_file(self.options.tree, host, utils.jsonify(result2,format=True))
예제 #11
0
    def _transfer_str(self, conn, tmp, name, data):
        ''' transfer string to remote file '''

        if type(data) == dict:
            data = utils.jsonify(data)

        afd, afile = tempfile.mkstemp()
        afo = os.fdopen(afd, 'w')
        try:
            if not isinstance(data, unicode):
                #ensure the data is valid UTF-8
                data.decode('utf-8')
            else:
                data = data.encode('utf-8')
            afo.write(data)
        except:
            raise errors.AnsibleError("failure encoding into utf-8")
        afo.flush()
        afo.close()

        remote = os.path.join(tmp, name)
        try:
            conn.put_file(afile, remote)
        finally:
            os.unlink(afile)
        return remote
예제 #12
0
파일: fireball.py 프로젝트: bezhermoso/home
    def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bin/sh', in_data=None):
        ''' run a command on the remote host '''

        if in_data:
            raise errors.AnsibleError("Internal Error: this module does not support optimized module pipelining")

        vvv("EXEC COMMAND %s" % cmd)

        if self.runner.sudo and sudoable:
            raise errors.AnsibleError(
                "When using fireball, do not specify sudo to run your tasks. " +
                "Instead sudo the fireball action with sudo. " +
                "Task will communicate with the fireball already running in sudo mode."
            )

        data = dict(
            mode='command',
            cmd=cmd,
            tmp_path=tmp_path,
            executable=executable,
        )
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        self.socket.send(data)
        
        response = self.socket.recv()
        response = utils.decrypt(self.key, response)
        response = utils.parse_json(response)

        return (response.get('rc',None), '', response.get('stdout',''), response.get('stderr',''))
예제 #13
0
def get_ezjail_module(args):
    import ezjail
    encoded_args = repr(args.encode('utf-8'))
    encoded_lang = repr(ansible.constants.DEFAULT_MODULE_LANG)
    encoded_complex = repr(jsonify({}))
    fn = ezjail.__file__.replace('.pyc', '.py')
    with open(fn) as f:
        module_data = f.read()
    module_data = module_data.replace(module_common.REPLACER, module_common.MODULE_COMMON)
    module_data = module_data.replace(module_common.REPLACER_ARGS, encoded_args)
    module_data = module_data.replace(module_common.REPLACER_LANG, encoded_lang)
    module_data = module_data.replace(module_common.REPLACER_COMPLEX, encoded_complex)
    ofn = fn.replace('/ezjail.py', '/tmp_ezjail.py')
    with open(ofn, 'w') as f:
        f.write(module_data)
    code = compiler.compile(module_data, ofn, 'exec')
    ezjail = imp.new_module('ezjail')
    exec code in ezjail.__dict__
    ezjail.__file__ = ofn

    class AnsibleModule(ezjail.AnsibleModule):
        def get_bin_path(self, arg, required=False, opt_dirs=[]):
            return '/usr/bin/%s' % arg

    ezjail.AnsibleModule = AnsibleModule

    module = AnsibleModule(**ezjail.MODULE_SPECS)

    return ezjail, module
예제 #14
0
파일: tasks.py 프로젝트: rackeric/destiny
def ansible_jeneric(job_id, user_id):
    
    # firebase authentication
    SECRET = os.environ['SECRET']
    authentication = FirebaseAuthentication(SECRET, True, True)

    # set the specific job from firebase with user
    user = '******' + user_id
    URL = 'https://deploynebula.firebaseio.com/users/' + user + '/external_data/'
    myExternalData = FirebaseApplication(URL, authentication)

    # update status to RUNNING in firebase
    myExternalData.patch(job_id, json.loads('{"status":"RUNNING"}'))
    
    # finally, get the actual job
    job = myExternalData.get(URL, job_id)

    myHostList = job['host_list'] +','
    myModuleName = job['module_name']
    myModuleArgs = job['module_args']
    myPattern = job['pattern']
    myRemoteUser = job['remote_user']
    myRemotePass = job['remote_pass']

    runString = ""

    for arg in myHostList, myModuleName, myModuleArgs, myPattern, myRemoteUser, myRemotePass:
        if ( arg ):
            runString = runString + arg
    
    results = ansible.runner.Runner(
        pattern=myPattern,
        forks=10,
        module_name=myModuleName,
        module_args=myModuleArgs,
        remote_user=myRemoteUser,
        remote_pass=myRemotePass,
        host_list=myHostList,
    ).run()
    # run the ansible stuffs
    #results = ansible.runner.Runner(
    #    pattern=myHost, forks=10,
    #    module_name='command', module_args=myCommand,
    #).run()    

    # get it to a good format
    #data = json.loads(results)
    #data = json.dumps(results)

    # set status to COMPLETE
    myExternalData.patch(job_id, json.loads('{"status":"COMPLETE"}'))
    
    if type(results) == dict:
        results = utils.jsonify(results)
    
    # post results to firebase
    myExternalData.post(job_id + '/returns', results)
    #returns.patch(job_id + '/returns', json.dumps(results))
    return results
예제 #15
0
파일: redis.py 프로젝트: dataxu/ansible
    def set(self, key, value):
        value2 = jsonify(value)
        if self._timeout > 0: # a timeout of 0 is handled as meaning 'never expire'
            self._cache.setex(self._make_key(key), int(self._timeout), value2)
        else:
            self._cache.set(self._make_key(key), value2)

        self._cache.zadd(self._keys_set, time.time(), key)
예제 #16
0
    def _copy_module(self, conn, tmp, module_name, module_args, inject, complex_args=None):
        ''' transfer a module over SFTP, does not run it '''

        # FIXME if complex args is none, set to {}

        if module_name.startswith("/"):
            raise errors.AnsibleFileNotFound("%s is not a module" % module_name)

        # Search module path(s) for named module.
        in_path = utils.plugins.module_finder.find_plugin(module_name)
        if in_path is None:
            raise errors.AnsibleFileNotFound("module %s not found in %s" % (module_name, utils.plugins.module_finder.print_paths()))

        out_path = os.path.join(tmp, module_name)

        module_data = ""
        module_style = 'old'

        with open(in_path) as f:
            module_data = f.read()
            if module_common.REPLACER in module_data:
                module_style = 'new'
            if 'WANT_JSON' in module_data:
                module_style = 'non_native_want_json'

            complex_args_json = utils.jsonify(complex_args)
            # We force conversion of module_args to str because module_common calls shlex.split,
            # a standard library function that incorrectly handles Unicode input before Python 2.7.3.
            encoded_args = repr(module_args.encode('utf-8'))
            encoded_lang = repr(C.DEFAULT_MODULE_LANG)
            encoded_complex = repr(complex_args_json)

            module_data = module_data.replace(module_common.REPLACER, module_common.MODULE_COMMON)
            module_data = module_data.replace(module_common.REPLACER_ARGS, encoded_args)
            module_data = module_data.replace(module_common.REPLACER_LANG, encoded_lang)
            module_data = module_data.replace(module_common.REPLACER_COMPLEX, encoded_complex)

            if module_style == 'new':
                facility = C.DEFAULT_SYSLOG_FACILITY
                if 'ansible_syslog_facility' in inject:
                    facility = inject['ansible_syslog_facility']
                module_data = module_data.replace('syslog.LOG_USER', "syslog.%s" % facility)

        lines = module_data.split("\n")
        shebang = None
        if lines[0].startswith("#!"):
            shebang = lines[0].strip()
            args = shlex.split(str(shebang[2:]))
            interpreter = args[0]
            interpreter_config = 'ansible_%s_interpreter' % os.path.basename(interpreter)

            if interpreter_config in inject:
                lines[0] = shebang = "#!%s %s" % (inject[interpreter_config], " ".join(args[1:]))
                module_data = "\n".join(lines)

        self._transfer_str(conn, tmp, module_name, module_data)

        return (out_path, module_style, shebang)
예제 #17
0
    def on_ok(self, host, host_result):
        if self.runner.delegate_to:
            host = "%s -> %s" % (host, self.runner.delegate_to)

        item = host_result.get("item", None)
        host_result2 = host_result.copy()
        host_result2.pop("invocation", None)
        verbose_always = host_result2.pop("verbose_always", False)
        changed = host_result.get("changed", False)
        ok_or_changed = "ok"

        if changed:
            ok_or_changed = "changed"

        # show verbose output for non-setup module results if --verbose is used
        msg = ""

        if (not self.verbose or host_result2.get("verbose_override", None) is not None) and not verbose_always:
            if item:
                msg = "%s: [%s] => (item=%s)" % (ok_or_changed, host, item)
            else:
                if "ansible_job_id" not in host_result or "finished" in host_result:
                    msg = "%s: [%s]" % (ok_or_changed, host)
        else:
            # verbose ...
            if item:
                msg = "%s: [%s] => (item=%s) => %s" % (
                    ok_or_changed,
                    host,
                    item,
                    utils.jsonify(host_result2, format=verbose_always),
                )
            else:
                if "ansible_job_id" not in host_result or "finished" in host_result2:
                    msg = "%s: [%s] => %s" % (ok_or_changed, host, utils.jsonify(host_result2, format=verbose_always))

        if msg != "":
            if not changed:
                self.display(msg, color="green", runner=self.runner)
            else:
                self.display(msg, color="orange", runner=self.runner)

        if constants.COMMAND_WARNINGS and "warnings" in host_result2 and host_result2["warnings"]:
            for warning in host_result2["warnings"]:
                self.display("warning: %s" % warning, color="purple", runner=self.runner)
예제 #18
0
   def test_one(self):
       pb = 'test/playbook1.yml'
       actual = self._run(pb)

       expected =  {
            "localhost": {
                "changed": 9,
                "failures": 0,
                "ok": 11,
                "skipped": 1,
                "unreachable": 0
            }
       }

       assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)

       # make sure the template module took options from the vars section
       data = file('/tmp/ansible_test_data_template.out').read()
       assert data.find("ears") != -1, "template success"
예제 #19
0
파일: callbacks.py 프로젝트: Silaco/Plus
 def on_unreachable(self, host, res):
     if type(res) == dict:
         res = res.get('msg','')
     res = to_bytes(res)
     display("%s | FAILED => %s" % (host, res), stderr=True, color='red', runner=self.runner)
     if self.options.tree:
         utils.write_tree_file(
             self.options.tree, host,
             utils.jsonify(dict(failed=True, msg=res),format=True)
         )
     super(CliRunnerCallbacks, self).on_unreachable(host, res)
    def on_ok(self, host, host_result):
        if self.runner.delegate_to:
            host = '%s -> %s' % (host, self.runner.delegate_to)

        item = host_result.get('item', None)

        host_result2 = host_result.copy()
        host_result2.pop('invocation', None)
        verbose_always = host_result2.pop('verbose_always', False)
        changed = host_result.get('changed', False)
        ok_or_changed = 'ok'
        if changed:
            ok_or_changed = 'changed'

        # show verbose output for non-setup module results if --verbose is used
        msg = ''
        if (not self.verbose or host_result2.get("verbose_override", None) is not
                None) and not verbose_always:
            if item:
                msg = "%s: [%s] => (item=%s)" % (ok_or_changed, host, item)
            else:
                if 'ansible_job_id' not in host_result or 'finished' in host_result:
                    msg = "%s: [%s]" % (ok_or_changed, host)
        else:
            # verbose ...
            if item:
                msg = "%s: [%s] => (item=%s) => %s" % (ok_or_changed, host, item,
                                                       utils.jsonify(host_result2, format=verbose_always))
            else:
                if 'ansible_job_id' not in host_result or 'finished' in host_result2:
                    msg = "%s: [%s] => %s" % (ok_or_changed, host, utils.jsonify(host_result2, format=verbose_always))

        if msg != '':
            if not changed:
                display(msg, color='green', runner=self.runner, task_id=self.task_id)
            else:
                display(msg, color='yellow', runner=self.runner, task_id=self.task_id)
        if constants.COMMAND_WARNINGS and 'warnings' in host_result2 and host_result2['warnings']:
            for warning in host_result2['warnings']:
                display("warning: %s" % warning, color='purple', runner=self.runner, task_id=self.task_id)
        super(PlaybookRunnerCallbacks, self).on_ok(host, host_result)
예제 #21
0
   def test_one(self):
       pb = os.path.join(self.test_dir, 'playbook1.yml')
       actual = self._run(pb)

       # if different, this will output to screen
       print "**ACTUAL**"
       print utils.jsonify(actual, format=True)
       expected =  {
            "localhost": {
                "changed": 9,
                "failures": 0,
                "ok": 11,
                "skipped": 1,
                "unreachable": 0
            }
       }
       print "**EXPECTED**"
       print utils.jsonify(expected, format=True)

       assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)

       # make sure the template module took options from the vars section
       data = file('/tmp/ansible_test_data_template.out').read()
       print data
       assert data.find("ears") != -1, "template success"
예제 #22
0
    def fetch_file(self, in_path, out_path):
        ''' save a remote file to the specified path '''
        vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host)

        data = dict(mode='fetch', in_path=in_path)
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        if self.send_data(data):
            raise errors.AnsibleError("failed to initiate the file fetch with %s" % self.host)

        fh = open(out_path, "w")
        try:
            bytes = 0
            while True:
                response = self.recv_data()
                if not response:
                    raise errors.AnsibleError("Failed to get a response from %s" % self.host)
                response = utils.decrypt(self.key, response)
                response = utils.parse_json(response)
                if response.get('failed', False):
                    raise errors.AnsibleError("Error during file fetch, aborting")
                out = base64.b64decode(response['data'])
                fh.write(out)
                bytes += len(out)
                # send an empty response back to signify we 
                # received the last chunk without errors
                data = utils.jsonify(dict())
                data = utils.encrypt(self.key, data)
                if self.send_data(data):
                    raise errors.AnsibleError("failed to send ack during file fetch")
                if response.get('last', False):
                    break
        finally:
            # we don't currently care about this final response,
            # we just receive it and drop it. It may be used at some
            # point in the future or we may just have the put/fetch
            # operations not send back a final response at all
            response = self.recv_data()
            vvv("FETCH wrote %d bytes to %s" % (bytes, out_path))
            fh.close()
예제 #23
0
   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)
예제 #24
0
   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)
예제 #25
0
   def test_templated_includes(self):
       pb = os.path.join(self.test_dir, 'playbook-templated-includer.yml')
       actual = self._run(pb, extra_vars={ 'dir': self.test_dir })

       # if different, this will output to screen
       print "**ACTUAL**"
       actual_json = utils.jsonify(actual, format=True)
       print actual_json
       expected =  {
           "localhost": {
               "changed": 0,
               "failures": 0,
               "ok": 2,
               "skipped": 0,
               "unreachable": 0
           }
       }
       expected_json = utils.jsonify(expected, format=True)
       print "**EXPECTED**"
       print expected_json 

       assert actual_json == expected_json
예제 #26
0
    def modify_module(self, module_path, complex_args, module_args, inject):

        with open(module_path) as f:

            # read in the module source
            module_data = f.read()

            (module_data, module_style) = self._find_snippet_imports(module_data, module_path)

            complex_args_json = utils.jsonify(complex_args)
            # We force conversion of module_args to str because module_common calls shlex.split,
            # a standard library function that incorrectly handles Unicode input before Python 2.7.3.
            # Note: it would be better to do all this conversion at the border
            # (when the data is originally parsed into data structures) but
            # it's currently coming from too many sources to make that
            # effective.
            try:
                encoded_args = repr(module_args.encode('utf-8'))
            except UnicodeDecodeError:
                encoded_args = repr(module_args)
            try:
                encoded_complex = repr(complex_args_json.encode('utf-8'))
            except UnicodeDecodeError:
                encoded_complex = repr(complex_args_json.encode('utf-8'))

            # these strings should be part of the 'basic' snippet which is required to be included
            module_data = module_data.replace(REPLACER_VERSION, repr(__version__))
            module_data = module_data.replace(REPLACER_SELINUX, ','.join(C.DEFAULT_SELINUX_SPECIAL_FS))
            module_data = module_data.replace(REPLACER_ARGS, encoded_args)
            module_data = module_data.replace(REPLACER_COMPLEX, encoded_complex)

            if module_style == 'new':
                facility = C.DEFAULT_SYSLOG_FACILITY
                if 'ansible_syslog_facility' in inject:
                    facility = inject['ansible_syslog_facility']
                module_data = module_data.replace('syslog.LOG_USER', "syslog.%s" % facility)

            lines = module_data.split("\n")
            shebang = None
            if lines[0].startswith("#!"):
                shebang = lines[0].strip()
                args = shlex.split(str(shebang[2:]))
                interpreter = args[0]
                interpreter_config = 'ansible_%s_interpreter' % os.path.basename(interpreter)

                if interpreter_config in inject:
                    interpreter = to_bytes(inject[interpreter_config], errors='strict')
                    lines[0] = shebang = "#!%s %s" % (interpreter, " ".join(args[1:]))
                    module_data = "\n".join(lines)

            return (module_data, module_style, shebang)
예제 #27
0
    def on_ok(self, host, host_result):
        delegate_to = self.runner.module_vars.get('delegate_to')
        if delegate_to:
            host = '%s -> %s' % (host, delegate_to)

        item = host_result.get('item', None)

        host_result2 = host_result.copy()
        host_result2.pop('invocation', None)
        verbose_always = host_result2.pop('verbose_always', False)
        changed = host_result.get('changed', False)
        ok_or_changed = 'ok'
        if changed:
            ok_or_changed = 'changed'

        # show verbose output for non-setup module results if --verbose is used
        msg = ''
        if (not self.verbose or host_result2.get("verbose_override",None) is not
                None) and not verbose_always:
            if item:
                msg = "%s: [%s] => (item=%s)" % (ok_or_changed, host, item)
            else:
                if 'ansible_job_id' not in host_result or 'finished' in host_result:
                    msg = "%s: [%s]" % (ok_or_changed, host)
        else:
            # verbose ...
            if item:
                msg = "%s: [%s] => (item=%s) => %s" % (ok_or_changed, host, item, utils.jsonify(host_result2, format=verbose_always))
            else:
                if 'ansible_job_id' not in host_result or 'finished' in host_result2:
                    msg = "%s: [%s] => %s" % (ok_or_changed, host, utils.jsonify(host_result2, format=verbose_always))

        if msg != '':
            if not changed:
                display(msg, self.sqs_response_queue, self.sqs_request_message)
            else:
                display(msg, self.sqs_response_queue, self.sqs_request_message)
        super(PlaybookRunnerCallbacks, self).on_ok(host, host_result)
예제 #28
0
    def put_file(self, in_path, out_path):

        ''' transfer a file from local to remote '''
        vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)

        if not os.path.exists(in_path):
            raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path)
        data = file(in_path).read()
        
        data = dict(mode='put', data=data, out_path=out_path)
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        self.socket.send(data)

        response = self.socket.recv()
        response = utils.decrypt(self.key, response)
        response = utils.parse_json(response)
예제 #29
0
    def fetch_file(self, in_path, out_path):
        ''' save a remote file to the specified path '''
        vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host)

        data = dict(mode='fetch', file=in_path)
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        self.socket.send(data)

        response = self.socket.recv()
        response = utils.decrypt(self.key, response)
        response = utils.parse_json(response)
        response = response['data']

        fh = open(out_path, "w")
        fh.write(response)
        fh.close()
예제 #30
0
    def put_file(self, in_path, out_path):

        ''' transfer a file from local to remote '''
        vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)

        if not os.path.exists(in_path):
            raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path)

        fd = file(in_path, 'rb')
        fstat = os.stat(in_path)
        try:
            vvv("PUT file is %d bytes" % fstat.st_size)
            last = False
            while fd.tell() <= fstat.st_size and not last:
                vvvv("file position currently %ld, file size is %ld" % (fd.tell(), fstat.st_size))
                data = fd.read(CHUNK_SIZE)
                if fd.tell() >= fstat.st_size:
                    last = True
                data = dict(mode='put', data=base64.b64encode(data), out_path=out_path, last=last)
                if self.runner.sudo:
                    data['user'] = self.runner.sudo_user
                data = utils.jsonify(data)
                data = utils.encrypt(self.key, data)

                if self.send_data(data):
                    raise errors.AnsibleError("failed to send the file to %s" % self.host)

                response = self.recv_data()
                if not response:
                    raise errors.AnsibleError("Failed to get a response from %s" % self.host)
                response = utils.decrypt(self.key, response)
                response = utils.parse_json(response)

                if response.get('failed',False):
                    raise errors.AnsibleError("failed to put the file in the requested location")
        finally:
            fd.close()
            vvvv("waiting for final response after PUT")
            response = self.recv_data()
            if not response:
                raise errors.AnsibleError("Failed to get a response from %s" % self.host)
            response = utils.decrypt(self.key, response)
            response = utils.parse_json(response)

            if response.get('failed',False):
                raise errors.AnsibleError("failed to put the file in the requested location")
예제 #31
0
    def put_file(self, in_path, out_path):

        ''' transfer a file from local to remote '''
        vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)

        if not os.path.exists(in_path):
            raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path)
        data = file(in_path).read()
        data = base64.b64encode(data)

        data = dict(mode='put', data=data, out_path=out_path)
        # TODO: support chunked file transfer
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        self.socket.send(data)

        response = self.socket.recv()
        response = utils.decrypt(self.key, response)
        response = utils.parse_json(response)
예제 #32
0
    def modify_module(self, module_path, complex_args, module_args, inject):

        with open(module_path) as f:

            # read in the module source
            module_data = f.read()

            (module_data, module_style) = self._find_snippet_imports(module_data, module_path)

            complex_args_json = utils.jsonify(complex_args)
            # We force conversion of module_args to str because module_common calls shlex.split,
            # a standard library function that incorrectly handles Unicode input before Python 2.7.3.
            try:
                encoded_args = repr(module_args.encode('utf-8'))
            except UnicodeDecodeError:
                encoded_args = repr(module_args)
            encoded_complex = repr(complex_args_json)

            # these strings should be part of the 'basic' snippet which is required to be included
            module_data = module_data.replace(REPLACER_VERSION, repr(__version__))
            module_data = module_data.replace(REPLACER_ARGS, encoded_args)
            module_data = module_data.replace(REPLACER_COMPLEX, encoded_complex)

            if module_style == 'new':
                facility = C.DEFAULT_SYSLOG_FACILITY
                if 'ansible_syslog_facility' in inject:
                    facility = inject['ansible_syslog_facility']
                module_data = module_data.replace('syslog.LOG_USER', "syslog.%s" % facility)

            lines = module_data.split("\n")
            shebang = None
            if lines[0].startswith("#!"):
                shebang = lines[0].strip()
                args = shlex.split(str(shebang[2:]))
                interpreter = args[0]
                interpreter_config = 'ansible_%s_interpreter' % os.path.basename(interpreter)

                if interpreter_config in inject:
                    lines[0] = shebang = "#!%s %s" % (inject[interpreter_config], " ".join(args[1:]))
                    module_data = "\n".join(lines)

            return (module_data, module_style, shebang)
예제 #33
0
    def validate_user(self):
        '''
        Checks the remote uid of the accelerated daemon vs. the 
        one specified for this play and will cause the accel 
        daemon to exit if they don't match
        '''

        vvvv("%s: sending request for validate_user" % self.host)
        data = dict(
            mode='validate_user',
            username=self.user,
        )
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        if self.send_data(data):
            raise AnsibleError("Failed to send command to %s" % self.host)

        vvvv("%s: waiting for validate_user response" % self.host)
        while True:
            # we loop here while waiting for the response, because a
            # long running command may cause us to receive keepalive packets
            # ({"pong":"true"}) rather than the response we want.
            response = self.recv_data()
            if not response:
                raise AnsibleError("Failed to get a response from %s" %
                                   self.host)
            response = utils.decrypt(self.key, response)
            response = utils.parse_json(response)
            if "pong" in response:
                # it's a keepalive, go back to waiting
                vvvv("%s: received a keepalive packet" % self.host)
                continue
            else:
                vvvv("%s: received the validate_user response: %s" %
                     (self.host, response))
                break

        if response.get('failed'):
            return False
        else:
            return response.get('rc') == 0
예제 #34
0
    def exec_command(self,
                     cmd,
                     tmp_path,
                     sudo_user,
                     sudoable=False,
                     executable='/bin/sh',
                     in_data=None,
                     su_user=None,
                     su=None):
        ''' run a command on the remote host '''

        if in_data:
            raise errors.AnsibleError(
                "Internal Error: this module does not support optimized module pipelining"
            )

        vvv("EXEC COMMAND %s" % cmd)

        if (self.runner.sudo and sudoable) or (self.runner.su and su):
            raise errors.AnsibleError(
                "When using fireball, do not specify sudo or su to run your tasks. "
                + "Instead sudo the fireball action with sudo. " +
                "Task will communicate with the fireball already running in sudo mode."
            )

        data = dict(
            mode='command',
            cmd=cmd,
            tmp_path=tmp_path,
            executable=executable,
        )
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        self.socket.send(data)

        response = self.socket.recv()
        response = utils.decrypt(self.key, response)
        response = utils.parse_json(response)

        return (response.get('rc', None), '', response.get('stdout', ''),
                response.get('stderr', ''))
예제 #35
0
 def _copy_module(self, conn, tmp, module_name, module_args, inject, complex_args=None):
     ''' transfer a module over SFTP, does not run it '''
     # FIXME if complex args is none, set to {}
     if module_name.startswith("/"):
         raise errors.AnsibleFileNotFound("%s is not a module" % module_name)
     # Search module path(s) for named module.
     in_path = utils.plugins.module_finder.find_plugin(module_name)
     if in_path is None:
         raise errors.AnsibleFileNotFound("module %s not found in %s" % (module_name, utils.plugins.module_finder.print_paths()))
     out_path = os.path.join(tmp, module_name)
     module_data = ""
     is_new_style=False
     with open(in_path) as f:
         module_data = f.read()
         if module_common.REPLACER in module_data:
             is_new_style=True
         complex_args_json = utils.jsonify(complex_args)
         encoded_args = "\"\"\"%s\"\"\"" % module_args.replace("\"","\\\"")
         encoded_lang = "\"\"\"%s\"\"\"" % C.DEFAULT_MODULE_LANG
         encoded_complex = "\"\"\"%s\"\"\"" % complex_args_json.replace("\\", "\\\\")
         module_data = module_data.replace(module_common.REPLACER, module_common.MODULE_COMMON)
         module_data = module_data.replace(module_common.REPLACER_ARGS, encoded_args)
         module_data = module_data.replace(module_common.REPLACER_LANG, encoded_lang)
         module_data = module_data.replace(module_common.REPLACER_COMPLEX, encoded_complex)
         if is_new_style:
             facility = C.DEFAULT_SYSLOG_FACILITY
             if 'ansible_syslog_facility' in inject:
                 facility = inject['ansible_syslog_facility']
             module_data = module_data.replace('syslog.LOG_USER', "syslog.%s" % facility)
     lines = module_data.split("\n")
     shebang = None
     if lines[0].startswith("#!"):
         shebang = lines[0]
         args = shlex.split(str(shebang[2:]))
         interpreter = args[0]
         interpreter_config = 'ansible_%s_interpreter' % os.path.basename(interpreter)
         if interpreter_config in inject:
             lines[0] = shebang = "#!%s %s" % (inject[interpreter_config], " ".join(args[1:]))
             module_data = "\n".join(lines)
     self._transfer_str(conn, tmp, module_name, module_data)
     return (out_path, is_new_style, shebang)
예제 #36
0
    def _transfer_str(self, conn, tmp, name, data):
        ''' transfer string to remote file '''

        if type(data) == dict:
            data = utils.jsonify(data)

        afd, afile = tempfile.mkstemp()
        afo = os.fdopen(afd, 'w')
        try:
            afo.write(data.encode('utf8'))
        except:
            raise errors.AnsibleError("failure encoding into utf-8")
        afo.flush()
        afo.close()

        remote = os.path.join(tmp, name)
        try:
            conn.put_file(afile, remote)
        finally:
            os.unlink(afile)
        return remote
예제 #37
0
    def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bin/sh'):
        ''' run a command on the remote host '''

        if executable == "":
            executable = constants.DEFAULT_EXECUTABLE

        if self.runner.sudo and sudoable and sudo_user:
            cmd, prompt, success_key = utils.make_sudo_cmd(sudo_user, executable, cmd)

        vvv("EXEC COMMAND %s" % cmd)

        data = dict(
            mode='command',
            cmd=cmd,
            tmp_path=tmp_path,
            executable=executable,
        )
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        if self.send_data(data):
            raise errors.AnsibleError("Failed to send command to %s" % self.host)
        
        while True:
            # we loop here while waiting for the response, because a 
            # long running command may cause us to receive keepalive packets
            # ({"pong":"true"}) rather than the response we want. 
            response = self.recv_data()
            if not response:
                raise errors.AnsibleError("Failed to get a response from %s" % self.host)
            response = utils.decrypt(self.key, response)
            response = utils.parse_json(response)
            if "pong" in response:
                # it's a keepalive, go back to waiting
                vvvv("%s: received a keepalive packet" % self.host)
                continue
            else:
                vvvv("%s: received the response" % self.host)
                break

        return (response.get('rc',None), '', response.get('stdout',''), response.get('stderr',''))
예제 #38
0
    def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False):
        ''' run a command on the remote host '''

        vvv("EXEC COMMAND %s" % cmd)

        if self.runner.sudo and sudoable:
            raise errors.AnsibleError("fireball does not use sudo, but runs as whoever it was initiated as.  (That itself is where to use sudo).")

        data = dict(
            mode='command',
            cmd=cmd,
            tmp_path=tmp_path,
        )
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        self.socket.send(data)
        
        response = self.socket.recv()
        response = utils.decrypt(self.key, response)
        response = utils.parse_json(response)

        return (response.get('rc',None), '', response.get('stdout',''), response.get('stderr',''))
예제 #39
0
    def _executor_internal_inner(self, host, module_name, module_args, inject, port, is_chained=False):
        ''' decides how to invoke a module '''

        # special non-user/non-fact variables:
        # 'groups' variable is a list of host name in each group
        # 'hostvars' variable contains variables for each host name
        #  ... and is set elsewhere
        # 'inventory_hostname' is also set elsewhere
        inject['groups'] = self.inventory.groups_list()

        # allow module args to work as a dictionary
        # though it is usually a string
        new_args = ""
        if type(module_args) == dict:
            for (k,v) in module_args.iteritems():
                new_args = new_args + "%s='%s' " % (k,v)
            module_args = new_args

        conditional = utils.template(self.basedir, self.conditional, inject)
        if not utils.check_conditional(conditional):
            result = utils.jsonify(dict(skipped=True))
            self.callbacks.on_skipped(host, inject.get('item',None))
            return ReturnData(host=host, result=result)

        conn = None
        actual_host = host
        try:
            delegate_to = inject.get('delegate_to', None)
            alternative_host = inject.get('ansible_ssh_host', None)
            if delegate_to is not None:
                actual_host = delegate_to
            elif alternative_host is not None:
                actual_host = alternative_host
            conn = self.connector.connect(actual_host, port)
            if delegate_to is not None or alternative_host is not None:
                conn._delegate_for = host
        except errors.AnsibleConnectionFailed, e:
            result = dict(failed=True, msg="FAILED: %s" % str(e))
            return ReturnData(host=host, comm_ok=False, result=result)
예제 #40
0
    def exec_command(self,
                     cmd,
                     tmp_path,
                     sudo_user,
                     sudoable=False,
                     executable='/bin/sh'):
        ''' run a command on the remote host '''

        if executable == "":
            executable = constants.DEFAULT_EXECUTABLE

        if self.runner.sudo and sudoable and sudo_user:
            cmd, prompt = utils.make_sudo_cmd(sudo_user, executable, cmd)

        vvv("EXEC COMMAND %s" % cmd)

        data = dict(
            mode='command',
            cmd=cmd,
            tmp_path=tmp_path,
            executable=executable,
        )
        data = utils.jsonify(data)
        data = utils.encrypt(self.key, data)
        if self.send_data(data):
            raise errors.AnsibleError("Failed to send command to %s" %
                                      self.host)

        response = self.recv_data()
        if not response:
            raise errors.AnsibleError("Failed to get a response from %s" %
                                      self.host)
        response = utils.decrypt(self.key, response)
        response = utils.parse_json(response)

        return (response.get('rc', None), '', response.get('stdout', ''),
                response.get('stderr', ''))
예제 #41
0
   def test_includes(self):
       pb = os.path.join(self.test_dir, 'playbook-includer.yml')
       actual = self._run(pb)

       # if different, this will output to screen
       print "**ACTUAL**"
       print utils.jsonify(actual, format=True)
       expected =  {
           "localhost": {
               "changed": 0,
               "failures": 0,
               "ok": 10,
               "skipped": 0,
               "unreachable": 0
           }   
       }   
       print "**EXPECTED**"
       print utils.jsonify(expected, format=True)

       assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)
예제 #42
0
   def test_lookups(self):
       pb = os.path.join(self.test_dir, 'lookup_plugins.yml')
       actual = self._run(pb)

       # if different, this will output to screen
       print "**ACTUAL**"
       print utils.jsonify(actual, format=True)
       expected =  {
           "localhost": {
               "changed": 7,
               "failures": 0,
               "ok": 9,
               "skipped": 1,
               "unreachable": 0
           }   
       }   
       print "**EXPECTED**"
       print utils.jsonify(expected, format=True)

       assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)

       print "len(EVENTS) = %d" % len(EVENTS)
       assert len(EVENTS) == 26
예제 #43
0
    def _executor_internal_inner(self,
                                 host,
                                 module_name,
                                 module_args,
                                 inject,
                                 port,
                                 is_chained=False,
                                 complex_args=None):
        ''' decides how to invoke a module '''

        # allow module args to work as a dictionary
        # though it is usually a string
        new_args = ""
        if type(module_args) == dict:
            for (k, v) in module_args.iteritems():
                new_args = new_args + "%s='%s' " % (k, v)
            module_args = new_args

        module_name = utils.template(self.basedir, module_name, inject)
        module_args = utils.template(self.basedir, module_args, inject)
        complex_args = utils.template(self.basedir, complex_args, inject)

        if module_name in utils.plugins.action_loader:
            if self.background != 0:
                raise errors.AnsibleError(
                    "async mode is not supported with the %s module" %
                    module_name)
            handler = utils.plugins.action_loader.get(module_name, self)
        elif self.background == 0:
            handler = utils.plugins.action_loader.get('normal', self)
        else:
            handler = utils.plugins.action_loader.get('async', self)

        conditional = utils.template(self.basedir,
                                     self.conditional,
                                     inject,
                                     expand_lists=False)
        if not utils.check_conditional(conditional):
            result = utils.jsonify(dict(skipped=True))
            self.callbacks.on_skipped(host, inject.get('item', None))
            return ReturnData(host=host, result=result)

        conn = None
        actual_host = inject.get('ansible_ssh_host', host)
        actual_port = port
        actual_user = inject.get('ansible_ssh_user', self.remote_user)
        actual_pass = inject.get('ansible_ssh_pass', self.remote_pass)
        actual_transport = inject.get('ansible_connection', self.transport)
        if actual_transport in ['paramiko', 'ssh']:
            actual_port = inject.get('ansible_ssh_port', port)

        # the delegated host may have different SSH port configured, etc
        # and we need to transfer those, and only those, variables
        delegate_to = inject.get('delegate_to', None)
        if delegate_to is not None:
            delegate_to = utils.template(self.basedir, delegate_to, inject)
            inject = inject.copy()
            interpreters = []
            for i in inject:
                if i.startswith("ansible_") and i.endswith("_interpreter"):
                    interpreters.append(i)
            for i in interpreters:
                del inject[i]
            port = C.DEFAULT_REMOTE_PORT
            try:
                delegate_info = inject['hostvars'][delegate_to]
                actual_host = delegate_info.get('ansible_ssh_host',
                                                delegate_to)
                actual_port = delegate_info.get('ansible_ssh_port', port)
                actual_user = delegate_info.get('ansible_ssh_user',
                                                actual_user)
                actual_pass = delegate_info.get('ansible_ssh_pass',
                                                actual_pass)
                actual_transport = delegate_info.get('ansible_connection',
                                                     self.transport)
                for i in delegate_info:
                    if i.startswith("ansible_") and i.endswith("_interpreter"):
                        inject[i] = delegate_info[i]
            except errors.AnsibleError:
                actual_host = delegate_to
                actual_port = port

        actual_user = utils.template(self.basedir, actual_user, inject)
        actual_pass = utils.template(self.basedir, actual_pass, inject)

        try:
            if actual_port is not None:
                actual_port = int(actual_port)
        except ValueError, e:
            result = dict(
                failed=True,
                msg=
                "FAILED: Configured port \"%s\" is not a valid port, expected integer"
                % actual_port)
            return ReturnData(host=host, comm_ok=False, result=result)
예제 #44
0
    def _executor_internal_inner(self, host, module_name, module_args, inject, port, is_chained=False, complex_args=None):
        ''' decides how to invoke a module '''

        # late processing of parameterized sudo_user (with_items,..)
        if self.sudo_user_var is not None:
            self.sudo_user = template.template(self.basedir, self.sudo_user_var, inject)

        # allow module args to work as a dictionary
        # though it is usually a string
        new_args = ""
        if type(module_args) == dict:
            for (k,v) in module_args.iteritems():
                new_args = new_args + "%s='%s' " % (k,v)
            module_args = new_args

        # module_name may be dynamic (but cannot contain {{ ansible_ssh_user }})
        module_name  = template.template(self.basedir, module_name, inject)

        if module_name in utils.plugins.action_loader:
            if self.background != 0:
                raise errors.AnsibleError("async mode is not supported with the %s module" % module_name)
            handler = utils.plugins.action_loader.get(module_name, self)
        elif self.background == 0:
            handler = utils.plugins.action_loader.get('normal', self)
        else:
            handler = utils.plugins.action_loader.get('async', self)

        if type(self.conditional) != list:
            self.conditional = [ self.conditional ]

        for cond in self.conditional:

            if not utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars):
                result = utils.jsonify(dict(changed=False, skipped=True))
                self.callbacks.on_skipped(host, inject.get('item',None))
                return ReturnData(host=host, result=result)

        if getattr(handler, 'setup', None) is not None:
            handler.setup(module_name, inject)
        conn = None
        actual_host = inject.get('ansible_ssh_host', host)
        # allow ansible_ssh_host to be templated
        actual_host = template.template(self.basedir, actual_host, inject, fail_on_undefined=True)
        actual_port = port
        actual_user = inject.get('ansible_ssh_user', self.remote_user)
        actual_pass = inject.get('ansible_ssh_pass', self.remote_pass)
        actual_transport = inject.get('ansible_connection', self.transport)
        actual_private_key_file = inject.get('ansible_ssh_private_key_file', self.private_key_file)

        if self.accelerate and actual_transport != 'local':
            #Fix to get the inventory name of the host to accelerate plugin
            if inject.get('ansible_ssh_host', None):
                self.accelerate_inventory_host = host
            else:
                self.accelerate_inventory_host = None
            # if we're using accelerated mode, force the
            # transport to accelerate
            actual_transport = "accelerate"
            if not self.accelerate_port:
                self.accelerate_port = C.ACCELERATE_PORT

        if actual_transport in [ 'paramiko', 'ssh', 'accelerate' ]:
            actual_port = inject.get('ansible_ssh_port', port)

        # the delegated host may have different SSH port configured, etc
        # and we need to transfer those, and only those, variables
        delegate_to = inject.get('delegate_to', None)
        if delegate_to is not None:
            delegate_to = template.template(self.basedir, delegate_to, inject)
            inject = inject.copy()
            interpreters = []
            for i in inject:
                if i.startswith("ansible_") and i.endswith("_interpreter"):
                    interpreters.append(i)
            for i in interpreters:
                del inject[i]
            port = C.DEFAULT_REMOTE_PORT
            try:
                delegate_info = inject['hostvars'][delegate_to]
                actual_host = delegate_info.get('ansible_ssh_host', delegate_to)
                # allow ansible_ssh_host to be templated
                actual_host = template.template(self.basedir, actual_host, inject, fail_on_undefined=True)
                actual_port = delegate_info.get('ansible_ssh_port', port)
                actual_user = delegate_info.get('ansible_ssh_user', actual_user)
                actual_pass = delegate_info.get('ansible_ssh_pass', actual_pass)
                actual_private_key_file = delegate_info.get('ansible_ssh_private_key_file', self.private_key_file)
                actual_transport = delegate_info.get('ansible_connection', self.transport)
                for i in delegate_info:
                    if i.startswith("ansible_") and i.endswith("_interpreter"):
                        inject[i] = delegate_info[i]
            except errors.AnsibleError:
                actual_host = delegate_to
                actual_port = port

        # user/pass may still contain variables at this stage
        actual_user = template.template(self.basedir, actual_user, inject)
        actual_pass = template.template(self.basedir, actual_pass, inject)

        # make actual_user available as __magic__ ansible_ssh_user variable
        inject['ansible_ssh_user'] = actual_user

        try:
            if actual_transport == 'accelerate':
                # for accelerate, we stuff both ports into a single
                # variable so that we don't have to mangle other function
                # calls just to accomodate this one case
                actual_port = [actual_port, self.accelerate_port]
            elif actual_port is not None:
                actual_port = int(template.template(self.basedir, actual_port, inject))
        except ValueError, e:
            result = dict(failed=True, msg="FAILED: Configured port \"%s\" is not a valid port, expected integer" % actual_port)
            return ReturnData(host=host, comm_ok=False, result=result)
예제 #45
0
    def _execute_module(self, conn, tmp, module_name, args,
        async_jid=None, async_module=None, async_limit=None, inject=None, persist_files=False, complex_args=None):

        ''' runs a module that has already been transferred '''

        # hack to support fireball mode
        if module_name == 'fireball':
            args = "%s password=%s" % (args, base64.b64encode(str(utils.key_for_hostname(conn.host))))
            if 'port' not in args:
                args += " port=%s" % C.ZEROMQ_PORT

        (remote_module_path, module_style, shebang) = self._copy_module(conn, tmp, module_name, args, inject, complex_args)

        environment_string = self._compute_environment_string(inject)

        cmd_mod = ""
        if self.sudo and self.sudo_user != 'root':
            # deal with possible umask issues once sudo'ed to other user
            cmd_chmod = "chmod a+r %s" % remote_module_path
            self._low_level_exec_command(conn, cmd_chmod, tmp, sudoable=False)

        cmd = ""
        if module_style != 'new':
            if 'CHECKMODE=True' in args:
                # if module isn't using AnsibleModuleCommon infrastructure we can't be certain it knows how to
                # do --check mode, so to be safe we will not run it.
                return ReturnData(conn=conn, result=dict(skippped=True, msg="cannot yet run check mode against old-style modules"))

            args = template.template(self.basedir, args, inject)

            # decide whether we need to transfer JSON or key=value
            argsfile = None
            if module_style == 'non_native_want_json':
                if complex_args:
                    complex_args.update(utils.parse_kv(args))
                    argsfile = self._transfer_str(conn, tmp, 'arguments', utils.jsonify(complex_args))
                else:
                    argsfile = self._transfer_str(conn, tmp, 'arguments', utils.jsonify(utils.parse_kv(args)))

            else:
                argsfile = self._transfer_str(conn, tmp, 'arguments', args)

            if self.sudo and self.sudo_user != 'root':
                # deal with possible umask issues once sudo'ed to other user
                cmd_args_chmod = "chmod a+r %s" % argsfile
                self._low_level_exec_command(conn, cmd_args_chmod, tmp, sudoable=False)

            if async_jid is None:
                cmd = "%s %s" % (remote_module_path, argsfile)
            else:
                cmd = " ".join([str(x) for x in [remote_module_path, async_jid, async_limit, async_module, argsfile]])
        else:
            if async_jid is None:
                cmd = "%s" % (remote_module_path)
            else:
                cmd = " ".join([str(x) for x in [remote_module_path, async_jid, async_limit, async_module]])

        if not shebang:
            raise errors.AnsibleError("module is missing interpreter line")

        cmd = " ".join([environment_string.strip(), shebang.replace("#!","").strip(), cmd])
        cmd = cmd.strip()

        if tmp.find("tmp") != -1 and not C.DEFAULT_KEEP_REMOTE_FILES and not persist_files:
            if not self.sudo or self.sudo_user == 'root':
                # not sudoing or sudoing to root, so can cleanup files in the same step
                cmd = cmd + "; rm -rf %s >/dev/null 2>&1" % tmp

        sudoable = True
        if module_name == "accelerate":
            # always run the accelerate module as the user
            # specified in the play, not the sudo_user
            sudoable = False

        res = self._low_level_exec_command(conn, cmd, tmp, sudoable=sudoable)

        if self.sudo and self.sudo_user != 'root':
            # not sudoing to root, so maybe can't delete files as that other user
            # have to clean up temp files as original user in a second step
            if tmp.find("tmp") != -1 and not C.DEFAULT_KEEP_REMOTE_FILES and not persist_files:
                cmd2 = "rm -rf %s >/dev/null 2>&1" % tmp
                self._low_level_exec_command(conn, cmd2, tmp, sudoable=False)

        data = utils.parse_json(res['stdout'])
        if 'parsed' in data and data['parsed'] == False:
            data['msg'] += res['stderr']
        return ReturnData(conn=conn, result=data)
예제 #46
0
    def _executor_internal_inner(self,
                                 host,
                                 module_name,
                                 module_args,
                                 inject,
                                 port,
                                 is_chained=False):
        ''' decides how to invoke a module '''

        # special non-user/non-fact variables:
        # 'groups' variable is a list of host name in each group
        # 'hostvars' variable contains variables for each host name
        #  ... and is set elsewhere
        # 'inventory_hostname' is also set elsewhere
        inject['groups'] = self.inventory.groups_list()

        # allow module args to work as a dictionary
        # though it is usually a string
        new_args = ""
        if type(module_args) == dict:
            for (k, v) in module_args.iteritems():
                new_args = new_args + "%s='%s' " % (k, v)
            module_args = new_args

        conditional = utils.template(self.basedir, self.conditional, inject)
        if not utils.check_conditional(conditional):
            result = utils.jsonify(dict(skipped=True))
            self.callbacks.on_skipped(host, inject.get('item', None))
            return ReturnData(host=host, result=result)

        conn = None
        actual_host = inject.get('ansible_ssh_host', host)
        actual_port = port
        if self.transport in ['paramiko', 'ssh']:
            actual_port = inject.get('ansible_ssh_port', port)

        # the delegated host may have different SSH port configured, etc
        # and we need to transfer those, and only those, variables
        delegate_to = inject.get('delegate_to', None)
        if delegate_to is not None:
            delegate_to = utils.template(self.basedir, delegate_to, inject)
            inject = inject.copy()
            interpreters = []
            for i in inject:
                if i.startswith("ansible_") and i.endswith("_interpreter"):
                    interpreters.append(i)
            for i in interpreters:
                del inject[i]
            port = C.DEFAULT_REMOTE_PORT
            try:
                delegate_info = inject['hostvars'][delegate_to]
                actual_host = delegate_info.get('ansible_ssh_host',
                                                delegate_to)
                actual_port = delegate_info.get('ansible_ssh_port', port)
                for i in delegate_info:
                    if i.startswith("ansible_") and i.endswith("_interpreter"):
                        inject[i] = delegate_info[i]
            except errors.AnsibleError:
                actual_host = delegate_to
                actual_port = port

        try:
            if actual_port is not None:
                actual_port = int(actual_port)
            conn = self.connector.connect(actual_host, actual_port)
            if delegate_to or host != actual_host:
                conn.delegate = host

        except errors.AnsibleConnectionFailed, e:
            result = dict(failed=True, msg="FAILED: %s" % str(e))
            return ReturnData(host=host, comm_ok=False, result=result)
예제 #47
0
    def _copy_module(self,
                     conn,
                     tmp,
                     module_name,
                     module_args,
                     inject,
                     complex_args=None):
        ''' transfer a module over SFTP, does not run it '''

        # FIXME if complex args is none, set to {}

        if module_name.startswith("/"):
            raise errors.AnsibleFileNotFound("%s is not a module" %
                                             module_name)

        # Search module path(s) for named module.
        in_path = utils.plugins.module_finder.find_plugin(module_name)
        if in_path is None:
            raise errors.AnsibleFileNotFound(
                "module %s not found in %s" %
                (module_name, utils.plugins.module_finder.print_paths()))

        out_path = os.path.join(tmp, module_name)

        module_data = ""
        module_style = 'old'

        with open(in_path) as f:
            module_data = f.read()
            if module_common.REPLACER in module_data:
                module_style = 'new'
            if 'WANT_JSON' in module_data:
                module_style = 'non_native_want_json'

            complex_args_json = utils.jsonify(complex_args)
            # We force conversion of module_args to str because module_common calls shlex.split,
            # a standard library function that incorrectly handles Unicode input before Python 2.7.3.
            encoded_args = repr(str(module_args))
            encoded_lang = repr(C.DEFAULT_MODULE_LANG)
            encoded_complex = repr(complex_args_json)

            module_data = module_data.replace(module_common.REPLACER,
                                              module_common.MODULE_COMMON)
            module_data = module_data.replace(module_common.REPLACER_ARGS,
                                              encoded_args)
            module_data = module_data.replace(module_common.REPLACER_LANG,
                                              encoded_lang)
            module_data = module_data.replace(module_common.REPLACER_COMPLEX,
                                              encoded_complex)

            if module_style == 'new':
                facility = C.DEFAULT_SYSLOG_FACILITY
                if 'ansible_syslog_facility' in inject:
                    facility = inject['ansible_syslog_facility']
                module_data = module_data.replace('syslog.LOG_USER',
                                                  "syslog.%s" % facility)

        lines = module_data.split("\n")
        shebang = None
        if lines[0].startswith("#!"):
            shebang = lines[0].strip()
            args = shlex.split(str(shebang[2:]))
            interpreter = args[0]
            interpreter_config = 'ansible_%s_interpreter' % os.path.basename(
                interpreter)

            if interpreter_config in inject:
                lines[0] = shebang = "#!%s %s" % (inject[interpreter_config],
                                                  " ".join(args[1:]))
                module_data = "\n".join(lines)

        self._transfer_str(conn, tmp, module_name, module_data)

        return (out_path, module_style, shebang)
예제 #48
0
            return value
        finally:
            f.close()

    def set(self, key, value):

        self._cache[key] = value

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            f = codecs.open(cachefile, 'w', encoding='utf-8')
        except (OSError, IOError), e:
            utils.warning("error while trying to read %s : %s" %
                          (cachefile, str(e)))
        else:
            f.write(utils.jsonify(value))
        finally:
            f.close()

    def has_expired(self, key):

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            st = os.stat(cachefile)
        except (OSError, IOError), e:
            if e.errno == errno.ENOENT:
                return False
            else:
                utils.warning("error while trying to stat %s : %s" %
                              (cachefile, str(e)))