Skip to content

Commit

Permalink
Check validity of 'become_method' values from code
Browse files Browse the repository at this point in the history
  • Loading branch information
audgirka committed May 30, 2023
1 parent 4e62882 commit 1ce7962
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
WSLENV: FORCE_COLOR:PYTEST_REQPASS:TOXENV:GITHUB_STEP_SUMMARY
# Number of expected test passes, safety measure for accidental skip of
# tests. Update value if you add/remove tests.
PYTEST_REQPASS: 801
PYTEST_REQPASS: 802
steps:
- name: Activate WSL1
if: "contains(matrix.shell, 'wsl')"
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ repos:
# empty args needed in order to match mypy cli behavior
args: [--strict]
additional_dependencies:
- ansible-compat>=4.0.1
- ansible-compat>=4.1.0
- black>=22.10.0
- cryptography>=39.0.1
- filelock
Expand Down
5 changes: 5 additions & 0 deletions examples/playbooks/rule-schema-become-method.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: Test 'become_method' plugin validity
hosts: localhost
become: true
become_method: ansible.builtin.sudo
52 changes: 30 additions & 22 deletions src/ansiblelint/rules/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
},
}

FIELD_CHECKS = {
"become_method": get_app().runtime.plugins.become.keys(),
}


class ValidateSchemaRule(AnsibleLintRule):
"""Perform JSON Schema Validation for known lintable kinds."""
Expand Down Expand Up @@ -77,47 +81,30 @@ class ValidateSchemaRule(AnsibleLintRule):
"schema[vars]": "",
}

become_method_msg = f"'become_method' must be one of the currently installed plugins: {', '.join(FIELD_CHECKS['become_method'])}"

def matchplay(self, file: Lintable, data: dict[str, Any]) -> list[MatchError]:
"""Return matches found for a specific playbook."""
results = []

results: list[MatchError] = []
if not data or file.kind not in ("tasks", "handlers", "playbook"):
return results
# check at play level
become_method = data.get("become_method", None)
available_become_plugins = get_app().runtime.plugins.become
available_become_plugins_keys = available_become_plugins.keys()
if (
become_method
and not has_jinja(become_method)
and not available_become_plugins.get(become_method)
and become_method not in FIELD_CHECKS["become_method"]
):
results.append(
MatchError(
message=f"'become_method' must be one of the currently installed plugins: {', '.join(available_become_plugins_keys)}",
message=self.become_method_msg,
lintable=file or Lintable(""),
rule=ValidateSchemaRule(),
details=ValidateSchemaRule.description,
tag=f"schema[{file.kind}]",
),
)

# check at task level
tasks = data.get("tasks", [])
if tasks:
for task in tasks:
become_method = task.get("become_method", None)
if become_method and not has_jinja(become_method):
results.append(
MatchError(
message=f"'become_method' must be one of the currently installed plugins: {', '.join(available_become_plugins_keys)}",
lintable=file or Lintable(""),
rule=ValidateSchemaRule(),
details=ValidateSchemaRule.description,
tag=f"schema[{file.kind}]",
),
)

return results

def matchtask(
Expand All @@ -126,6 +113,21 @@ def matchtask(
file: Lintable | None = None,
) -> bool | str | MatchError | list[MatchError]:
result = []
become_method = task.raw_task.get("become_method", None)
if (
become_method
and not has_jinja(become_method)
and become_method not in FIELD_CHECKS["become_method"]
):
result.append(
MatchError(
message=self.become_method_msg,
lintable=file or Lintable(""),
rule=ValidateSchemaRule(),
details=ValidateSchemaRule.description,
tag=f"schema[{file.kind}]", # type: ignore[union-attr]
),
)
for key in pre_checks["task"]:
if key in task.raw_task:
msg = pre_checks["task"][key]["msg"]
Expand Down Expand Up @@ -300,6 +302,12 @@ def matchyaml(self, file: Lintable) -> list[MatchError]:
[],
id="rulebook2",
),
pytest.param(
"examples/playbooks/rule-schema-become-method.yml",
"playbook",
[],
id="playbook",
),
),
)
def test_schema(file: str, expected_kind: str, expected: list[str]) -> None:
Expand Down

0 comments on commit 1ce7962

Please sign in to comment.