-2

I am gathering data using a Netapp module in Ansible. Thereafter using Python Inline Code to apply an operation on that list. Using that Python operation I try to find specific string values in a list. I am using the command module to execute Python code inline.

---
- hosts: exec-node

  collections:
    - netapp.ontap

  vars_files:
    - secretvars.yaml

  tasks:

    - name: Gather volume info
      tags: vol
      netapp.ontap.na_ontap_rest_info:
        gather_subset:
          - storage/volumes
        hostname: "nas3.test.com"
        username: "{{ username }}"
        password: "{{ password }}"
        https: true
        validate_certs: false
      register: result

    - debug: var=result['ontap_info']['storage/volumes']['records']
      tags: vol

    - name: create volume list
      tags: vol
      set_fact:
        volume_list: "{{ volume_list|default([]) + [item.name] }}"
      loop: "{{result['ontap_info']['storage/volumes']['records']}}"

    - debug: var=volume_list
      tags: vol

    - name: Python inline code
      command: python3
      args:
        stdin: |
          finallist="{{ volume_list }}"
          finallist1=[]
          for i in finallist:
              if i[0:2]=='yz':
                  finallist1.append(i)
          print(finallist1)
      register: results

    - set_fact:
        x: "{{ results.stdout }}"

I am expecting a list (finallist1) of my required data like below.

['yz16', 'yz18', 'yz11', 'yz13', 'yz14', 'yz17', 'yz15', 'yz32']

My raw list (finallist) is as below:

['yz16', 'yz18', 'yz11', 'yz13', 'yz14', 'yz17', 'yz15', 'yz32', 'test', 'test1']

2 Answers2

1

Don't use inline Python. Write a custom filter plugin. It's easy to do, and a great option when your logic is starting to get complex to pull off using the standard playbook syntax.

https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html#filter-plugins

https://netdevops.be/developing-a-custom-ansible-filter-plugin/

john.w
  • 323
  • 4
  • 13
0

Just some notes and considerations ... It is not recommended to use Python inline code except there a strong and valid reasons for. Furthermore I like to recommend to name your variables like list_in or inList and list_out or outList so that it is easier to understand what they are for.


My raw list (finallist) is as below: ['yz16', 'yz18', 'yz11', 'yz13', 'yz14', 'yz17', 'yz15', 'yz32', 'test', 'test1']

According the minimal example in order to debug what is going on internally

- hosts: localhost
  become: false
  gather_facts: false

  vars:

    LIST: ['yz16', 'yz18', 'yz11', 'yz13', 'yz14', 'yz17', 'yz15', 'yz32', 'test', 'test1']

  tasks:

  - name: Python inline code example
    command: /usr/bin/python
    args:
      stdin: |
        list_in = "{{ LIST }}"
        for i in list_in:
          print(i)
        print("Is of type: ", type(list_in))
        print(len(list_in))
    register: results

  - name: Show result
    debug:
      msg: "{{ results.stdout}}"

which results into the output of

TASK [Show result] *******
ok: [localhost] =>
  msg: |-
    [
    u
    '
    y
    z
    1
    6
    '
    ,
...
    u
    '
    t
    e
    s
    t
    1
    '
    ]
    ('Is of type: ', <type 'str'>)
    91

your input is a string not a list.

So, some of the assumptions made are incorrect, if i[0:2] == 'yz' can never be true and that's why you get an empty list.

At least you would need to cast the type before

        list_in = list_in.split()
        print("Is of type: ", type(list_in))
        print(len(list_in))

resulting into an output

...
    ('Is of type: ', <type 'list'>)
    10

For further debugging you may have a look into

        list_in = list_in.split()
        for i in range(len(list_in)):
          print(list_in[i])

or

        list_in = list_in.split()
        list_out = [i for i in list_in if "yz" in i]
        print(list_out)

Similar Python Q&A


Whereby for rapid and fast prototyping, debugging and learning purpose such kind of coding might be OK, it will probably cause an error prone implementation and non idempotent behavior, will be hard to read and maintain, etc. and shouldn't go into production environments.

U880D
  • 8,601
  • 6
  • 24
  • 40