Home > Software engineering >  Ansible version sort filter error - AttributeError: 'map' object has no attribute 'po
Ansible version sort filter error - AttributeError: 'map' object has no attribute 'po

Time:02-18

Im using anisble 2.9.7 on ubuntu18 and i use this playbook:

---
- name: Get all subinterface
  hosts: localhost
  connection: local
  vars:
       - ansible_python_interpreter: /usr/bin/env python3
  roles:
     - role: PaloAltoNetworks.paloaltonetworks
  gather_facts: False
  tasks:
  - name: Grab the credentials from ansible-vault
    include_vars: 'firewall-secrets.yml'

  - name: Get facts
    panos_facts:
      ip_address: '{{ ip_address }}'
      username: '{{ username }}'
      password: '{{ password }}'
      gather_subset: ['interfaces']
    register: facts
  - debug:
          msg:  "{{ facts['ansible_facts'] | to_json | from_json | json_query('ansible_net_interfaces[?starts_with(name,`ae2`)].name') | list| sort |version_sort }}"

I have run all test on ubuntu host and playbook with version sort works fine, but when i run the playbook through a container i get this error:

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AttributeError: 'map' object has no attribute 'pop'
fatal: [localhost]: FAILED! => {"msg": "Unexpected failure during module execution."}

This is the version sort i use:

from distutils.version import LooseVersion

def version_sort(l):
    start_range_1 = int(10)
    end_range_1 = int(120)

    start_range_2 = int(160)
    end_range_2 = int(200)

    l_new= []
    l = map(str, l)
    l.pop(0)
    for interface in l:
        interface = interface.split(".")[1]
        l_new.append(interface)
    interface_inuse = sorted(l_new, key=LooseVersion)
    interface_inuse = [int(item) for item in interface_inuse]
    interface_available_1= []
    interface_available_2= []
    for i in range(start_range_1,end_range_1):
        interface_available_1.append(i)
    for element in interface_inuse:
        if element in interface_available_1:
            interface_available_1.remove(element)

    for i in range(start_range_2,end_range_2):
        interface_available_2.append(i)
    for element in interface_inuse:
        if element in interface_available_2:
            interface_available_2.remove(element)
    print("interface_available_1", interface_available_1)
    print("interface_available_2", interface_available_2)
    interface_available = interface_available_1   interface_available_2
    return interface_available

class FilterModule(object):
    def filters(self):
        return {
            'version_sort' : version_sort
            }

the container run with the same ansible version with image - python:3-stretch I dont understand what is missing why on the host it runs fine and on container i get this python error.

CodePudding user response:

Well i dont know what the issue was but changing :

l = map(str, l)

to this:

l = list(map(str, l))

fixed the issue

CodePudding user response:

In Python 3 map doesn't return a list. Instead, it returns an iterator object. pop is the method of the list object. There is no pop method of an iterator object, hence it's considered an attribute, which is missing. As a result, you're getting the error.

'map' object has no attribute 'pop'

When you convert the iterator object to a list then you can use the method pop.

  • Related