I'm trying to get the address 192.168.176.129 from a variable interf:
"interf": {
"1": {
"adminstatus": "up",
"description": "",
"ifindex": "1",
"ipv4": [
{
"address": "192.168.176.129",
"netmask": "255.255.255.0"
}
],
"mac": "000c29788c7f",
"mtu": "1500",
"name": "ether1",
"operstatus": "up",
"speed": "1000000000"
}
}
I tried to do this, but nothing comes out
- set_fact:
test_name: "{{ interf|
select('regex', my_regex)|
first|
regex_replace(my_regex, my_replace) }}"
vars:
my_regex: '^address (.*)$'
my_replace: '\1'
- debug:
var: test_name
How do I get the address value: 192.168.176.129 and the operstatus value: up? What am I doing wrong?
CodePudding user response:
Why using a regex? Ansible is capable of accessing JSON and YAML properties of dictionaries as well as accessing lists.
If you only care about one IP address, you can do:
- debug:
var: interf['1'].ipv4.0.address
If you care about the possibility to have multiple addresses, then you'll get a list of addresses with:
- debug:
var: interf['1'].ipv4 | map(attribute='address')
Given the playbook:
- hosts: localhost
gather_facts: no
vars:
interf:
'1':
adminstatus: up
description: ''
ifindex: '1'
ipv4:
- address: 192.168.176.129
netmask: 255.255.255.0
mac: 000c29788c7f
mtu: '1500'
name: ether1
operstatus: up
speed: '1000000000'
tasks:
- name: Get the first IP address only
debug:
var: interf['1'].ipv4.0.address
- name: Get a list of (possibly) all the IPs address
debug:
var: interf['1'].ipv4 | map(attribute='address')
This yields:
TASK [Get the first IP address only] **************************************************
ok: [localhost] =>
interf['1'].ipv4.0.address: 192.168.176.129
TASK [Get a list of (possibly) all the IPs address] ***********************************
ok: [localhost] =>
interf['1'].ipv4 | map(attribute='address'):
- 192.168.176.129
CodePudding user response:
I took a slightly different approach assuming that the var is being parsed as a JSON object and not directly converted to YAML.
In this example, we parse the JSON first then use JMESPATH to extract the addresses. The debug statement loops through the list and outputs each address.
If you know that you'll only ever need the first item, then you can change the json query to interf.*.ipv4[*].address | [0][0]
and only the one address is returned.
- name: Test
hosts: localhost
vars:
json: |
{
"interf": {
"1": {
"adminstatus": "up",
"description": "",
"ifindex": "1",
"ipv4": [
{
"address": "192.168.176.129",
"netmask": "255.255.255.0"
}
],
"mac": "000c29788c7f",
"mtu": "1500",
"name": "ether1",
"operstatus": "up",
"speed": "1000000000"
}
}
}
tasks:
- name: Extract IPs
set_fact:
addresses: "{{ json | from_json | json_query(\"interf.*.ipv4[*].address | [0]\") | list }}"
- name: Loop through addresses
debug:
msg: "{{ item }}"
with_items: "{{ addresses }}"