Пример #1
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        ''' handler for template operations '''

        # note: since this module just calls the copy module, the --check mode support
        # can be implemented entirely over there

        if not self.runner.is_playbook:
            raise errors.AnsibleError("in current versions of ansible, templates are only usable in playbooks")

        # load up options
        options  = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))

        source   = options.get('src', None)
        dest     = options.get('dest', None)

        if (source is None and 'first_available_file' not in inject) or dest is None:
            result = dict(failed=True, msg="src and dest are required")
            return ReturnData(conn=conn, comm_ok=False, result=result)

        # if we have first_available_file in our vars
        # look up the files and use the first one we find as src

        if 'first_available_file' in inject:
            found = False
            for fn in self.runner.module_vars.get('first_available_file'):
                fn_orig = fn
                fnt = template.template(self.runner.basedir, fn, inject)
                fnd = utils.path_dwim(self.runner.basedir, fnt)
                if not os.path.exists(fnd) and '_original_file' in inject:
                    fnd = utils.path_dwim_relative(inject['_original_file'], 'templates', fnt, self.runner.basedir, check=False)
                if os.path.exists(fnd):
                    source = fnd
                    found = True
                    break
            if not found:
                result = dict(failed=True, msg="could not find src in first_available_file list")
                return ReturnData(conn=conn, comm_ok=False, result=result)
        else:
            source = template.template(self.runner.basedir, source, inject)
                
            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'], 'templates', source, self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)


        if dest.endswith("/"): # CCTODO: Fix path for Windows hosts.
            base = os.path.basename(source)
            dest = os.path.join(dest, base)

        # template the source data locally & get ready to transfer
        try:
            resultant = template.template_from_file(self.runner.basedir, source, inject, vault_password=self.runner.vault_pass)
        except Exception, e:
            result = dict(failed=True, msg=type(e).__name__ + ": " + str(e))
            return ReturnData(conn=conn, comm_ok=False, result=result)
Пример #2
0
    def run(self, terms, inject=None, **kwargs):

        terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)
        ret = []

        # this can happen if the variable contains a string, strictly not desired for lookup
        # plugins, but users may try it, so make it work.
        if not isinstance(terms, list):
            terms = [ terms ]

        for term in terms:
            basedir_path  = utils.path_dwim(self.basedir, term)
            relative_path = None
            playbook_path = None

            # Special handling of the file lookup, used primarily when the
            # lookup is done from a role. If the file isn't found in the
            # basedir of the current file, use dwim_relative to look in the
            # role/files/ directory, and finally the playbook directory
            # itself (which will be relative to the current working dir)
            if '_original_file' in inject:
                relative_path = utils.path_dwim_relative(inject['_original_file'], 'files', term, self.basedir, check=False)
            if 'playbook_dir' in inject:
                playbook_path = os.path.join(inject['playbook_dir'], term)

            for path in (basedir_path, relative_path, playbook_path):
                if path and os.path.exists(path):
                    ret.append(path)
                    break
            else:
                raise errors.AnsibleError("could not locate file in lookup: %s" % term)

        return ret
Пример #3
0
                def run(self, terms, inject=None, **kwargs):

                    terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)
                    ret = []

                    # this can happen if the variable contains a string, strictly not desired for lookup
                    # plugins, but users may try it, so make it work.
                    if not isinstance(terms, list):
                        terms = [ terms ]

                    # We need to search for the term in the relative path, and return
                    # the file path, instead of the contents due to how this lookup
                    # is used in a playbook

                    for term in terms:
                        path  = None

                        if '_original_file' in inject:
                            path = utils.path_dwim_relative(inject['_original_file'], 'templates', '', self.basedir, check=False)
                            path = os.path.join(path, term)

                        if path and os.path.exists(path):
                            ret.append(path)
                            break
                        else:
                            raise errors.AnsibleError("could not locate template in lookup: %s" % term)

                    return ret
Пример #4
0
    def run(self, terms, inject=None, **kwargs):

        terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)
        ret = []

        # this can happen if the variable contains a string, strictly not desired for lookup
        # plugins, but users may try it, so make it work.
        if not isinstance(terms, list):
            terms = [ terms ]

        project_root = find_debops_project(required=False)
        config = read_config(project_root)
        places = []

        if 'paths' in config and conf_template_paths in config['paths']:
            custom_places = config['paths'][conf_template_paths].split(':')
            for custom_path in custom_places:
                if os.path.isabs(custom_path):
                    places.append(custom_path)
                else:
                    places.append(os.path.join(project_root, custom_path))

        for term in terms:
            if '_original_file' in inject:
                relative_path = utils.path_dwim_relative(inject['_original_file'], 'tasks', '', self.basedir, check=False)
                places.append(relative_path)
            for path in places:
                template = os.path.join(path, term)
                if template and os.path.exists(template):
                    ret.append(template)
                    break
            else:
                raise errors.AnsibleError("could not locate file in lookup: %s" % term)

        return ret
Пример #5
0
def test_all_role_templates_tested(ctrl, monkeypatch, request):
    instance = ctrl.instances['jailhost']
    instance.config['roles'] = ' '.join(get_all_roles())
    pb = instance.get_playbook()
    plays = []
    monkeypatch.setattr('ansible.playbook.PlayBook._run_play', plays.append)
    pb.run()
    # import after running to avoid module import issues
    from ansible.utils import parse_kv, path_dwim_relative
    templates = []
    for play, task in iter_tasks(plays):
        if task.module_name != 'template':
            continue
        module_args_dict = task.args
        if not module_args_dict and task.module_args:
            module_args_dict = parse_kv(task.module_args)
        template_path = path_dwim_relative(
            task.module_vars['_original_file'], 'templates',
            module_args_dict['src'], play.basedir)
        if not os.path.exists(template_path):  # pragma: nocover - only on failure
            raise ValueError
        name = module_args_dict['src'].lower()
        for rep in ('-', '.'):
            name = name.replace(rep, '_')
        templates.append((
            name,
            dict(
                path=task.module_vars.get('_original_file'),
                role_name=task.role_name,
                name=module_args_dict['src'], task_name=task.name)))
    test_names = [x.name for x in request.session.items]
    for name, info in templates:
        test_name = 'test_%s_%s' % (info['role_name'], name)
        if not any(x for x in test_names if x.startswith(test_name)):  # pragma: nocover - only on failure
            pytest.fail("No test '{0}' for template '{name}' of task '{task_name}' in role '{role_name}' at '{path}'.".format(test_name, **info))
  def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):

    if not module_args:
      result = dict(failed=True, msg="No source file given")
      return ReturnData(conn=conn, comm_ok=True, result=result)

    source = template.template(self.runner.basedir, module_args, inject)

    if '_original_file' in inject:
      source = utils.path_dwim_relative(inject['_original_file'], 'vars', source, self.runner.basedir, False)
    else:
      source = utils.path_dwim(self.runner.basedir, source)

    data = {}

    if os.path.exists(source):
      data = utils.parse_yaml_from_file(source, vault_password=self.runner.vault_pass)

      if data and type(data) != dict:
        raise errors.AnsibleError("%s must be stored as a dictionary/hash" % source)

    if not hasattr(conn.runner, 'mergeBuffer'):
      conn.runner.mergeBuffer = {}

    if conn.host in conn.runner.mergeBuffer:
      data = utils.merge_hash(conn.runner.mergeBuffer[conn.host], data)

    conn.runner.mergeBuffer[conn.host] = data

    result = dict(ansible_facts=data)
    return ReturnData(conn=conn, comm_ok=True, result=result)
Пример #7
0
 def run(self, terms, inject=None, **kwargs):
     terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)
     ret = []
     if not isinstance(terms, list):
         terms = [terms]
     for term in terms:
         basedir_path = utils.path_dwim(self.basedir, term)
         relative_path = None
         playbook_path = None
         if '_original_file' in inject:
             relative_path = utils.path_dwim_relative(inject['_original_file'], 'files', term, self.basedir, check=False)
         if 'playbook_dir' in inject:
             playbook_path = os.path.join(inject['playbook_dir'], term)
         for path in (basedir_path, relative_path, playbook_path):
             if path and os.path.exists(path):
                 vaultlib = inject['_ploy_instance'].get_vault_lib()
                 with open(path) as f:
                     data = f.read()
                 if vaultlib.is_encrypted(data):
                     data = vaultlib.decrypt(data)
                 try:
                     data = data.decode('utf8')
                 except UnicodeDecodeError as e:
                     raise errors.AnsibleError("UnicodeDecodeError encrypted file lookup, only ascii and utf8 supported: %s\n%s" % (term, e))
                 ret.append(data)
                 break
         else:
             raise errors.AnsibleError("could not locate encrypted file in lookup: %s" % term)
     return ret
Пример #8
0
                def run(self, terms, inject=None, **kwargs):

                    terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)
                    ret = []

                    # this can happen if the variable contains a string, strictly not desired for lookup
                    # plugins, but users may try it, so make it work.
                    if not isinstance(terms, list):
                        terms = [ terms ]

                    places = []

                    for term in terms:
                        if '_original_file' in inject:
                            relative_path = utils.path_dwim_relative(inject['_original_file'], 'tasks', '', self.basedir, check=False)
                            places.append(relative_path)
                        for path in places:
                            template = os.path.join(path, term)
                            if template and os.path.exists(template):
                                ret.append(template)
                                break
                        else:
                            raise errors.AnsibleError("could not locate file in lookup: %s" % term)

                    return ret
Пример #9
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):

        if not module_args:
            result = dict(failed=True, msg="No source file given")
            return ReturnData(conn=conn, comm_ok=True, result=result)

        source = module_args
        source = template.template(self.runner.basedir, source, inject)

        if '_original_file' in inject:
            source = utils.path_dwim_relative(inject['_original_file'], 'vars', source, self.runner.basedir)
        else:
            source = utils.path_dwim(self.runner.basedir, source)

        if os.path.exists(source):
            data = utils.parse_yaml_from_file(source, vault_password=self.runner.vault_pass)
            if data and type(data) != dict:
                raise errors.AnsibleError("%s must be stored as a dictionary/hash" % source)
            elif data is None:
                data = {}
            result = dict(ansible_facts=data)
            return ReturnData(conn=conn, comm_ok=True, result=result)
        else:
            result = dict(failed=True, msg="Source file not found.", file=source)
            return ReturnData(conn=conn, comm_ok=True, result=result)
Пример #10
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):

        # load up options
        options  = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))

        src = options.get('src', None)
        dest = options.get('dest', None)
        delimiter = options.get('delimiter', None)
        remote_src = utils.boolean(options.get('remote_src', 'yes'))

        if src is None or dest is None:
            result = dict(failed=True, msg="src and dest are required")
            return ReturnData(conn=conn, comm_ok=False, result=result)

        if remote_src:
            return self.runner._execute_module(conn, tmp, 'assemble', module_args, inject=inject, complex_args=complex_args)
        elif '_original_file' in inject:
            src = utils.path_dwim_relative(inject['_original_file'], 'files', src, self.runner.basedir)
        else:
            # the source is local, so expand it here
            src = os.path.expanduser(src)

        # Does all work assembling the file
        path = self._assemble_from_fragments(src, delimiter)

        pathmd5 = utils.md5s(path)
        remote_md5 = self.runner._remote_md5(conn, tmp, dest)

        if pathmd5 != remote_md5:
            resultant = file(path).read()
            if self.runner.diff:
                dest_result = self.runner._execute_module(conn, tmp, 'slurp', "path=%s" % dest, inject=inject, persist_files=True)
                if 'content' in dest_result.result:
                    dest_contents = dest_result.result['content']
                    if dest_result.result['encoding'] == 'base64':
                        dest_contents = base64.b64decode(dest_contents)
                    else:
                        raise Exception("unknown encoding, failed: %s" % dest_result.result)
            xfered = self.runner._transfer_str(conn, tmp, 'src', resultant)

            # fix file permissions when the copy is done as a different user
            if self.runner.sudo and self.runner.sudo_user != 'root':
                self.runner._low_level_exec_command(conn, "chmod a+r %s" % xfered, tmp)

            # run the copy module
            module_args = "%s src=%s dest=%s original_basename=%s" % (module_args, pipes.quote(xfered), pipes.quote(dest), pipes.quote(os.path.basename(src)))

            if self.runner.noop_on_check(inject):
                return ReturnData(conn=conn, comm_ok=True, result=dict(changed=True), diff=dict(before_header=dest, after_header=src, after=resultant))
            else:
                res = self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject)
                res.diff = dict(after=resultant)
                return res
        else:
            module_args = "%s src=%s dest=%s original_basename=%s" % (module_args, pipes.quote(xfered), pipes.quote(dest), pipes.quote(os.path.basename(src)))
            return self.runner._execute_module(conn, tmp, 'file', module_args, inject=inject)
Пример #11
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))
        source  = options.get('src', None)
        dest    = options.get('dest', None)
        copy    = utils.boolean(options.get('copy', 'yes'))

        if source is None or dest is None:
            result = dict(failed=True, msg="src (or content) and dest are required")
            return ReturnData(conn=conn, result=result)

        dest = os.path.expanduser(dest) # CCTODO: Fix path for Windows hosts.
        source = template.template(self.runner.basedir, os.path.expanduser(source), inject)
        if copy:
            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        remote_md5 = self.runner._remote_md5(conn, tmp, dest)
        if remote_md5 != '3':
            result = dict(failed=True, msg="dest '%s' must be an existing dir" % dest)
            return ReturnData(conn=conn, result=result)

        if copy:
            # transfer the file to a remote tmp location
            tmp_src = tmp + 'source'
            conn.put_file(source, tmp_src)

        # handle diff mode client side
        # handle check mode client side
        # fix file permissions when the copy is done as a different user
        if copy:
            if self.runner.sudo and self.runner.sudo_user != 'root' or self.runner.su and self.runner.su_user != 'root':
                if not self.runner.noop_on_check(inject):
                    self.runner._remote_chmod(conn, 'a+r', tmp_src, tmp)
            # Build temporary module_args.
            new_module_args = dict(
                src=tmp_src,
                original_basename=os.path.basename(source),
            )

            # make sure checkmod is passed on correctly
            if self.runner.noop_on_check(inject):
                new_module_args['CHECKMODE'] = True

            module_args = utils.merge_module_args(module_args, new_module_args)
        else:
            module_args = "%s original_basename=%s" % (module_args, pipes.quote(os.path.basename(source)))
            # make sure checkmod is passed on correctly
            if self.runner.noop_on_check(inject):
                module_args += " CHECKMODE=True"
        return self.runner._execute_module(conn, tmp, 'unarchive', module_args, inject=inject, complex_args=complex_args)
Пример #12
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        """Run the method"""
        if not self.runner.is_playbook:
            raise errors.AnsibleError("FAILED: `config_templates` are only available in playbooks")

        options = self.grab_options(complex_args, module_args)
        try:
            source = options["src"]
            dest = options["dest"]

            config_overrides = options.get("config_overrides", dict())
            config_type = options["config_type"]
            assert config_type.lower() in ["ini", "json", "yaml"]
        except KeyError as exp:
            result = dict(failed=True, msg=exp)
            return ReturnData(conn=conn, comm_ok=False, result=result)

        source_template = template.template(self.runner.basedir, source, inject)

        if "_original_file" in inject:
            source_file = utils.path_dwim_relative(
                inject["_original_file"], "templates", source_template, self.runner.basedir
            )
        else:
            source_file = utils.path_dwim(self.runner.basedir, source_template)

        # Open the template file and return the data as a string. This is
        #  being done here so that the file can be a vault encrypted file.
        resultant = template.template_from_file(
            self.runner.basedir, source_file, inject, vault_password=self.runner.vault_pass
        )

        if config_overrides:
            type_merger = getattr(self, CONFIG_TYPES.get(config_type))
            resultant = type_merger(config_overrides=config_overrides, resultant=resultant)

        # Retemplate the resultant object as it may have new data within it
        #  as provided by an override variable.
        template.template_from_string(basedir=self.runner.basedir, data=resultant, vars=inject, fail_on_undefined=True)

        # Access to protected method is unavoidable in Ansible 1.x.
        new_module_args = dict(
            src=self.runner._transfer_str(conn, tmp, "source", resultant),
            dest=dest,
            original_basename=os.path.basename(source),
            follow=True,
        )

        module_args_tmp = utils.merge_module_args(module_args, new_module_args)

        # Remove data types that are not available to the copy module
        complex_args.pop("config_overrides")
        complex_args.pop("config_type")

        # Return the copy module status. Access to protected method is
        #  unavoidable in Ansible 1.x.
        return self.runner._execute_module(conn, tmp, "copy", module_args_tmp, inject=inject, complex_args=complex_args)
Пример #13
0
    def _get_absolute_path(self, path=None):
        if 'vars' in self.inject:
            if '_original_file' in self.inject['vars']:
                # roles
                path = utils.path_dwim_relative(self.inject['_original_file'], 'files', path, self.runner.basedir)
            elif 'inventory_dir' in self.inject['vars']:
                # non-roles
                abs_dir = os.path.abspath(self.inject['vars']['inventory_dir'])
                path = os.path.join(abs_dir, path)

        return path
Пример #14
0
    def _get_absolute_path(self, path=None):
        if 'vars' in self.inject:
            if '_original_file' in self.inject['vars']:
                # roles
                original_path = path
                path = utils.path_dwim_relative(self.inject['_original_file'], 'files', path, self.runner.basedir)
                if original_path and original_path[-1] == '/' and path[-1] != '/':
                    # make sure the dwim'd path ends in a trailing "/"
                    # if the original path did
                    path += '/'

        return path
Пример #15
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))
        source  = options.get('src', None)
        content = options.get('content', None)
        dest    = options.get('dest', None)
        raw     = utils.boolean(options.get('raw', 'no'))
        force   = utils.boolean(options.get('force', 'yes'))

        if (source is None and content is None and not 'first_available_file' in inject) or dest is None:
            result=dict(failed=True, msg="src (or content) and dest are required")
            return ReturnData(conn=conn, result=result)
        elif (source is not None or 'first_available_file' in inject) and content is not None:
            result=dict(failed=True, msg="src and content are mutually exclusive")
            return ReturnData(conn=conn, result=result)

        source_trailing_slash = False
        if source:
            source_trailing_slash = source.endswith("/")

        # if we have first_available_file in our vars
        # look up the files and use the first one we find as src
        if 'first_available_file' in inject:
            found = False
            for fn in inject.get('first_available_file'):
                fn_orig = fn
                fnt = template.template(self.runner.basedir, fn, inject)
                fnd = utils.path_dwim(self.runner.basedir, fnt)
                if not os.path.exists(fnd) and '_original_file' in inject:
                    fnd = utils.path_dwim_relative(inject['_original_file'], 'files', fnt, self.runner.basedir, check=False)
                if os.path.exists(fnd):
                    source = fnd
                    found = True
                    break
            if not found:
                results=dict(failed=True, msg="could not find src in first_available_file list")
                return ReturnData(conn=conn, result=results)
        elif content is not None:
            fd, tmp_content = tempfile.mkstemp()
            f = os.fdopen(fd, 'w')
            try:
                f.write(content)
            except Exception, err:
                os.remove(tmp_content)
                result = dict(failed=True, msg="could not write content temp file: %s" % err)
                return ReturnData(conn=conn, result=result)
            f.close()
            source = tmp_content
Пример #16
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        ''' handler for file transfer operations '''

        if self.runner.noop_on_check(inject):
            # in check mode, always skip this module
            return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module'))

        # Decode the result of shlex.split() to UTF8 to get around a bug in that's been fixed in Python 2.7 but not Python 2.6.
        # See: http://bugs.python.org/issue6988
        tokens  = shlex.split(module_args.encode('utf8'))
        tokens = [s.decode('utf8') for s in tokens]

        source  = tokens[0]
        # FIXME: error handling
        args    = " ".join(tokens[1:])
        source  = template.template(self.runner.basedir, source, inject)
        if '_original_file' in inject:
            source = utils.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
        else:
            source = utils.path_dwim(self.runner.basedir, source)

        # transfer the file to a remote tmp location
        source  = source.replace('\x00','') # why does this happen here?
        args    = args.replace('\x00','') # why does this happen here?
        tmp_src = os.path.join(tmp, os.path.basename(source))
        tmp_src = tmp_src.replace('\x00', '') 

        conn.put_file(source, tmp_src)

        sudoable=True
        # set file permissions, more permisive when the copy is done as a different user
        if self.runner.sudo and self.runner.sudo_user != 'root':
            cmd_args_chmod = "chmod a+rx %s" % tmp_src
            sudoable=False
        else:
            cmd_args_chmod = "chmod +rx %s" % tmp_src
        self.runner._low_level_exec_command(conn, cmd_args_chmod, tmp, sudoable=sudoable)

        # add preparation steps to one ssh roundtrip executing the script
        env_string = self.runner._compute_environment_string(inject)
        module_args = env_string + tmp_src + ' ' + args

        handler = utils.plugins.action_loader.get('raw', self.runner)
        result = handler.run(conn, tmp, 'raw', module_args, inject)

        # clean up after
        if tmp.find("tmp") != -1 and not C.DEFAULT_KEEP_REMOTE_FILES:
            self.runner._low_level_exec_command(conn, 'rm -rf %s >/dev/null 2>&1' % tmp, tmp)

        result.result['changed'] = True

        return result
Пример #17
0
    def _resolve_file_path(self, filepath, dirname, inject):
        ''' Resolve absolute path of the file. '''

        basedir = self.runner.basedir
        filepath = template.template(basedir, filepath, inject)

        if '_original_file' in inject:
            origin_path = inject['_original_file']
            filepath = utils.path_dwim_relative(origin_path, dirname, filepath, basedir)
        else:
            filepath = utils.path_dwim(basedir, filepath)

        return filepath
Пример #18
0
    def run(self, terms, inject=None, **kwargs):
        
        terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject) 
        ret = []

        # this can happen if the variable contains a string, strictly not desired for lookup
        # plugins, but users may try it, so make it work.
        if not isinstance(terms, list):
            terms = [ terms ]

        buffersize = 65536

        for term in terms:
            basedir_path  = utils.path_dwim(self.basedir, term)
            relative_path = None
            playbook_path = None

            # Special handling of the file lookup, used primarily when the
            # lookup is done from a role. If the file isn't found in the
            # basedir of the current file, use dwim_relative to look in the
            # role/files/ directory, and finally the playbook directory
            # itself (which will be relative to the current working dir)
            if '_original_file' in inject:
                relative_path = utils.path_dwim_relative(inject['_original_file'], 'files', term, self.basedir, check=False)
            if 'playbook_dir' in inject:
                playbook_path = os.path.join(inject['playbook_dir'], term)

            for path in (basedir_path, relative_path, playbook_path):
                if path and os.path.exists(path):
                    afile = open(path, 'r')
                    break
            else:
                raise errors.AnsibleError("could not locate file in lookup: %s" % term)

            # Read file buffered into hasher (good for memory). 
            hasher = hashlib.md5()
            buffer = afile.read(buffersize)
            while(len(buffer) > 0):
                hasher.update(buffer)
                buffer = afile.read(buffersize)

            # Append hex digest to ret list.
            ret.append(hasher.hexdigest())

            # Close file.
            afile.close()

        # Return hex digest.
        return ret
Пример #19
0
    def get_paths(self, inject):
        paths = []
        
        paths.append(utils.path_dwim(self.basedir, ''))
        
        if '_original_file' in inject:
            paths.append(utils.path_dwim_relative(inject['_original_file'], '', '', self.basedir, check=False))
            
        if 'playbook_dir' in inject and paths[0] != inject['playbook_dir']:
            paths.append(inject['playbook_dir'])

        for path in C.get_config(C.p, C.DEFAULTS, 'lookup_file_paths', None, [], islist=True):
            path = utils.unfrackpath(path)
            if os.path.exists(path):
                paths.append(path)

        return paths
Пример #20
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):

        options  = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))

        src = options.get('src', None)
        dest = options.get('dest', None)
        remote_src = utils.boolean(options.get('remote_src', 'no'))

        if src is None:
            result = dict(failed=True, msg="src is required")
            return ReturnData(conn=conn, comm_ok=False, result=result)

        if remote_src:
            return self.runner._execute_module(conn, tmp, 'patch', module_args, inject=inject, complex_args=complex_args)

        # Source is local
        if '_original_file' in inject:
            src = utils.path_dwim_relative(inject['_original_file'], 'files', src, self.runner.basedir)
        else:
            src = utils.path_dwim(self.runner.basedir, src)

        tmp_path = self.runner._make_tmp_path(conn)
        tmp_src = tmp_path + 'patch_source'
        conn.put_file(src, tmp_src)

        if self.runner.become and self.runner.become_user != 'root':
            if not self.runner.noop_on_check(inject):
                self.runner._remote_chmod(conn, 'a+r', tmp_src, tmp_path)

        new_module_args = dict(
            src=tmp_src,
        )

        if self.runner.noop_on_check(inject):
            new_module_args['CHECKMODE'] = True

        module_args = utils.merge_module_args(module_args, new_module_args)

        data = self.runner._execute_module(conn, tmp, 'patch', module_args, inject=inject, complex_args=complex_args)
        if not C.DEFAULT_KEEP_REMOTE_FILES:
            self.runner._remove_tmp_path(conn, tmp_path)

        return data
Пример #21
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):

        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))

        src = options.get("src", None)
        dest = options.get("dest", None)
        remote_src = utils.boolean(options.get("remote_src", "no"))

        if src is None:
            result = dict(failed=True, msg="src is required")
            return ReturnData(conn=conn, comm_ok=False, result=result)

        if remote_src:
            return self.runner._execute_module(
                conn, tmp, "patch", module_args, inject=inject, complex_args=complex_args
            )

        # Source is local
        if "_original_file" in inject:
            src = utils.path_dwim_relative(inject["_original_file"], "files", src, self.runner.basedir)
        else:
            src = utils.path_dwim(self.runner.basedir, src)

        if tmp is None or "-tmp-" not in tmp:
            tmp = self.runner._make_tmp_path(conn)

        tmp_src = conn.shell.join_path(tmp, os.path.basename(src))
        conn.put_file(src, tmp_src)

        if self.runner.become and self.runner.become_user != "root":
            if not self.runner.noop_on_check(inject):
                self.runner._remote_chmod(conn, "a+r", tmp_src, tmp)

        new_module_args = dict(src=tmp_src)

        if self.runner.noop_on_check(inject):
            new_module_args["CHECKMODE"] = True

        module_args = utils.merge_module_args(module_args, new_module_args)

        return self.runner._execute_module(conn, tmp, "patch", module_args, inject=inject, complex_args=complex_args)
Пример #22
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))
        source  = options.get('src', None)
        dest    = options.get('dest', None)
        copy    = utils.boolean(options.get('copy', 'yes'))

        if source is None or dest is None:
            result = dict(failed=True, msg="src (or content) and dest are required")
            return ReturnData(conn=conn, result=result)

        dest = os.path.expanduser(dest)
        source = template.template(self.runner.basedir, os.path.expanduser(source), inject)
        if copy:
            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        remote_md5 = self.runner._remote_md5(conn, tmp, dest)
        if remote_md5 != '3':
            result = dict(failed=True, msg="dest '%s' must be an existing dir" % dest)
            return ReturnData(conn=conn, result=result)

        if copy:
            # transfer the file to a remote tmp location
            tmp_src = tmp + 'source'
            conn.put_file(source, tmp_src)

        # handle diff mode client side
        # handle check mode client side
        # fix file permissions when the copy is done as a different user
        if copy:
            if self.runner.sudo and self.runner.sudo_user != 'root':
                self.runner._low_level_exec_command(conn, "chmod a+r %s" % tmp_src, tmp)
            module_args = "%s src=%s original_basename=%s" % (module_args, pipes.quote(tmp_src), pipes.quote(os.path.basename(source)))
        else:
            module_args = "%s original_basename=%s" % (module_args, pipes.quote(os.path.basename(source)))
        return self.runner._execute_module(conn, tmp, 'unarchive', module_args, inject=inject, complex_args=complex_args)
    def run(self, terms, inject=None, **kwargs):

        terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)
        ret = []

        if not isinstance(terms, list):
            terms = [ terms ]

        for term in terms:
            playbook_path = None
            relative_path = None
            paramvals = {"file": None, "key": None}
            params = term.split()

            try:
                for param in params:
                    name, value = param.split('=')
                    assert(name in paramvals)
                    paramvals[name] = value

            except (ValueError, AssertionError), e:
                # In case "file" or "key" are not present
                raise errors.AnsibleError(e)

            file = paramvals['file']
            key = paramvals['key']
            basedir_path  = utils.path_dwim(self.basedir, file)

            # Search also in the role/files directory and in the playbook directory
            if '_original_file' in inject:
                relative_path = utils.path_dwim_relative(inject['_original_file'], 'files', file, self.basedir, check=False)
            if 'playbook_dir' in inject:
                playbook_path = os.path.join(inject['playbook_dir'], file)

            for path in (basedir_path, relative_path, playbook_path):
                if path and os.path.exists(path):
                    res = self.read_shelve(path, key)
                    if res is None:
                        raise errors.AnsibleError("Key %s not found in shelve file %s" % (key, file))
                    # Convert the value read to string
                    ret.append(str(res))
                    break
            else:
                raise errors.AnsibleError("Could not locate shelve file in lookup: %s" % file)
Пример #24
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        ''' handler for file transfer operations '''

        if self.runner.noop_on_check(inject):
            # in check mode, always skip this module
            return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module'))

        tokens  = shlex.split(module_args)
        source  = tokens[0]
        # FIXME: error handling
        args    = " ".join(tokens[1:])
        source  = template.template(self.runner.basedir, source, inject)
        if '_original_file' in inject:
            source = utils.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
        else:
            source = utils.path_dwim(self.runner.basedir, source)

        # transfer the file to a remote tmp location
        source  = source.replace('\x00','') # why does this happen here?
        args    = args.replace('\x00','') # why does this happen here?
        tmp_src = os.path.join(tmp, os.path.basename(source))
        tmp_src = tmp_src.replace('\x00', '') 

        conn.put_file(source, tmp_src)

        # fix file permissions when the copy is done as a different user
        if self.runner.sudo and self.runner.sudo_user != 'root':
            prepcmd = 'chmod a+rx %s' % tmp_src
        else:
            prepcmd = 'chmod +x %s' % tmp_src

        # add preparation steps to one ssh roundtrip executing the script
        env_string = self.runner._compute_environment_string(inject)
        module_args = prepcmd + '; ' + env_string + tmp_src + ' ' + args

        handler = utils.plugins.action_loader.get('raw', self.runner)
        result = handler.run(conn, tmp, 'raw', module_args, inject)

        # clean up after
        if tmp.find("tmp") != -1 and not C.DEFAULT_KEEP_REMOTE_FILES:
            self.runner._low_level_exec_command(conn, 'rm -rf %s >/dev/null 2>&1' % tmp, tmp)

        return result
Пример #25
0
    def run(self, conn, tmp_path, module_name, module_args, inject,
            complex_args=None, **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options  = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))

        if "-tmp-" not in tmp_path:
            tmp_path = self.runner._make_tmp_path(conn)

        self.tmp_path = tmp_path
        self.conn = conn
        self.facts = inject

        self._copy_setup_storage()

        # copy user defined partion file if needed
        partition = options.get('partition')
        if not partition is None and partition != 'auto':
            fnd = utils.path_dwim(
                os.path.sep.join((self.runner.basedir, 'files')),
                partition)
            if not os.path.exists(fnd):
                fnd = utils.path_dwim_relative(
                    partition, 'files', partition, self.runner.basedir)
            self.conn.put_file(
                fnd,
                os.path.sep.join([self.tmp_path, 'setup-storage', 'conf.d', partition]))

        ret=self.runner._execute_module(
            conn, tmp_path, 'system_install',
            module_args, inject=inject,
            complex_args=complex_args)

        return ret
Пример #26
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        args = parse_kv(module_args)
        environment = args.get('environment')
        account_id = args.get('account_id')
        assume_role = args.get('assume_role')

        for name, val in (("environment", environment), ("account_id", account_id), ("assume_role", assume_role)):
            if val is None:
                result = dict(failed=True, msg="No {0} specified".format(name))
                return ReturnData(conn=conn, comm_ok=True, result=result)

        source = template.template(self.runner.basedir, environment, inject)

        if '_original_file' in inject:
            source = utils.path_dwim_relative(inject['_original_file'], 'vars', source, self.runner.basedir)
        else:
            source = utils.path_dwim(self.runner.basedir, source)

        if os.path.exists(source):
            decrypted_data = {}
            data = json.load(open(source))

            with assume(account_id, assume_role):
                kms = boto.kms.connect_to_region('ap-southeast-2')

                for key, val in data.items():
                    data_key = kms.decrypt(base64.b64decode(val['key']))["Plaintext"]
                    content = base64.b64decode(val['content'])
                    counter = Counter.new(128)
                    decryptor = AES.new(data_key[:32], AES.MODE_CTR, counter=counter)
                    decrypted_data[key] = decryptor.decrypt(content)

                result = dict(ansible_facts=decrypted_data)
                return ReturnData(conn=conn, comm_ok=True, result=result)
        else:
            result = dict(failed=True, msg="Couldn't find secrets!", file=source)
            return ReturnData(conn=conn, comm_ok=True, result=result)
Пример #27
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):
        ''' handler for file transfer operations '''

        if self.runner.noop_on_check(inject):
            # in check mode, always skip this module
            return ReturnData(
                conn=conn,
                comm_ok=True,
                result=dict(skipped=True,
                            msg='check mode not supported for this module'))

        # Decode the result of shlex.split() to UTF8 to get around a bug in that's been fixed in Python 2.7 but not Python 2.6.
        # See: http://bugs.python.org/issue6988
        tokens = shlex.split(module_args.encode('utf8'))
        tokens = [s.decode('utf8') for s in tokens]

        source = tokens[0]
        # FIXME: error handling
        args = " ".join(tokens[1:])
        source = template.template(self.runner.basedir, source, inject)
        if '_original_file' in inject:
            source = utils.path_dwim_relative(inject['_original_file'],
                                              'files', source,
                                              self.runner.basedir)
        else:
            source = utils.path_dwim(self.runner.basedir, source)

        # transfer the file to a remote tmp location
        source = source.replace('\x00', '')  # why does this happen here?
        args = args.replace('\x00', '')  # why does this happen here?
        tmp_src = os.path.join(tmp, os.path.basename(source))
        tmp_src = tmp_src.replace('\x00', '')

        conn.put_file(source, tmp_src)

        # fix file permissions when the copy is done as a different user
        if self.runner.sudo and self.runner.sudo_user != 'root':
            prepcmd = 'chmod a+rx %s' % tmp_src
        else:
            prepcmd = 'chmod +x %s' % tmp_src

        # add preparation steps to one ssh roundtrip executing the script
        env_string = self.runner._compute_environment_string(inject)
        module_args = prepcmd + '; ' + env_string + tmp_src + ' ' + args

        handler = utils.plugins.action_loader.get('raw', self.runner)
        result = handler.run(conn, tmp, 'raw', module_args, inject)

        # clean up after
        if tmp.find("tmp") != -1 and not C.DEFAULT_KEEP_REMOTE_FILES:
            self.runner._low_level_exec_command(
                conn, 'rm -rf %s >/dev/null 2>&1' % tmp, tmp)

        result.result['changed'] = True

        return result
Пример #28
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):
        ''' handler for template operations '''

        # note: since this module just calls the copy module, the --check mode support
        # can be implemented entirely over there

        if not self.runner.is_playbook:
            raise errors.AnsibleError(
                "in current versions of ansible, templates are only usable in playbooks"
            )

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))

        source = options.get('src', None)
        dest = options.get('dest', None)

        if (source is None
                and 'first_available_file' not in inject) or dest is None:
            result = dict(failed=True, msg="src and dest are required")
            return ReturnData(conn=conn, comm_ok=False, result=result)

        # if we have first_available_file in our vars
        # look up the files and use the first one we find as src

        if 'first_available_file' in inject:
            found = False
            for fn in self.runner.module_vars.get('first_available_file'):
                fn_orig = fn
                fnt = template.template(self.runner.basedir, fn, inject)
                fnd = utils.path_dwim(self.runner.basedir, fnt)
                if not os.path.exists(fnd) and '_original_file' in inject:
                    fnd = utils.path_dwim_relative(inject['_original_file'],
                                                   'templates',
                                                   fnt,
                                                   self.runner.basedir,
                                                   check=False)
                if os.path.exists(fnd):
                    source = fnd
                    found = True
                    break
            if not found:
                result = dict(
                    failed=True,
                    msg="could not find src in first_available_file list")
                return ReturnData(conn=conn, comm_ok=False, result=result)
        else:
            source = template.template(self.runner.basedir, source, inject)

            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'],
                                                  'templates', source,
                                                  self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        if dest.endswith("/"):  # CCTODO: Fix path for Windows hosts.
            base = os.path.basename(source)
            dest = os.path.join(dest, base)

        # template the source data locally & get ready to transfer
        try:
            resultant = template.template_from_file(
                self.runner.basedir,
                source,
                inject,
                vault_password=self.runner.vault_pass)
        except Exception, e:
            result = dict(failed=True, msg=str(e))
            return ReturnData(conn=conn, comm_ok=False, result=result)
Пример #29
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):
        """Run the method"""
        if not self.runner.is_playbook:
            raise errors.AnsibleError(
                'FAILED: `config_templates` are only available in playbooks')

        options = self.grab_options(complex_args, module_args)
        try:
            source = options['src']
            dest = options['dest']

            config_overrides = options.get('config_overrides', dict())
            config_type = options['config_type']
            assert config_type.lower() in ['ini', 'json', 'yaml']
        except KeyError as exp:
            result = dict(failed=True, msg=exp)
            return ReturnData(conn=conn, comm_ok=False, result=result)

        source_template = template.template(self.runner.basedir, source,
                                            inject)

        if '_original_file' in inject:
            source_file = utils.path_dwim_relative(inject['_original_file'],
                                                   'templates',
                                                   source_template,
                                                   self.runner.basedir)
        else:
            source_file = utils.path_dwim(self.runner.basedir, source_template)

        # Open the template file and return the data as a string. This is
        #  being done here so that the file can be a vault encrypted file.
        resultant = template.template_from_file(
            self.runner.basedir,
            source_file,
            inject,
            vault_password=self.runner.vault_pass)

        if config_overrides:
            type_merger = getattr(self, CONFIG_TYPES.get(config_type))
            resultant = type_merger(config_overrides=config_overrides,
                                    resultant=resultant)

        # Retemplate the resultant object as it may have new data within it
        #  as provided by an override variable.
        template.template_from_string(basedir=self.runner.basedir,
                                      data=resultant,
                                      vars=inject,
                                      fail_on_undefined=True)

        # Access to protected method is unavoidable in Ansible 1.x.
        new_module_args = dict(
            src=self.runner._transfer_str(conn, tmp, 'source', resultant),
            dest=dest,
            original_basename=os.path.basename(source),
            follow=True,
        )

        module_args_tmp = utils.merge_module_args(module_args, new_module_args)

        # Remove data types that are not available to the copy module
        complex_args.pop('config_overrides')
        complex_args.pop('config_type')

        # Return the copy module status. Access to protected method is
        #  unavoidable in Ansible 1.x.
        return self.runner._execute_module(conn,
                                           tmp,
                                           'copy',
                                           module_args_tmp,
                                           inject=inject,
                                           complex_args=complex_args)
Пример #30
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))
        source = options.get('src', None)
        dest = options.get('dest', None)
        copy = utils.boolean(options.get('copy', 'yes'))
        creates = options.get('creates', None)

        if source is None or dest is None:
            result = dict(failed=True,
                          msg="src (or content) and dest are required")
            return ReturnData(conn=conn, result=result)

        if creates:
            # do not run the command if the line contains creates=filename
            # and the filename already exists. This allows idempotence
            # of command executions.
            module_args_tmp = ""
            complex_args_tmp = dict(path=creates,
                                    get_md5=False,
                                    get_checksum=False)
            module_return = self.runner._execute_module(
                conn,
                tmp,
                'stat',
                module_args_tmp,
                inject=inject,
                complex_args=complex_args_tmp,
                persist_files=True)
            stat = module_return.result.get('stat', None)
            if stat and stat.get('exists', False):
                return ReturnData(conn=conn,
                                  comm_ok=True,
                                  result=dict(skipped=True,
                                              changed=False,
                                              msg=("skipped, since %s exists" %
                                                   creates)))

        dest = self.runner._remote_expand_user(
            conn, dest, tmp)  # CCTODO: Fix path for Windows hosts.
        source = template.template(self.runner.basedir,
                                   os.path.expanduser(source), inject)
        if copy:
            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'],
                                                  'files', source,
                                                  self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        remote_checksum = self.runner._remote_checksum(conn, tmp, dest, inject)
        if remote_checksum == '4':
            result = dict(
                failed=True,
                msg=
                "python isn't present on the system.  Unable to compute checksum"
            )
            return ReturnData(conn=conn, result=result)
        if remote_checksum != '3':
            result = dict(failed=True,
                          msg="dest '%s' must be an existing dir" % dest)
            return ReturnData(conn=conn, result=result)

        if copy:
            # transfer the file to a remote tmp location
            tmp_src = tmp + 'source'
            conn.put_file(source, tmp_src)

        # handle diff mode client side
        # handle check mode client side
        # fix file permissions when the copy is done as a different user
        if copy:
            if self.runner.sudo and self.runner.sudo_user != 'root' or self.runner.su and self.runner.su_user != 'root':
                if not self.runner.noop_on_check(inject):
                    self.runner._remote_chmod(conn, 'a+r', tmp_src, tmp)
            # Build temporary module_args.
            new_module_args = dict(
                src=tmp_src,
                original_basename=os.path.basename(source),
            )

            # make sure checkmod is passed on correctly
            if self.runner.noop_on_check(inject):
                new_module_args['CHECKMODE'] = True

            module_args = utils.merge_module_args(module_args, new_module_args)
        else:
            module_args = "%s original_basename=%s" % (
                module_args, pipes.quote(os.path.basename(source)))
            # make sure checkmod is passed on correctly
            if self.runner.noop_on_check(inject):
                module_args += " CHECKMODE=True"
        return self.runner._execute_module(conn,
                                           tmp,
                                           'unarchive',
                                           module_args,
                                           inject=inject,
                                           complex_args=complex_args)
Пример #31
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))
        source  = options.get('src', None)
        dest    = options.get('dest', None)
        copy    = utils.boolean(options.get('copy', 'yes'))
        creates = options.get('creates', None)

        if source is None or dest is None:
            result = dict(failed=True, msg="src (or content) and dest are required")
            return ReturnData(conn=conn, result=result)

        if creates:
            # do not run the command if the line contains creates=filename
            # and the filename already exists. This allows idempotence
            # of command executions.
            module_args_tmp = ""
            complex_args_tmp = dict(path=creates, get_md5=False, get_checksum=False)
            module_return = self.runner._execute_module(conn, tmp, 'stat', module_args_tmp, inject=inject,
                                                        complex_args=complex_args_tmp, persist_files=True)
            stat = module_return.result.get('stat', None)
            if stat and stat.get('exists', False):
                return ReturnData(
	            conn=conn,
                    comm_ok=True,
                    result=dict(
                        skipped=True,
                        changed=False,
                        msg=("skipped, since %s exists" % creates)
                    )
                )

        dest = self.runner._remote_expand_user(conn, dest, tmp) # CCTODO: Fix path for Windows hosts.
        source = template.template(self.runner.basedir, os.path.expanduser(source), inject)
        if copy:
            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        remote_checksum = self.runner._remote_checksum(conn, tmp, dest, inject)
        if remote_checksum == '4':
            result = dict(failed=True, msg="python isn't present on the system.  Unable to compute checksum")
            return ReturnData(conn=conn, result=result)
        if remote_checksum != '3':
            result = dict(failed=True, msg="dest '%s' must be an existing dir" % dest)
            return ReturnData(conn=conn, result=result)

        if copy:
            # transfer the file to a remote tmp location
            tmp_src = tmp + 'source'
            conn.put_file(source, tmp_src)

        # handle diff mode client side
        # handle check mode client side
        # fix file permissions when the copy is done as a different user
        if copy:
            if self.runner.sudo and self.runner.sudo_user != 'root' or self.runner.su and self.runner.su_user != 'root':
                if not self.runner.noop_on_check(inject):
                    self.runner._remote_chmod(conn, 'a+r', tmp_src, tmp)
            # Build temporary module_args.
            new_module_args = dict(
                src=tmp_src,
                original_basename=os.path.basename(source),
            )

            # make sure checkmod is passed on correctly
            if self.runner.noop_on_check(inject):
                new_module_args['CHECKMODE'] = True

            module_args = utils.merge_module_args(module_args, new_module_args)
        else:
            module_args = "%s original_basename=%s" % (module_args, pipes.quote(os.path.basename(source)))
            # make sure checkmod is passed on correctly
            if self.runner.noop_on_check(inject):
                module_args += " CHECKMODE=True"
        return self.runner._execute_module(conn, tmp, 'unarchive', module_args, inject=inject, complex_args=complex_args)
Пример #32
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))
        source = options.get('src', None)
        dest = options.get('dest', None)
        copy = utils.boolean(options.get('copy', 'yes'))

        if source is None or dest is None:
            result = dict(failed=True,
                          msg="src (or content) and dest are required")
            return ReturnData(conn=conn, result=result)

        dest = os.path.expanduser(dest)  # CCTODO: Fix path for Windows hosts.
        source = template.template(self.runner.basedir,
                                   os.path.expanduser(source), inject)
        if copy:
            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'],
                                                  'files', source,
                                                  self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        remote_md5 = self.runner._remote_md5(conn, tmp, dest)
        if remote_md5 != '3':
            result = dict(failed=True,
                          msg="dest '%s' must be an existing dir" % dest)
            return ReturnData(conn=conn, result=result)

        if copy:
            # transfer the file to a remote tmp location
            tmp_src = tmp + 'source'
            conn.put_file(source, tmp_src)

        # handle diff mode client side
        # handle check mode client side
        # fix file permissions when the copy is done as a different user
        if copy:
            if self.runner.sudo and self.runner.sudo_user != 'root':
                self.runner._remote_chmod(conn, 'a+r', tmp_src, tmp)
            # Build temporary module_args.
            new_module_args = dict(
                src=tmp_src,
                original_basename=os.path.basename(source),
            )
            module_args = utils.merge_module_args(module_args, new_module_args)
        else:
            module_args = "%s original_basename=%s" % (
                module_args, pipes.quote(os.path.basename(source)))
        return self.runner._execute_module(conn,
                                           tmp,
                                           'unarchive',
                                           module_args,
                                           inject=inject,
                                           complex_args=complex_args)
Пример #33
0
class ActionModule(object):
    def __init__(self, runner):
        self.runner = runner

    def run(self,
            conn,
            tmp_path,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))
        source = options.get('src', None)
        content = options.get('content', None)
        dest = options.get('dest', None)
        raw = utils.boolean(options.get('raw', 'no'))
        force = utils.boolean(options.get('force', 'yes'))

        # content with newlines is going to be escaped to safely load in yaml
        # now we need to unescape it so that the newlines are evaluated properly
        # when writing the file to disk
        if content:
            if isinstance(content, unicode):
                try:
                    content = content.decode('unicode-escape')
                except UnicodeDecodeError:
                    pass

        if (source is None and content is None
                and not 'first_available_file' in inject) or dest is None:
            result = dict(failed=True,
                          msg="src (or content) and dest are required")
            return ReturnData(conn=conn, result=result)
        elif (source is not None
              or 'first_available_file' in inject) and content is not None:
            result = dict(failed=True,
                          msg="src and content are mutually exclusive")
            return ReturnData(conn=conn, result=result)

        # Check if the source ends with a "/"
        source_trailing_slash = False
        if source:
            source_trailing_slash = source.endswith("/")

        # Define content_tempfile in case we set it after finding content populated.
        content_tempfile = None

        # If content is defined make a temp file and write the content into it.
        if content is not None:
            try:
                # If content comes to us as a dict it should be decoded json.
                # We need to encode it back into a string to write it out.
                if type(content) is dict:
                    content_tempfile = self._create_content_tempfile(
                        json.dumps(content))
                else:
                    content_tempfile = self._create_content_tempfile(content)
                source = content_tempfile
            except Exception, err:
                result = dict(failed=True,
                              msg="could not write content temp file: %s" %
                              err)
                return ReturnData(conn=conn, result=result)
        # if we have first_available_file in our vars
        # look up the files and use the first one we find as src
        elif 'first_available_file' in inject:
            found = False
            for fn in inject.get('first_available_file'):
                fn_orig = fn
                fnt = template.template(self.runner.basedir, fn, inject)
                fnd = utils.path_dwim(self.runner.basedir, fnt)
                if not os.path.exists(fnd) and '_original_file' in inject:
                    fnd = utils.path_dwim_relative(inject['_original_file'],
                                                   'files',
                                                   fnt,
                                                   self.runner.basedir,
                                                   check=False)
                if os.path.exists(fnd):
                    source = fnd
                    found = True
                    break
            if not found:
                results = dict(
                    failed=True,
                    msg="could not find src in first_available_file list")
                return ReturnData(conn=conn, result=results)
Пример #34
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)

        options.update(utils.parse_kv(module_args))

        src = options.get('src', None)
        dest = options.get('dest', None)
        delimiter = options.get('delimiter', None)
        remote_src = utils.boolean(options.get('remote_src', 'yes'))
        regexp = options.get('regexp', None)

        if src is None or dest is None:
            result = dict(failed=True, msg="src and dest are required")
            return ReturnData(conn=conn, comm_ok=False, result=result)

        if remote_src:
            return self.runner._execute_module(conn,
                                               tmp,
                                               'assemble',
                                               module_args,
                                               inject=inject,
                                               complex_args=complex_args)
        elif '_original_file' in inject:
            src = utils.path_dwim_relative(inject['_original_file'], 'files',
                                           src, self.runner.basedir)
        else:
            # the source is local, so expand it here
            src = os.path.expanduser(src)

        _re = None
        if regexp is not None:
            _re = re.compile(regexp)

        # Does all work assembling the file
        path = self._assemble_from_fragments(src, delimiter, _re)

        path_checksum = utils.checksum_s(path)
        dest = self.runner._remote_expand_user(conn, dest, tmp)
        remote_checksum = self.runner._remote_checksum(conn, tmp, dest, inject)

        if path_checksum != remote_checksum:
            resultant = file(path).read()
            if self.runner.diff:
                dest_result = self.runner._execute_module(conn,
                                                          tmp,
                                                          'slurp',
                                                          "path=%s" % dest,
                                                          inject=inject,
                                                          persist_files=True)
                if 'content' in dest_result.result:
                    dest_contents = dest_result.result['content']
                    if dest_result.result['encoding'] == 'base64':
                        dest_contents = base64.b64decode(dest_contents)
                    else:
                        raise Exception("unknown encoding, failed: %s" %
                                        dest_result.result)
            xfered = self.runner._transfer_str(conn, tmp, 'src', resultant)

            # fix file permissions when the copy is done as a different user
            if self.runner.become and self.runner.become_user != 'root':
                self.runner._remote_chmod(conn, 'a+r', xfered, tmp)

            # run the copy module
            new_module_args = dict(
                src=xfered,
                dest=dest,
                original_basename=os.path.basename(src),
            )
            module_args_tmp = utils.merge_module_args(module_args,
                                                      new_module_args)

            if self.runner.noop_on_check(inject):
                return ReturnData(conn=conn,
                                  comm_ok=True,
                                  result=dict(changed=True),
                                  diff=dict(before_header=dest,
                                            after_header=src,
                                            after=resultant))
            else:
                res = self.runner._execute_module(conn,
                                                  tmp,
                                                  'copy',
                                                  module_args_tmp,
                                                  inject=inject)
                res.diff = dict(after=resultant)
                return res
        else:
            new_module_args = dict(
                src=xfered,
                dest=dest,
                original_basename=os.path.basename(src),
            )

            # make sure checkmod is passed on correctly
            if self.runner.noop_on_check(inject):
                new_module_args['CHECKMODE'] = True

            module_args_tmp = utils.merge_module_args(module_args,
                                                      new_module_args)

            return self.runner._execute_module(conn,
                                               tmp,
                                               'file',
                                               module_args_tmp,
                                               inject=inject)
Пример #35
0
                fnd = utils.path_dwim(self.runner.basedir, fnt)
                if not os.path.exists(fnd) and "_original_file" in inject:
                    fnd = utils.path_dwim_relative(
                        inject["_original_file"], "files", fnt, self.runner.basedir, check=False
                    )
                if os.path.exists(fnd):
                    source = fnd
                    found = True
                    break
            if not found:
                results = dict(failed=True, msg="could not find src in first_available_file list")
                return ReturnData(conn=conn, result=results)
        else:
            source = template.template(self.runner.basedir, source, inject)
            if "_original_file" in inject:
                source = utils.path_dwim_relative(inject["_original_file"], "files", source, self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        # A list of source file tuples (full_path, relative_path) which will try to copy to the destination
        source_files = []

        # If source is a directory populate our list else source is a file and translate it to a tuple.
        if os.path.isdir(source):
            # Get the amount of spaces to remove to get the relative path.
            if source_trailing_slash:
                sz = len(source) + 1
            else:
                sz = len(source.rsplit("/", 1)[0]) + 1

            # Walk the directory and append the file tuples to source_files.
Пример #36
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)

        options.update(utils.parse_kv(module_args))

        src = options.get('src', None)
        dest = options.get('dest', None)
        delimiter = options.get('delimiter', None)
        remote_src = utils.boolean(options.get('remote_src', 'yes'))

        if src is None or dest is None:
            result = dict(failed=True, msg="src and dest are required")
            return ReturnData(conn=conn, comm_ok=False, result=result)

        if remote_src:
            return self.runner._execute_module(conn,
                                               tmp,
                                               'assemble',
                                               module_args,
                                               inject=inject,
                                               complex_args=complex_args)
        elif '_original_file' in inject:
            src = utils.path_dwim_relative(inject['_original_file'], 'files',
                                           src, self.runner.basedir)
        else:
            # the source is local, so expand it here
            src = os.path.expanduser(src)

        # Does all work assembling the file
        path = self._assemble_from_fragments(src, delimiter)

        pathmd5 = utils.md5s(path)
        remote_md5 = self.runner._remote_md5(conn, tmp, dest)

        if pathmd5 != remote_md5:
            resultant = file(path).read()
            if self.runner.diff:
                dest_result = self.runner._execute_module(conn,
                                                          tmp,
                                                          'slurp',
                                                          "path=%s" % dest,
                                                          inject=inject,
                                                          persist_files=True)
                if 'content' in dest_result.result:
                    dest_contents = dest_result.result['content']
                    if dest_result.result['encoding'] == 'base64':
                        dest_contents = base64.b64decode(dest_contents)
                    else:
                        raise Exception("unknown encoding, failed: %s" %
                                        dest_result.result)
            xfered = self.runner._transfer_str(conn, tmp, 'src', resultant)

            # fix file permissions when the copy is done as a different user
            if self.runner.sudo and self.runner.sudo_user != 'root':
                self.runner._low_level_exec_command(conn,
                                                    "chmod a+r %s" % xfered,
                                                    tmp)

            # run the copy module
            module_args = "%s src=%s dest=%s original_basename=%s" % (
                module_args, pipes.quote(xfered), pipes.quote(dest),
                pipes.quote(os.path.basename(src)))

            if self.runner.noop_on_check(inject):
                return ReturnData(conn=conn,
                                  comm_ok=True,
                                  result=dict(changed=True),
                                  diff=dict(before_header=dest,
                                            after_header=src,
                                            after=resultant))
            else:
                res = self.runner._execute_module(conn,
                                                  tmp,
                                                  'copy',
                                                  module_args,
                                                  inject=inject)
                res.diff = dict(after=resultant)
                return res
        else:
            module_args = "%s src=%s dest=%s original_basename=%s" % (
                module_args, pipes.quote(xfered), pipes.quote(dest),
                pipes.quote(os.path.basename(src)))
            return self.runner._execute_module(conn,
                                               tmp,
                                               'file',
                                               module_args,
                                               inject=inject)
Пример #37
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):

        # load up options
        options  = {}
        if complex_args:
            options.update(complex_args)

        options.update(utils.parse_kv(module_args))

        src = options.get('src', None)
        dest = options.get('dest', None)
        delimiter = options.get('delimiter', None)
        remote_src = utils.boolean(options.get('remote_src', 'yes'))
        regexp = options.get('regexp', None)


        if src is None or dest is None:
            result = dict(failed=True, msg="src and dest are required")
            return ReturnData(conn=conn, comm_ok=False, result=result)

        if remote_src:
            return self.runner._execute_module(conn, tmp, 'assemble', module_args, inject=inject, complex_args=complex_args)
        elif '_original_file' in inject:
            src = utils.path_dwim_relative(inject['_original_file'], 'files', src, self.runner.basedir)
        else:
            # the source is local, so expand it here
            src = os.path.expanduser(src)

        _re = None
        if regexp is not None:
            _re = re.compile(regexp)

        # Does all work assembling the file
        path = self._assemble_from_fragments(src, delimiter, _re)

        path_checksum = utils.checksum_s(path)
        dest = self.runner._remote_expand_user(conn, dest, tmp)
        remote_checksum = self.runner._remote_checksum(conn, tmp, dest, inject)

        if path_checksum != remote_checksum:
            resultant = file(path).read()
            if self.runner.diff:
                dest_result = self.runner._execute_module(conn, tmp, 'slurp', "path=%s" % dest, inject=inject, persist_files=True)
                if 'content' in dest_result.result:
                    dest_contents = dest_result.result['content']
                    if dest_result.result['encoding'] == 'base64':
                        dest_contents = base64.b64decode(dest_contents)
                    else:
                        raise Exception("unknown encoding, failed: %s" % dest_result.result)
            xfered = self.runner._transfer_str(conn, tmp, 'src', resultant)

            # fix file permissions when the copy is done as a different user
            if self.runner.become and self.runner.become_user != 'root':
                self.runner._remote_chmod(conn, 'a+r', xfered, tmp)

            # run the copy module
            new_module_args = dict(
                src=xfered,
                dest=dest,
                original_basename=os.path.basename(src),
            )
            module_args_tmp = utils.merge_module_args(module_args, new_module_args)

            if self.runner.noop_on_check(inject):
                return ReturnData(conn=conn, comm_ok=True, result=dict(changed=True), diff=dict(before_header=dest, after_header=src, after=resultant))
            else:
                res = self.runner._execute_module(conn, tmp, 'copy', module_args_tmp, inject=inject)
                res.diff = dict(after=resultant)
                return res
        else:
            new_module_args = dict(
                src=xfered,
                dest=dest,
                original_basename=os.path.basename(src),
            )

            # make sure checkmod is passed on correctly
            if self.runner.noop_on_check(inject):
                new_module_args['CHECKMODE'] = True

            module_args_tmp = utils.merge_module_args(module_args, new_module_args)

            return self.runner._execute_module(conn, tmp, 'file', module_args_tmp, inject=inject)
Пример #38
0
                fn_orig = fn
                fnt = template.template(self.runner.basedir, fn, inject)
                fnd = utils.path_dwim(self.runner.basedir, fnt)
                if not os.path.exists(fnd) and '_original_file' in inject:
                    fnd = utils.path_dwim_relative(inject['_original_file'], 'files', fnt, self.runner.basedir, check=False)
                if os.path.exists(fnd):
                    source = fnd
                    found = True
                    break
            if not found:
                results = dict(failed=True, msg="could not find src in first_available_file list")
                return ReturnData(conn=conn, result=results)
        else:
            source = template.template(self.runner.basedir, source, inject)
            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        # A list of source file tuples (full_path, relative_path) which will try to copy to the destination
        source_files = []

        # If source is a directory populate our list else source is a file and translate it to a tuple.
        if os.path.isdir(source):
            # Get the amount of spaces to remove to get the relative path.
            if source_trailing_slash:
                sz = len(source) + 1
            else:
                sz = len(source.rsplit('/', 1)[0]) + 1

            # Walk the directory and append the file tuples to source_files.
Пример #39
0
    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
        ''' handler for file transfer operations '''

        if self.runner.noop_on_check(inject):
            # in check mode, always skip this module
            return ReturnData(conn=conn, comm_ok=True,
                              result=dict(skipped=True, msg='check mode not supported for this module'))

        # extract ansible reserved parameters
        # From library/command keep in sync
        creates = None
        removes = None
        r = re.compile(r'(^|\s)(creates|removes)=(?P<quote>[\'"])?(.*?)(?(quote)(?<!\\)(?P=quote))((?<!\\)(?=\s)|$)')
        for m in r.finditer(module_args):
            v = m.group(4).replace("\\", "")
            if m.group(2) == "creates":
                creates = v
            elif m.group(2) == "removes":
                removes = v
        module_args = r.sub("", module_args)

        if creates:
            # do not run the command if the line contains creates=filename
            # and the filename already exists. This allows idempotence
            # of command executions.
            module_args_tmp = "path=%s" % creates
            module_return = self.runner._execute_module(conn, tmp, 'stat', module_args_tmp, inject=inject,
                                                        complex_args=complex_args, persist_files=True)
            stat = module_return.result.get('stat', None)
            if stat and stat.get('exists', False):
                return ReturnData(
                    conn=conn,
                    comm_ok=True,
                    result=dict(
                        skipped=True,
                        msg=("skipped, since %s exists" % creates)
                    )
                )
        if removes:
            # do not run the command if the line contains removes=filename
            # and the filename does not exist. This allows idempotence
            # of command executions.
            module_args_tmp = "path=%s" % removes
            module_return = self.runner._execute_module(conn, tmp, 'stat', module_args_tmp, inject=inject,
                                                        complex_args=complex_args, persist_files=True)
            stat = module_return.result.get('stat', None)
            if stat and not stat.get('exists', False):
                return ReturnData(
                    conn=conn,
                    comm_ok=True,
                    result=dict(
                        skipped=True,
                        msg=("skipped, since %s does not exist" % removes)
                    )
                )

        # Decode the result of shlex.split() to UTF8 to get around a bug in that's been fixed in Python 2.7 but not Python 2.6.
        # See: http://bugs.python.org/issue6988
        tokens = shlex.split(module_args.encode('utf8'))
        tokens = [s.decode('utf8') for s in tokens]
        # extract source script
        source = tokens[0]

        # FIXME: error handling
        args = " ".join(tokens[1:])
        source = template.template(self.runner.basedir, source, inject)
        if '_original_file' in inject:
            source = utils.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
        else:
            source = utils.path_dwim(self.runner.basedir, source)

        # transfer the file to a remote tmp location
        source = source.replace('\x00', '')  # why does this happen here?
        args = args.replace('\x00', '')  # why does this happen here?
        tmp_src = os.path.join(tmp, os.path.basename(source))
        tmp_src = tmp_src.replace('\x00', '')

        conn.put_file(source, tmp_src)

        sudoable = True
        # set file permissions, more permisive when the copy is done as a different user
        if self.runner.sudo and self.runner.sudo_user != 'root':
            cmd_args_chmod = "chmod a+rx %s" % tmp_src
            sudoable = False
        else:
            cmd_args_chmod = "chmod +rx %s" % tmp_src
        self.runner._low_level_exec_command(conn, cmd_args_chmod, tmp, sudoable=sudoable)

        # add preparation steps to one ssh roundtrip executing the script
        env_string = self.runner._compute_environment_string(inject)
        module_args = env_string + tmp_src + ' ' + args

        handler = utils.plugins.action_loader.get('raw', self.runner)
        result = handler.run(conn, tmp, 'raw', module_args, inject)

        # clean up after
        if tmp.find("tmp") != -1 and not C.DEFAULT_KEEP_REMOTE_FILES:
            self.runner._low_level_exec_command(conn, 'rm -rf %s >/dev/null 2>&1' % tmp, tmp)

        result.result['changed'] = True

        return result
Пример #40
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):
        ''' handler for file transfer operations '''

        # load up options
        options = {}
        if complex_args:
            options.update(complex_args)
        options.update(utils.parse_kv(module_args))
        source = options.get('src', None)
        content = options.get('content', None)
        dest = options.get('dest', None)
        force = utils.boolean(options.get('force', 'yes'))

        if (source is None and content is None
                and not 'first_available_file' in inject) or dest is None:
            result = dict(failed=True,
                          msg="src (or content) and dest are required")
            return ReturnData(conn=conn, result=result)
        elif (source is not None
              or 'first_available_file' in inject) and content is not None:
            result = dict(failed=True,
                          msg="src and content are mutually exclusive")
            return ReturnData(conn=conn, result=result)

        # if we have first_available_file in our vars
        # look up the files and use the first one we find as src
        if 'first_available_file' in inject:
            found = False
            for fn in inject.get('first_available_file'):
                fn_orig = fn
                fn = template.template(self.runner.basedir, fn, inject)
                fn = utils.path_dwim(self.runner.basedir, fn)
                if not os.path.exists(fn) and '_original_file' in inject:
                    fn = utils.path_dwim_relative(inject['_original_file'],
                                                  'files',
                                                  fn_orig,
                                                  self.runner.basedir,
                                                  check=False)
                if os.path.exists(fn):
                    source = fn
                    found = True
                    break
            if not found:
                results = dict(
                    failed=True,
                    msg="could not find src in first_available_file list")
                return ReturnData(conn=conn, result=results)
        elif content is not None:
            fd, tmp_content = tempfile.mkstemp()
            f = os.fdopen(fd, 'w')
            try:
                f.write(content)
            except Exception, err:
                os.remove(tmp_content)
                result = dict(failed=True,
                              msg="could not write content temp file: %s" %
                              err)
                return ReturnData(conn=conn, result=result)
            f.close()
            source = tmp_content
Пример #41
0
            f = os.fdopen(fd, 'w')
            try:
                f.write(content)
            except Exception, err:
                os.remove(tmp_content)
                result = dict(failed=True,
                              msg="could not write content temp file: %s" %
                              err)
                return ReturnData(conn=conn, result=result)
            f.close()
            source = tmp_content
        else:
            source = template.template(self.runner.basedir, source, inject)
            if '_original_file' in inject:
                source = utils.path_dwim_relative(inject['_original_file'],
                                                  'files', source,
                                                  self.runner.basedir)
            else:
                source = utils.path_dwim(self.runner.basedir, source)

        local_md5 = utils.md5(source)
        if local_md5 is None:
            result = dict(failed=True, msg="could not find src=%s" % source)
            return ReturnData(conn=conn, result=result)

        if dest.endswith("/"):
            base = os.path.basename(source)
            dest = os.path.join(dest, base)

        remote_md5 = self.runner._remote_md5(conn, tmp, dest)
        if remote_md5 == '3':