Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize action names using builtins #1581

Merged
merged 1 commit into from May 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 12 additions & 11 deletions src/ansiblelint/rules/MissingFilePermissionsRule.py
Expand Up @@ -214,6 +214,10 @@ def matchtask(
file:
path: foo
state: touch
- name: permissions missing and might create file (fqcn)
ansible.builtin.file:
path: foo
state: touch
'''

FAIL_MISSING_PERMISSIONS_DIRECTORY = '''
Expand All @@ -223,6 +227,11 @@ def matchtask(
file:
path: foo
state: directory
- name: lineinfile when create is true (fqcn)
ansible.builtin.lineinfile:
path: foo
create: true
line: some content here
'''

FAIL_LINEINFILE_CREATE = '''
Expand All @@ -242,14 +251,6 @@ def matchtask(
replace:
path: foo
mode: preserve
- name: permissions are missing (fqcn)
ansible.builtin.file:
path: bar
- name: lineinfile when create is true (fqcn)
ansible.builtin.lineinfile:
path: foo
create: true
line: some content here
'''

FAIL_PERMISSION_COMMENT = '''
Expand Down Expand Up @@ -353,15 +354,15 @@ def test_fail_preserve_mode(rule_runner: RunFromText) -> None:
def test_fail_missing_permissions_touch(rule_runner: RunFromText) -> None:
"""Missing permissions when possibly creating file."""
results = rule_runner.run_playbook(FAIL_MISSING_PERMISSIONS_TOUCH)
assert len(results) == 1
assert len(results) == 2

@pytest.mark.parametrize(
'rule_runner', (MissingFilePermissionsRule,), indirect=['rule_runner']
)
def test_fail_missing_permissions_directory(rule_runner: RunFromText) -> None:
"""Missing permissions when possibly creating a directory."""
results = rule_runner.run_playbook(FAIL_MISSING_PERMISSIONS_DIRECTORY)
assert len(results) == 1
assert len(results) == 2

@pytest.mark.parametrize(
'rule_runner', (MissingFilePermissionsRule,), indirect=['rule_runner']
Expand All @@ -377,7 +378,7 @@ def test_fail_lineinfile_create(rule_runner: RunFromText) -> None:
def test_fail_replace_preserve(rule_runner: RunFromText) -> None:
"""Replace does not allow preserve mode."""
results = rule_runner.run_playbook(FAIL_REPLACE_PRESERVE)
assert len(results) == 3
assert len(results) == 1

@pytest.mark.parametrize(
'rule_runner', (MissingFilePermissionsRule,), indirect=['rule_runner']
Expand Down
8 changes: 8 additions & 0 deletions src/ansiblelint/text.py
Expand Up @@ -23,3 +23,11 @@ def toidentifier(text: str) -> str:
"Unable to convert role name '%s' to valid variable name." % text
)
return result


# https://www.python.org/dev/peps/pep-0616/
def removeprefix(self: str, prefix: str) -> str:
"""Remove prefix from string."""
if self.startswith(prefix):
return self[len(prefix) :]
return self[:]
10 changes: 9 additions & 1 deletion src/ansiblelint/utils.py
Expand Up @@ -74,6 +74,7 @@
from ansiblelint.constants import FileType
from ansiblelint.errors import MatchError
from ansiblelint.file_utils import Lintable, discover_lintables
from ansiblelint.text import removeprefix

# ansible-lint doesn't need/want to know about encrypted secrets, so we pass a
# string as the password to enable such yaml files to be opened and parsed
Expand Down Expand Up @@ -527,7 +528,7 @@ def _sanitize_task(task: Dict[str, Any]) -> Dict[str, Any]:


def normalize_task_v2(task: Dict[str, Any]) -> Dict[str, Any]:
"""Ensure tasks have an action key and strings are converted to python objects."""
"""Ensure tasks have a normalized action key and strings are converted to python objects."""
result = dict()

sanitized_task = _sanitize_task(task)
Expand Down Expand Up @@ -556,6 +557,13 @@ def normalize_task_v2(task: Dict[str, Any]) -> Dict[str, Any]:
continue
result[k] = v

if not isinstance(action, str):
raise RuntimeError("Task actions can only be strings, got %s" % 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)

if '_raw_params' in arguments:
Expand Down