コード例 #1
0
 def test_action_with_complex_and_complex_args(self):
     m = ModuleArgsParser(dict(action=dict(module="copy", args=dict(src="a", dest="b"))))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, "copy")
     self.assertEqual(args, dict(src="a", dest="b"))
     self.assertIsNone(to)
コード例 #2
0
    def test_bogus_action(self):
        args_dict = {'bogusaction': {}}
        m = ModuleArgsParser(args_dict)
        with pytest.raises(AnsibleParserError) as err:
            m.parse()

        assert err.value.args[0].startswith("couldn't resolve module/action 'bogusaction'")
コード例 #3
0
ファイル: task.py プロジェクト: conlini/frozen-ansible
    def munge(self, ds):
        '''
        tasks are especially complex arguments so need pre-processing.
        keep it short.
        '''

        assert isinstance(ds, dict)

        # the new, cleaned datastructure, which will have legacy
        # items reduced to a standard structure suitable for the
        # attributes of the task class
        new_ds = dict()

        # use the args parsing class to determine the action, args,
        # and the delegate_to value from the various possible forms
        # supported as legacy
        args_parser = ModuleArgsParser()
        (action, args, delegate_to) = args_parser.parse(ds)

        new_ds['action']      = action
        new_ds['args']        = args
        new_ds['delegate_to'] = delegate_to

        for (k,v) in ds.iteritems():
            if k in ('action', 'local_action', 'args', 'delegate_to') or k == action:
                # we don't want to re-assign these values, which were
                # determined by the ModuleArgsParser() above
                continue
            elif "with_%s" % k in lookup_finder:
                self._munge_loop(ds, new_ds, k, v)
            else:
                new_ds[k] = v

        return new_ds
コード例 #4
0
 def test_complex_args(self):
     m = ModuleArgsParser(dict(copy=dict(src="a", dest="b")))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, "copy")
     self.assertEqual(args, dict(src="a", dest="b"))
     self.assertIsNone(to)
コード例 #5
0
def normalize_task_v2(task):
    '''Ensures tasks have an action key and strings are converted to python objects'''

    result = dict()
    mod_arg_parser = ModuleArgsParser(task)
    action, arguments, result['delegate_to'] = mod_arg_parser.parse()

    # denormalize shell -> command conversion
    if '_use_shell' in arguments:
        action = 'shell'
        del(arguments['_use_shell'])

    for (k, v) in list(task.items()):
        if k in ('action', 'local_action', 'args', 'delegate_to') or k == action:
            # we don't want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        else:
            result[k] = v

    result['action'] = dict(module=action)

    if '_raw_params' in arguments:
        result['action']['module_arguments'] = arguments['_raw_params'].split()
        del(arguments['_raw_params'])
    else:
        result['action']['module_arguments'] = list()
    result['action'].update(arguments)
    return result
コード例 #6
0
 def test_basic_shell(self):
     m = ModuleArgsParser(dict(shell="echo hi"))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, "command")
     self.assertEqual(args, dict(_raw_params="echo hi", _uses_shell=True))
     self.assertIsNone(to)
コード例 #7
0
 def test_normal_usage(self):
     m = ModuleArgsParser(dict(copy='src=a dest=b'))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, 'copy')
     self.assertEqual(args, dict(src='a', dest='b'))
     self.assertIsNone(to)
コード例 #8
0
 def test_complex_args(self):
     m = ModuleArgsParser(dict(copy=dict(src='a', dest='b')))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, 'copy')
     self.assertEqual(args, dict(src='a', dest='b'))
     self.assertIsNone(to)
コード例 #9
0
 def test_local_action_string(self):
     m = ModuleArgsParser(dict(local_action='copy src=a dest=b'))
     mod, args, delegate_to = m.parse()
     self._debug(mod, args, delegate_to)
     self.assertEqual(mod, 'copy')
     self.assertEqual(args, dict(src='a', dest='b'))
     self.assertIs(delegate_to, 'localhost')
コード例 #10
0
 def test_action_with_complex(self):
     m = ModuleArgsParser(dict(action=dict(module='copy', src='a', dest='b')))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, 'copy')
     self.assertEqual(args, dict(src='a', dest='b'))
     self.assertIsNone(to)
コード例 #11
0
 def test_local_action_string(self):
     m = ModuleArgsParser(dict(local_action='copy src=a dest=b'))
     mod, args, connection = m.parse()
     self._debug(mod, args, connection)
     self.assertEqual(mod, 'copy')
     self.assertEqual(args, dict(src='a', dest='b', _local_action=True))
     self.assertIs(connection, 'local')
コード例 #12
0
 def test_shell_with_modifiers(self):
     m = ModuleArgsParser(dict(shell="/bin/foo creates=/tmp/baz removes=/tmp/bleep"))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, "command")
     self.assertEqual(args, dict(creates="/tmp/baz", removes="/tmp/bleep", _raw_params="/bin/foo", _uses_shell=True))
     self.assertIsNone(to)
コード例 #13
0
ファイル: utils.py プロジェクト: cloudnull/ansible-lint
def normalize_task_v2(task):
    '''Ensures tasks have an action key and strings are converted to python objects'''

    result = dict()
    mod_arg_parser = ModuleArgsParser(task)
    action, arguments, result['delegate_to'] = mod_arg_parser.parse()

    # denormalize shell -> command conversion
    if '_use_shell' in arguments:
        action = 'shell'
        del(arguments['_use_shell'])

    for (k, v) in list(task.items()):
        if k in ('action', 'local_action', 'args', 'delegate_to') or k == action:
            # we don't want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        else:
            result[k] = v

    result['action'] = dict(module=action)

    if '_raw_params' in arguments:
        result['action']['module_arguments'] = arguments['_raw_params'].split()
        del(arguments['_raw_params'])
    else:
        result['action']['module_arguments'] = list()
    result['action'].update(arguments)
    return result
コード例 #14
0
    def munge(self, ds):
        '''
        tasks are especially complex arguments so need pre-processing.
        keep it short.
        '''

        assert isinstance(ds, dict)

        # the new, cleaned datastructure, which will have legacy
        # items reduced to a standard structure suitable for the
        # attributes of the task class
        new_ds = dict()

        # use the args parsing class to determine the action, args,
        # and the delegate_to value from the various possible forms
        # supported as legacy
        args_parser = ModuleArgsParser()
        (action, args, delegate_to) = args_parser.parse(ds)

        new_ds['action'] = action
        new_ds['args'] = args
        new_ds['delegate_to'] = delegate_to

        for (k, v) in ds.iteritems():
            if k in ('action', 'local_action', 'args',
                     'delegate_to') or k == action:
                # we don't want to re-assign these values, which were
                # determined by the ModuleArgsParser() above
                continue
            elif "with_%s" % k in lookup_finder:
                self._munge_loop(ds, new_ds, k, v)
            else:
                new_ds[k] = v

        return new_ds
コード例 #15
0
ファイル: test_mod_args.py プロジェクト: kkrdevops/ansible-1
 def test_basic_command(self):
     m = ModuleArgsParser(dict(command='echo hi'))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, 'command')
     self.assertEqual(args, dict(_raw_params='echo hi', ))
     self.assertIsNone(to)
コード例 #16
0
 def test_normal_usage(self):
     m = ModuleArgsParser(dict(copy="src=a dest=b"))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, "copy")
     self.assertEqual(args, dict(src="a", dest="b"))
     self.assertIsNone(to)
コード例 #17
0
 def test_local_action_string(self):
     m = ModuleArgsParser(dict(local_action="copy src=a dest=b"))
     mod, args, connection = m.parse()
     self._debug(mod, args, connection)
     self.assertEqual(mod, "copy")
     self.assertEqual(args, dict(src="a", dest="b"))
     self.assertIs(connection, "local")
コード例 #18
0
 def test_basic_command(self):
     m = ModuleArgsParser(dict(command="echo hi"))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, "command")
     self.assertEqual(args, dict(_raw_params="echo hi"))
     self.assertIsNone(to)
コード例 #19
0
ファイル: test_mod_args.py プロジェクト: kkrdevops/ansible-1
 def test_local_action_string(self):
     m = ModuleArgsParser(dict(local_action='copy src=a dest=b'))
     mod, args, connection = m.parse()
     self._debug(mod, args, connection)
     self.assertEqual(mod, 'copy')
     self.assertEqual(args, dict(src='a', dest='b', _local_action=True))
     self.assertIs(connection, 'local')
コード例 #20
0
def normalize_task(task, filename, custom_modules=[]):
    """Ensure tasks have an action key and strings are converted to python objects."""
    ansible_action_type = task.get("__ansible_action_type__", "task")
    if "__ansible_action_type__" in task:
        del (task["__ansible_action_type__"])

    # temp. extract metadata
    ansible_meta = dict()
    for key in ["__line__", "__file__", "__ansible_action_meta__"]:
        default = None

        if key == "__ansible_action_meta__":
            default = dict()

        ansible_meta[key] = task.pop(key, default)

    normalized = dict()

    builtin = list(ansible.parsing.mod_args.BUILTIN_TASKS)
    builtin = list(set(builtin + custom_modules))
    ansible.parsing.mod_args.BUILTIN_TASKS = frozenset(builtin)
    mod_arg_parser = ModuleArgsParser(task)

    try:
        action, arguments, normalized["delegate_to"] = mod_arg_parser.parse()
    except AnsibleParserError as e:
        raise LaterAnsibleError("syntax error", e)

    # denormalize shell -> command conversion
    if "_uses_shell" in arguments:
        action = "shell"
        del (arguments["_uses_shell"])

    for (k, v) in list(task.items()):
        if k in ("action", "local_action", "args", "delegate_to") or k == action:
            # we don"t want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        else:
            normalized[k] = v

    normalized["action"] = dict(__ansible_module__=action)

    if "_raw_params" in arguments:
        normalized["action"]["__ansible_arguments__"] = arguments["_raw_params"].strip().split()
        del (arguments["_raw_params"])
    else:
        normalized["action"]["__ansible_arguments__"] = list()
    normalized["action"].update(arguments)

    normalized[FILENAME_KEY] = filename
    normalized["__ansible_action_type__"] = ansible_action_type

    # add back extracted metadata
    for (k, v) in ansible_meta.items():
        if v:
            normalized[k] = v

    return normalized
コード例 #21
0
    def test_complex_args(self):
        m = ModuleArgsParser(dict(copy=dict(src='a', dest='b')))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod, 'copy'
        assert args, dict(src='a', dest='b')
        assert to is Sentinel
コード例 #22
0
    def test_normal_usage(self):
        m = ModuleArgsParser(dict(copy='src=a dest=b'))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod, 'copy'
        assert args, dict(src='a', dest='b')
        assert to is Sentinel
コード例 #23
0
    def test_basic_shell(self):
        m = ModuleArgsParser(dict(shell='echo hi'))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod == 'shell'
        assert args == dict(_raw_params='echo hi', )
        assert to is Sentinel
コード例 #24
0
    def test_local_action_string(self):
        m = ModuleArgsParser(dict(local_action='copy src=a dest=b'))
        mod, args, delegate_to = m.parse()
        self._debug(mod, args, delegate_to)

        assert mod == 'copy'
        assert args == dict(src='a', dest='b')
        assert delegate_to == 'localhost'
コード例 #25
0
    def test_action_with_complex_and_complex_args(self):
        m = ModuleArgsParser(dict(action=dict(module='copy', args=dict(src='a', dest='b'))))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod == 'copy'
        assert args == dict(src='a', dest='b')
        assert to is None
コード例 #26
0
ファイル: test_mod_args.py プロジェクト: awiddersheim/ansible
    def test_complex_args(self):
        m = ModuleArgsParser(dict(copy=dict(src='a', dest='b')))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod, 'copy'
        assert args, dict(src='a', dest='b')
        assert to is None
コード例 #27
0
ファイル: test_mod_args.py プロジェクト: awiddersheim/ansible
    def test_normal_usage(self):
        m = ModuleArgsParser(dict(copy='src=a dest=b'))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod, 'copy'
        assert args, dict(src='a', dest='b')
        assert to is None
コード例 #28
0
    def test_basic_command(self):
        m = ModuleArgsParser(dict(command='echo hi'))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod == 'command'
        assert args == dict(_raw_params='echo hi', )
        assert to is Sentinel
コード例 #29
0
ファイル: test_mod_args.py プロジェクト: awiddersheim/ansible
    def test_local_action_string(self):
        m = ModuleArgsParser(dict(local_action='copy src=a dest=b'))
        mod, args, delegate_to = m.parse()
        self._debug(mod, args, delegate_to)

        assert mod == 'copy'
        assert args == dict(src='a', dest='b')
        assert delegate_to == 'localhost'
コード例 #30
0
    def preprocess_data(self, ds):
        '''
        tasks are especially complex arguments so need pre-processing.
        keep it short.
        '''

        assert isinstance(ds, dict)

        # the new, cleaned datastructure, which will have legacy
        # items reduced to a standard structure suitable for the
        # attributes of the task class
        new_ds = AnsibleMapping()
        if isinstance(ds, AnsibleBaseYAMLObject):
            new_ds.ansible_pos = ds.ansible_pos

        # use the args parsing class to determine the action, args,
        # and the delegate_to value from the various possible forms
        # supported as legacy
        args_parser = ModuleArgsParser(task_ds=ds)
        (action, args, connection) = args_parser.parse()

        new_ds['action'] = action
        new_ds['args'] = args
        new_ds['connection'] = connection

        # we handle any 'vars' specified in the ds here, as we may
        # be adding things to them below (special handling for includes).
        # When that deprecated feature is removed, this can be too.
        if 'vars' in ds:
            # _load_vars is defined in Base, and is used to load a dictionary
            # or list of dictionaries in a standard way
            new_ds['vars'] = self._load_vars(None, ds.pop('vars'))
        else:
            new_ds['vars'] = dict()

        for (k, v) in iteritems(ds):
            if k in ('action', 'local_action', 'args',
                     'connection') or k == action or k == 'shell':
                # we don't want to re-assign these values, which were
                # determined by the ModuleArgsParser() above
                continue
            elif k.replace("with_", "") in lookup_loader:
                self._preprocess_loop(ds, new_ds, k, v)
            else:
                # pre-2.0 syntax allowed variables for include statements at the
                # top level of the task, so we move those into the 'vars' dictionary
                # here, and show a deprecation message as we will remove this at
                # some point in the future.
                if action == 'include' and k not in self._get_base_attributes(
                ) and k not in self.DEPRECATED_ATTRIBUTES:
                    self._display.deprecated(
                        "Specifying include variables at the top-level of the task is deprecated. Please see:\nhttp://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse\n\nfor currently supported syntax regarding included files and variables"
                    )
                    new_ds['vars'][k] = v
                else:
                    new_ds[k] = v

        return super(Task, self).preprocess_data(new_ds)
コード例 #31
0
def normalize_task_v2(task: dict) -> dict:  # noqa: C901
    """Ensure tasks have an action key and strings are converted to python objects."""
    result = dict()
    if 'always_run' in task:
        # FIXME(ssbarnea): Delayed import to avoid circular import
        # See https://github.com/ansible/ansible-lint/issues/880
        # noqa: # pylint:disable=cyclic-import,import-outside-toplevel
        from ansiblelint.rules.AlwaysRunRule import AlwaysRunRule

        raise MatchError(rule=AlwaysRunRule,
                         filename=task[FILENAME_KEY],
                         linenumber=task[LINE_NUMBER_KEY])

    sanitized_task = _sanitize_task(task)
    mod_arg_parser = ModuleArgsParser(sanitized_task)
    try:
        action, arguments, result['delegate_to'] = mod_arg_parser.parse()
    except AnsibleParserError as e:
        try:
            task_info = "%s:%s" % (task[FILENAME_KEY], task[LINE_NUMBER_KEY])
        except KeyError:
            task_info = "Unknown"
        pp = pprint.PrettyPrinter(indent=2)
        task_pprint = pp.pformat(sanitized_task)

        _logger.critical("Couldn't parse task at %s (%s)\n%s", task_info,
                         e.message, task_pprint)
        raise SystemExit(ANSIBLE_FAILURE_RC)

    # denormalize shell -> command conversion
    if '_uses_shell' in arguments:
        action = 'shell'
        del arguments['_uses_shell']

    for (k, v) in list(task.items()):
        if k in ('action', 'local_action', 'args',
                 'delegate_to') or k == action:
            # we don't want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        else:
            result[k] = v

    result['action'] = dict(__ansible_module__=action)

    if '_raw_params' in arguments:
        result['action']['__ansible_arguments__'] = arguments[
            '_raw_params'].split(' ')
        del arguments['_raw_params']
    else:
        result['action']['__ansible_arguments__'] = list()

    if 'argv' in arguments and not result['action']['__ansible_arguments__']:
        result['action']['__ansible_arguments__'] = arguments['argv']
        del arguments['argv']

    result['action'].update(arguments)
    return result
コード例 #32
0
    def test_multiple_actions(self):
        args_dict = {'ping': 'data=hi', 'shell': 'echo hi'}
        m = ModuleArgsParser(args_dict)
        with pytest.raises(AnsibleParserError) as err:
            m.parse()

        assert err.value.args[0].startswith("conflicting action statements: ")
        actions = set(re.search(r'(\w+), (\w+)', err.value.args[0]).groups())
        assert actions == set(['ping', 'shell'])
コード例 #33
0
    def test_multiple_actions(self):
        args_dict = {'ping': 'data=hi', 'shell': 'echo hi'}
        m = ModuleArgsParser(args_dict)
        with pytest.raises(AnsibleParserError) as err:
            m.parse()

        assert err.value.args[0].startswith("conflicting action statements: ")
        conflicts = set(err.value.args[0][len("conflicting action statements: "):].split(', '))
        assert conflicts == set(('ping', 'shell'))
コード例 #34
0
ファイル: test_mod_args.py プロジェクト: awiddersheim/ansible
    def test_basic_shell(self):
        m = ModuleArgsParser(dict(shell='echo hi'))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod == 'shell'
        assert args == dict(
            _raw_params='echo hi',
        )
        assert to is None
コード例 #35
0
ファイル: test_mod_args.py プロジェクト: awiddersheim/ansible
    def test_basic_command(self):
        m = ModuleArgsParser(dict(command='echo hi'))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod == 'command'
        assert args == dict(
            _raw_params='echo hi',
        )
        assert to is None
コード例 #36
0
ファイル: test_mod_args.py プロジェクト: 2ndQuadrant/ansible
 def test_basic_shell(self):
     m = ModuleArgsParser(dict(shell='echo hi'))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, 'command')
     self.assertEqual(args, dict(
                             _raw_params = 'echo hi',
                             _uses_shell = True,
                     ))
     self.assertIsNone(to)
コード例 #37
0
 def handle_task(self, a_task, ru_task):
     """handle a single task"""
     mod_arg_parser = ModuleArgsParser(a_task)
     try:
         action, args, delegate_to = mod_arg_parser.parse(
             skip_action_validation=True)
     except AnsibleParserError as e:
         raise LSRException("Couldn't parse task at %s (%s)\n%s" %
                            (a_task.ansible_pos, e.message, a_task))
     self.task_cb(a_task, ru_task, action, args, delegate_to)
コード例 #38
0
ファイル: task.py プロジェクト: JaredPennella/DevOps_Script
    def preprocess_data(self, ds):
        '''
        tasks are especially complex arguments so need pre-processing.
        keep it short.
        '''

        assert isinstance(ds, dict)

        # the new, cleaned datastructure, which will have legacy
        # items reduced to a standard structure suitable for the
        # attributes of the task class
        new_ds = AnsibleMapping()
        if isinstance(ds, AnsibleBaseYAMLObject):
            new_ds.ansible_pos = ds.ansible_pos

        # use the args parsing class to determine the action, args,
        # and the delegate_to value from the various possible forms
        # supported as legacy
        args_parser = ModuleArgsParser(task_ds=ds)
        (action, args, connection) = args_parser.parse()

        new_ds['action']      = action
        new_ds['args']        = args
        new_ds['connection'] = connection

        # we handle any 'vars' specified in the ds here, as we may
        # be adding things to them below (special handling for includes).
        # When that deprecated feature is removed, this can be too.
        if 'vars' in ds:
            # _load_vars is defined in Base, and is used to load a dictionary
            # or list of dictionaries in a standard way
            new_ds['vars'] = self._load_vars(None, ds.pop('vars'))
        else:
            new_ds['vars'] = dict()

        for (k,v) in iteritems(ds):
            if k in ('action', 'local_action', 'args', 'connection') or k == action or k == 'shell':
                # we don't want to re-assign these values, which were
                # determined by the ModuleArgsParser() above
                continue
            elif k.replace("with_", "") in lookup_loader:
                self._preprocess_loop(ds, new_ds, k, v)
            else:
                # pre-2.0 syntax allowed variables for include statements at the
                # top level of the task, so we move those into the 'vars' dictionary
                # here, and show a deprecation message as we will remove this at
                # some point in the future.
                if action == 'include' and k not in self._get_base_attributes() and k not in self.DEPRECATED_ATTRIBUTES:
                    self._display.deprecated("Specifying include variables at the top-level of the task is deprecated. Please see:\nhttp://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse\n\nfor currently supported syntax regarding included files and variables")
                    new_ds['vars'][k] = v
                else:
                    new_ds[k] = v

        return super(Task, self).preprocess_data(new_ds)
コード例 #39
0
ファイル: utils.py プロジェクト: awcrosby/ansible-lint
def normalize_task_v2(task: Dict[str, Any]) -> Dict[str, Any]:
    """Ensure tasks have a normalized action key and strings are converted to python objects."""
    result = dict()

    sanitized_task = _sanitize_task(task)
    mod_arg_parser = ModuleArgsParser(sanitized_task)
    try:
        action, arguments, result['delegate_to'] = mod_arg_parser.parse(
            skip_action_validation=options.skip_action_validation)
    except AnsibleParserError as e:
        raise MatchError(
            rule=AnsibleParserErrorRule(),
            message=e.message,
            filename=task.get(FILENAME_KEY, "Unknown"),
            linenumber=task.get(LINE_NUMBER_KEY, 0),
        )

    # denormalize shell -> command conversion
    if '_uses_shell' in arguments:
        action = 'shell'
        del arguments['_uses_shell']

    for (k, v) in list(task.items()):
        if k in ('action', 'local_action', 'args',
                 'delegate_to') or k == action:
            # we don't want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        result[k] = v

    if not isinstance(action, str):
        raise RuntimeError("Task actions can only be strings, got %s" % action)
    action_unnormalized = action
    # convert builtin fqn calls to short forms because most rules know only
    # about short calls but in the future we may switch the normalization to do
    # the opposite. Mainly we currently consider normalized the module listing
    # used by `ansible-doc -t module -l 2>/dev/null`
    action = removeprefix(action, "ansible.builtin.")
    result['action'] = dict(__ansible_module__=action,
                            __ansible_module_original__=action_unnormalized)

    if '_raw_params' in arguments:
        result['action']['__ansible_arguments__'] = arguments[
            '_raw_params'].split(' ')
        del arguments['_raw_params']
    else:
        result['action']['__ansible_arguments__'] = list()

    if 'argv' in arguments and not result['action']['__ansible_arguments__']:
        result['action']['__ansible_arguments__'] = arguments['argv']
        del arguments['argv']

    result['action'].update(arguments)
    return result
コード例 #40
0
 def test_shell_with_modifiers(self):
     m = ModuleArgsParser(dict(shell='/bin/foo creates=/tmp/baz removes=/tmp/bleep'))
     mod, args, to = m.parse()
     self._debug(mod, args, to)
     self.assertEqual(mod, 'command')
     self.assertEqual(args, dict(
                             creates     = '/tmp/baz',
                             removes     = '/tmp/bleep',
                             _raw_params = '/bin/foo',
                             _uses_shell = True,
                     ))
     self.assertIsNone(to)
コード例 #41
0
    def test_multiple_actions(self):
        m = ModuleArgsParser(dict(action='shell echo hi', local_action='shell echo hi'))
        self.assertRaises(AnsibleParserError, m.parse)

        m = ModuleArgsParser(dict(action='shell echo hi', shell='echo hi'))
        self.assertRaises(AnsibleParserError, m.parse)

        m = ModuleArgsParser(dict(local_action='shell echo hi', shell='echo hi'))
        self.assertRaises(AnsibleParserError, m.parse)

        m = ModuleArgsParser(dict(ping='data=hi', shell='echo hi'))
        self.assertRaises(AnsibleParserError, m.parse)
コード例 #42
0
    def test_shell_with_modifiers(self):
        m = ModuleArgsParser(dict(shell='/bin/foo creates=/tmp/baz removes=/tmp/bleep'))
        mod, args, to = m.parse()
        self._debug(mod, args, to)

        assert mod == 'shell'
        assert args == dict(
            creates='/tmp/baz',
            removes='/tmp/bleep',
            _raw_params='/bin/foo',
        )
        assert to is None
コード例 #43
0
def normalize_task_v2(task):
    '''Ensures tasks have an action key and strings are converted to python objects'''

    result = dict()
    mod_arg_parser = ModuleArgsParser(task)
    try:
        action, arguments, result['delegate_to'] = mod_arg_parser.parse()
    except AnsibleParserError as e:
        try:
            task_info = "%s:%s" % (task[FILENAME_KEY], task[LINE_NUMBER_KEY])
            del task[FILENAME_KEY]
            del task[LINE_NUMBER_KEY]
        except KeyError:
            task_info = "Unknown"
        try:
            import pprint
            pp = pprint.PrettyPrinter(indent=2)
            task_pprint = pp.pformat(task)
        except ImportError:
            task_pprint = task
        raise SystemExit("Couldn't parse task at %s (%s)\n%s" %
                         (task_info, e.message, task_pprint))

    # denormalize shell -> command conversion
    if '_uses_shell' in arguments:
        action = 'shell'
        del (arguments['_uses_shell'])

    for (k, v) in list(task.items()):
        if k in ('action', 'local_action', 'args',
                 'delegate_to') or k == action:
            # we don't want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        else:
            result[k] = v

    result['action'] = dict(__ansible_module__=action)

    if '_raw_params' in arguments:
        result['action']['__ansible_arguments__'] = arguments[
            '_raw_params'].split(' ')
        del (arguments['_raw_params'])
    else:
        result['action']['__ansible_arguments__'] = list()

    if 'argv' in arguments and not result['action']['__ansible_arguments__']:
        result['action']['__ansible_arguments__'] = arguments['argv']
        del (arguments['argv'])

    result['action'].update(arguments)
    return result
コード例 #44
0
ファイル: test_mod_args.py プロジェクト: leucos/ansible
class TestModArgsDwim(unittest.TestCase):
    def setUp(self):
        self.m = ModuleArgsParser()
        pass

    def tearDown(self):
        pass

    def test_action_to_shell(self):
        mod, args, to = self.m.parse('action', 'shell echo hi')
        assert mod == 'shell'
        assert args == dict(free_form='echo hi', use_shell=True)
        assert to is None

    def test_basic_shell(self):
        mod, args, to = self.m.parse('shell', 'echo hi')
        assert mod == 'shell'
        assert args == dict(free_form='echo hi', use_shell=True)
        assert to is None

    def test_basic_command(self):
        mod, args, to = self.m.parse('command', 'echo hi')
        assert mod == 'command'
        assert args == dict(free_form='echo hi', use_shell=False)
        assert to is None

    def test_shell_with_modifiers(self):
        mod, args, to = self.m.parse(
            'shell', '/bin/foo creates=/tmp/baz removes=/tmp/bleep')
        assert mod == 'shell'
        assert args == dict(free_form='echo hi',
                            use_shell=False,
                            creates='/tmp/baz',
                            removes='/tmp/bleep')
        assert to is None

    def test_normal_usage(self):
        mod, args, to = self.m.parse('copy', 'src=a dest=b')
        assert mod == 'copy'
        assert args == dict(src='a', dest='b')
        assert to is None

    def test_complex_args(self):
        mod, args, to = self.m.parse('copy', dict(src=a, dest=b))
        assert mod == 'copy'
        assert args == dict(src='a', dest='b')
        assert to is None

    def test_action_with_complex(self):
        mod, args, to = self.m.parse('action',
                                     dict(module='copy', src='a', dest='b'))
        assert mod == 'action'
        assert args == dict(src='a', dest='b')
        assert to is None

    def test_local_action_string(self):
        mod, args, to = self.m.parse('local_action', 'copy src=a dest=b')
        assert mod == 'copy'
        assert args == dict(src=a, dest=b)
        assert to is 'localhost'
コード例 #45
0
ファイル: utils.py プロジェクト: willthames/ansible-lint
def normalize_task_v2(task):
    '''Ensures tasks have an action key and strings are converted to python objects'''

    result = dict()
    mod_arg_parser = ModuleArgsParser(task)
    try:
        action, arguments, result['delegate_to'] = mod_arg_parser.parse()
    except AnsibleParserError as e:
        try:
            task_info = "%s:%s" % (task[FILENAME_KEY], task[LINE_NUMBER_KEY])
            del task[FILENAME_KEY]
            del task[LINE_NUMBER_KEY]
        except KeyError:
            task_info = "Unknown"
        try:
            import pprint
            pp = pprint.PrettyPrinter(indent=2)
            task_pprint = pp.pformat(task)
        except ImportError:
            task_pprint = task
        raise SystemExit("Couldn't parse task at %s (%s)\n%s" % (task_info, e.message, task_pprint))

    # denormalize shell -> command conversion
    if '_uses_shell' in arguments:
        action = 'shell'
        del(arguments['_uses_shell'])

    for (k, v) in list(task.items()):
        if k in ('action', 'local_action', 'args', 'delegate_to') or k == action:
            # we don't want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        else:
            result[k] = v

    result['action'] = dict(__ansible_module__=action)

    if '_raw_params' in arguments:
        result['action']['__ansible_arguments__'] = arguments['_raw_params'].split(' ')
        del(arguments['_raw_params'])
    else:
        result['action']['__ansible_arguments__'] = list()

    if 'argv' in arguments and not result['action']['__ansible_arguments__']:
        result['action']['__ansible_arguments__'] = arguments['argv']
        del(arguments['argv'])

    result['action'].update(arguments)
    return result
コード例 #46
0
ファイル: api.py プロジェクト: Courouge/ansible-beautify
def cleanAnsible(x):
    f = StringIO(x)
    ymlfiles = []

    ## load all modules name in list ##
    listmodules = [line.rstrip('\n') for line in open("modules.txt")]

    ### open all *.yml ###
    composefile = []
    flag = 0
    try:
        for x in f:
            for e in listmodules:
                if x.startswith("  " + e +
                                ":") == True and len(x.strip()) > len(e + ":"):
                    module = x.split(':', 1)[0].strip()
                    arguments = x.split(':', 1)[1]
                    composefile.append("  " + module + ":\n")
                    res = dict()
                    flag = 1
                    res[module] = arguments
                    m = ModuleArgsParser(res)
                    mod, args, to = m.parse()
                    for x in args:
                        if x == "_raw_params":
                            del composefile[-1]
                            composefile.append("  " + module + ": " + args[x] +
                                               "\n")
                        else:
                            tmp = args[x].replace("\n", "\\n")
                            if tmp.find('{{') != -1 and tmp.find('}}') != -1:
                                composefile.append("    " + x + ": " + '"' +
                                                   tmp + '"' + "\n")
                            else:
                                composefile.append("    " + x + ": " + tmp +
                                                   "\n")
                    break
            composefile.append(x)
            if flag == 1:
                flag = 0
                composefile.pop(len(composefile) - 1)

    except (AnsibleParserError):
        composefile = "Error Ansible Syntax"
    return composefile
コード例 #47
0
ファイル: utils.py プロジェクト: senyoltw/ansible-lint
def normalize_task_v2(task: dict) -> dict:  # noqa: C901
    """Ensure tasks have an action key and strings are converted to python objects."""
    result = dict()

    sanitized_task = _sanitize_task(task)
    mod_arg_parser = ModuleArgsParser(sanitized_task)
    try:
        action, arguments, result['delegate_to'] = mod_arg_parser.parse()
    except AnsibleParserError as e:
        raise MatchError(
            rule=AnsibleParserErrorRule(),
            message=e.message,
            filename=task.get(FILENAME_KEY, "Unknown"),
            linenumber=task.get(LINE_NUMBER_KEY, 0),
        )

    # denormalize shell -> command conversion
    if '_uses_shell' in arguments:
        action = 'shell'
        del arguments['_uses_shell']

    for (k, v) in list(task.items()):
        if k in ('action', 'local_action', 'args',
                 'delegate_to') or k == action:
            # we don't want to re-assign these values, which were
            # determined by the ModuleArgsParser() above
            continue
        else:
            result[k] = v

    result['action'] = dict(__ansible_module__=action)

    if '_raw_params' in arguments:
        result['action']['__ansible_arguments__'] = arguments[
            '_raw_params'].split(' ')
        del arguments['_raw_params']
    else:
        result['action']['__ansible_arguments__'] = list()

    if 'argv' in arguments and not result['action']['__ansible_arguments__']:
        result['action']['__ansible_arguments__'] = arguments['argv']
        del arguments['argv']

    result['action'].update(arguments)
    return result
コード例 #48
0
def parse_task(task):
  if 'block' in task:
    print("BLOCK")
    return 'block', '', ''
  else:
    (action, args, delegate_to) = ModuleArgsParser(task).parse(skip_action_validation=True)
    if action in ('include', 'import_tasks', 'include_tasks'):
      print("include task")
    elif action in ('include_role', 'import_role'):
      print("include role")

    return action, args, ( delegate_to if delegate_to is not Sentinel else None)
コード例 #49
0
ファイル: task.py プロジェクト: victron/paramiko_ssh-i
    def preprocess_data(self, ds):
        '''
        tasks are especially complex arguments so need pre-processing.
        keep it short.
        '''

        assert isinstance(ds, dict)

        # the new, cleaned datastructure, which will have legacy
        # items reduced to a standard structure suitable for the
        # attributes of the task class
        new_ds = AnsibleMapping()
        if isinstance(ds, AnsibleBaseYAMLObject):
            new_ds.ansible_pos = ds.ansible_pos

        # use the args parsing class to determine the action, args,
        # and the delegate_to value from the various possible forms
        # supported as legacy
        args_parser = ModuleArgsParser(task_ds=ds)
        (action, args, delegate_to) = args_parser.parse()

        new_ds['action']      = action
        new_ds['args']        = args
        new_ds['delegate_to'] = delegate_to

        for (k,v) in ds.iteritems():
            if k in ('action', 'local_action', 'args', 'delegate_to') or k == action or k == 'shell':
                # we don't want to re-assign these values, which were
                # determined by the ModuleArgsParser() above
                continue
            elif k.replace("with_", "") in lookup_loader:
                self._preprocess_loop(ds, new_ds, k, v)
            else:
                new_ds[k] = v

        return super(Task, self).preprocess_data(new_ds)
コード例 #50
0
    def preprocess_data(self, ds):
        """
        tasks are especially complex arguments so need pre-processing.
        keep it short.
        """

        assert isinstance(ds, dict)

        # the new, cleaned datastructure, which will have legacy
        # items reduced to a standard structure suitable for the
        # attributes of the task class
        new_ds = AnsibleMapping()
        if isinstance(ds, AnsibleBaseYAMLObject):
            new_ds.ansible_pos = ds.ansible_pos

        # use the args parsing class to determine the action, args,
        # and the delegate_to value from the various possible forms
        # supported as legacy
        args_parser = ModuleArgsParser(task_ds=ds)
        try:
            (action, args, delegate_to) = args_parser.parse()
        except AnsibleParserError as e:
            raise AnsibleParserError(to_str(e), obj=ds)

        # the command/shell/script modules used to support the `cmd` arg,
        # which corresponds to what we now call _raw_params, so move that
        # value over to _raw_params (assuming it is empty)
        if action in ("command", "shell", "script"):
            if "cmd" in args:
                if args.get("_raw_params", "") != "":
                    raise AnsibleError(
                        "The 'cmd' argument cannot be used when other raw parameters are specified."
                        " Please put everything in one or the other place.",
                        obj=ds,
                    )
                args["_raw_params"] = args.pop("cmd")

        new_ds["action"] = action
        new_ds["args"] = args
        new_ds["delegate_to"] = delegate_to

        # we handle any 'vars' specified in the ds here, as we may
        # be adding things to them below (special handling for includes).
        # When that deprecated feature is removed, this can be too.
        if "vars" in ds:
            # _load_vars is defined in Base, and is used to load a dictionary
            # or list of dictionaries in a standard way
            new_ds["vars"] = self._load_vars(None, ds.get("vars"))
        else:
            new_ds["vars"] = dict()

        for (k, v) in iteritems(ds):
            if k in ("action", "local_action", "args", "delegate_to") or k == action or k == "shell":
                # we don't want to re-assign these values, which were
                # determined by the ModuleArgsParser() above
                continue
            elif k.replace("with_", "") in lookup_loader:
                self._preprocess_loop(ds, new_ds, k, v)
            else:
                # pre-2.0 syntax allowed variables for include statements at the
                # top level of the task, so we move those into the 'vars' dictionary
                # here, and show a deprecation message as we will remove this at
                # some point in the future.
                if action == "include" and k not in self._get_base_attributes() and k not in self.DEPRECATED_ATTRIBUTES:
                    display.deprecated(
                        "Specifying include variables at the top-level of the task is deprecated."
                        " Please see:\nhttp://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse\n\n"
                        " for currently supported syntax regarding included files and variables"
                    )
                    new_ds["vars"][k] = v
                else:
                    new_ds[k] = v

        return super(Task, self).preprocess_data(new_ds)
コード例 #51
0
ファイル: test_mod_args.py プロジェクト: awiddersheim/ansible
    def test_multiple_actions(self, args_dict, msg):
        m = ModuleArgsParser(args_dict)
        with pytest.raises(AnsibleParserError) as err:
            m.parse()

        assert err.value.args[0] == msg
コード例 #52
0
ファイル: task.py プロジェクト: ernstp/ansible
    def preprocess_data(self, ds):
        '''
        tasks are especially complex arguments so need pre-processing.
        keep it short.
        '''

        assert isinstance(ds, dict), 'ds (%s) should be a dict but was a %s' % (ds, type(ds))

        # the new, cleaned datastructure, which will have legacy
        # items reduced to a standard structure suitable for the
        # attributes of the task class
        new_ds = AnsibleMapping()
        if isinstance(ds, AnsibleBaseYAMLObject):
            new_ds.ansible_pos = ds.ansible_pos

        # use the args parsing class to determine the action, args,
        # and the delegate_to value from the various possible forms
        # supported as legacy
        args_parser = ModuleArgsParser(task_ds=ds)
        try:
            (action, args, delegate_to) = args_parser.parse()
        except AnsibleParserError as e:
            raise AnsibleParserError(to_native(e), obj=ds, orig_exc=e)

        # the command/shell/script modules used to support the `cmd` arg,
        # which corresponds to what we now call _raw_params, so move that
        # value over to _raw_params (assuming it is empty)
        if action in ('command', 'shell', 'script'):
            if 'cmd' in args:
                if args.get('_raw_params', '') != '':
                    raise AnsibleError("The 'cmd' argument cannot be used when other raw parameters are specified."
                                       " Please put everything in one or the other place.", obj=ds)
                args['_raw_params'] = args.pop('cmd')

        new_ds['action'] = action
        new_ds['args'] = args
        new_ds['delegate_to'] = delegate_to

        # we handle any 'vars' specified in the ds here, as we may
        # be adding things to them below (special handling for includes).
        # When that deprecated feature is removed, this can be too.
        if 'vars' in ds:
            # _load_vars is defined in Base, and is used to load a dictionary
            # or list of dictionaries in a standard way
            new_ds['vars'] = self._load_vars(None, ds.get('vars'))
        else:
            new_ds['vars'] = dict()

        for (k, v) in iteritems(ds):
            if k in ('action', 'local_action', 'args', 'delegate_to') or k == action or k == 'shell':
                # we don't want to re-assign these values, which were determined by the ModuleArgsParser() above
                continue
            elif k.replace("with_", "") in lookup_loader:
                # transform into loop property
                self._preprocess_loop(ds, new_ds, k, v)
            else:
                # pre-2.0 syntax allowed variables for include statements at the top level of the task,
                # so we move those into the 'vars' dictionary here, and show a deprecation message
                # as we will remove this at some point in the future.
                if action in ('include', 'include_tasks') and k not in self._valid_attrs and k not in self.DEPRECATED_ATTRIBUTES:
                    display.deprecated("Specifying include variables at the top-level of the task is deprecated."
                                       " Please see:\nhttp://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse\n\n"
                                       " for currently supported syntax regarding included files and variables", version="2.7")
                    new_ds['vars'][k] = v
                elif k in self._valid_attrs:
                    new_ds[k] = v
                else:
                    display.warning("Ignoring invalid attribute: %s" % k)

        return super(Task, self).preprocess_data(new_ds)