ansible / ansible-lint

ansible-lint checks playbooks for practices and behavior that could potentially be improved and can fix some of the most common ones for you
https://ansible.readthedocs.io/projects/lint/
GNU General Public License v3.0
3.49k stars 663 forks source link

Erorr BLOCK_NAME_TO_ACTION_TYPE_MAP[action_type] TypeError: 'str' object does not support item assignment #341

Closed yodatak closed 4 years ago

yodatak commented 6 years ago

Issue Type

With ansible molecule test

Ansible and Ansible Lint details

ansible --version
ansible 2.5.2
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/yodatak/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.14 (default, Mar 14 2018, 16:45:33) [GCC 8.0.1 20180222 (Red Hat 8.0.1-0.16)]

ansible-lint --version
ansible-lint 3.4.21

Desired Behaviour

Please give some details of the feature being requested or what should happen if providing a bug report

Actual Behaviour (Bug report only)

Please give some details of what is actually happening.

Traceback (most recent call last): File "/usr/bin/ansible-lint", line 11, in load_entry_point('ansible-lint==3.4.21', 'console_scripts', 'ansible-lint')() File "/usr/lib/python2.7/site-packages/ansiblelint/main.py", line 173, in main matches.extend(runner.run()) File "/usr/lib/python2.7/site-packages/ansiblelint/init.py", line 243, in run skip_list=set(self.skip_list))) File "/usr/lib/python2.7/site-packages/ansiblelint/init.py", line 139, in run matches.extend(rule.matchtasks(playbookfile, text)) File "/usr/lib/python2.7/site-packages/ansiblelint/init.py", line 68, in matchtasks for task in ansiblelint.utils.get_normalized_tasks(yaml, file): File "/usr/lib/python2.7/site-packages/ansiblelint/utils.py", line 504, in get_normalized_tasks tasks = get_action_tasks(yaml, file) File "/usr/lib/python2.7/site-packages/ansiblelint/utils.py", line 488, in get_action_tasks tasks = add_action_type(yaml, file['type']) File "/usr/lib/python2.7/site-packages/ansiblelint/utils.py", line 480, in add_action_type action['ansible_action_type'] = BLOCK_NAME_TO_ACTION_TYPE_MAP[action_type] TypeError: 'str' object does not support item assignment

willthames commented 6 years ago

There is nowhere near enough information here to reproduce this issue.

decentral1se commented 6 years ago

I just hit this. It appears to be related to handlers with notify+listen. My setup was:

# tasks/main.yml
---
- name: Create a new Linode.
  linode:
  ... # cut ...
  notify: "Run Linode bootstrap."

# handlers/main.yml
---
handlers:
  - name: Set SSH connection facts.
    # cut ...
    listen: "Run Linode bootstrap."

And then I got hit, when running ansible-lint under pipenv run molecule lint using Molecule.

I saw:

--> Executing Ansible Lint on /home/decentral1se/aptivate/aptivate/linode-create/molecule/default/playbook.yml...                                                                                  
Traceback (most recent call last):
  File "/home/decentral1se/.local/share/virtualenvs/linode-create-O_CBFJjj/bin/ansible-lint", line 11, in <module>                                                                                 
    sys.exit(main())
  File "/home/decentral1se/.local/share/virtualenvs/linode-create-O_CBFJjj/lib/python3.7/site-packages/ansiblelint/__main__.py", line 176, in main                                                 
    matches.extend(runner.run())
  File "/home/decentral1se/.local/share/virtualenvs/linode-create-O_CBFJjj/lib/python3.7/site-packages/ansiblelint/__init__.py", line 243, in run                                                  
    skip_list=self.skip_list))
  File "/home/decentral1se/.local/share/virtualenvs/linode-create-O_CBFJjj/lib/python3.7/site-packages/ansiblelint/__init__.py", line 139, in run                                                  
    matches.extend(rule.matchtasks(playbookfile, text))
  File "/home/decentral1se/.local/share/virtualenvs/linode-create-O_CBFJjj/lib/python3.7/site-packages/ansiblelint/__init__.py", line 68, in matchtasks                                            
    for task in ansiblelint.utils.get_normalized_tasks(yaml, file):
  File "/home/decentral1se/.local/share/virtualenvs/linode-create-O_CBFJjj/lib/python3.7/site-packages/ansiblelint/utils.py", line 519, in get_normalized_tasks                                    
    tasks = get_action_tasks(yaml, file)
  File "/home/decentral1se/.local/share/virtualenvs/linode-create-O_CBFJjj/lib/python3.7/site-packages/ansiblelint/utils.py", line 503, in get_action_tasks                                        
    tasks = add_action_type(yaml, file['type'])
  File "/home/decentral1se/.local/share/virtualenvs/linode-create-O_CBFJjj/lib/python3.7/site-packages/ansiblelint/utils.py", line 495, in add_action_type                                         
    action['__ansible_action_type__'] = BLOCK_NAME_TO_ACTION_TYPE_MAP[action_type]
TypeError: 'AnsibleUnicode' object does not support item assignment
decentral1se commented 6 years ago

Can provide more information if needed!

BenWaller commented 6 years ago

I ran into this issue as well. It looks like the offending line was handlers: which I'm not sure is even valid syntax. I just removed that line, fixed the indentation and it fixed the issue.

awcrosby commented 5 years ago

Removing handlers: from the handlers/main.yml file resolved this in my testing also.

As for the original issue, there is not enough information to reproduce, so I am closing this.

ssbarnea commented 5 years ago

@awcrosby Can we reopen this I have proof the bug is real:

Examining /Users/ssbarnea/rdo/tripleo-quickstart/roles/libvirt/setup/overcloud/tasks/vars/libvirt_nodepool_vars.yml of type tasks
 [WARNING]: Unable to find 'baremetalvm.xml.j2' in expected paths (use -vvvvv
to see paths)

WARNING: Couldn't open /Users/ssbarnea/rdo/tripleo-quickstart/roles/tripleo-inventory/tests/tasks/provision.yml - No such file or directory
Traceback (most recent call last):
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/bin/ansible-lint", line 11, in <module>
    sys.exit(main())
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/__main__.py", line 187, in main
    matches.extend(runner.run())
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 282, in run
    skip_list=self.skip_list))
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 174, in run
    matches.extend(rule.matchtasks(playbookfile, text))
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 86, in matchtasks
    for task in ansiblelint.utils.get_normalized_tasks(yaml, file):
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 532, in get_normalized_tasks
    tasks = get_action_tasks(yaml, file)
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 516, in get_action_tasks
    tasks = add_action_type(yaml, file['type'])
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 508, in add_action_type
    action['__ansible_action_type__'] = BLOCK_NAME_TO_ACTION_TYPE_MAP[action_type]
TypeError: 'AnsibleUnicode' object does not support item assignment
 [WARNING]: Unable to find 'baremetalvm.xml.j2' in expected paths (use -vvvvv
to see paths)

Traceback (most recent call last):
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/bin/ansible-lint", line 11, in <module>
    sys.exit(main())
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/__main__.py", line 187, in main
    matches.extend(runner.run())
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 282, in run
    skip_list=self.skip_list))
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 174, in run
    matches.extend(rule.matchtasks(playbookfile, text))
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 86, in matchtasks
    for task in ansiblelint.utils.get_normalized_tasks(yaml, file):
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 532, in get_normalized_tasks
    tasks = get_action_tasks(yaml, file)
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 516, in get_action_tasks
    tasks = add_action_type(yaml, file['type'])
  File "/Users/ssbarnea/.cache/pre-commit/repoIbD7W3/py_env-python3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 508, in add_action_type
    action['__ansible_action_type__'] = BLOCK_NAME_TO_ACTION_TYPE_MAP[action_type]
TypeError: 'AnsibleUnicode' object does not support item assignment

It happens with v4.1.0a0 and v4.1.0 but not with v4.0.1.

awcrosby commented 5 years ago

@ssbarnea - sure thing... would you mind adding the yml that is causing this? (if you know)

ssbarnea commented 5 years ago

Done, finally managed to get rid of a huge amount of file and do something that can reproduce the error: https://github.com/ssbarnea/bug-ansible-lint

ssbarnea commented 5 years ago

Was anyone able to reproduce the bug with my example?

sparky005 commented 5 years ago

I'm not a maintainer here but I was able to reproduce with your example @ssbarnea. I ran a git bisect looks like b66376de5ab69d0f11fa0bd8fa530a8d330dc023 is the first bad commit.

ArtemChekunov commented 4 years ago

I have the same bug when i add :

grep -A2 'dependencies:' meta/main.yml
dependencies:
  - role: handlers

dependency has been installed via ansible-galaxy install -r requirements.yml

mcandre commented 4 years ago

Can we get a regression test added to CI to catch this earlier next time?

KernelPryanic commented 4 years ago

Fix also would be nice to have :)

askb commented 4 years ago

Move my molecule v2 to v3 required updating the yamllint to ansible-lint, this is returning the below error:

Traceback (most recent call last):
  File "/home/abelur/.virtualenvs/ansible-py3.6/bin/ansible-lint", line 8, in <module>
    sys.exit(main())
  File "/home/abelur/.virtualenvs/ansible-py3.6/lib/python3.6/site-packages/ansiblelint/__main__.py", line 187, in main
    matches.extend(runner.run())
  File "/home/abelur/.virtualenvs/ansible-py3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 282, in run
    skip_list=self.skip_list))
  File "/home/abelur/.virtualenvs/ansible-py3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 174, in run
    matches.extend(rule.matchtasks(playbookfile, text))
  File "/home/abelur/.virtualenvs/ansible-py3.6/lib/python3.6/site-packages/ansiblelint/__init__.py", line 86, in matchtasks
    for task in ansiblelint.utils.get_normalized_tasks(yaml, file):
  File "/home/abelur/.virtualenvs/ansible-py3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 532, in get_normalized_tasks
    tasks = get_action_tasks(yaml, file)
  File "/home/abelur/.virtualenvs/ansible-py3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 516, in get_action_tasks
    tasks = add_action_type(yaml, file['type'])
  File "/home/abelur/.virtualenvs/ansible-py3.6/lib/python3.6/site-packages/ansiblelint/utils.py", line 508, in add_action_type
    action['__ansible_action_type__'] = BLOCK_NAME_TO_ACTION_TYPE_MAP[action_type]
TypeError: 'AnsibleUnicode' object does not support item assignment
ERROR: Lint failed: Command 'set -e
ansible-lint -v */*.yml
' returned non-zero exit status 1.: Command 'set -e
ansible-lint -v */*.yml
' returned non-zero exit status 1.

Is there are work around for a fix for this yet?

$ grep -A2 'dependencies:' meta/main.yml dependencies: []

berndfinger commented 4 years ago

I have a similar issue with ansible-lint 4.2.0 when running against a playbook which is calling role sap-hana-preconfigure (https://github.com/berndfinger/sap-hana-preconfigure/tree/6edb1339a1a79c9e47f8023534e0a3db429dbf20):

$ ansible-lint --version
ansible-lint 4.2.0
$ ansible-lint sap-hana.yml
Traceback (most recent call last):
  File "/usr/local/bin/ansible-lint", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.6/site-packages/ansiblelint/__main__.py", line 187, in main
    matches.extend(runner.run())
  File "/usr/local/lib/python3.6/site-packages/ansiblelint/__init__.py", line 287, in run
    skip_list=self.skip_list))
  File "/usr/local/lib/python3.6/site-packages/ansiblelint/__init__.py", line 177, in run
    matches.extend(rule.matchtasks(playbookfile, text))
  File "/usr/local/lib/python3.6/site-packages/ansiblelint/__init__.py", line 87, in matchtasks
    yaml = ansiblelint.utils.append_skipped_rules(yaml, text, file['type'])
  File "/usr/local/lib/python3.6/site-packages/ansiblelint/utils.py", line 596, in append_skipped_rules
    yaml_skip = _append_skipped_rules(pyyaml_data, file_text, file_type)
  File "/usr/local/lib/python3.6/site-packages/ansiblelint/utils.py", line 635, in _append_skipped_rules
    if pyyaml_task.get('name') != ruamel_task.get('name'):
AttributeError: 'AnsibleUnicode' object has no attribute 'get'
webknjaz commented 4 years ago

@berndfinger please verify against master. We don't backport things to older releases.

webknjaz commented 4 years ago

@nixfu @benyanke @tohtohro @benyanke do any of you want to write a regression test integrated into our pytest setup per https://pganssle-talks.github.io/xfail-lightning and #725?

ssbarnea commented 4 years ago

I wanted to say the same, the best way to help with any bug is to create a regression test with xfail, which is quite simple.

Over the years I was considering enabling the stale bot to close bugs as not reproduced if no test is added for it but maybe we don't need to go so aggressive with the linter. I only hope we do not end-up flooded with tickets like ansible main repo did.

berndfinger commented 4 years ago

@webknjaz I followed the installation instructions in README.rst after cloning ansible-lint from here (https://github.com/ansible/ansible-lint.git):

$ pip3 install git+https://github.com/ansible/ansible-lint.git

After that, ansible-lint --version displays:

ansible-lint 0.0.0

As I mentioned in https://github.com/linux-system-roles/sap-hana-preconfigure/issues/113#issuecomment-667415012, the issue disappears after renaming three files in role sap-hana-preconfigure.

berndfinger commented 4 years ago

The issue also disappears after changing the line starting with: fail to:

webknjaz commented 4 years ago

Interesting, you must be using an outdated pip version... FWIW we need a full repro embedded here, not pointers to external issues that also look incomplete.

ssbarnea commented 4 years ago

If confirmed as bug we need to assure we test with oldest supported and newest release of pip.

berndfinger commented 4 years ago

Running on just the failing file outside of a role does not reproduce the issue. So I created a simple role as a reproducer with all empty files main.yml in defaults, handlers, meta, and vars, and file tasks/main.yml with the following content:

---

fail:
    msg: Failing

...

This causes ansible-lint to fail with AttributeError: 'AnsibleUnicode' object has no attribute 'get' when called with ansible-lint ansible_lint_issue_341.yml using the following playbook:

---
- hosts: all
  roles:
  - ansible_lint_issue_341
...

Please let me know if you need a reproducible test case with any other release of pip, python, ansible, or ansible-lint.

webknjaz commented 4 years ago

@berndfinger it'd be great if you could submit that as a PR embedded into our pytest-based test suite per https://pganssle-talks.github.io/xfail-lightning and #725

berndfinger commented 4 years ago

@webknjaz I would be happy to assist but I would need some more explanations on the process which is described on https://pganssle-talks.github.io/xfail-lightning and #725. I looked at all the examples https://pganssle-talks.github.io/xfail-lightning but still don't have all the information I need to get started. Is there maybe a more basic step-by-step guide or howto available? Or can you show me an example of a similar case, where similar steps have been performed?

webknjaz commented 4 years ago

@berndfinger alright, forget about xfail for now. It's just a mark on a test.

Your goal is to write a test as if it passes when there's no but. But of course, it'll fail for as long as it's not fixed.

Do do this, you'll need to write a broken file structure that triggers a bug into a temporary test dir using tmp_dir pytest fixture. Here's an example of making your own fixture that writes files to disk and then returns a path: https://github.com/ansible/ansible-lint/blob/e133bdc/test/TestSkipImportPlaybook.py#L5-L32. That fixture is then reused as a test argument by name and pytest will automatically run the fixture function and inject the return value into the test run. Once you have the structure on disk, use run_ansible_lint() as follows, to call ansible-lint CLI in a subprocess: https://github.com/ansible/ansible-lint/blob/e133bdc/test/TestCliRolePaths.py#L15. Finally, add some assert statement checking for a successful run indicator in the standard output returned by run_ansible_lint().

Only when this will be done and it's visible how the test fails in the CI, we'll be able to add an xfail mark in order to accept that test in the repo. With xfail mark, it won't make the CI fail as long as it fails but it's good to have the test in Git even without a fix. This way, it'd be a baseline for some future work on the fix.

ssbarnea commented 4 years ago

Closing as I am unable to reproduce but if you think the bug is real, just make PR with an xfail marked test that reproduces it.