ansible.utils/docs/ansible.utils.update_fact_m...

406 lines
12 KiB
ReStructuredText

.. _ansible.utils.update_fact_module:
*************************
ansible.utils.update_fact
*************************
**Update currently set facts**
Version added: 1.0.0
.. contents::
:local:
:depth: 1
Synopsis
--------
- This module allows updating existing variables.
- Variables are updated on a host-by-host basis.
- Variables are not modified in place, instead they are returned by the module.
Parameters
----------
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="2">Parameter</th>
<th>Choices/<font color="blue">Defaults</font></th>
<th width="100%">Comments</th>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>updates</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">list</span>
/ <span style="color: purple">elements=dictionary</span>
/ <span style="color: red">required</span>
</div>
</td>
<td>
</td>
<td>
<div>A list of dictionaries, each a desired update to make.</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder"></td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>path</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
/ <span style="color: red">required</span>
</div>
</td>
<td>
</td>
<td>
<div>The path in a currently set variable to update.</div>
<div>The path can be in dot or bracket notation.</div>
<div>It should be a valid jinja reference.</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder"></td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>value</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">raw</span>
/ <span style="color: red">required</span>
</div>
</td>
<td>
</td>
<td>
<div>The value to be set at the path.</div>
<div>Can be a simple or complex data structure.</div>
</td>
</tr>
</table>
<br/>
Examples
--------
.. code-block:: yaml
# Update an existing fact, dot or bracket notation
- name: Set a fact
ansible.builtin.set_fact:
a:
b:
c:
- 1
- 2
- name: Update the fact
ansible.utils.update_fact:
updates:
- path: a.b.c.0
value: 10
- path: "a['b']['c'][1]"
value: 20
register: updated
- debug:
var: updated.a
# updated:
# a:
# b:
# c:
# - 10
# - 20
# changed: true
# Lists can be appended, new keys added to dictionaries
- name: Set a fact
ansible.builtin.set_fact:
a:
b:
b1:
- 1
- 2
- name: Update, add to list, add new key
ansible.utils.update_fact:
updates:
- path: a.b.b1.2
value: 3
- path: a.b.b2
value:
- 10
- 20
- 30
register: updated
- debug:
var: updated.a
# updated:
# a:
# b:
# b1:
# - 1
# - 2
# - 3
# b2:
# - 10
# - 20
# - 30
# changed: true
#####################################################################
# Update every item in a list of dictionaries
# build the update list ahead of time using a loop
# and then apply the changes to the fact
#####################################################################
- name: Set fact
ansible.builtin.set_fact:
addresses:
- raw: 10.1.1.0/255.255.255.0
name: servers
- raw: 192.168.1.0/255.255.255.0
name: printers
- raw: 8.8.8.8
name: dns
- name: Build a list of updates
ansible.builtin.set_fact:
update_list: "{{ update_list + update }}"
loop: "{{ addresses }}"
loop_control:
index_var: idx
vars:
update_list: []
update:
- path: addresses[{{ idx }}].network
value: "{{ item['raw'] | ansible.netcommon.ipaddr('network') }}"
- path: addresses[{{ idx }}].prefix
value: "{{ item['raw'] | ansible.netcommon.ipaddr('prefix') }}"
- debug:
var: update_list
# TASK [debug] *******************
# ok: [localhost] =>
# update_list:
# - path: addresses[0].network
# value: 10.1.1.0
# - path: addresses[0].prefix
# value: '24'
# - path: addresses[1].network
# value: 192.168.1.0
# - path: addresses[1].prefix
# value: '24'
# - path: addresses[2].network
# value: 8.8.8.8
# - path: addresses[2].prefix
# value: '32'
- name: Make the updates
ansible.utils.update_fact:
updates: "{{ update_list }}"
register: updated
- debug:
var: updated
# TASK [debug] ***********************
# ok: [localhost] =>
# updated:
# addresses:
# - name: servers
# network: 10.1.1.0
# prefix: '24'
# raw: 10.1.1.0/255.255.255.0
# - name: printers
# network: 192.168.1.0
# prefix: '24'
# raw: 192.168.1.0/255.255.255.0
# - name: dns
# network: 8.8.8.8
# prefix: '32'
# raw: 8.8.8.8
# changed: true
# failed: false
#####################################################################
# Retrieve, update, and apply interface description change
# use index_of to locate Etherent1/1
#####################################################################
- name: Get the current interface config
cisco.nxos.nxos_interfaces:
state: gathered
register: interfaces
- name: Update the description of Ethernet1/1
ansible.utils.update_fact:
updates:
- path: "interfaces.gathered[{{ index }}].description"
value: "Configured by ansible"
vars:
index: "{{ interfaces.gathered|ansible.utils.index_of('eq', 'Ethernet1/1', 'name') }}"
register: updated
- name: Update the configuration
cisco.nxos.nxos_interfaces:
config: "{{ updated.interfaces.gathered }}"
state: overridden
register: result
- name: Show the commands issued
debug:
msg: "{{ result['commands'] }}"
# TASK [Show the commands issued] *************************************
# ok: [nxos101] => {
# "msg": [
# "interface Ethernet1/1",
# "description Configured by ansible"
# ]
# }
#####################################################################
# Retrieve, update, and apply an ipv4 ACL change
# finding the index of AFI ipv4 acls
# finding the index of the ACL named 'test1'
# finding the index of sequence 10
#####################################################################
- name: Retrieve the current acls
arista.eos.eos_acls:
state: gathered
register: current
- name: Update the source of sequence 10 in the IPv4 ACL named test1
ansible.utils.update_fact:
updates:
- path: current.gathered[{{ afi }}].acls[{{ acl }}].aces[{{ ace }}].source
value:
subnet_address: "192.168.2.0/24"
vars:
afi: "{{ current.gathered|ansible.utils.index_of('eq', 'ipv4', 'afi') }}"
acl: "{{ current.gathered[afi|int].acls|ansible.utils.index_of('eq', 'test1', 'name') }}"
ace: "{{ current.gathered[afi|int].acls[acl|int].aces|ansible.utils.index_of('eq', 10, 'sequence') }}"
register: updated
- name: Apply the changes
arista.eos.eos_acls:
config: "{{ updated.current.gathered }}"
state: overridden
register: changes
- name: Show the commands issued
debug:
msg: "{{ changes['commands'] }}"
# TASK [Show the commands issued] *************************************
# ok: [eos101] => {
# "msg": [
# "ip access-list test1",
# "no 10",
# "10 permit ip 192.168.2.0/24 host 10.1.1.2"
# ]
# }
#####################################################################
# Disable ip redirects on any layer3 interface
# find the layer 3 interfaces
# use each name to find their index in l3 interface
# build an 'update' list and apply the updates
#####################################################################
- name: Get the current interface and L3 interface configuration
cisco.nxos.nxos_facts:
gather_subset: min
gather_network_resources:
- interfaces
- l3_interfaces
- name: Build the list of updates to make
ansible.builtin.set_fact:
updates: "{{ updates + [entry] }}"
vars:
updates: []
entry:
path: "ansible_network_resources.l3_interfaces[{{ item }}].redirects"
value: false
w_mode: "{{ ansible_network_resources.interfaces|selectattr('mode', 'defined') }}"
m_l3: "{{ w_mode|selectattr('mode', 'eq', 'layer3') }}"
names: "{{ m_l3|map(attribute='name')|list }}"
l3_indicies: "{{ ansible_network_resources.l3_interfaces|ansible.utils.index_of('in', names, 'name', wantlist=True) }}"
loop: "{{ l3_indicies }}"
# TASK [Build the list of updates to make] ****************************
# ok: [nxos101] => (item=99) => changed=false
# ansible_facts:
# updates:
# - path: ansible_network_resources.l3_interfaces[99].redirects
# value: false
# ansible_loop_var: item
# item: 99
- name: Update the l3 interfaces
ansible.utils.update_fact:
updates: "{{ updates }}"
register: updated
# TASK [Update the l3 interfaces] *************************************
# changed: [nxos101] => changed=true
# ansible_network_resources:
# l3_interfaces:
# <...>
# - ipv4:
# - address: 10.1.1.1/24
# name: Ethernet1/100
# redirects: false
- name: Apply the configuration changes
cisco.nxos.l3_interfaces:
config: "{{ updated.ansible_network_resources.l3_interfaces }}"
state: overridden
register: changes
# TASK [Apply the configuration changes] ******************************
# changed: [nxos101] => changed=true
# commands:
# - interface Ethernet1/100
# - no ip redirects
Status
------
Authors
~~~~~~~
- Bradley Thornton (@cidrblock)