Regex match for key in jinja2 selectattr() - ansible

Given the data:
"serverName", [
serverData: [
{
"internal_ip": "10.1.1.100",
"external_ip": "172.16.1.10",
"name": "dns-1"
},
],
]
This extracts the name value dns-1 when the internal_ip matches the equalto. So far, so good.
- debug:
msg: "{{ mydict | selectattr('internal_ip', 'equalto', '10.1.1.100') |
map(attribute='name') | list }}"
In the real problem, I do not know which type of *_ip will the ip address I'm searching for will reside. It could be under internal_ip, it could be under external_ip and for all I know, there could be even more options, the only thing that will always be there - is the actual IP address I'm searching for: '10.1.1.100`.
So I need to regex match like so:
- debug:
msg: "{{ mydict | selectattr('^.*$', 'equalto', '10.1.1.100') |
map(attribute='name') | list }}"
I'm not sure if this is possible, but it seems to be one of the ways out of this jam.

For example, the playbook
shell> cat playbook.yml
- hosts: localhost
vars:
mylist:
- {internal_ip: 10.1.1.101, external_ip: 172.16.1.10, name: dns-1}
- {internal_ip: 10.1.1.102, external_ip: 172.16.1.10, name: dns-2}
- {internal_ip: 10.1.1.103, external_ip: 172.16.1.10, name: dns-3}
tasks:
- set_fact:
sel: "{{ sel|default([]) + [item.name] }}"
loop: "{{ mylist }}"
when: sel_ip|default('') in item.values()|list
- debug:
var: sel
gives
shell> ansible-playbook playbook.yml -e sel_ip=172.16.1.10
...
sel:
- dns-1
- dns-2
- dns-3
shell> ansible-playbook playbook.yml -e sel_ip=10.1.1.103
...
sel:
- dns-3

Related

Get Odd or Even Index Value from Variable in Ansible Playbook

I need to get odd or even index value from a variable list:
For example:
- hosts: myhost
vars:
- var1: ["test1","test2","test3","test4","test5"]
- odd_var: []
- even_var: []
I need odd_var to be ["test1","test3","test5"] and even_var to be ["test2","test4"] and also concatenate each variable string of odd_var and even_var to be one string like:
odd_string: "test1,test3,test5"
even_string: "test2,test4"
What should i do to achieve this?
I have tried :
- name: test
set_fact:
odd_list: "{{ odd_list | default([]) + [item] }}"
loop: "{{ var1 }}"
when: "{{ lookup('ansible.utils.index_of', var1, 'eq', item) is even }}
it works but i wonder if i can get more eficient way to do this
Since you said "index value", I'm going to take you at your word and base it on position in the list, not the numbers contained in the strings.
- hosts: localhost
vars:
var1:
- test1
- test2
- test3
- test4
- test5
odd_var: "{{ var1[::2] | join(',') }}"
even_var: "{{ var1[1::2] | join(',') }}"
tasks:
- debug:
msg: "{{ odd_var }} / {{ even_var }}"
Output:
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "test1,test3,test5 / test2,test4"
}
Using regex, checking the last character.
- var1: ["test1","test2","test3","test4","test5"]
- even: "{{ var1 | select('search','.*[02468]$') | join(',') }}"
- odd: "{{ var1 | select('search','.*[13579]$') | join(',') }}"

How to reduce a list against another list of patterns?

I need to write with Ansible's built in filters and tests the similar logic of shell one-liner:
for path in $(find PATH_TO_DIR); do for pattern in $PATTERNS; do echo $path | grep -v $pattern; done; done
---
- hosts: localhost
connection: local
gather_facts: False
vars:
paths:
- "/home/vagrant/.ansible"
- path-one
- path-two
- path-three
- "/home/vagrant/.ssh"
- "/home/vagratn/"
patterns:
- ".*ssh.*"
- ".*ansible.*"
- ".*one.*"
tasks:
- name: set empty list
set_fact:
files_to_be_removed: [ ]
In the end I would like to have a list like this:
ok: [localhost] => {
"msg": [
"path-two",
"path-three",
"/home/vagratn/"
]
}
With this form I getting a list where only last item from patterns is applied.
- set_fact:
files_to_be_removed: |
{{ paths
|reject("search", item)
|list }}
with_items:
- "{{ patterns }}"
The tasks below do the job
- set_fact:
files_to_be_removed: "{{ paths }}"
- set_fact:
files_to_be_removed: "{{ files_to_be_removed|
reject('search', item)|
list }}"
loop: "{{ patterns }}"
- debug:
var: files_to_be_removed
give
"files_to_be_removed": [
"path-two",
"path-three",
"/home/vagratn/"
]

Ansible returns only one item from a dictionary

I'm trying to get a list of IPs from an specific Service, and ansible returns only one item from the loop.
I have tried many things and is always the same result.
Need help.
- name: "Amazon IPs"
include_vars:
file: /home/user1/ansible/AWS/ip-ranges.json
name: amazon
# - set_fact:
# # # test: "{{ (variable.stdout | from_json).prefixes | map(attribute='ip_prefix') | list }}"
# amazonipv4: "{{ item }}"
# # amazonipv6: "{{ amazon.ipv6_prefixes | map(attribute='ipv6_prefix') | list }}"
# loop: "{{amazon.prefixes | map(attribute='ip_prefix') | list }}"
# # when: '"AMAZON" in item.service'
- set_fact:
test3: "{{item.ip_prefix}}"
loop: "{{amazon.prefixes | list }}"
when: '"AMAZON" in item.service'
- debug:
var: test3
I expect to get a list based on the service, but I only get one item.
example:
TASK [debug] ***********************************************
ok: [localhost] => {
"test3": "54.190.198.32/28"
in each iteration in the set_fact loop, you are setting the value, not pushing to a list. you need to change your syntax to:
- set_fact:
test3: "{{ test3 | default([]) + [item.ip_prefix] }}"
hope it helps.

VARIABLE IS NOT DEFINED when trying to register output in playbook

I'm trying to register a variable with the output to a query of a F5 pool and I'm getting this error:
"<type 'list'>": "VARIABLE IS NOT DEFINED!",
What is that I'm doing wrong?
Any help appreciated.
Thanks!
---
- name: GRAB F5 FACTS
hosts: f5
connection: local
gather_facts: no
tasks:
- name: Collect BIG-IP facts
bigip_device_facts:
gather_subset: ltm-pools
provider: "{{ prov }}"
register: bigip_device_facts
- name: FACTS OUTPUT
debug:
var: "{{ item.members | rejectattr('state', 'match', '^present$') | map(attribute='name') | list }}"
register: jkout
with_items: "{{ bigip_device_facts.ltm_pools }}"
when: item.full_path == "/Common/mypool"
- name: Set a variable
debug:
msg: "jkvar={{ jkout }}"
You are using the debug: module with the option var: and this expects a variable, not a jinja2 template.
So either change it to:
debug:
var: item.members
or
debug:
msg: "{{ item.members }}"
Like said by #dgw, the problem is with the var option of debug module.
https://docs.ansible.com/ansible/latest/modules/debug_module.html#parameters
This playbooks works:
- name: test rejectattr
hosts: localhost
gather_facts: no
vars:
members:
- { name: "one", state: "present" }
- { name: "two", state: "absent" }
- { name: "three", state: "present" }
tasks:
- name: FACTS OUTPUT
debug:
msg: "{{ members | rejectattr('state', 'match', '^present$') | map(attribute='name') | list }}"
Thanks for your responses. I'll investigate it further.
Apart from that, I think I've been able to solve it another way.
- name: FACTS OUTPUT
set_fact:
listado: "{{ item.members | rejectattr('state', 'match', '^present$') | map(attribute='name') | list }}"
with_items: "{{ bigip_device_facts.ltm_pools }}"
when: item.full_path == "/Common/mypool"
- debug: msg={{ listado }}
register: jkout
- name: Set a variable
debug:
msg: "jkvar={{ jkout }}"
Is that a right way to do it?
Thanks!!

Ansible get first element from list

Suppose I have the following vars_file:
mappings:
- primary: 1.1.1.1
secondary: 2.2.2.2
- primary: 12.12.12.12
secondary: 11.11.11.11
and hosts file
1.1.1.1
12.12.12.12
5.5.5.5
and the following playbook task
- name: Extract secondary from list
debug:
msg: "{{ (mappings | selectattr('primary', 'search', inventory_hostname) | list | first | default({'secondary':None})).secondary }}"
The current task works and will give empty string when no match are found, but I would like to know if there is a better way/cleaner way of doing it without passing a dictionary to the default constructor.
An option would be to use json_query
- debug:
msg: "{{ mappings | json_query(\"[?primary=='\" + inventory_hostname + \"'].secondary\") }}"
, but selectattr works too
- debug:
msg: "{{ mappings | selectattr('primary', 'equalto', inventory_hostname) | map(attribute='secondary') | list }}"

Resources