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

Version 6.12.0 contains regression for resolving modules/actions. #2969

Closed
TylerJang27 opened this issue Feb 1, 2023 · 14 comments · Fixed by #3025
Closed

Version 6.12.0 contains regression for resolving modules/actions. #2969

TylerJang27 opened this issue Feb 1, 2023 · 14 comments · Fixed by #3025
Assignees
Labels
bug new Triage required

Comments

@TylerJang27
Copy link

TylerJang27 commented Feb 1, 2023

Summary

Ansible-lint fails to resolve some modules/actions in playbooks.

Issue Type
  • Bug Report
OS / ENVIRONMENT
ansible-lint --version  # 6.12.0
  • ansible-lint installation method: pip installed (using trunk) on Ubuntu 20.04.5 LTS
STEPS TO REPRODUCE
# jboss-standalone/demo-aws-launch.yml (relative to workspace)
---
- name: Provision instances
  hosts: localhost
  connection: local
  gather_facts: False

  # load AWS variables from this group vars file
  vars_files:
    - group_vars/all

  tasks:
    - name: Launch instances
      ec2:
        access_key: "{{ ec2_access_key }}"
        secret_key: "{{ ec2_secret_key }}"
        keypair: "{{ ec2_keypair }}"
        group: "{{ ec2_security_group }}"
        type: "{{ ec2_instance_type }}"
        image: "{{ ec2_image }}"
        region: "{{ ec2_region }}"
        instance_tags:
          "{'ansible_group':'jboss', 'type':'{{ ec2_instance_type }}', 'group':'{{
          ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}"
        count: "{{ ec2_instance_count }}"
        wait: true
      register: ec2

    - name: Wait for SSH to come up
      wait_for:
        host: "{{ item.public_dns_name }}"
        port: 22
        delay: 60
        timeout: 320
        state: started
      with_items: "{{ ec2.instances }}"
ansible-lint
Desired Behavior

< 6.12.0 (specifically 6.11.0):

yaml[indentation]: Wrong indentation: expected 4 but found 2
.trunk/trunk.yaml:6

yaml[truthy]: Truthy value should be one of [false, true]
jboss-standalone/demo-aws-launch.yml:5

role-name: Role name ZbSoIn does not match ``^[a-z][a-z0-9_]*$`` pattern. (warning)
tmp/trunk-1001/ZbSoIn:1

You can skip specific rules or tags by adding them to your configuration file:
# .config/ansible-lint.yml
warn_list:  # or 'skip_list' to silence them completely
  - yaml[indentation]  # Violations reported by yamllint.
  - yaml[truthy]  # Violations reported by yamllint.

                      Rule Violation Summary                      
 count tag               profile rule associated tags             
     1 role-name         basic   deprecations, metadata (warning) 
     1 yaml[indentation] basic   formatting, yaml                 
     1 yaml[truthy]      basic   formatting, yaml                 

Failed after min profile: 2 failure(s), 1 warning(s) on 14 files.
Actual Behavior

>= 6.12.0:

syntax-check[specific]: couldn't resolve module/action 'ec2'. This often indicates a misspelling, missing collection, or incorrect module path.
jboss-standalone/demo-aws-launch.yml:12:7

You can skip specific rules or tags by adding them to your configuration file:
# .config/ansible-lint.yml
warn_list:  # or 'skip_list' to silence them completely
  - syntax-check[specific]  # Ansible syntax check failed.

                  Rule Violation Summary                   
 count tag                    profile rule associated tags 
     1 syntax-check[specific] min     core                 

Failed after : 1 failure(s), 0 warning(s) on 14 files.

Issue was first identified when running newly released version with trunk

@hollow
Copy link

hollow commented Feb 2, 2023

same here – just spent two hours trying to figure out why all of my ansible projects are failing pre-commit after updating today ...

@ssbarnea
Copy link
Member

ssbarnea commented Feb 2, 2023

Sorry but this reports sounds more of a support ticket than a bug and I will likely have to convert it to a discussion.

What I see for sure here is that lack of use of fully qualified module names. Read https://ansible-lint.readthedocs.io/rules/fqcn/#correct-code

Also remember that "collections" keyword is not supported.

@hollow
Copy link

hollow commented Feb 2, 2023

@ssbarnea this bug also exists for FQCNs

@ssbarnea
Copy link
Member

ssbarnea commented Feb 2, 2023

@hollow In this case, please try to produce a minimal example that reproduces this bug an nothing else. This should help us reproduce it and produce a fix.

While using pre-commit you need to be careful because their SaaS version does not have network access, so it cannot install required collections. If you run it yourself, you do not have this problem. Also, you could use https://github.com/ansible/ansible-lint-action which is the GHA we maintain. Still, with the action there is a slight delay of few days as we do not update it instantly after releasing a new linter, especially if the release was not a patch version.

@hollow
Copy link

hollow commented Feb 3, 2023

@ssbarnea while trying to come up with a minimal example I have realized that the actual issue seems to be burried in a lot of warnings that ansible-lint 6.12.0+ produces:

WARNING  Unable to resolve FQCN for module community.libvirt.virt
WARNING  Unable to resolve FQCN for module netbox.netbox.netbox_tag
WARNING  Unable to resolve FQCN for module netbox.netbox.netbox_virtual_machine
WARNING  Unable to load module community.general.nomad_job at playbooks/pushgateway.yaml:7 for options validation
WARNING  Unable to resolve FQCN for module community.general.nomad_job
WARNING  Unable to load module netbox.netbox.netbox_device at playbooks/tasks/netbox_tags.yaml:58 for options validation
WARNING  Unable to load module netbox.netbox.netbox_virtual_machine at playbooks/tasks/netbox_tags.yaml:70 for options validation
WARNING  Unable to resolve FQCN for module netbox.netbox.netbox_device
WARNING  Unable to load module community.general.parted at playbooks/tasks/optimize_nvme.yaml:22 for options validation
WARNING  Unable to resolve FQCN for module community.general.parted

the list goes on and on, but eventually ansible-lint fails with:

jinja[invalid]: An unhandled exception occurred while templating '{{ lookup('community.general.dig', item.key) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: lookup plugin (community.general.dig) not found
playbooks/pxe.yaml:74 Task/Handler: Create kickstart files

I have extracted the affected task and reproduced the error with the ansible-lint action without pre-commit here: https://github.com/hollow/ansible-lint-regression/actions/runs/4083566375/jobs/7039250446

Not sure if the issue is related to all the new warnings about not being able to load modules though.

@skokhanovskiy
Copy link

skokhanovskiy commented Feb 6, 2023

@hollow @ssbarnea here is the minimal Dockerfile for reproduction of this issue.

# syntax=docker/dockerfile:1

FROM debian

RUN apt-get update && apt install -y git python3-pip python3-wheel

RUN pip install ansible-core==2.13.7 && ansible --version
RUN ansible-galaxy collection install community.general:==6.3.0

RUN pip install ansible-lint==6.12.1 && ansible-lint --version

COPY <<-EOF /playbook.yml
---
- name: Test ansible-lint
  hosts: all
  vars:
    pam_rhel_modules: []
  tasks:
    - name: Ensure pam modules are configured
      community.general.pamd:
        foo: bar
        bar: foo
      loop_control:
        label: "{{ item.name }}"
      loop: "{{ pam_rhel_modules }}"
EOF

ENTRYPOINT [ "ansible-lint", "-v", "/playbook.yml" ]

Output of the container:

WARNING  Ignore loading rule from /usr/local/lib/python3.9/dist-packages/ansiblelint/rules/galaxy.py due to No module named 'pytest'
INFO     Set ANSIBLE_LIBRARY=/root/.cache/ansible-compat/e3b0c4/modules:/root/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO     Set ANSIBLE_COLLECTIONS_PATH=/root/.cache/ansible-compat/e3b0c4/collections:/root/.ansible/collections:/usr/share/ansible/collections
INFO     Set ANSIBLE_ROLES_PATH=/root/.cache/ansible-compat/e3b0c4/roles:/root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO     Executing syntax check on playbook.yml (0.43s)
WARNING  Unable to load module community.general.pamd at playbook.yml:7 for options validation
WARNING  Unable to resolve FQCN for module community.general.pamd

Passed with production profile: 0 failure(s), 0 warning(s) on 1 files.

For previous version ansible-lint everything works fine:

INFO     Set ANSIBLE_LIBRARY=/root/.cache/ansible-compat/e3b0c4/modules:/root/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO     Set ANSIBLE_COLLECTIONS_PATH=/root/.cache/ansible-compat/e3b0c4/collections:/root/.ansible/collections:/usr/share/ansible/collections
INFO     Set ANSIBLE_ROLES_PATH=/root/.cache/ansible-compat/e3b0c4/roles:/root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO     Executing syntax check on playbook.yml (0.43s)
WARNING  Listing 1 violation(s) that are fatal
args[module]: missing required arguments: control, module_path, name, type (warning)
playbook.yml:7 Task/Handler: Ensure pam modules are configured

You can skip specific rules or tags by adding them to your configuration file:
# .config/ansible-lint.yml
warn_list:  # or 'skip_list' to silence them completely
  - experimental  # all rules tagged as experimental

                  Rule Violation Summary                   
 count tag          profile rule associated tags           
     1 args[module]         syntax, experimental (warning) 

Passed with production profile, 5/5 star rating: 0 failure(s), 1 warning(s) on 1 files.
A new release of ansible-lint is available: 6.11.0 → 6.12.1

@skokhanovskiy
Copy link

IMHO this issue connected with closed #2828 that @ssbarnea moved to discussions #2861.

@kristof-mattei
Copy link

@skokhanovskiy

Output of the container:

WARNING  Ignore loading rule from /usr/local/lib/python3.9/dist-packages/ansiblelint/rules/galaxy.py due to No module named 'pytest'
INFO     Set ANSIBLE_LIBRARY=/root/.cache/ansible-compat/e3b0c4/modules:/root/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO     Set ANSIBLE_COLLECTIONS_PATH=/root/.cache/ansible-compat/e3b0c4/collections:/root/.ansible/collections:/usr/share/ansible/collections
INFO     Set ANSIBLE_ROLES_PATH=/root/.cache/ansible-compat/e3b0c4/roles:/root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO     Executing syntax check on playbook.yml (0.43s)
WARNING  Unable to load module community.general.pamd at playbook.yml:7 for options validation
WARNING  Unable to resolve FQCN for module community.general.pamd

Passed with production profile: 0 failure(s), 0 warning(s) on 1 files.

python -m pip install pytest seems to fix it for me.

@skokhanovskiy
Copy link

@kristof-mattei In my case installing of the pytest module resolves only the first warning.

Check this out.

# syntax=docker/dockerfile:1

FROM debian

RUN apt-get update && apt install -y git python3-pip python3-wheel

RUN pip install ansible-core==2.13.7 && ansible --version
RUN ansible-galaxy collection install community.general:==6.3.0

RUN pip install pytest ansible-lint==6.12.0 && ansible-lint --version

COPY <<-EOF /playbook.yml
---
- name: Test ansible-lint
  hosts: all
  vars:
    pam_rhel_modules: []
  tasks:
    - name: Ensure pam modules are configured
      community.general.pamd:
        foo: bar
        bar: foo
      loop_control:
        label: "{{ item.name }}"
      loop: "{{ pam_rhel_modules }}"
EOF

ENTRYPOINT [ "ansible-lint", "-v", "/playbook.yml" ]
docker build -t test-ansible-lint .
docker run --rm test-ansible-lint

We are expecting error message from linter about missed parameters:

args[module]: missing required arguments: control, module_path, name, type (warning)
playbook.yml:7 Task/Handler: Ensure pam modules are configured

But gets only this:

WARNING  Unable to load module community.general.pamd at playbook.yml:7 for options validation
WARNING  Unable to resolve FQCN for module community.general.pamd

Passed with production profile: 0 failure(s), 0 warning(s) on 1 files.

@bluikko
Copy link
Contributor

bluikko commented Feb 13, 2023

@hollow are you using offline mode? I am seeing also a ton of those warnings + errors, it seems everything outside of ansible.builtin is not found.

Edit: going back to 6.11 and everything works again.

@hollow
Copy link

hollow commented Feb 13, 2023

@bluikko I'm not using offline mode. Despite the warnings (which I ignore for now) I have mitigated the one remaining error (that I have reproduced in the linked repo above) with a # noqa directive 🤷‍♂️

@apatard
Copy link
Contributor

apatard commented Feb 13, 2023

hm. After seeing the same issue, I may have an idea of what's going on.
Can you someone try the following workaround please ?

--- ansiblelint/_vendor/ansible_compat/runtime.py.orig	2023-02-13 15:42:31.266911773 +0100
+++ ansiblelint/_vendor/ansible_compat/runtime.py	2023-02-13 15:44:51.132685168 +0100
@@ -142,11 +142,10 @@ class Runtime:
 
                 # noinspection PyProtectedMember
                 # pylint: disable=protected-access
-                _AnsibleCollectionFinder(
-                    paths=[
-                        os.path.dirname(os.environ.get(ansible_collections_path(), "."))
-                    ]
-                )._install()  # pylint: disable=protected-access
+                col_path = [f"{self.cache_dir}/collections"]
+                col_path += self.config.collections_paths
+                col_path += [os.path.dirname(os.environ.get(ansible_collections_path(), "."))]
+                _AnsibleCollectionFinder(paths=col_path)._install()  # pylint: disable=protected-access
             Runtime.initialized = True
 
     def clean(self) -> None:

@skokhanovskiy
Copy link

@apatard it works!

# syntax=docker/dockerfile:1

FROM debian

RUN apt-get update && apt install -y git python3-pip python3-wheel

RUN pip install ansible-core==2.13.7 && ansible --version
RUN ansible-galaxy collection install community.general:==6.3.0

RUN pip install pytest ansible-lint==6.12.2 && ansible-lint --version

COPY <<-EOF /runtime.patch
--- ansiblelint/_vendor/ansible_compat/runtime.py.orig	2023-02-13 15:42:31.266911773 +0100
+++ ansiblelint/_vendor/ansible_compat/runtime.py	2023-02-13 15:44:51.132685168 +0100
@@ -142,11 +142,10 @@ class Runtime:

                 # noinspection PyProtectedMember
                 # pylint: disable=protected-access
-                _AnsibleCollectionFinder(
-                    paths=[
-                        os.path.dirname(os.environ.get(ansible_collections_path(), "."))
-                    ]
-                )._install()  # pylint: disable=protected-access
+                col_path = [f"{self.cache_dir}/collections"]
+                col_path += self.config.collections_paths
+                col_path += [os.path.dirname(os.environ.get(ansible_collections_path(), "."))]
+                _AnsibleCollectionFinder(paths=col_path)._install()  # pylint: disable=protected-access
             Runtime.initialized = True

     def clean(self) -> None:
EOF

RUN patch /usr/local/lib/python3.9/dist-packages/ansiblelint/_vendor/ansible_compat/runtime.py /runtime.patch

COPY <<-EOF /playbook.yml
---
- name: Test ansible-lint
  hosts: all
  vars:
    pam_rhel_modules: []
  tasks:
    - name: Ensure pam modules are configured
      community.general.pamd:
        foo: bar
        bar: foo
      loop_control:
        label: "{{ item.name }}"
      loop: "{{ pam_rhel_modules }}"
EOF

ENTRYPOINT [ "ansible-lint", "-v", "/playbook.yml" ]

Output:

INFO     Schema ansible-lint-config was updated
INFO     Set ANSIBLE_LIBRARY=/root/.cache/ansible-compat/e3b0c4/modules:/root/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO     Set ANSIBLE_COLLECTIONS_PATH=/root/.cache/ansible-compat/e3b0c4/collections:/root/.ansible/collections:/usr/share/ansible/collections
INFO     Set ANSIBLE_ROLES_PATH=/root/.cache/ansible-compat/e3b0c4/roles:/root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO     Executing syntax check on playbook.yml (0.44s)
WARNING  Listing 1 violation(s) that are fatal
args[module]: missing required arguments: control, module_path, name, type (warning)
playbook.yml:7 Task/Handler: Ensure pam modules are configured

You can skip specific rules or tags by adding them to your configuration file:
# .config/ansible-lint.yml
warn_list:  # or 'skip_list' to silence them completely
  - experimental  # all rules tagged as experimental

                  Rule Violation Summary                   
 count tag          profile rule associated tags           
     1 args[module]         syntax, experimental (warning) 

Passed with production profile, 5/5 star rating: 0 failure(s), 1 warning(s) on 1 files.

apatard added a commit to apatard/ansible-compat that referenced this issue Feb 13, 2023
- Ensure the cache dir is added to the collection loader
  path, in order to allow linting a collection role against
  a module this collection is providing

- Add missing default collection path to the loader for ansible
  version prior 2.15.0.dev0, as done by ansible's
  _configure_collection_loader(). The only remaining difference
  is the missing handling of COLLECTIONS_SCAN_SYS_PATH.

See ansible/ansible-lint#2969 for
reference.

Signed-off-by: Arnaud Patard <apatard@hupstream.com>
@apatard
Copy link
Contributor

apatard commented Feb 13, 2023

@skokhanovskiy thanks for testing. I'm working on a PR for ansible-compat. If it gets merged, then the local version needs to be updated.

apatard added a commit to apatard/ansible-compat that referenced this issue Feb 13, 2023
- Ensure the cache dir is added to the collection loader
  path, in order to allow linting a collection role against
  a module this collection is providing

- Add missing default collection path to the loader for ansible
  version prior 2.15.0.dev0, as done by ansible's
  _configure_collection_loader(). The only remaining difference
  is the missing handling of COLLECTIONS_SCAN_SYS_PATH.

See ansible/ansible-lint#2969 for
reference.

Signed-off-by: Arnaud Patard <apatard@hupstream.com>
ssbarnea added a commit to ansible/ansible-compat that referenced this issue Feb 14, 2023
* src/ansible_compat/runtime.py: Fix collection loading

- Ensure the cache dir is added to the collection loader
  path, in order to allow linting a collection role against
  a module this collection is providing

- Add missing default collection path to the loader for ansible
  version prior 2.15.0.dev0, as done by ansible's
  _configure_collection_loader(). The only remaining difference
  is the missing handling of COLLECTIONS_SCAN_SYS_PATH.

See ansible/ansible-lint#2969 for
reference.

Signed-off-by: Arnaud Patard <apatard@hupstream.com>

* Collection path is a list

---------

Signed-off-by: Arnaud Patard <apatard@hupstream.com>
Co-authored-by: Sorin Sbarnea <ssbarnea@redhat.com>
@ssbarnea ssbarnea self-assigned this Feb 14, 2023
ssbarnea added a commit that referenced this issue Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug new Triage required
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants