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

Avoid warnings from loading of deprecated modules #3715

Merged
merged 1 commit into from
Nov 27, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions src/ansiblelint/rules/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import logging
import re
import sys
from functools import lru_cache
from typing import TYPE_CHECKING, Any

# pylint: disable=preferred-module
Expand All @@ -18,11 +17,11 @@
# pylint: disable=reimported
import ansible.module_utils.basic as mock_ansible_module
from ansible.module_utils import basic
from ansible.plugins.loader import PluginLoadContext, module_loader

from ansiblelint.constants import LINE_NUMBER_KEY
from ansiblelint.rules import AnsibleLintRule, RulesCollection
from ansiblelint.text import has_jinja
from ansiblelint.utils import load_plugin
from ansiblelint.yaml_utils import clean_json

if TYPE_CHECKING:
Expand Down Expand Up @@ -66,12 +65,6 @@
}


@lru_cache
def load_module(module_name: str) -> PluginLoadContext:
"""Load plugin from module name and cache it."""
return module_loader.find_plugin_with_context(module_name)


class ValidationPassedError(Exception):
"""Exception to be raised when validation passes."""

Expand Down Expand Up @@ -111,7 +104,7 @@ def matchtask(
if module_name in self.module_aliases:
return []

loaded_module = load_module(module_name)
loaded_module = load_plugin(module_name)

# https://github.com/ansible/ansible-lint/issues/3200
# since "ps1" modules cannot be executed on POSIX platforms, we will
Expand Down
18 changes: 13 additions & 5 deletions src/ansiblelint/rules/fqcn.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
import sys
from typing import TYPE_CHECKING, Any

from ansible.plugins.loader import module_loader

from ansiblelint.constants import LINE_NUMBER_KEY
from ansiblelint.rules import AnsibleLintRule, TransformMixin
from ansiblelint.utils import load_plugin

if TYPE_CHECKING:
from ruamel.yaml.comments import CommentedMap, CommentedSeq
Expand Down Expand Up @@ -116,9 +115,12 @@ def matchtask(
) -> list[MatchError]:
result = []
module = task["action"]["__ansible_module_original__"]
if not isinstance(module, str):
msg = "Invalid data for module."
raise RuntimeError(msg)

if module not in self.module_aliases:
loaded_module = module_loader.find_plugin_with_context(module)
loaded_module = load_plugin(module)
target = loaded_module.resolved_fqcn
self.module_aliases[module] = target
if target is None:
Expand All @@ -137,10 +139,16 @@ def matchtask(
1,
)
if module != legacy_module:
if module == "ansible.builtin.include":
message = f"Avoid deprecated module ({module})"
details = "Use `ansible.builtin.include_task` or `ansible.builtin.import_tasks` instead."
else:
message = f"Use FQCN for builtin module actions ({module})."
details = f"Use `{module_alias}` or `{legacy_module}` instead."
result.append(
self.create_matcherror(
message=f"Use FQCN for builtin module actions ({module}).",
details=f"Use `{module_alias}` or `{legacy_module}` instead.",
message=message,
details=details,
filename=file,
lineno=task["__line__"],
tag="fqcn[action-core]",
Expand Down
6 changes: 3 additions & 3 deletions src/ansiblelint/schemas/__store__.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json"
},
"meta": {
"etag": "9eb5c611e25cc9e0a180119904f8dfe39c59409b37da972f66a6c60f040a3a08",
"etag": "097a20155bc7936b6eae292a556bb38202d34a0a333ff5cbaaa1b4d3a4cc7bf5",
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta.json"
},
"meta-runtime": {
Expand All @@ -36,7 +36,7 @@
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/molecule.json"
},
"playbook": {
"etag": "48d584b10235804c13de78177dcfeeba433bd4d196ef3872aac7fc26a26303f5",
"etag": "8ae42e48318ff6da41f6d383dc19b643221258ea6521886f834e31cb8d3a7322",
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/playbook.json"
},
"requirements": {
Expand All @@ -48,7 +48,7 @@
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/role-arg-spec.json"
},
"rulebook": {
"etag": "b8c4ddf5d8d276d7a27335f2042554b3528ad9a091f13f1ffe7241be08a9671b",
"etag": "8a421671574fa65a57fb0d08e45879bfa005f271aa8c0243982a84b49fb0fe54",
"url": "https://raw.githubusercontent.com/ansible/ansible-rulebook/main/ansible_rulebook/schema/ruleset_schema.json"
},
"tasks": {
Expand Down
3 changes: 3 additions & 0 deletions src/ansiblelint/schemas/rulebook.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@
{
"type": "string"
},
{
"type": "boolean"
},
{
"$ref": "#/$defs/all-condition"
},
Expand Down
22 changes: 20 additions & 2 deletions src/ansiblelint/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import re
from collections.abc import Generator, ItemsView, Iterator, Mapping, Sequence
from dataclasses import _MISSING_TYPE, dataclass, field
from functools import cache
from functools import cache, lru_cache
from pathlib import Path
from typing import Any

Expand All @@ -44,7 +44,7 @@
from ansible.parsing.yaml.constructor import AnsibleConstructor, AnsibleMapping
from ansible.parsing.yaml.loader import AnsibleLoader
from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleSequence
from ansible.plugins.loader import add_all_plugin_dirs
from ansible.plugins.loader import PluginLoadContext, add_all_plugin_dirs, module_loader
from ansible.template import Templar
from ansible.utils.collection_loader import AnsibleCollectionConfig
from yaml.composer import Composer
Expand Down Expand Up @@ -1056,3 +1056,21 @@ def parse_examples_from_plugin(lintable: Lintable) -> tuple[int, str]:
# Ignore the leading newline and lack of document start
# as including those in EXAMPLES would be weird.
return offset, (f"---{examples}" if examples else "")


@lru_cache
def load_plugin(name: str) -> PluginLoadContext:
"""Return loaded ansible plugin/module."""
loaded_module = module_loader.find_plugin_with_context(
name,
ignore_deprecated=True,
check_aliases=True,
)
if not loaded_module.resolved and name.startswith("ansible.builtin."):
# fallback to core behavior of using legacy
loaded_module = module_loader.find_plugin_with_context(
name.replace("ansible.builtin.", "ansible.legacy."),
ignore_deprecated=True,
check_aliases=True,
)
return loaded_module
11 changes: 10 additions & 1 deletion test/test_task_includes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Tests related to task inclusions."""
import sys

import pytest

from ansiblelint.file_utils import Lintable
Expand All @@ -9,7 +11,14 @@
@pytest.mark.parametrize(
("filename", "file_count", "match_count"),
(
pytest.param("examples/playbooks/blockincludes.yml", 4, 3, id="blockincludes"),
pytest.param(
"examples/playbooks/blockincludes.yml",
4,
3
if sys.version_info >= (3, 10, 0)
else 4, # 3 with py310/ansible2.16, or 4 with py39/ansible2.15,
id="blockincludes",
),
pytest.param(
"examples/playbooks/blockincludes2.yml",
4,
Expand Down