Score:2

Search a list of Dicts using a list of items and find if the item exists under the attribute 'value'. Store only the Items NOT found as a new list

in flag

This one has been stomping me for a good while now. Hoping you guys can help.

I have a list of dicts registered like the example below (These are 'objects' from a Firewall)

"objects": [
      { 
         "name": "Test1",  
         "type": "ip-netmask", 
         "value": "8.8.8.8"
      },
      { 
         "name": "Test2", 
         "type": "ip-netmask", 
         "value": "8.8.4.4"
      }
   ]
}

Using a list of IP addresses called 'sources' I am currently able to search the 'values' in 'objects' to see if they exist. If they are found, I create a new list using set_fact and populate this with the 'name' of the object associated with the found 'value'. This is working OK.

The problem I am trying to solve is how I can create a new list with the 'sources' that are NOT found in my search of the values.

My working code for finding existing 'sources' and storing as names is as below:

vars
sources: ['8.8.8.8','8.8.4.4']

tasks:

  - name: Fetch all objects and store result
     panos_object_facts:
      provider: "{{ cli }}"
      device_group: DG_Test
      name_regex: '.*'
      object_type: 'address'
      register: result 

 - name: Search result for our sources and store as list if found
     set_fact:
        existing_source_addr: "{{  existing_source_addr|default([]) + [(result.objects | selectattr('value', 'search', item ) | list  | first).name ] }}"   
      with_items: "{{ sources }}"
    - debug: var=existing_source_addr

This returns an example as below:

"existing_source_addr": "['Test1', 'Test2']"

The below example is the code I am testing to create a new list which only contains the 'sources' which are NOT found. This is not working as expected.

vars
sources: ['8.8.8.8','8.8.4.4','4.4.4.4'] 

# 4.4.4.4 does not exist in our list of dicts 'objects' #

tasks:

  - name: Fetch all objects and store result
     panos_object_facts:
      provider: "{{ cli }}"
      device_group: DG_Test
      name_regex: '.*'
      object_type: 'address'
      register: result 

  - name: Search result for our sources and store as list if NOT found 
      set_fact:
        non_existing_source_addr: "{{ non_existing_source_addr|default([]) + [item] }}"
      with_items: "{{ sources }}"
      when: item not in result.objects | selectattr('value', 'search', item ) | list
   - debug: var=non_existing_source_addr

This returns an example as below:

"non_existing_source_addr": "[u'8.8.8.8', u'8.8.4.4', AnsibleUndefined]"

The condition is true as the 3rd item is not found as expected, but my variable is being set with all items from the list 'sources' + 'AnsibleUndefined' for the entry which does not exist.

Is there a way to have this new list ONLY contain the item which was not found '4.4.4.4'? This would allow me to then use the new list to create the missing objects.

Drusstheledg3 avatar
in flag
Sorry that's a typo. These are just examples. The actual list of dicts 'objects' has about 2000 entries. As mentioned the first part of the code works as intended in our live environment.
Drusstheledg3 avatar
in flag
Thanks for the feedback Vladimir. I have edited the post so hopefully it is more comprehensible now.
Score:1
br flag

Q: "New list only contains the item which was not found '4.4.4.4'."

A: For example

    - debug:
        msg: "{{ sources|difference(_values) }}"
      vars:
        _values: "{{ objects|map(attribute='value')|list }}"

gives

  msg:
  - 4.4.4.4
Drusstheledg3 avatar
in flag
Many thanks for the quick response. This worked a treat!
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.