diff options
Diffstat (limited to 'src/ansiblelint/rules/no_log_password.py')
-rw-r--r-- | src/ansiblelint/rules/no_log_password.py | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/src/ansiblelint/rules/no_log_password.py b/src/ansiblelint/rules/no_log_password.py index 7cc7439..c3f6d34 100644 --- a/src/ansiblelint/rules/no_log_password.py +++ b/src/ansiblelint/rules/no_log_password.py @@ -15,17 +15,25 @@ """NoLogPasswordsRule used with ansible-lint.""" from __future__ import annotations +import os import sys +from pathlib import Path from typing import TYPE_CHECKING -from ansiblelint.rules import AnsibleLintRule +from ansiblelint.rules import AnsibleLintRule, RulesCollection, TransformMixin +from ansiblelint.runner import get_matches +from ansiblelint.transformer import Transformer from ansiblelint.utils import Task, convert_to_boolean if TYPE_CHECKING: + from ruamel.yaml.comments import CommentedMap, CommentedSeq + + from ansiblelint.config import Options + from ansiblelint.errors import MatchError from ansiblelint.file_utils import Lintable -class NoLogPasswordsRule(AnsibleLintRule): +class NoLogPasswordsRule(AnsibleLintRule, TransformMixin): """Password should not be logged.""" id = "no-log-password" @@ -72,12 +80,26 @@ class NoLogPasswordsRule(AnsibleLintRule): has_password and not convert_to_boolean(no_log) and len(has_loop) > 0, ) + def transform( + self, + match: MatchError, + lintable: Lintable, + data: CommentedMap | CommentedSeq | str, + ) -> None: + if match.tag == self.id: + task = self.seek(match.yaml_path, data) + task["no_log"] = True + + match.fixed = True + if "pytest" in sys.modules: + from unittest import mock + import pytest if TYPE_CHECKING: - from ansiblelint.testing import RunFromText # pylint: disable=ungrouped-imports + from ansiblelint.testing import RunFromText NO_LOG_UNUSED = """ - name: Test @@ -304,3 +326,33 @@ if "pytest" in sys.modules: """The task does not actually lock the user.""" results = rule_runner.run_playbook(PASSWORD_LOCK_FALSE) assert len(results) == 0 + + @mock.patch.dict(os.environ, {"ANSIBLE_LINT_WRITE_TMP": "1"}, clear=True) + def test_no_log_password_transform( + config_options: Options, + ) -> None: + """Test transform functionality for no-log-password rule.""" + playbook = Path("examples/playbooks/transform-no-log-password.yml") + config_options.write_list = ["all"] + rules = RulesCollection(options=config_options) + rules.register(NoLogPasswordsRule()) + + config_options.lintables = [str(playbook)] + runner_result = get_matches(rules=rules, options=config_options) + transformer = Transformer(result=runner_result, options=config_options) + transformer.run() + + matches = runner_result.matches + assert len(matches) == 2 + + orig_content = playbook.read_text(encoding="utf-8") + expected_content = playbook.with_suffix( + f".transformed{playbook.suffix}", + ).read_text(encoding="utf-8") + transformed_content = playbook.with_suffix(f".tmp{playbook.suffix}").read_text( + encoding="utf-8", + ) + + assert orig_content != transformed_content + assert expected_content == transformed_content + playbook.with_suffix(f".tmp{playbook.suffix}").unlink() |