generated from ansible-collections/collection_template
-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add module_utils and filters for quoting and unquoting (#53)
* Move splitting code to own file. * Move list to dictionary code to quoting as well. * Add quoting functionality. * Add quoting filters. * Add integration tests to CI. * Fix bugs, increase coverage. * Make parsing more strict. * Extract function parse_argument_value from split_routeros_command to make proper parsing of WHERE possible. * Adjust expected error message in integration tests. * Simplify code and improve coverage. * Add changelog fragment for WHERE strictness in api module. * Add documenation. * Fix typo. * Add documentation references. * Add example to api module which uses quote_argument_value. * Fix bug, and add tests which prevent this in the future. * Add more escape sequence tests. * Make sure all control characters are quoted.
- Loading branch information
1 parent
f9d246c
commit d73eb1c
Showing
14 changed files
with
803 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
minor_changes: | ||
- "api - make validation of ``WHERE`` for ``query`` more strict (https://github.com/ansible-collections/community.routeros/pull/53)." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
add plugin.filter: | ||
- name: split | ||
description: Split a command into arguments | ||
- name: quote_argument_value | ||
description: Quote an argument value | ||
- name: quote_argument | ||
description: Quote an argument | ||
- name: join | ||
description: Join a list of arguments to a command | ||
- name: list_to_dict | ||
description: Convert a list of arguments to a list of dictionary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ sections: | |
toctree: | ||
- api-guide | ||
- ssh-guide | ||
- quoting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.. _ansible_collections.community.routeros.docsite.quoting: | ||
|
||
How to quote and unquote commands and arguments | ||
=============================================== | ||
|
||
When using the :ref:`community.routeros.command module <ansible_collections.community.routeros.command_module>` or the :ref:`community.routeros.api module <ansible_collections.community.routeros.api_module>` modules, you need to pass text data in quoted form. While in some cases quoting is not needed (when passing IP addresses or names without spaces, for example), in other cases it is required, like when passing a comment which contains a space. | ||
|
||
The community.routeros collection provides a set of Jinja2 filter plugins which helps you with these tasks: | ||
|
||
- The ``community.routeros.quote_argument_value`` filter quotes an argument value: ``'this is a "comment"' | community.routeros.quote_argument_value == '"this is a \\"comment\\""'``. | ||
- The ``community.routeros.quote_argument`` filter quotes an argument with or without a value: ``'comment=this is a "comment"' | community.routeros.quote_argument == 'comment="this is a \\"comment\\""'``. | ||
- The ``community.routeros.join`` filter quotes a list of arguments and joins them to one string: ``['foo=bar', 'comment=foo is bar'] | community.routeros.join == 'foo=bar comment="foo is bar"'``. | ||
- The ``community.routeros.split`` filter splits a command into a list of arguments (with or without values): ``'foo=bar comment="foo is bar"' | community.routeros.split == ['foo=bar', 'comment=foo is bar']`` | ||
- The ``community.routeros.list_to_dict`` filter splits a list of arguments with values into a dictionary: ``['foo=bar', 'comment=foo is bar'] | community.routeros.list_to_dict == {'foo': 'bar', 'comment': 'foo is bar'}``. It has two optional arguments: ``require_assignment`` (default value ``true``) allows to accept arguments without values when set to ``false``; and ``skip_empty_values`` (default value ``false``) allows to skip arguments whose value is empty. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Copyright: (c) 2021, Felix Fontein <[email protected]> | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
|
||
from __future__ import absolute_import, division, print_function | ||
__metaclass__ = type | ||
|
||
from ansible.errors import AnsibleFilterError | ||
from ansible.module_utils.common.text.converters import to_text | ||
|
||
from ansible_collections.community.routeros.plugins.module_utils.quoting import ( | ||
ParseError, | ||
convert_list_to_dictionary, | ||
join_routeros_command, | ||
quote_routeros_argument, | ||
quote_routeros_argument_value, | ||
split_routeros_command, | ||
) | ||
|
||
|
||
def wrap_exception(fn, *args, **kwargs): | ||
try: | ||
return fn(*args, **kwargs) | ||
except ParseError as e: | ||
raise AnsibleFilterError(to_text(e)) | ||
|
||
|
||
def split(line): | ||
''' | ||
Split a command into arguments. | ||
Example: | ||
'add name=wrap comment="with space"' | ||
is converted to: | ||
['add', 'name=wrap', 'comment=with space'] | ||
''' | ||
return wrap_exception(split_routeros_command, line) | ||
|
||
|
||
def quote_argument_value(argument): | ||
''' | ||
Quote an argument value. | ||
Example: | ||
'with "space"' | ||
is converted to: | ||
r'"with \"space\""' | ||
''' | ||
return wrap_exception(quote_routeros_argument_value, argument) | ||
|
||
|
||
def quote_argument(argument): | ||
''' | ||
Quote an argument. | ||
Example: | ||
'comment=with "space"' | ||
is converted to: | ||
r'comment="with \"space\""' | ||
''' | ||
return wrap_exception(quote_routeros_argument, argument) | ||
|
||
|
||
def join(arguments): | ||
''' | ||
Join a list of arguments to a command. | ||
Example: | ||
['add', 'name=wrap', 'comment=with space'] | ||
is converted to: | ||
'add name=wrap comment="with space"' | ||
''' | ||
return wrap_exception(join_routeros_command, arguments) | ||
|
||
|
||
def list_to_dict(string_list, require_assignment=True, skip_empty_values=False): | ||
''' | ||
Convert a list of arguments to a list of dictionary. | ||
Example: | ||
['foo=bar', 'comment=with space', 'additional='] | ||
is converted to: | ||
{'foo': 'bar', 'comment': 'with space', 'additional': ''} | ||
If require_assignment is True (default), arguments without assignments are | ||
rejected. (Example: in ['add', 'name=foo'], 'add' is an argument without | ||
assignment.) If it is False, these are given value None. | ||
If skip_empty_values is True, arguments with empty value are removed from | ||
the result. (Example: in ['name='], 'name' has an empty value.) | ||
If it is False (default), these are kept. | ||
''' | ||
return wrap_exception( | ||
convert_list_to_dictionary, | ||
string_list, | ||
require_assignment=require_assignment, | ||
skip_empty_values=skip_empty_values, | ||
) | ||
|
||
|
||
class FilterModule(object): | ||
'''Ansible jinja2 filters for RouterOS command quoting and unquoting''' | ||
|
||
def filters(self): | ||
return { | ||
'split': split, | ||
'quote_argument': quote_argument, | ||
'quote_argument_value': quote_argument_value, | ||
'join': join, | ||
'list_to_dict': list_to_dict, | ||
} |
Oops, something went wrong.