Example #1
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 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.become:
                    data['user'] = self.runner.become_user
                data = utils.jsonify(data)
                data = utils.encrypt(self.key, data)

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

                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 response.get('failed', False):
                    raise 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 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 AnsibleError(
                    "failed to put the file in the requested location")
Example #2
0
    def exec_command(self,
                     cmd,
                     tmp_path,
                     sudo_user,
                     sudoable=False,
                     executable='/bin/sh'):
        ''' run a command on the remote host '''

        if self.runner.sudo or 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.AnisbleError("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', ''))
Example #3
0
def runtest(modfile, argspath):
    """Test run a module, piping it's output for reporting."""

    os.system("chmod +x %s" % modfile)

    invoke = "%s" % (modfile)
    if argspath is not None:
        invoke = "%s %s" % (modfile, argspath)

    cmd = subprocess.Popen(invoke,
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    (out, err) = cmd.communicate()

    try:
        print "***********************************"
        print "RAW OUTPUT"
        print out
        print err
        results = utils.parse_json(out)
    except:
        print "***********************************"
        print "INVALID OUTPUT FORMAT"
        print out
        traceback.print_exc()
        sys.exit(1)

    print "***********************************"
    print "PARSED OUTPUT"
    print utils.jsonify(results, format=True)
Example #4
0
    def _get_variables(self, hostname):

        host = self.get_host(hostname)
        if host is None:
            raise errors.AnsibleError("host not found: %s" % hostname)

        vars = {}
        for updated in map(lambda x: x.run(host),
                           utils.plugins.vars_loader.all(self)):
            if updated is not None:
                vars.update(updated)

        vars.update(host.get_variables())
        if self._is_script:
            cmd = [self.host_list, "--host", hostname]
            try:
                sp = subprocess.Popen(cmd,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
            except OSError, e:
                raise errors.AnsibleError("problem running %s (%s)" %
                                          (' '.join(cmd), e))
            (out, err) = sp.communicate()
            results = utils.parse_json(out)

            vars.update(results)
Example #5
0
    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',''))
Example #6
0
    def _parse(self):
        all_hosts = {}

        self.raw = utils.parse_json(self.data)
        all=Group('all')
        groups = dict(all=all)
        group = None
        for (group_name, data) in self.raw.items():
            group = groups[group_name] = Group(group_name)
            host = None
            if not isinstance(data, dict):
                data = {'hosts': data}
            if 'hosts' in data:
                for hostname in data['hosts']:
                    if not hostname in all_hosts:
                        all_hosts[hostname] = Host(hostname)
                    host = all_hosts[hostname]
                    group.add_host(host)
            if 'vars' in data:
                for k, v in data['vars'].iteritems():
                    group.set_variable(k, v)
            all.add_child_group(group)
        # Separate loop to ensure all groups are defined
        for (group_name, data) in self.raw.items():
            if isinstance(data, dict) and 'children' in data:
                for child_name in data['children']:
                    if child_name in groups:
                        groups[group_name].add_child_group(groups[child_name])
        return groups
Example #7
0
    def __init__(self,
                 conn=None,
                 host=None,
                 result=None,
                 comm_ok=True,
                 diff=dict()):

        # which host is this ReturnData about?
        if conn is not None:
            self.host = conn.host
            delegate = getattr(conn, 'delegate', None)
            if delegate is not None:
                self.host = delegate

        else:
            self.host = host

        self.result = result
        self.comm_ok = comm_ok

        # if these values are set and used with --diff we can show
        # changes made to particular files
        self.diff = diff

        if type(self.result) in [str, unicode]:
            self.result = utils.parse_json(self.result)

        if self.host is None:
            raise Exception("host not set")
        if type(self.result) != dict:
            raise Exception("dictionary result expected")
Example #8
0
    def _get_variables(self, hostname):

        host = self.get_host(hostname)
        if host is None:
            raise errors.AnsibleError("host not found: %s" % hostname)

        vars = {}
        for updated in map(lambda x: x.run(host),
                           utils.plugins.vars_loader.all(self)):
            if updated is not None:
                vars.update(updated)

        if self._is_script:
            cmd = [self.host_list, "--host", hostname]
            try:
                sp = subprocess.Popen(cmd,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
            except OSError, e:
                raise errors.AnsibleError("problem running %s (%s)" %
                                          (' '.join(cmd), e))
            (out, err) = sp.communicate()
            results = utils.parse_json(out)

            # FIXME: this is a bit redundant with host.py and should share code
            results['inventory_hostname'] = hostname
            results['inventory_hostname_short'] = hostname.split('.')[0]
            groups = [g.name for g in host.get_groups() if g.name != 'all']
            results['group_names'] = sorted(groups)
            vars.update(results)
    def _execute_module(self, conn, tmp, remote_module_path, args, 
        async_jid=None, async_module=None, async_limit=None):

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

        inject = self.setup_cache.get(conn.host,{}).copy()
        host_variables = self.inventory.get_variables(conn.host)
        inject.update(host_variables)
        inject.update(self.module_vars)

        if self.module_name == 'setup':
            if not args:
                args = {}
            args = self._add_setup_vars(inject, args)
            args = self._add_setup_metadata(args)

        if type(args) == dict:
            args = utils.bigjson(args)
        args = utils.template(args, inject, self.setup_cache)

        module_name_tail = remote_module_path.split("/")[-1]

        argsfile = self._transfer_str(conn, tmp, 'arguments', args)
        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]])

        res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
        result1 = utils.parse_json(res)

        executed_str = "%s %s" % (module_name_tail, args.strip())

        return ReturnData(host=conn.host, result=res, executed_str=executed_str)
Example #10
0
    def exec_command(self,
                     cmd,
                     tmp_path,
                     become_user=None,
                     sudoable=False,
                     executable='/bin/sh',
                     in_data=None):
        ''' run a command on the remote host '''

        if sudoable and self.runner.become and self.runner.become_method not in self.become_methods_supported:
            raise errors.AnsibleError(
                "Internal Error: this module does not support running commands via %s"
                % self.runner.become_method)

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

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

        if self.runner.become and sudoable:
            cmd, prompt, success_key = utils.make_become_cmd(
                cmd, become_user, executable, self.runner.become_method, '',
                self.runner.become_exe)

        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 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 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', ''))
Example #11
0
    def __init__(self, conn=None, host=None, result=None, 
        comm_ok=True, diff=dict()):

        # which host is this ReturnData about?
        if conn is not None:
            self.host = conn.host
            delegate = getattr(conn, 'delegate', None)
            if delegate is not None:
                self.host = delegate

        else:
            self.host = host

        self.result = result
        self.comm_ok = comm_ok

        # if these values are set and used with --diff we can show
        # changes made to particular files
        self.diff = diff

        if type(self.result) in [ str, unicode ]:
            self.result = utils.parse_json(self.result)


        if self.host is None:
            raise Exception("host not set")
        if type(self.result) != dict:
            raise Exception("dictionary result expected")
Example #12
0
    def _parse(self, err):

        all_hosts = {}
        self.raw  = utils.parse_json(self.data)
        all       = Group('all')
        groups    = dict(all=all)
        group     = None


        if 'failed' in self.raw:
            sys.stderr.write(err + "\n")
            raise errors.AnsibleError("failed to parse executable inventory script results: %s" % self.raw)

        for (group_name, data) in self.raw.items():
 
            # in Ansible 1.3 and later, a "_meta" subelement may contain
            # a variable "hostvars" which contains a hash for each host
            # if this "hostvars" exists at all then do not call --host for each
            # host.  This is for efficiency and scripts should still return data
            # if called with --host for backwards compat with 1.2 and earlier.

            if group_name == '_meta':
                if 'hostvars' in data:
                    self.host_vars_from_top = data['hostvars']
                    continue

            group = groups[group_name] = Group(group_name)
            host = None

            if not isinstance(data, dict):
                data = {'hosts': data}
            elif not any(k in data for k in ('hosts','vars')):
                data = {'hosts': [group_name], 'vars': data}

            if 'hosts' in data:

                for hostname in data['hosts']:
                    if not hostname in all_hosts:
                        all_hosts[hostname] = Host(hostname)
                    host = all_hosts[hostname]
                    group.add_host(host)

            if 'vars' in data:
                for k, v in data['vars'].iteritems():
                    if group.name == all.name:
                        all.set_variable(k, v)
                    else:
                        group.set_variable(k, v)
            if group.name != all.name:
                all.add_child_group(group)

        # Separate loop to ensure all groups are defined
        for (group_name, data) in self.raw.items():
            if group_name == '_meta':
                continue
            if isinstance(data, dict) and 'children' in data:
                for child_name in data['children']:
                    if child_name in groups:
                        groups[group_name].add_child_group(groups[child_name])
        return groups
Example #13
0
    def exec_command(self,
                     cmd,
                     tmp_path,
                     sudo_user,
                     sudoable=False,
                     executable='/bin/sh'):
        ''' 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,
            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', ''))
Example #14
0
    def exec_command(self, cmd, tmp_path, become_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.become and sudoable:
            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',''))
Example #15
0
def _state_func(state, **kws):
    """Map salt state invocation to ansible module invocation."""

    state = kws.pop('fun')
    if __opts__['test']:
        return dict(result=None, changes={}, name=state,
                    comment='test is not supported by Ansible modules!')
    argline = kws.pop('args', '')
    for k in SALT_KEYS:
        del kws[k]

    # detect and translate argument 'name_' into 'name'
    NAME_ARG = 'name_'
    if NAME_ARG in kws:
        kws['name'] = kws[NAME_ARG]
        del kws[NAME_ARG]

    modpath = os.path.join(ANSIBLE_MOD_DIR, STATE_NAMES[state])
    output = parse_json(run(modpath, argline, kws, raise_exc=True))

    ret = dict(name=state, result=False, changes={}, comment='')

    if 'failed' not in output:
        ret['result'] = True
    if state in ('command', 'shell') and output['rc'] != 0:
        ret['result'] = False

    if 'msg' in output:
        ret['comment'] = output['msg']
    elif state in ('command', 'shell') and output['stderr']:
        ret['comment'] = output['stderr']

    if ret.get('changed', True):
        ret['changes'] = dict(ansible=output)
    return ret
Example #16
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")
Example #17
0
    def _return_from_module(self, conn, host, result, executed=None):
        """ helper function to handle JSON parsing of results """

        try:
            result = utils.parse_json(result)
            if executed is not None:
                result["invocation"] = executed
            return [host, True, result]
        except Exception, e:
            return [host, False, "%s/%s/%s" % (str(e), result, executed)]
Example #18
0
    def _return_from_module(self, conn, host, result, err, executed=None):
        ''' helper function to handle JSON parsing of results '''

        try:
            result = utils.parse_json(result) 
            if executed is not None:
                result['invocation'] = executed
                if 'stderr' in result:
                    err="%s%s"%(err,result['stderr'])
            return [host, True, result, err]
        except Exception, e:
            return [host, False, "%s/%s/%s" % (str(e), result, executed), err]
    def _return_from_module(self, conn, host, result, err, executed=None):
        ''' helper function to handle JSON parsing of results '''

        try:
            result = utils.parse_json(result) 
            if executed is not None:
                result['invocation'] = executed
                if 'stderr' in result:
                    err="%s%s"%(err,result['stderr'])
            return [host, True, result, err]
        except Exception, e:
            return [host, False, "%s/%s/%s" % (str(e), result, executed), err]
    def __init__(self, host=None, result=None, comm_ok=True, executed_str=''):
        self.host = host
        self.result = result
        self.comm_ok = comm_ok
        self.executed_str = executed_str

        if type(self.result) in [str, unicode]:
            self.result = utils.parse_json(self.result)

        if host is None:
            raise Exception("host not set")
        if type(self.result) != dict:
            raise Exception("dictionary result expected")
Example #21
0
    def __init__(self, host=None, result=None, comm_ok=True, executed_str=''):
        self.host = host
        self.result = result
        self.comm_ok = comm_ok
        self.executed_str = executed_str

        if type(self.result) in [ str, unicode ]:
            self.result = utils.parse_json(self.result)

        if host is None:
            raise Exception("host not set")
        if type(self.result) != dict:
            raise Exception("dictionary result expected")
    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, is_new_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 not is_new_style:
            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 run check mode against old-style modules"))

            args = utils.template(self.basedir, args, inject)
            argsfile = self._transfer_str(conn, tmp, 'arguments', args)
            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, shebang.replace("#!",""), cmd])
        if tmp.find("tmp") != -1 and C.DEFAULT_KEEP_REMOTE_FILES != '1' and not persist_files:
            cmd = cmd + "; rm -rf %s >/dev/null 2>&1" % tmp
        res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
        data = utils.parse_json(res['stdout'])
        if 'parsed' in data and data['parsed'] == False:
            data['msg'] += res['stderr']
        return ReturnData(conn=conn, result=data)
Example #23
0
    def _parse(self, err):

        all_hosts = {}
        self.raw = utils.parse_json(self.data)
        all = Group('all')
        groups = dict(all=all)
        group = None

        if 'failed' in self.raw:
            sys.stderr.write(err + "\n")
            raise errors.AnsibleError(
                "failed to parse executable inventory script results: %s" %
                self.raw)

        for (group_name, data) in self.raw.items():

            group = groups[group_name] = Group(group_name)
            host = None

            if not isinstance(data, dict):
                data = {'hosts': data}
            elif not any(k in data for k in ('hosts', 'vars')):
                data = {'hosts': [group_name], 'vars': data}

            if 'hosts' in data:

                for hostname in data['hosts']:
                    if not hostname in all_hosts:
                        all_hosts[hostname] = Host(hostname)
                    host = all_hosts[hostname]
                    group.add_host(host)

            if 'vars' in data:
                for k, v in data['vars'].iteritems():
                    if group.name == all.name:
                        all.set_variable(k, v)
                    else:
                        group.set_variable(k, v)
            if group.name != all.name:
                all.add_child_group(group)

        # Separate loop to ensure all groups are defined
        for (group_name, data) in self.raw.items():
            if isinstance(data, dict) and 'children' in data:
                for child_name in data['children']:
                    if child_name in groups:
                        groups[group_name].add_child_group(groups[child_name])
        return groups
Example #24
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)

        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', ''))
Example #25
0
 def _parse(self):
     groups = {}
     self.raw = utils.parse_json(self.data)
     all=Group('all')
     self.groups = dict(all=all)
     group = None
     for (group_name, hosts) in self.raw.items():
         group = groups[group_name] = Group(group_name)
         host = None
         for hostname in hosts:
             host = Host(hostname)
             group.add_host(host)
             # FIXME: hack shouldn't be needed
             all.add_host(host)
         all.add_child_group(group)
     return groups  
Example #26
0
 def _parse(self):
     groups = {}
     self.raw = utils.parse_json(self.data)
     all = Group('all')
     self.groups = dict(all=all)
     group = None
     for (group_name, hosts) in self.raw.items():
         group = groups[group_name] = Group(group_name)
         host = None
         for hostname in hosts:
             host = Host(hostname)
             group.add_host(host)
             # FIXME: hack shouldn't be needed
             all.add_host(host)
         all.add_child_group(group)
     return groups
Example #27
0
    def exec_command(self, cmd, tmp_path, become_user=None, sudoable=False, executable='/bin/sh', in_data=None):
        ''' run a command on the remote host '''

        if sudoable and self.runner.become and self.runner.become_method not in self.become_methods_supported:
            raise AnsibleError("Internal Error: this module does not support running commands via %s" % self.runner.become_method)

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

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

        if self.runner.become and sudoable:
            cmd, prompt, success_key = utils.make_become_cmd(cmd, become_user, executable, self.runner.become_method, '', self.runner.become_exe)

        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 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 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',''))
    def _add_result_to_setup_cache(self, conn, result):
        ''' allows discovered variables to be used in templates and action statements '''

        host = conn.host
        try:
            var_result = utils.parse_json(result)
        except:
            var_result = {}

        # note: do not allow variables from playbook to be stomped on
        # by variables coming up from facter/ohai/etc.  They
        # should be prefixed anyway
        if not host in self.setup_cache:
            self.setup_cache[host] = {}
        for (k, v) in var_result.iteritems():
            if not k in self.setup_cache[host]:
                self.setup_cache[host][k] = v
Example #29
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)
Example #30
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()
Example #31
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()
Example #32
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)
Example #33
0
    def _add_result_to_setup_cache(self, conn, result):
        ''' allows discovered variables to be used in templates and action statements '''

        host = conn.host
        try:
            var_result = utils.parse_json(result)
        except:
            var_result = {}

        # note: do not allow variables from playbook to be stomped on
        # by variables coming up from facter/ohai/etc.  They
        # should be prefixed anyway
        if not host in self.setup_cache:
            self.setup_cache[host] = {}
        for (k, v) in var_result.iteritems():
            if not k in self.setup_cache[host]:
                self.setup_cache[host][k] = v
Example #34
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()
Example #35
0
    def get_variables(self, hostname):

        if self._is_script:
            # TODO: move this to inventory_script.py
            host = self.get_host(hostname)
            cmd = subprocess.Popen([self.host_list, "--host", hostname],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            (out, err) = cmd.communicate()
            results = utils.parse_json(out)
            results['inventory_hostname'] = hostname
            groups = [g.name for g in host.get_groups() if g.name != 'all']
            results['group_names'] = sorted(groups)
            return results

        host = self.get_host(hostname)
        if host is None:
            raise Exception("host not found: %s" % hostname)
        return host.get_variables()
Example #36
0
    def exec_command(
        self, cmd, tmp_path, sudo_user=None, sudoable=False, executable="/bin/sh", in_data=None, su=None, su_user=None
    ):
        """ run a command on the remote host """

        if su or su_user:
            raise AnsibleError("Internal Error: this module does not support running commands via su")

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

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

        if self.runner.sudo and sudoable and sudo_user:
            cmd, prompt, success_key = utils.make_sudo_cmd(self.runner.sudo_exe, 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 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 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", ""))
Example #37
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
Example #38
0
    def get_variables(self, hostname):

        if self._is_script:
            # TODO: move this to inventory_script.py 
            host = self.get_host(hostname)
            cmd = subprocess.Popen(
                [self.host_list,"--host",hostname], 
                stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE
            )
            (out, err) = cmd.communicate()
            results = utils.parse_json(out)
            results['inventory_hostname'] = hostname
            groups = [ g.name for g in host.get_groups() if g.name != 'all' ]
            results['group_names'] = sorted(groups)
            return results

        host = self.get_host(hostname)
        if host is None:
            raise Exception("host not found: %s" % hostname)
        return host.get_variables()
Example #39
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()
Example #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)
        
        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',''))
Example #41
0
    def __init__(self, conn=None, host=None, result=None, comm_ok=True):

        # which host is this ReturnData about?
        if conn is not None:
            self.host = conn.host
            delegate = getattr(conn, 'delegate', None)
            if delegate is not None:
                self.host = delegate

        else:
            self.host = host

        self.result = result
        self.comm_ok = comm_ok

        if type(self.result) in [str, unicode]:
            self.result = utils.parse_json(self.result)

        if self.host is None:
            raise Exception("host not set")
        if type(self.result) != dict:
            raise Exception("dictionary result expected")
Example #42
0
    def __init__(self, conn=None, host=None, result=None, comm_ok=True):

        # which host is this ReturnData about?
        if conn is not None:
            delegate_for = getattr(conn, '_delegate_for', None)
            if delegate_for:
                self.host = delegate_for
            else:
                self.host = conn.host
        else:
            self.host = host

        self.result = result
        self.comm_ok = comm_ok

        if type(self.result) in [ str, unicode ]:
            self.result = utils.parse_json(self.result)

        if self.host is None:
            raise Exception("host not set")
        if type(self.result) != dict:
            raise Exception("dictionary result expected")
Example #43
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('stdout',''), response.get('stderr',''))
Example #44
0
    def _get_variables(self, hostname):

        host = self.get_host(hostname)
        if host is None:
            raise errors.AnsibleError("host not found: %s" % hostname)

        vars = {}
        for updated in map(lambda x: x.run(host), utils.plugins.vars_loader.all(self)):
            if updated is not None:
                vars.update(updated)

        vars.update(host.get_variables())
        if self._is_script:
            cmd = [self.host_list,"--host",hostname]
            try:
                sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            except OSError, e:
                raise errors.AnsibleError("problem running %s (%s)" % (' '.join(cmd), e))
            (out, err) = sp.communicate()
            results = utils.parse_json(out)

            vars.update(results)
Example #45
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
Example #46
0
    def _get_variables(self, hostname):

        if self._is_script:
            host = self.get_host(hostname)
            cmd = subprocess.Popen([self.host_list, "--host", hostname],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            (out, err) = cmd.communicate()
            results = utils.parse_json(out)

            # FIXME: this is a bit redundant with host.py and should share code
            results['inventory_hostname'] = hostname
            results['inventory_hostname_short'] = hostname.split('.')[0]
            groups = [g.name for g in host.get_groups() if g.name != 'all']
            results['group_names'] = sorted(groups)

            return results

        host = self.get_host(hostname)
        if host is None:
            raise Exception("host not found: %s" % hostname)
        return host.get_variables()
Example #47
0
    def _get_variables(self, hostname):

        if self._is_script:
            host = self.get_host(hostname)
            cmd = subprocess.Popen(
                [self.host_list,"--host",hostname],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            (out, err) = cmd.communicate()
            results = utils.parse_json(out)

            # FIXME: this is a bit redundant with host.py and should share code
            results['inventory_hostname'] = hostname
            results['inventory_hostname_short'] = hostname.split('.')[0]
            groups = [ g.name for g in host.get_groups() if g.name != 'all' ]
            results['group_names'] = sorted(groups)

            return results

        host = self.get_host(hostname)
        if host is None:
            raise Exception("host not found: %s" % hostname)
        return host.get_variables()
Example #48
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)
Example #49
0
                for child_name in data['children']:
                    if child_name in groups:
                        groups[group_name].add_child_group(groups[child_name])

        for group in groups.values():
            if group.depth == 0 and group.name != 'all':
                all.add_child_group(group)

        return groups

    def get_host_variables(self, host):
        """ Runs <script> --host <hostname> to determine additional host variables """
        if self.host_vars_from_top is not None:
            got = self.host_vars_from_top.get(host.name, {})
            return got


        cmd = [self.filename, "--host", host.name]
        try:
            sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except OSError, e:
            raise errors.AnsibleError("problem running %s (%s)" % (' '.join(cmd), e))
        (out, err) = sp.communicate()
        if out.strip() == '':
            return dict()
        try:
            return json_dict_unicode_to_bytes(utils.parse_json(out))
        except ValueError:
            raise errors.AnsibleError("could not parse post variable response: %s, %s" % (cmd, out))

Example #50
0
                        all.set_variable(k, v)
                    else:
                        group.set_variable(k, v)
            if group.name != all.name:
                all.add_child_group(group)

        # Separate loop to ensure all groups are defined
        for (group_name, data) in self.raw.items():
            if group_name == '_meta':
                continue
            if isinstance(data, dict) and 'children' in data:
                for child_name in data['children']:
                    if child_name in groups:
                        groups[group_name].add_child_group(groups[child_name])
        return groups

    def get_host_variables(self, host):
        """ Runs <script> --host <hostname> to determine additional host variables """
        if self.host_vars_from_top is not None:
            got = self.host_vars_from_top.get(host.name, {})
            return got


        cmd = [self.filename, "--host", host.name]
        try:
            sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except OSError, e:
            raise errors.AnsibleError("problem running %s (%s)" % (' '.join(cmd), e))
        (out, err) = sp.communicate()
        return utils.parse_json(out)
Example #51
0
    def _parse(self, err):

        all_hosts = {}

        # not passing from_remote because data from CMDB is trusted
        self.raw  = utils.parse_json(self.data)
        self.raw  = json_dict_bytes_to_unicode(self.raw)

        all       = Group('all')
        groups    = dict(all=all)
        group     = None


        if 'failed' in self.raw:
            sys.stderr.write(err + "\n")
            raise errors.AnsibleError("failed to parse executable inventory script results: %s" % self.raw)

        for (group_name, data) in self.raw.items():

            # in Ansible 1.3 and later, a "_meta" subelement may contain
            # a variable "hostvars" which contains a hash for each host
            # if this "hostvars" exists at all then do not call --host for each
            # host.  This is for efficiency and scripts should still return data
            # if called with --host for backwards compat with 1.2 and earlier.

            if group_name == '_meta':
                if 'hostvars' in data:
                    self.host_vars_from_top = data['hostvars']
                    continue

            if group_name != all.name:
                group = groups[group_name] = Group(group_name)
            else:
                group = all
            host = None

            if not isinstance(data, dict):
                data = {'hosts': data}
            # is not those subkeys, then simplified syntax, host with vars
            elif not any(k in data for k in ('hosts','vars')):
                data = {'hosts': [group_name], 'vars': data}

            if 'hosts' in data:
                if not isinstance(data['hosts'], list):
                    raise errors.AnsibleError("You defined a group \"%s\" with bad "
                        "data for the host list:\n %s" % (group_name, data))

                for hostname in data['hosts']:
                    if not hostname in all_hosts:
                        all_hosts[hostname] = Host(hostname)
                    host = all_hosts[hostname]
                    group.add_host(host)

            if 'vars' in data:
                if not isinstance(data['vars'], dict):
                    raise errors.AnsibleError("You defined a group \"%s\" with bad "
                        "data for variables:\n %s" % (group_name, data))

                for k, v in data['vars'].iteritems():
                    if group.name == all.name:
                        all.set_variable(k, v)
                    else:
                        group.set_variable(k, v)

        # Separate loop to ensure all groups are defined
        for (group_name, data) in self.raw.items():
            if group_name == '_meta':
                continue
            if isinstance(data, dict) and 'children' in data:
                for child_name in data['children']:
                    if child_name in groups:
                        groups[group_name].add_child_group(groups[child_name])

        for group in groups.values():
            if group.depth == 0 and group.name != 'all':
                all.add_child_group(group)

        return groups
Example #52
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 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)
Example #53
0
    def _parse(self, err):

        all_hosts = {}

        # not passing from_remote because data from CMDB is trusted
        self.raw  = utils.parse_json(self.data) # 还是使用self.data来解析标准输出,需要self.data为json格式数据
        self.raw  = json_dict_bytes_to_unicode(self.raw) # 将self.raw中的kv都转换成unicode格式。

        all       = Group('all') # 设置Group("all")
        groups    = dict(all=all) # 初始化groups字典
        group     = None


        if 'failed' in self.raw: # 如果self.raw中有failed字段,则报错。不过在上面parser_json的时候no_exception是false,不会出现failed情况
            sys.stderr.write(err + "\n")
            raise errors.AnsibleError("failed to parse executable inventory script results: %s" % self.raw)

        for (group_name, data) in self.raw.items():
            # 1.3 以上版本使用--list的时返回结果中会包含_meta这样的key,该key的value中会有一个hostvars变量,该变量包含每个host的主机变量
            # 1.2及以下版本仍然需要使用--host命令为每一个host返回主机变量

            # in Ansible 1.3 and later, a "_meta" subelement may contain
            # a variable "hostvars" which contains a hash for each host
            # if this "hostvars" exists at all then do not call --host for each
            # host.  This is for efficiency and scripts should still return data
            # if called with --host for backwards compat with 1.2 and earlier.


            """
            {
                "databases"   : {
                    "hosts"   : [ "host1.example.com", "host2.example.com" ],
                    "vars"    : {
                        "a"   : true
                    }
                },
                "webservers"  : [ "host2.example.com", "host3.example.com" ],
                "atlanta"     : {
                    "hosts"   : [ "host1.example.com", "host4.example.com", "host5.example.com" ],
                    "vars"    : {
                        "b"   : false
                    },
                    "children": [ "marietta", "5points" ]
                },
                "marietta"    : [ "host6.example.com" ],
                "5points"     : [ "host7.example.com" ]
            }

            {

                # results of inventory script as above go here
                # ...

                "_meta" : {
                   "hostvars" : {
                      "moocow.example.com"     : { "asdf" : 1234 },
                      "llama.example.com"      : { "asdf" : 5678 },
                   }
                }


            {
                "moocow.example.com"     : { "asdf" : 1234 },
                "llama.example.com"      : { "asdf" : 5678 }
            }
            """

            if group_name == '_meta': # 如果key为_meta,则该value为meta数据。
                if 'hostvars' in data:
                    self.host_vars_from_top = data['hostvars'] # 如果meta数据中包含hostvars,则缓存到self.host_vars_from_top中。
                    continue # 跳过之后的处理

            if group_name != all.name: # group_name不是all则创建新的Group对象,并加入groups字典。
                group = groups[group_name] = Group(group_name) # 如果data中出现无group的hostname,则会出现以hostname为名称的组
            else:
                group = all
            host = None

            if not isinstance(data, dict): # 如果data不是字典类型,则表示data为主机列表
                data = {'hosts': data}
            # is not those subkeys, then simplified syntax, host with vars
            elif not any(k in data for k in ('hosts','vars','children')): # any函数表示可迭代对象中任何一个为True,则为True.否则为False
                # 如果data对象是字典类型,但key中不存在hosts、vars、children时,既该行数据为主机变量数据时,group_name为主机名
                data = {'hosts': [group_name], 'vars': data}

            # 上面两步为了统一data的格式,不带变量的data,格式为{'hosts': [host1,host2...]
            # 带变量的data,格式为: {'hosts': [group_name], 'vars': data }

            if 'hosts' in data:
                if not isinstance(data['hosts'], list): # 主机列表必须是list对象,上面的'hosts': [group_name] 也是为校验统一格式
                    raise errors.AnsibleError("You defined a group \"%s\" with bad "
                        "data for the host list:\n %s" % (group_name, data))

                for hostname in data['hosts']: # 遍历主机名
                    if not hostname in all_hosts:
                        all_hosts[hostname] = Host(hostname) # 如果主机对象不存在, 则创建并添加到all_hosts列表中,去重
                    host = all_hosts[hostname] # 将Host对象赋值给host变量
                    group.add_host(host) # 将Host对象添加到该group中

            if 'vars' in data: # 如果是带有vars的data
                if not isinstance(data['vars'], dict):
                    raise errors.AnsibleError("You defined a group \"%s\" with bad "
                        "data for variables:\n %s" % (group_name, data))

                for k, v in data['vars'].iteritems(): # 遍历所有的变量
                    if group.name == all.name: # 如果当前组名为“all",则将变量加到all group中,否则加到当前group中。
                        all.set_variable(k, v)
                    else:
                        group.set_variable(k, v)

        # Separate loop to ensure all groups are defined
        for (group_name, data) in self.raw.items():
            if group_name == '_meta':
                continue
            if isinstance(data, dict) and 'children' in data: # 如果data中包含子组,遍历子组并将子组添加到父组中
                for child_name in data['children']:
                    if child_name in groups:
                        groups[group_name].add_child_group(groups[child_name])

        for group in groups.values():
            if group.depth == 0 and group.name != 'all': # 如果该组深度为0,且名称不是"all",则加入all组的子组列表中。
                all.add_child_group(group)

        return groups
Example #54
0
                for child_name in data['children']:
                    if child_name in groups:
                        groups[group_name].add_child_group(groups[child_name])

        for group in groups.values():
            if group.depth == 0 and group.name != 'all':
                all.add_child_group(group)

        return groups

    def get_host_variables(self, host):
        """ Runs <script> --host <hostname> to determine additional host variables """
        if self.host_vars_from_top is not None:
            got = self.host_vars_from_top.get(host.name, {})
            return got


        cmd = [self.filename, "--host", host.name]
        try:
            sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except OSError, e:
            raise errors.AnsibleError("problem running %s (%s)" % (' '.join(cmd), e))
        (out, err) = sp.communicate()
        if out.strip() == '':
            return dict()
        try:
            return json_dict_bytes_to_unicode(utils.parse_json(out))
        except ValueError:
            raise errors.AnsibleError("could not parse post variable response: %s, %s" % (cmd, out))