Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new rule that detects use of blind ignore_errors: true (#1540)
* add new rule ignore-errors Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com> * Update src/ansiblelint/rules/IgnoreErrorsRule.py Co-authored-by: MarkusTeufelberger <mteufelberger@mgit.at> * allow ignore_errors: if register: is used Signed-off-by: Thomas Sjögren <konstruktoid@users.noreply.github.com> * Correct number of rules in test Co-authored-by: Sorin Sbarnea <ssbarnea@redhat.com> Co-authored-by: MarkusTeufelberger <mteufelberger@mgit.at>
- Loading branch information
1 parent
99c7d53
commit d1dbd87
Showing
3 changed files
with
114 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
"""IgnoreErrorsRule used with ansible-lint.""" | ||
import sys | ||
from typing import TYPE_CHECKING, Any, Dict, Union | ||
|
||
from ansiblelint.rules import AnsibleLintRule | ||
|
||
if TYPE_CHECKING: | ||
from typing import Optional | ||
|
||
from ansiblelint.file_utils import Lintable | ||
|
||
|
||
class IgnoreErrorsRule(AnsibleLintRule): | ||
"""Describe and test the IgnoreErrorsRule.""" | ||
|
||
id = "ignore-errors" | ||
shortdesc = ( | ||
'Use failed_when and specify error conditions instead of using ignore_errors' | ||
) | ||
description = ( | ||
'Instead of ignoring all errors, use ``failed_when:`` ' | ||
'and specify acceptable error conditions ' | ||
'to reduce the risk of ignoring important failures' | ||
) | ||
severity = 'LOW' | ||
tags = ['unpredictability', 'experimental'] | ||
version_added = 'v5.0.7' | ||
|
||
def matchtask( | ||
self, task: Dict[str, Any], file: 'Optional[Lintable]' = None | ||
) -> Union[bool, str]: | ||
|
||
if task.get("ignore_errors") and not task.get("register"): | ||
return True | ||
|
||
return False | ||
|
||
|
||
if "pytest" in sys.modules: | ||
import pytest | ||
|
||
IGNORE_ERRORS_TRUE = ''' | ||
- hosts: all | ||
tasks: | ||
- name: run apt-get update | ||
command: apt-get update | ||
ignore_errors: true | ||
''' | ||
|
||
IGNORE_ERRORS_FALSE = ''' | ||
- hosts: all | ||
tasks: | ||
- name: run apt-get update | ||
command: apt-get update | ||
ignore_errors: false | ||
''' | ||
|
||
IGNORE_ERRORS_REGISTER = ''' | ||
- hosts: all | ||
tasks: | ||
- name: run apt-get update | ||
command: apt-get update | ||
ignore_errors: true | ||
register: ignore_errors_register | ||
''' | ||
|
||
FAILED_WHEN = ''' | ||
- hosts: all | ||
tasks: | ||
- name: disable apport | ||
become: 'yes' | ||
lineinfile: | ||
line: "enabled=0" | ||
dest: /etc/default/apport | ||
mode: 0644 | ||
state: present | ||
register: default_apport | ||
failed_when: default_apport.rc !=0 and not default_apport.rc == 257 | ||
''' | ||
|
||
@pytest.mark.parametrize( | ||
'rule_runner', (IgnoreErrorsRule,), indirect=['rule_runner'] | ||
) | ||
def test_ignore_errors_true(rule_runner: Any) -> None: | ||
"""The task uses ignore_errors.""" | ||
results = rule_runner.run_playbook(IGNORE_ERRORS_TRUE) | ||
assert len(results) == 1 | ||
|
||
@pytest.mark.parametrize( | ||
'rule_runner', (IgnoreErrorsRule,), indirect=['rule_runner'] | ||
) | ||
def test_ignore_errors_false(rule_runner: Any) -> None: | ||
"""The task uses ignore_errors: false, oddly enough.""" | ||
results = rule_runner.run_playbook(IGNORE_ERRORS_FALSE) | ||
assert len(results) == 0 | ||
|
||
@pytest.mark.parametrize( | ||
'rule_runner', (IgnoreErrorsRule,), indirect=['rule_runner'] | ||
) | ||
def test_ignore_errors_register(rule_runner: Any) -> None: | ||
"""The task uses ignore_errors: but output is registered and managed.""" | ||
results = rule_runner.run_playbook(IGNORE_ERRORS_REGISTER) | ||
assert len(results) == 0 | ||
|
||
@pytest.mark.parametrize( | ||
'rule_runner', (IgnoreErrorsRule,), indirect=['rule_runner'] | ||
) | ||
def test_failed_when(rule_runner: Any) -> None: | ||
"""Instead of ignore_errors, this task uses failed_when.""" | ||
results = rule_runner.run_playbook(FAILED_WHEN) | ||
assert len(results) == 0 |
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