예제 #1
0
def find_children(playbook, playbook_dir):
    if not os.path.exists(playbook[0]):
        return []
    if playbook[1] == 'role':
        playbook_ds = {'roles': [{'role': playbook[0]}]}
    else:
        try:
            playbook_ds = parse_yaml_from_file(playbook[0])
        except AnsibleError as e:
            raise SystemExit(str(e))
    results = []
    basedir = os.path.dirname(playbook[0])
    items = _playbook_items(playbook_ds)
    for item in items:
        for child in play_children(basedir, item, playbook[1], playbook_dir):
            if "$" in child['path'] or "{{" in child['path']:
                continue
            valid_tokens = list()
            for token in split_args(child['path']):
                if '=' in token:
                    break
                valid_tokens.append(token)
            path = ' '.join(valid_tokens)
            results.append({
                'path': path_dwim(basedir, path),
                'type': child['type']
            })
    return results
예제 #2
0
    def _munge_include(self, ds, new_ds, k, v):
        '''
        Splits the include line up into filename and parameters
        '''

        # The include line must include at least one item, which is the filename
        # to include. Anything after that should be regarded as a parameter to the include
        items = split_args(v)
        if len(items) == 0:
            raise AnsibleParserError(
                "include statements must specify the file name to include",
                obj=ds)
        else:
            # FIXME/TODO: validate that items[0] is a file, which also
            #             exists and is readable
            new_ds['include'] = items[0]
            if len(items) > 1:
                # rejoin the parameter portion of the arguments and
                # then use parse_kv() to get a dict of params back
                params = parse_kv(" ".join(items[1:]))
                if 'vars' in new_ds:
                    # FIXME: see fixme above regarding merging vars
                    raise AnsibleParserError(
                        "include parameters cannot be mixed with 'vars' entries for include statements",
                        obj=ds)
                new_ds['vars'] = params
예제 #3
0
 def get_vars(self, args):
     """Updates variables based on given arguments from CLI."""
     variables = {}
     args_split = split_args(args)
     for arg in args_split:
         variables.update(parse_kv(arg))
     return variables
예제 #4
0
def find_children(playbook: Tuple[str, str], playbook_dir: str) -> List:
    if not os.path.exists(playbook[0]):
        return []
    _set_collections_basedir(playbook_dir or '.')
    add_all_plugin_dirs(playbook_dir or '.')
    if playbook[1] == 'role':
        playbook_ds = {'roles': [{'role': playbook[0]}]}
    else:
        try:
            playbook_ds = parse_yaml_from_file(playbook[0])
        except AnsibleError as e:
            raise SystemExit(str(e))
    results = []
    basedir = os.path.dirname(playbook[0])
    items = _playbook_items(playbook_ds)
    for item in items:
        for child in _rebind_match_filename(playbook[0],
                                            play_children)(basedir, item,
                                                           playbook[1],
                                                           playbook_dir):
            if "$" in child['path'] or "{{" in child['path']:
                continue
            valid_tokens = list()
            for token in split_args(child['path']):
                if '=' in token:
                    break
                valid_tokens.append(token)
            path = ' '.join(valid_tokens)
            results.append({
                'path': path_dwim(basedir, path),
                'type': child['type']
            })
    return results
예제 #5
0
def find_children(playbook, playbook_dir):
    if not os.path.exists(playbook[0]):
        return []
    if playbook[1] == 'role':
        playbook_ds = {'roles': [{'role': playbook[0]}]}
    else:
        try:
            playbook_ds = parse_yaml_from_file(playbook[0])
        except AnsibleError as e:
            raise SystemExit(str(e))
    results = []
    basedir = os.path.dirname(playbook[0])
    items = _playbook_items(playbook_ds)
    for item in items:
        for child in play_children(basedir, item, playbook[1], playbook_dir):
            if "$" in child['path'] or "{{" in child['path']:
                continue
            valid_tokens = list()
            for token in split_args(child['path']):
                if '=' in token:
                    break
                valid_tokens.append(token)
            path = ' '.join(valid_tokens)
            results.append({
                'path': path_dwim(basedir, path),
                'type': child['type']
            })
    return results
예제 #6
0
    def _preprocess_import(self, ds, new_ds, k, v):
        '''
        Splits the playbook import line up into filename and parameters
        '''

        if v is None:
            raise AnsibleParserError("playbook import parameter is missing", obj=ds)
        elif not isinstance(v, string_types):
            raise AnsibleParserError("playbook import parameter must be a string indicating a file path, got %s instead" % type(v), obj=ds)

        # The import_playbook line must include at least one item, which is the filename
        # to import. Anything after that should be regarded as a parameter to the import
        items = split_args(v)
        if len(items) == 0:
            raise AnsibleParserError("import_playbook statements must specify the file name to import", obj=ds)
        else:
            new_ds['import_playbook'] = items[0].strip()
            if len(items) > 1:
                display.deprecated("Additional parameters in import_playbook statements are deprecated. "
                                   "Use 'vars' instead. See 'import_playbook' documentation for examples.", version='2.14')
                # rejoin the parameter portion of the arguments and
                # then use parse_kv() to get a dict of params back
                params = parse_kv(" ".join(items[1:]))
                if 'tags' in params:
                    new_ds['tags'] = params.pop('tags')
                if 'vars' in new_ds:
                    raise AnsibleParserError("import_playbook parameters cannot be mixed with 'vars' entries for import statements", obj=ds)
                new_ds['vars'] = params
예제 #7
0
    def _preprocess_include(self, ds, new_ds, k, v):
        '''
        Splits the include line up into filename and parameters
        '''

        # The include line must include at least one item, which is the filename
        # to include. Anything after that should be regarded as a parameter to the include
        items = split_args(v)
        if len(items) == 0:
            raise AnsibleParserError(
                "include statements must specify the file name to include",
                obj=ds)
        else:
            new_ds['include'] = items[0]
            if len(items) > 1:
                # rejoin the parameter portion of the arguments and
                # then use parse_kv() to get a dict of params back
                params = parse_kv(" ".join(items[1:]))
                if 'tags' in params:
                    new_ds['tags'] = params.pop('tags')
                if 'vars' in new_ds:
                    raise AnsibleParserError(
                        "include parameters cannot be mixed with 'vars' entries for include statements",
                        obj=ds)
                new_ds['vars'] = params
예제 #8
0
def TestInput(input_bytes):
    fdp = atheris.FuzzedDataProvider(input_bytes)

    try:
        # Test splitter module
        args = splitter.split_args(fdp.ConsumeString(50))
        splitter.join_args(args)

        # Test quoting module
        quoting.is_quoted(fdp.ConsumeString(10))
        quoting.unquote(fdp.ConsumeString(10))
    except (AnsibleError, AnsibleParserError) as e:
        pass
예제 #9
0
    def _split_module_string(self, module_string):
        '''
        when module names are expressed like:
        action: copy src=a dest=b
        the first part of the string is the name of the module
        and the rest are strings pertaining to the arguments.
        '''

        tokens = split_args(module_string)
        if len(tokens) > 1:
            return (tokens[0], " ".join(tokens[1:]))
        else:
            return (tokens[0], "")
예제 #10
0
def find_children(lintable: Lintable) -> List[Lintable]:  # noqa: C901
    if not lintable.path.exists():
        return []
    playbook_dir = str(lintable.path.parent)
    _set_collections_basedir(playbook_dir or os.path.abspath('.'))
    add_all_plugin_dirs(playbook_dir or '.')
    if lintable.kind == 'role':
        playbook_ds = AnsibleMapping({'roles': [{'role': str(lintable.path)}]})
    elif lintable.kind not in ("playbook", "tasks"):
        return []
    else:
        try:
            playbook_ds = parse_yaml_from_file(str(lintable.path))
        except AnsibleError as e:
            raise SystemExit(str(e))
    results = []
    basedir = os.path.dirname(str(lintable.path))
    # playbook_ds can be an AnsibleUnicode string, which we consider invalid
    if isinstance(playbook_ds, str):
        raise MatchError(filename=str(lintable.path),
                         rule=LoadingFailureRule())
    for item in _playbook_items(playbook_ds):
        # if lintable.kind not in ["playbook"]:
        #     continue
        for child in play_children(basedir, item, lintable.kind, playbook_dir):
            # We avoid processing parametrized children
            path_str = str(child.path)
            if "$" in path_str or "{{" in path_str:
                continue

            # Repair incorrect paths obtained when old syntax was used, like:
            # - include: simpletask.yml tags=nginx
            valid_tokens = list()
            for token in split_args(path_str):
                if '=' in token:
                    break
                valid_tokens.append(token)
            path = ' '.join(valid_tokens)
            if path != path_str:
                child.path = Path(path)
                child.name = child.path.name

            results.append(child)
    return results
예제 #11
0
    def _preprocess_include(self, ds, new_ds, k, v):
        '''
        Splits the include line up into filename and parameters
        '''

        # The include line must include at least one item, which is the filename
        # to include. Anything after that should be regarded as a parameter to the include
        items = split_args(v)
        if len(items) == 0:
            raise AnsibleParserError("include statements must specify the file name to include", obj=ds)
        else:
            new_ds['include'] = items[0]
            if len(items) > 1:
                # rejoin the parameter portion of the arguments and
                # then use parse_kv() to get a dict of params back
                params = parse_kv(" ".join(items[1:]))
                if 'tags' in params:
                    new_ds['tags'] = params.pop('tags')
                if 'vars' in new_ds:
                    raise AnsibleParserError("include parameters cannot be mixed with 'vars' entries for include statements", obj=ds)
                new_ds['vars'] = params
예제 #12
0
def find_children(playbook: Tuple[str, str],
                  playbook_dir: str) -> List[Lintable]:
    if not os.path.exists(playbook[0]):
        return []
    _set_collections_basedir(playbook_dir or os.path.abspath('.'))
    add_all_plugin_dirs(playbook_dir or '.')
    if playbook[1] == 'role':
        playbook_ds = {'roles': [{'role': playbook[0]}]}
    else:
        try:
            playbook_ds = parse_yaml_from_file(playbook[0])
        except AnsibleError as e:
            raise SystemExit(str(e))
    results = []
    basedir = os.path.dirname(playbook[0])
    # playbook_ds can be an AnsibleUnicode string, which we consider invalid
    if isinstance(playbook_ds, str):
        raise MatchError(filename=playbook[0], rule=LoadingFailureRule)
    items = _playbook_items(playbook_ds)
    for item in items:
        for child in play_children(basedir, item, playbook[1], playbook_dir):
            # We avoid processing parametrized children
            path_str = str(child.path)
            if "$" in path_str or "{{" in path_str:
                continue

            # Repair incorrect paths obtained when old syntax was used, like:
            # - include: simpletask.yml tags=nginx
            valid_tokens = list()
            for token in split_args(path_str):
                if '=' in token:
                    break
                valid_tokens.append(token)
            path = ' '.join(valid_tokens)
            if path != path_str:
                child.path = Path(path)
                child.name = child.path.name

            results.append(child)
    return results
예제 #13
0
    def _munge_include(self, ds, new_ds, k, v):
        '''
        Splits the include line up into filename and parameters
        '''

        # The include line must include at least one item, which is the filename
        # to include. Anything after that should be regarded as a parameter to the include
        items = split_args(v)
        if len(items) == 0:
            raise AnsibleParserError("include statements must specify the file name to include", obj=ds)
        else:
            # FIXME/TODO: validate that items[0] is a file, which also
            #             exists and is readable 
            new_ds['include'] = items[0]
            if len(items) > 1:
                # rejoin the parameter portion of the arguments and
                # then use parse_kv() to get a dict of params back
                params = parse_kv(" ".join(items[1:]))
                if 'vars' in new_ds:
                    # FIXME: see fixme above regarding merging vars
                    raise AnsibleParserError("include parameters cannot be mixed with 'vars' entries for include statements", obj=ds)
                new_ds['vars'] = params
예제 #14
0
    def _preprocess_import(self, ds, new_ds, k, v):
        '''
        Splits the playbook import line up into filename and parameters
        '''
        if v is None:
            raise AnsibleParserError("playbook import parameter is missing",
                                     obj=ds)
        elif not isinstance(v, string_types):
            raise AnsibleParserError(
                "playbook import parameter must be a string indicating a file path, got %s instead"
                % type(v),
                obj=ds)

        # The import_playbook line must include at least one item, which is the filename
        # to import. Anything after that should be regarded as a parameter to the import
        items = split_args(v)
        if len(items) == 0:
            raise AnsibleParserError(
                "import_playbook statements must specify the file name to import",
                obj=ds)

        new_ds['import_playbook'] = items[0].strip()
예제 #15
0
def build_filters(filters):
    """
    This will build the filters to be handed to NetBox endpoint call if they exist.

    Args:
        filters (str): String of filters to parse.

    Returns:
        result (list): List of dictionaries to filter by.
    """
    filter = {}
    args_split = split_args(filters)
    args = [parse_kv(x) for x in args_split]
    for arg in args:
        for k, v in arg.items():
            if k not in filter:
                filter[k] = list()
                filter[k].append(v)
            else:
                filter[k].append(v)

    return filter
예제 #16
0
def test_split_args(args, expected):
    assert split_args(args) == expected
def test_split_args(args, expected):
    assert split_args(args) == expected
예제 #18
0
    def run(self, terms, variables=None, **kwargs):

        netbox_api_token = kwargs.get("token")
        netbox_api_endpoint = kwargs.get("api_endpoint")
        netbox_ssl_verify = kwargs.get("validate_certs", True)
        netbox_private_key_file = kwargs.get("key_file")
        netbox_api_filter = kwargs.get("api_filter")
        netbox_raw_return = kwargs.get("raw_data")

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

        try:
            session = requests.Session()
            session.verify = netbox_ssl_verify

            netbox = pynetbox.api(
                netbox_api_endpoint,
                token=netbox_api_token if netbox_api_token else None,
                private_key_file=netbox_private_key_file,
            )
            netbox.http_session = session
        except FileNotFoundError:
            raise AnsibleError(
                "%s cannot be found. Please make sure file exists." %
                netbox_private_key_file)

        results = []
        for term in terms:

            try:
                endpoint = get_endpoint(netbox, term)
            except KeyError:
                raise AnsibleError(
                    "Unrecognised term %s. Check documentation" % term)

            Display().vvvv(
                u"Netbox lookup for %s to %s using token %s filter %s" %
                (term, netbox_api_endpoint, netbox_api_token,
                 netbox_api_filter))

            if netbox_api_filter:
                args_split = split_args(netbox_api_filter)
                args = [parse_kv(x) for x in args_split]
                filter = {}
                for arg in args:
                    for k, v in arg.items():
                        if k not in filter:
                            filter[k] = list()
                            filter[k].append(v)
                        else:
                            filter[k].append(v)

                Display().vvvv("filter is %s" % filter)

                for res in endpoint.filter(**filter):

                    Display().vvvvv(pformat(dict(res)))

                    if netbox_raw_return:
                        results.append(dict(res))

                    else:
                        key = dict(res)["id"]
                        result = {key: dict(res)}
                        results.extend(self._flatten_hash_to_list(result))

            else:
                for res in endpoint.all():

                    Display().vvvvv(pformat(dict(res)))

                    if netbox_raw_return:
                        results.append(dict(res))

                    else:
                        key = dict(res)["id"]
                        result = {key: dict(res)}
                        results.extend(self._flatten_hash_to_list(result))

        return results
예제 #19
0
 def check_split_args(self, args, expected):
     tools.eq_(split_args(args), expected)
예제 #20
0
 def check_split_args(self, args, expected):
     tools.eq_(split_args(args), expected)