Skip to content

Commit

Permalink
Avoid warnings from loading of deprecated modules (#3715)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssbarnea committed Nov 27, 2023
1 parent fa9d1c7 commit 99344ca
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 20 deletions.
11 changes: 2 additions & 9 deletions src/ansiblelint/rules/args.py
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
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
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
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
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
@@ -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

0 comments on commit 99344ca

Please sign in to comment.