-
Notifications
You must be signed in to change notification settings - Fork 635
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a new experimental rule to disallow the use of `vars_prompt` or `ansible.builtin.pause` to better accommodate unattended playbook runs and use in CI pipelines. This rule is opt-in for now and needs to be explicitly enabled to be used. Fixes: #2036 Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
- Loading branch information
1 parent
6ffd7a8
commit f41e000
Showing
3 changed files
with
96 additions
and
2 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,56 @@ | ||
"""Implementation of no-prompting rule.""" | ||
|
||
from typing import TYPE_CHECKING, Any, Dict, List, Union | ||
|
||
from ansiblelint.rules import AnsibleLintRule | ||
from ansiblelint.utils import LINE_NUMBER_KEY | ||
|
||
if TYPE_CHECKING: | ||
from typing import Optional | ||
|
||
from ansiblelint.constants import odict | ||
from ansiblelint.errors import MatchError | ||
from ansiblelint.file_utils import Lintable | ||
|
||
|
||
class NoPromptingRule(AnsibleLintRule): | ||
"""Disallow prompting.""" | ||
|
||
id = "no-prompting" | ||
description = ( | ||
"Disallow the use of vars_prompt or ansible.builtin.pause to better" | ||
"accommodate unattended playbook runs and use in CI pipelines." | ||
) | ||
tags = ["opt-in", "experimental"] | ||
severity = "VERY_LOW" | ||
version_added = "v6.0.3" | ||
|
||
def matchplay( | ||
self, file: "Lintable", data: "odict[str, Any]" | ||
) -> List["MatchError"]: | ||
"""Return matches found for a specific playbook.""" | ||
# If the Play uses the 'vars_prompt' section to set variables | ||
|
||
if file.kind != "playbook": | ||
return [] | ||
|
||
vars_prompt = data.get("vars_prompt", None) | ||
if not vars_prompt: | ||
return [] | ||
|
||
return [ | ||
self.create_matcherror( | ||
message="Play uses vars_prompt", | ||
linenumber=vars_prompt[LINE_NUMBER_KEY], | ||
filename=file, | ||
) | ||
] | ||
|
||
def matchtask( | ||
self, task: Dict[str, Any], file: "Optional[Lintable]" = None | ||
) -> Union[bool, str]: | ||
"""Return matches for ansible.builtin.pause tasks.""" | ||
return task["action"]["__ansible_module_original__"] in [ | ||
"pause", | ||
"ansible.builtin.pause", | ||
] |
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,39 @@ | ||
"""Tests for no-prompting rule.""" | ||
from ansiblelint.config import options | ||
from ansiblelint.rules import RulesCollection | ||
from ansiblelint.rules.no_prompting import NoPromptingRule | ||
from ansiblelint.testing import RunFromText | ||
|
||
FAIL_TASKS = """ | ||
--- | ||
- hosts: all | ||
vars_prompt: | ||
- name: username | ||
prompt: What is your username? | ||
private: no | ||
- name: password | ||
prompt: What is your password? | ||
tasks: | ||
- name: Pause for 5 minutes to build app cache | ||
pause: | ||
minutes: 5 | ||
- name: A helpful reminder of what to look out for post-update | ||
ansible.builtin.pause: | ||
prompt: "Make sure org.foo.FooOverload exception is not present" | ||
""" | ||
|
||
|
||
def test_no_prompting_fail() -> None: | ||
"""Negative test for no-prompting.""" | ||
# For testing we want to manually enable opt-in rules | ||
options.enable_list = ["no-prompting"] | ||
collection = RulesCollection(options=options) | ||
collection.register(NoPromptingRule()) | ||
runner = RunFromText(collection) | ||
results = runner.run_playbook(FAIL_TASKS) | ||
assert len(results) == 3 | ||
assert "Play uses vars_prompt" in str(results) |