summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PR408_README.md163
-rw-r--r--README.md1
-rw-r--r--changelogs/fragments/t6838_vrf.yml3
-rw-r--r--docs/vyos.vyos.vyos_config_module.rst41
-rw-r--r--docs/vyos.vyos.vyos_vrf_module.rst5087
-rw-r--r--meta/runtime.yml2
l---------plugins/action/vrf.py1
-rw-r--r--plugins/module_utils/network/vyos/argspec/vrf/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/argspec/vrf/vrf.py131
-rw-r--r--plugins/module_utils/network/vyos/config/vrf/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/config/vrf/vrf.old313
-rw-r--r--plugins/module_utils/network/vyos/config/vrf/vrf.py308
-rw-r--r--plugins/module_utils/network/vyos/facts/facts.py2
-rw-r--r--plugins/module_utils/network/vyos/facts/vrf/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/facts/vrf/vrf.py227
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/vrf.py249
-rw-r--r--plugins/module_utils/network/vyos/utils/utils.py22
-rw-r--r--plugins/modules/vyos_vrf.py1545
-rw-r--r--pr408-diagram.pngbin0 -> 161529 bytes
-rw-r--r--tests/integration/targets/vyos_vrf/defaults/main.yaml3
-rw-r--r--tests/integration/targets/vyos_vrf/tasks/cli.yaml20
-rw-r--r--tests/integration/targets/vyos_vrf/tasks/main.yaml5
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/_add_rm.yaml12
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/_parsed.cfg34
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/_populate.yaml10
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/_remove_config.yaml9
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/_remove_rm.yaml0
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/deleted.yaml34
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/empty_config.yaml60
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/gathered.yaml22
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/merged.yaml54
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/overridden.yaml49
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/parsed.yaml16
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/rendered.yaml133
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/replaced.yaml56
-rw-r--r--tests/integration/targets/vyos_vrf/tests/cli/rtt.yaml69
-rw-r--r--tests/integration/targets/vyos_vrf/vars/main.yaml278
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_vrf_config.cfg15
-rw-r--r--tests/unit/modules/network/vyos/test_vyos_vrf.py689
39 files changed, 9663 insertions, 0 deletions
diff --git a/PR408_README.md b/PR408_README.md
new file mode 100644
index 00000000..0423b56f
--- /dev/null
+++ b/PR408_README.md
@@ -0,0 +1,163 @@
+# ๐Ÿ“ฆ Pull Request Documentation
+
+## ๐Ÿงพ Summary
+
+<!-- Brief explanation of what this PR does and why. -->
+
+This is a new Ansible module to manage VyOS VRF configuration as requested by https://vyos.dev/T6836
+
+---
+
+## ๐Ÿ” Implementation
+
+<!-- Link to related issues or tasks -->
+
+The module implements a set of VyOS 1.4.2 and 1.5.x commands related to VRF configuration, described in https://docs.vyos.io/en/1.4/configuration/vrf/index.html
+The module allows to configure a global attribute (bind-all), as well as, VRF instance configuration.
+
+The structure of the parameters is depicted below
+![Diagram](pr408-diagram.png)
+
+The module supports the following states:
+
+- "deleted"
+- "merged"
+- "replaced"
+- "overridden"
+- "gathered"
+- "rendered"
+- "parsed"
+
+---
+
+## ๐Ÿ“ Examples
+
+### Replaced (to demo individual attribute processing)
+
+Initial coonfiguration
+
+```
+ - set vrf bind-to-all
+ - set vrf name vrf-blue description 'blue-vrf'
+ - set vrf name vrf-blue table '100'
+ - set vrf name vrf-blue vni '1000'
+ - set vrf name vrf-red description 'red-vrf'
+ - set vrf name vrf-red disable
+ - set vrf name vrf-red ip disable-forwarding
+ - set vrf name vrf-red ip protocol kernel route-map 'rm1'
+ - set vrf name vrf-red ip protocol rip route-map 'rm1'
+ - set vrf name vrf-red ipv6 nht no-resolve-via-default
+ - set vrf name vrf-red table '101'
+ - set vrf name vrf-red vni '1001'
+ - set vrf name vrf-pink table 111
+ - set vrf name vrf-pink vni 1111
+ - set vrf name vrf-pink description pink-vrf
+ - set vrf name vrf-pink protocols bgp system-as 65000
+ - set vrf name vrf-pink protocols bgp neighbor 192.0.2.1 remote-as 65002
+ - set vrf name vrf-pink protocols bgp neighbor 1.1.1.3 passive
+ - set vrf name vrf-pink protocols bgp neighbor 1.1.1.3 remote-as 400
+ - set vrf name vrf-pink protocols ospf log-adjacency-changes 'detail'
+ - set vrf name vrf-pink protocols ospf max-metric router-lsa administrative
+ - set vrf name vrf-pink protocols ospf max-metric router-lsa on-shutdown 10
+ - set vrf name vrf-pink protocols ospf max-metric router-lsa on-startup 10
+ - set vrf name vrf-pink protocols ospf default-information originate always
+ - set vrf name vrf-pink protocols ospf default-information originate metric 10
+ - set vrf name vrf-pink protocols ospf default-information originate metric-type 2
+ - set vrf name vrf-pink protocols ospf mpls-te router-address '192.0.11.12'
+ - set vrf name vrf-pink protocols ospf auto-cost reference-bandwidth '2'
+ - set vrf name vrf-pink protocols ospf neighbor 192.0.11.12
+ - set vrf name vrf-pink protocols ospf neighbor 192.0.11.12 poll-interval 10
+ - set vrf name vrf-pink protocols ospf neighbor 192.0.11.12 priority 2
+ - set vrf name vrf-pink protocols ospf redistribute bgp
+ - set vrf name vrf-pink protocols ospf redistribute bgp metric 10
+ - set vrf name vrf-pink protocols ospf redistribute bgp metric-type 2
+ - set vrf name vrf-pink protocols ospf parameters router-id '192.0.1.1'
+ - set vrf name vrf-pink protocols ospf parameters rfc1583-compatibility
+ - set vrf name vrf-pink protocols ospf parameters abr-type 'cisco'
+ - set vrf name vrf-pink protocols ospf area '2'
+ - set vrf name vrf-pink protocols ospf area 2 area-type normal
+ - set vrf name vrf-pink protocols ospf area 2 authentication plaintext-password
+ - set vrf name vrf-pink protocols ospf area 2 shortcut enable
+ - set vrf name vrf-pink protocols ospf area '3'
+ - set vrf name vrf-pink protocols ospf area 3 area-type nssa
+ - set vrf name vrf-pink protocols ospf area '4'
+ - set vrf name vrf-pink protocols ospf area 4 area-type stub default-cost 20
+ - set vrf name vrf-pink protocols ospf area 4 network 192.0.2.0/24
+ - set vrf name vrf-pink protocols ospf area 4 range 192.0.3.0/24
+ - set vrf name vrf-pink protocols ospf area 4 range 192.0.3.0/24 cost 10
+ - set vrf name vrf-pink protocols ospf area 4 range 192.0.4.0/24
+ - set vrf name vrf-pink protocols ospf area 4 range 192.0.4.0/24 cost 12
+ - set vrf name vrf-pink protocols ospfv3 area '2'
+ - set vrf name vrf-pink protocols ospfv3 area 2 export-list export1
+ - set vrf name vrf-pink protocols ospfv3 area 2 import-list import1
+ - set vrf name vrf-pink protocols ospfv3 area 2 range 2001:db10::/32
+ - set vrf name vrf-pink protocols ospfv3 area 2 range 2001:db20::/32
+ - set vrf name vrf-pink protocols ospfv3 area 2 range 2001:db30::/32
+ - set vrf name vrf-pink protocols ospfv3 area '3'
+ - set vrf name vrf-pink protocols ospfv3 area 3 range 2001:db40::/32
+ - set vrf name vrf-pink protocols ospfv3 parameters router-id '192.0.2.10'
+ - set vrf name vrf-pink protocols ospfv3 redistribute bgp
+ - set vrf name vrf-pink protocols static route 192.0.2.0/24
+ - set vrf name vrf-pink protocols static route 192.0.2.0/24 blackhole distance '10'
+ - set vrf name vrf-pink protocols static route 192.0.2.0/24 next-hop '203.0.113.1'
+ - set vrf name vrf-pink protocols static route 192.0.2.0/24 next-hop '203.0.113.2'
+ - set vrf name vrf-pink protocols static route6 2001:db8::/32
+ - set vrf name vrf-pink protocols static route6 2001:db8::/32 blackhole distance '20'
+ - set vrf name vrf-pink protocols static route6 2001:db8::/32 next-hop '2001:db8::1'
+```
+
+Module configuration
+
+```yaml
+vyos.vyos.vyos_vrf:
+ config:
+ instances:
+ - name: "vrf-blue"
+ description: "blue-vrf"
+ disable: true
+ table_id: 100
+ vni: 1000
+ - name: "vrf-red"
+ description: "Vermillion_VRF"
+ disable: false
+ table_id: 101
+ vni: 1011
+ address_family:
+ - afi: "ipv6"
+ nht_no_resolve_via_default: false
+ - name: "vrf-pink"
+ table_id: 111
+ protocols:
+ ospf:
+ default_information:
+ originate:
+ always: true
+ metric: 20
+ metric_type: 1
+ state: replaced
+```
+
+Will result in
+
+````
+- delete vrf bind-to-all
+- set vrf name vrf-blue disable
+- set vrf name vrf-red vni 1011
+- set vrf name vrf-red description Vermillion_VRF
+- delete vrf name vrf-red disable
+- delete vrf name vrf-red ipv6 nht no-resolve-via-default
+- delete vrf name vrf-pink vni 1111
+- delete vrf name vrf-pink description pink-vrf
+- delete vrf name vrf-pink protocols ospf log-adjacency-changes 'detail'
+- delete vrf name vrf-pink protocols ospf auto-cost
+- delete vrf name vrf-pink protocols ospf max-metric
+- delete vrf name vrf-pink protocols ospf mpls-te
+- delete vrf name vrf-pink protocols ospf area
+- delete vrf name vrf-pink protocols ospf parameters
+- delete vrf name vrf-pink protocols ospf neighbor
+- delete vrf name vrf-pink protocols ospf redistribute
+- set vrf name vrf-pink protocols ospf default-information originate metric 20
+- set vrf name vrf-pink protocols ospf default-information originate metric-type 1
+```
+---
+````
diff --git a/README.md b/README.md
index df9d916e..c453038b 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,7 @@ Name | Description
[vyos.vyos.vyos_system](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_system_module.rst)|Run `set system` commands on VyOS devices
[vyos.vyos.vyos_user](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_user_module.rst)|Manage the collection of local users on VyOS device
[vyos.vyos.vyos_vlan](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_vlan_module.rst)|Manage VLANs on VyOS network devices
+[vyos.vyos.vyos_vrf](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_vrf_module.rst)|VRF resource module
<!--end collection content-->
diff --git a/changelogs/fragments/t6838_vrf.yml b/changelogs/fragments/t6838_vrf.yml
new file mode 100644
index 00000000..9483e466
--- /dev/null
+++ b/changelogs/fragments/t6838_vrf.yml
@@ -0,0 +1,3 @@
+---
+minor_changes:
+ - vyos_vrf - Add VRF support
diff --git a/docs/vyos.vyos.vyos_config_module.rst b/docs/vyos.vyos.vyos_config_module.rst
index 1efbd38f..e2be25b9 100644
--- a/docs/vyos.vyos.vyos_config_module.rst
+++ b/docs/vyos.vyos.vyos_config_module.rst
@@ -134,6 +134,42 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>confirm</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>automatic</li>
+ <li>manual</li>
+ <li><div style="color: blue"><b>none</b>&nbsp;&larr;</div></li>
+ </ul>
+ </td>
+ <td>
+ <div>The <code>confirm</code> argument will tell vyos to revert to the previous configuration if not explicitly confirmed after applying the new config. When set to <code>automatic</code> this module will automatically confirm the configuration, if the current session remains working with the new config. When set to <code>manual</code>, this module does not issue the confirmation itself.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>confirm_timeout</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ <b>Default:</b><br/><div style="color: blue">10</div>
+ </td>
+ <td>
+ <div>Minutes to wait for confirmation before reverting the configuration. Does not apply when <code>confirm</code> is set to <code>none</code> .</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>lines</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -236,6 +272,11 @@ Examples
vyos.vyos.vyos_config:
src: vyos_template.j2
+ - name: revert after ten minutes, if connection is lost
+ vyos.vyos.vyos_config:
+ src: vyos_template.j2
+ confirm: automatic
+
- name: for idempotency, use full-form commands
vyos.vyos.vyos_config:
lines:
diff --git a/docs/vyos.vyos.vyos_vrf_module.rst b/docs/vyos.vyos.vyos_vrf_module.rst
new file mode 100644
index 00000000..a3fad8a3
--- /dev/null
+++ b/docs/vyos.vyos.vyos_vrf_module.rst
@@ -0,0 +1,5087 @@
+.. _vyos.vyos.vyos_vrf_module:
+
+
+******************
+vyos.vyos.vyos_vrf
+******************
+
+**VRF resource module**
+
+
+Version added: 1.0.0
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+Synopsis
+--------
+- This module manages vrf configuration on devices running Vyos
+
+
+
+
+Parameters
+----------
+
+.. raw:: html
+
+ <table border=0 cellpadding=0 class="documentation-table">
+ <tr>
+ <th colspan="9">Parameter</th>
+ <th>Choices/<font color="blue">Defaults</font></th>
+ <th width="100%">Comments</th>
+ </tr>
+ <tr>
+ <td colspan="9">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>config</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>List of vrf configuration.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td colspan="8">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>bind_to_all</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Enable binding services to all VRFs</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td colspan="8">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>instances</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Virtual Routing and Forwarding instance</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="7">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>address_family</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Address family configuration</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="6">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>afi</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>ipv4</li>
+ <li>ipv6</li>
+ </ul>
+ </td>
+ <td>
+ <div>Address family identifier</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="6">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>disable_forwarding</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disable forwarding for this address family</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="6">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>nht_no_resolve_via_default</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disable next-hop resolution via default route</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="6">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>route_maps</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>List of route maps for this address family</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>protocol</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>any</li>
+ <li>babel</li>
+ <li>bgp</li>
+ <li>eigrp</li>
+ <li>isis</li>
+ <li>ospf</li>
+ <li>rip</li>
+ <li>static</li>
+ </ul>
+ </td>
+ <td>
+ <div>Protocol to which the route map applies</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>rm_name</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>Route map name</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="7">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>description</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Description</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="7">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>disable</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Administratively disable interface</div>
+ <div style="font-size: small; color: darkgreen"><br/>aliases: disabled</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="7">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>name</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>VRF instance name</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="7">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>protocols</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Protocol configuration</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="6">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>bgp</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP configuration</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>as_number</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>AS number.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>bgp_params</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP parameters</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>always_compare_med</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Always compare MEDs from different neighbors</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>bestpath</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Default bestpath selection mechanism</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>as_path</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>confed</li>
+ <li>ignore</li>
+ </ul>
+ </td>
+ <td>
+ <div>AS-path attribute comparison parameters</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>compare_routerid</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Compare the router-id for identical EBGP paths</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>med</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>confed</li>
+ <li>missing-as-worst</li>
+ </ul>
+ </td>
+ <td>
+ <div>MED attribute comparison parameters</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>cluster_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Route-reflector cluster-id</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>confederation</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>AS confederation parameters</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>identifier</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Confederation AS identifier</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>peers</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Peer ASs in the BGP confederation</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>dampening</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Enable route-flap dampening</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>half_life</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Half-life penalty in seconds</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>max_suppress_time</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Maximum duration to suppress a stable route</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>re_use</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Time to start reusing a route</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>start_suppress_time</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>When to start suppressing a route</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>default</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP defaults</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>local_pref</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Default local preference</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_ipv4_unicast</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Deactivate IPv4 unicast for a peer by default
+ Deprecated: Unavailable after 1.4</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>deterministic_med</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Compare MEDs between different peers in the same AS</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>disable_network_import_check</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disable IGP route check for network statements</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>distance</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Administrative distances for BGP routes</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>prefix</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Administrative distance for a specific BGP prefix</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>type</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>external</li>
+ <li>internal</li>
+ <li>local</li>
+ </ul>
+ </td>
+ <td>
+ <div>Type of route</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <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">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>distance</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>enforce_first_as</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Require first AS in the path to match peer&#x27;s AS</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>graceful_restart</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Maximum time to hold onto restarting peer&#x27;s stale paths</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>log_neighbor_changes</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Log neighbor up/down changes and reset reason</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_client_to_client_reflection</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disable client to client route reflection</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_fast_external_failover</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disable immediate session reset if peer&#x27;s connected link goes down</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>router_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP router-id</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>scan_time</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP route scanner interval</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>neighbor</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP neighbor</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>address</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP neighbor address (v4/v6).</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>advertisement_interval</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Minimum interval for sending routing updates.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>capability</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Advertise capabilities to this neighbor.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>dynamic</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Advertise dynamic capability to this neighbor.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>extended_nexthop</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Advertise extended nexthop capability to this neighbor.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>default_originate</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Send default route to this neighbor</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>description</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Description of the neighbor</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>disable_capability_negotiation</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disbale capability negotiation with the neighbor</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>disable_connected_check</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disable check to see if EBGP peer&#x27;s address is a connected route.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>disable_send_community</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>extended</li>
+ <li>standard</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disable sending community attributes to this neighbor.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>ebgp_multihop</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Allow this EBGP neighbor to not be on a directly connected network. Specify the number hops.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>local_as</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>local as number not to be prepended to updates from EBGP peers</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>override_capability</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Ignore capability negotiation with specified neighbor.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>passive</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Do not initiate a session with this neighbor</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>password</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP MD5 password</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>peer_group</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>True if all the configs under this neighbor key is for peer group template.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>peer_group_name</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>IPv4 peer group for this peer</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>port</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Neighbor&#x27;s BGP port</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>remote_as</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Neighbor BGP AS number</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>shutdown</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Administratively shut down neighbor</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>solo</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Do not send back prefixes learned from the neighbor</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>strict_capability_match</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Enable strict capability negotiation</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>timers</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Neighbor timers</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>connect</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP connect timer for this neighbor.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>holdtime</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP hold timer for this neighbor</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>keepalive</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP keepalive interval for this neighbor</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>ttl_security</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Number of the maximum number of hops to the BGP peer</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>update_source</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Source IP of routing updates</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>timers</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>BGP protocol timers</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>holdtime</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Hold time interval</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>keepalive</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Keepalive interval</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="6">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>ospf</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 configuration</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>areas</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 area.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>area_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 area identity.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>area_type</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Area type.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>normal</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Normal OSPFv2 area.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>nssa</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>NSSA OSPFv2 area.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>default_cost</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Summary-default cost of NSSA area.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_summary</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Do not inject inter-area routes into stub.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>set</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Enabling NSSA.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>translate</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>always</li>
+ <li>candidate</li>
+ <li>never</li>
+ </ul>
+ </td>
+ <td>
+ <div>NSSA-ABR.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>stub</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Stub OSPFv2 area.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>default_cost</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Summary-default cost of stub area.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_summary</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Do not inject inter-area routes into stub.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>set</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Enabling stub.</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>authentication</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>plaintext-password</li>
+ <li>md5</li>
+ </ul>
+ </td>
+ <td>
+ <div>OSPFv2 area authentication type.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>network</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 network.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>address</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>OSPFv2 IPv4 network address.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>range</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Summarize routes matching prefix (border routers only).</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>address</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>border router IPv4 address.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>cost</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Metric for this range.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>not_advertise</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Don&#x27;t advertise this range.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>substitute</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Announce area range (IPv4 address) as another prefix.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>shortcut</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>default</li>
+ <li>disable</li>
+ <li>enable</li>
+ </ul>
+ </td>
+ <td>
+ <div>Area&#x27;s shortcut mode.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>virtual_link</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Virtual link address.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>address</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>virtual link address.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>authentication</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 area authentication type.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>md5</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>MD5 key id based authentication.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>key_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>MD5 key id.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>md5_key</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>MD5 key.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>plaintext_password</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Plain text password.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>dead_interval</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Interval after which a neighbor is declared dead.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>hello_interval</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Interval between hello packets.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>retransmit_interval</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Interval between retransmitting lost link state advertisements.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>transmit_delay</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Link state transmit delay.</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>auto_cost</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Calculate OSPFv2 interface cost according to bandwidth.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>reference_bandwidth</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Reference bandwidth cost in Mbits/sec.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>default_information</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Control distribution of default information.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>originate</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Distribute a default route.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>always</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Always advertise default route.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>metric</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 default metric.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>metric_type</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 Metric types for default routes.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>route_map</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Route map references.</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>default_metric</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Metric of redistributed routes</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>distance</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Administrative distance.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>global</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Global OSPFv2 administrative distance.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>ospf</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 administrative distance.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>external</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Distance for external routes.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>inter_area</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Distance for inter-area routes.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>intra_area</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Distance for intra-area routes.</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>log_adjacency_changes</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>detail</li>
+ </ul>
+ </td>
+ <td>
+ <div>Log changes in adjacency state.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>max_metric</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 maximum/infinite-distance metric.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>router_lsa</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Advertise own Router-LSA with infinite distance (stub router).</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>administrative</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Administratively apply, for an indefinite period.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>on_shutdown</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Time to advertise self as stub-router.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>on_startup</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Time to advertise self as stub-router</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>mpls_te</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>MultiProtocol Label Switching-Traffic Engineering (MPLS-TE) parameters.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>enabled</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Enable MPLS-TE functionality.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>router_address</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Stable IP address of the advertising router.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>neighbor</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Neighbor IP address.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>neighbor_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Identity (number/IP address) of neighbor.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>poll_interval</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Seconds between dead neighbor polling interval.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>priority</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Neighbor priority.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>parameters</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 specific parameters.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>abr_type</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>cisco</li>
+ <li>ibm</li>
+ <li>shortcut</li>
+ <li>standard</li>
+ </ul>
+ </td>
+ <td>
+ <div>OSPFv2 ABR Type.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>opaque_lsa</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Enable the Opaque-LSA capability (rfc2370).</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>rfc1583_compatibility</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Enable rfc1583 criteria for handling AS external routes.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>router_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Override the default router identifier.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>passive_interface</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=string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Suppress routing updates on an interface.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>passive_interface_exclude</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=string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Interface to exclude when using passive-interface default.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>redistribute</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Redistribute information from another routing protocol.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>metric</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Metric for redistribution routes.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>metric_type</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 Metric types.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>route_map</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Route map references.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>route_type</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>bgp</li>
+ <li>connected</li>
+ <li>kernel</li>
+ <li>rip</li>
+ <li>static</li>
+ </ul>
+ </td>
+ <td>
+ <div>Route type to redistribute.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>route_map</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=string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Filter routes installed in local route map.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>timers</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Adjust routing timers.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>refresh</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Adjust refresh parameters.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>timers</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>refresh timer.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>throttle</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Throttling adaptive timers.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>spf</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv2 SPF timers.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>delay</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Delay (msec) from first change received till SPF calculation.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>initial_holdtime</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Initial hold time(msec) between consecutive SPF calculations.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>max_holdtime</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>maximum hold time (sec).</div>
+ </td>
+ </tr>
+
+
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="6">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>ospfv3</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv3 configuration</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>areas</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv3 area.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>area_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv3 Area name/identity.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>export_list</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Name of export-list.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>import_list</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Name of import-list.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>interface</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Enable OSPVv3 on an interface for this area.</div>
+ <div style="font-size: small; color: darkgreen"><br/>aliases: interfaces</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>name</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Interface name.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>range</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Summarize routes matching prefix (border routers only).</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>address</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>border router IPv4 address.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>advertise</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Advertise this range.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>not_advertise</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Don&#x27;t advertise this range.</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>parameters</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>OSPFv3 specific parameters.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>router_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Override the default router identifier.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>redistribute</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Redistribute information from another routing protocol.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>route_map</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Route map references.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>route_type</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>bgp</li>
+ <li>connected</li>
+ <li>kernel</li>
+ <li>ripng</li>
+ <li>static</li>
+ </ul>
+ </td>
+ <td>
+ <div>Route type to redistribute.</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="6">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>static</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Static routes configuration</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="5">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>address_families</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>A dictionary specifying the address family to which the static route(s) belong.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>afi</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>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>ipv4</li>
+ <li>ipv6</li>
+ </ul>
+ </td>
+ <td>
+ <div>Specifies the type of route.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="4">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>routes</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>A dictionary that specify the static route configurations.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>blackhole_config</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Configured to silently discard packets.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>distance</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Distance for the route.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>type</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>This is to configure only blackhole.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>dest</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>An IPv4/v6 address in CIDR notation that specifies the destination network for the static route.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>next_hops</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>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Next hops to the specified destination.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>admin_distance</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Distance value for the route.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>enabled</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">boolean</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>no</li>
+ <li>yes</li>
+ </ul>
+ </td>
+ <td>
+ <div>Disable IPv4/v6 next-hop static route.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>forward_router_address</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The IP address of the next hop that can be used to reach the destination network.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>interface</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Name of the outgoing interface.</div>
+ </td>
+ </tr>
+
+
+
+
+
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="7">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>table_id</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Routing table associated with this instance</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td class="elbow-placeholder"></td>
+ <td colspan="7">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>vni</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">integer</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Virtual Network Identifier</div>
+ </td>
+ </tr>
+
+
+ <tr>
+ <td colspan="9">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>running_config</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>This option is used only with state <em>parsed</em>.</div>
+ <div>The value of this option should be the output received from the VYOS device by executing the command <b>show configuration commands | match &quot;set vrf&quot;</b>.</div>
+ <div>The states <em>replaced</em> and <em>overridden</em> have identical behaviour for this module.</div>
+ <div>The state <em>parsed</em> reads the configuration from <code>show configuration commands | match &quot;set vrf&quot;</code> option and transforms it into Ansible structured data as per the resource module&#x27;s argspec and the value is then returned in the <em>parsed</em> key within the result.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="9">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>state</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li>deleted</li>
+ <li><div style="color: blue"><b>merged</b>&nbsp;&larr;</div></li>
+ <li>overridden</li>
+ <li>replaced</li>
+ <li>gathered</li>
+ <li>rendered</li>
+ <li>parsed</li>
+ </ul>
+ </td>
+ <td>
+ <div>The state the configuration should be left in.</div>
+ </td>
+ </tr>
+ </table>
+ <br/>
+
+
+Notes
+-----
+
+.. note::
+ - Tested against vyos 1.4.2 and 1.5-stream-2025-Q1
+ - This module works with connection ``network_cli``.
+
+
+
+Examples
+--------
+
+.. code-block:: yaml
+
+ # # -------------------
+ # # 1. Using merged
+ # # -------------------
+
+ # # Before state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue disable
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # vyos@vyos:~$
+
+ # # Task
+ # # -------------
+ # - name: Merge provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # instances:
+ # - name: "vrf-green"
+ # description: "green-vrf"
+ # table_id: 110
+ # vni: 1010
+
+ # Task output:
+ # -------------
+ # "after": {
+ # "bind_to_all": false,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": true,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "description": "green-vrf",
+ # "disable": false,
+ # "name": "vrf-green",
+ # "table_id": 110,
+ # "vni": 1010
+ # }
+ # ]
+ # },
+ # "before": {
+ # "bind_to_all": false,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": true,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # }
+ # ]
+ # },
+ # "changed": true,
+ # "commands": [
+ # "set vrf name vrf-green table 110",
+ # "set vrf name vrf-green vni 1010",
+ # "set vrf name vrf-green description green-vrf"
+ # ]
+
+ # After state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue disable
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-green description 'green-vrf'
+ # set vrf name vrf-green table '110'
+ # set vrf name vrf-green vni '1010'
+ # vyos@vyos:~$
+
+ # # -------------------
+ # # 2. Using replaced
+ # # -------------------
+
+ # # Before state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+
+ # # Task
+ # # -------------
+ # - name: Merge provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # bind_to_all: true
+ # instances:
+ # - name: "vrf-blue"
+ # description: "blue-vrf"
+ # disable: false
+ # table_id: 100
+ # vni: 1002
+ # - name: "vrf-red"
+ # description: "red-vrf"
+ # disable: false
+ # table_id: 101
+ # vni: 1001
+ # address_family:
+ # - afi: "ipv4"
+ # disable_forwarding: false
+ # route_maps:
+ # - rm_name: "rm1"
+ # protocol: "ospf"
+ # - afi: "ipv6"
+ # nht_no_resolve_via_default: true
+ # state: replaced
+
+ # # Task output:
+ # # -------------
+ # "after": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1002
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": false,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "ospf",
+ # "rm_name": "rm1"
+ # },
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # },
+ # {
+ # "afi": "ipv6",
+ # "disable_forwarding": false,
+ # "nht_no_resolve_via_default": true
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": false,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "before": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "changed": true,
+ # "commands": [
+ # "set vrf name vrf-blue vni 1002",
+ # "delete vrf name vrf-red disable",
+ # "set vrf name vrf-red ip protocol ospf route-map rm1",
+ # "delete vrf name vrf-red ip disable-forwarding",
+ # "set vrf name vrf-red ipv6 nht no-resolve-via-default"
+ # ]
+
+ # After state:
+ # # -------------
+ # vyos@vyos:~$
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1002'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red ip protocol ospf route-map 'rm1'
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red ipv6 nht no-resolve-via-default
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+
+ # # -------------------
+ # # 3. Using overridden
+ # # -------------------
+
+ # # Before state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+ # Task
+ # -------------
+ # - name: Overridden provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # bind_to_all: true
+ # instances:
+ # - name: "vrf-blue"
+ # description: "blue-vrf"
+ # disable: true
+ # table_id: 100
+ # vni: 1000
+ # - name: "vrf-red"
+ # description: "red-vrf"
+ # disable: true
+ # table_id: 101
+ # vni: 1001
+ # address_family:
+ # - afi: "ipv4"
+ # disable_forwarding: false
+ # route_maps:
+ # - rm_name: "rm1"
+ # protocol: "rip"
+ # - afi: "ipv6"
+ # nht_no_resolve_via_default: false
+ # state: overridden
+
+ # # Task output:
+ # # -------------
+ # "after": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": true,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": false,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "before": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "changed": true,
+ # "commands": [
+ # "delete vrf name vrf-blue",
+ # "commit",
+ # "delete vrf name vrf-red",
+ # "commit",
+ # "set vrf name vrf-blue table 100",
+ # "set vrf name vrf-blue vni 1000",
+ # "set vrf name vrf-blue description blue-vrf",
+ # "set vrf name vrf-blue disable",
+ # "set vrf name vrf-red table 101",
+ # "set vrf name vrf-red vni 1001",
+ # "set vrf name vrf-red description red-vrf",
+ # "set vrf name vrf-red disable",
+ # "set vrf name vrf-red ip protocol rip route-map rm1"
+ # ]
+
+ # After state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue disable
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+ # 4. Using gathered
+ # -------------------
+
+ # # Before state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+ # Task
+ # -------------
+ # - name: Gather provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # state: gathered
+
+ # # Task output:
+ # # -------------
+ # "gathered": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # }
+
+ # After state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+
+ # # -------------------
+ # # 5. Using deleted
+ # # -------------------
+
+ # # Before state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+ # # Task
+ # # -------------
+ # - name: Replace provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # bind_to_all: false
+ # instances:
+ # - name: "vrf-blue"
+ # state: deleted
+
+
+ # # Task output:
+ # # -------------
+ # "after": {
+ # "bind_to_all": false,
+ # "instances": [
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "before": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "changed": true,
+ # "commands": [
+ # "delete vrf bind-to-all",
+ # "delete vrf name vrf-blue"
+ # ]
+
+ # After state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+ # # -------------------
+ # # 6. Using rendered
+ # # -------------------
+
+ # # Before state:
+ # # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+ # Task
+ # -------------
+ # - name: Render provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # bind_to_all: true
+ # instances:
+ # - name: "vrf-green"
+ # description: "green-vrf"
+ # disabled: true
+ # table_id: 105
+ # vni: 1000
+ # - name: "vrf-amber"
+ # description: "amber-vrf"
+ # disable: false
+ # table_id: 111
+ # vni: 1001
+ # address_family:
+ # - afi: "ipv4"
+ # disable_forwarding: true
+ # route_maps:
+ # - rm_name: "rm1"
+ # protocol: "ospf"
+ # - afi: "ipv6"
+ # nht_no_resolve_via_default: false
+ # state: rendered
+
+ # # Task output:
+ # # -------------
+ # "rendered": [
+ # "set vrf bind-to-all",
+ # "set vrf name vrf-green table 105",
+ # "set vrf name vrf-green vni 1000",
+ # "set vrf name vrf-green description green-vrf",
+ # "set vrf name vrf-green disable",
+ # "set vrf name vrf-amber table 111",
+ # "set vrf name vrf-amber vni 1001",
+ # "set vrf name vrf-amber description amber-vrf",
+ # "set vrf name vrf-amber ip protocol ospf route-map rm1",
+ # "set vrf name vrf-amber ip disable-forwarding"
+ # ]
+
+ # # -------------------
+ # # 7. Using parsed
+ # # -------------------
+
+ # # vrf_parsed.cfg:
+ # # -------------
+ # set vrf bind-to-all
+ # set vrf name vrf1 description 'red'
+ # set vrf name vrf1 disable
+ # set vrf name vrf1 table 101
+ # set vrf name vrf1 vni 501
+ # set vrf name vrf2 description 'blah2'
+ # set vrf name vrf2 disable
+ # set vrf name vrf2 table 102
+ # set vrf name vrf2 vni 102
+ # set vrf name vrf1 ip disable-forwarding
+ # set vrf name vrf1 ip nht no-resolve-via-default
+ # set vrf name vrf-red ip protocol ospf route-map 'rm1'
+ # set vrf name vrf-red ipv6 nht no-resolve-via-default
+
+ # Task:
+ # -------------
+ # - name: Parse provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # running_config: "{{ lookup('file', './vrf_parsed.cfg') }}"
+ # state: parsed
+
+
+ # # Task output:
+ # # -------------
+ # "parsed": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": true
+ # }
+ # ],
+ # "description": "red",
+ # "disable": true,
+ # "name": "vrf1"
+ # },
+ # {
+ # "description": "blah2",
+ # "disable": true,
+ # "name": "vrf2"
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": false,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "ospf",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # },
+ # {
+ # "afi": "ipv6",
+ # "disable_forwarding": false,
+ # "nht_no_resolve_via_default": true
+ # }
+ # ],
+ # "disable": false,
+ # "name": "vrf-red"
+ # }
+ # ]
+ # }
+
+
+
+Return Values
+-------------
+Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
+
+.. raw:: html
+
+ <table border=0 cellpadding=0 class="documentation-table">
+ <tr>
+ <th colspan="1">Key</th>
+ <th>Returned</th>
+ <th width="100%">Description</th>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>after</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>when changed</td>
+ <td>
+ <div>The resulting configuration after module execution.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>before</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>merged</code>, <code>replaced</code>, <code>overridden</code>, <code>deleted</code> or <code>purged</code></td>
+ <td>
+ <div>The configuration prior to the module execution.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>commands</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>merged</code>, <code>replaced</code>, <code>overridden</code>, <code>deleted</code> or <code>purged</code></td>
+ <td>
+ <div>The set of commands pushed to the remote device.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">[&#x27;set system ntp server server1 dynamic&#x27;, &#x27;set system ntp server server1 prefer&#x27;, &#x27;set system ntp server server2 noselect&#x27;, &#x27;set system ntp server server2 preempt&#x27;, &#x27;set system ntp server server_add preempt&#x27;]</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>gathered</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>gathered</code></td>
+ <td>
+ <div>Facts about the network resource gathered from the remote device as structured data.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>parsed</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>parsed</code></td>
+ <td>
+ <div>The device native config provided in <em>running_config</em> option parsed into structured data as per module argspec.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>rendered</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>rendered</code></td>
+ <td>
+ <div>The provided configuration in the task rendered in device-native format (offline).</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">[&#x27;set system ntp server server1 dynamic&#x27;, &#x27;set system ntp server server1 prefer&#x27;, &#x27;set system ntp server server2 noselect&#x27;, &#x27;set system ntp server server2 preempt&#x27;, &#x27;set system ntp server server_add preempt&#x27;]</div>
+ </td>
+ </tr>
+ </table>
+ <br/><br/>
+
+
+Status
+------
+
+
+Authors
+~~~~~~~
+
+- Evgeny Molotkov (@omnom62)
diff --git a/meta/runtime.yml b/meta/runtime.yml
index 58899674..36579e05 100644
--- a/meta/runtime.yml
+++ b/meta/runtime.yml
@@ -64,3 +64,5 @@ plugin_routing:
redirect: vyos.vyos.vyos_user
vlan:
redirect: vyos.vyos.vyos_vlan
+ vrf:
+ redirect: vyos.vyos.vyos_vrf
diff --git a/plugins/action/vrf.py b/plugins/action/vrf.py
new file mode 120000
index 00000000..331a791f
--- /dev/null
+++ b/plugins/action/vrf.py
@@ -0,0 +1 @@
+vyos.py \ No newline at end of file
diff --git a/plugins/module_utils/network/vyos/argspec/vrf/__init__.py b/plugins/module_utils/network/vyos/argspec/vrf/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/vrf/__init__.py
diff --git a/plugins/module_utils/network/vyos/argspec/vrf/vrf.py b/plugins/module_utils/network/vyos/argspec/vrf/vrf.py
new file mode 100644
index 00000000..e24fd537
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/vrf/vrf.py
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+# Copyright 2024 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the
+# cli_rm_builder.
+#
+# Manually editing this file is not advised.
+#
+# To update the argspec make the desired changes
+# in the module docstring and re-run
+# cli_rm_builder.
+#
+#############################################
+
+"""
+The arg spec for the vyos_vrf module
+"""
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.bgp_global.bgp_global import (
+ Bgp_globalArgs,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv2.ospfv2 import (
+ Ospfv2Args,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv3.ospfv3 import (
+ Ospfv3Args,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.static_routes.static_routes import (
+ Static_routesArgs,
+)
+
+
+class VrfArgs(object): # pylint: disable=R0903
+ """The arg spec for the vyos_vrf module"""
+
+ bgp_argument_spec = Bgp_globalArgs.argument_spec["config"]
+ static_routes_argument_spec = Static_routesArgs.argument_spec["config"]
+ ospfv2_argument_spec = Ospfv2Args.argument_spec["config"]
+ ospfv3_argument_spec = Ospfv3Args.argument_spec["config"]
+
+ argument_spec = {
+ "config": {
+ "type": "dict",
+ "options": {
+ "bind_to_all": {"type": "bool", "default": False},
+ "instances": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "name": {"required": True, "type": "str"},
+ "description": {"type": "str"},
+ "disable": {
+ "aliases": ["disabled"],
+ "default": False,
+ "type": "bool",
+ },
+ "table_id": {"type": "int"},
+ "vni": {"type": "int"},
+ "address_family": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "afi": {
+ "type": "str",
+ "choices": ["ipv4", "ipv6"],
+ },
+ "disable_forwarding": {"type": "bool", "default": False},
+ "nht_no_resolve_via_default": {"type": "bool", "default": False},
+ "route_maps": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "rm_name": {"type": "str", "required": True},
+ "protocol": {
+ "type": "str",
+ "choices": [
+ "any",
+ "babel",
+ "bgp",
+ "eigrp",
+ "isis",
+ "ospf",
+ "rip",
+ "static",
+ ],
+ },
+ },
+ },
+ },
+ },
+ "protocols": {
+ # "type": "list", # sanity
+ # "elements": "dict",
+ "type": "dict",
+ "options": {
+ "bgp": bgp_argument_spec,
+ "ospf": ospfv2_argument_spec,
+ "ospfv3": ospfv3_argument_spec,
+ "static": static_routes_argument_spec,
+ },
+ },
+ },
+ },
+ },
+ },
+ "state": {
+ "type": "str",
+ "choices": [
+ "deleted",
+ "merged",
+ "replaced",
+ "overridden",
+ "gathered",
+ "rendered",
+ "parsed",
+ ],
+ "default": "merged",
+ },
+ "running_config": {"type": "str"},
+ } # pylint: disable=C0301
diff --git a/plugins/module_utils/network/vyos/config/vrf/__init__.py b/plugins/module_utils/network/vyos/config/vrf/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/vrf/__init__.py
diff --git a/plugins/module_utils/network/vyos/config/vrf/vrf.old b/plugins/module_utils/network/vyos/config/vrf/vrf.old
new file mode 100644
index 00000000..b9f56cc6
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/vrf/vrf.old
@@ -0,0 +1,313 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+#
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+"""
+The vyos_vrf config file.
+It is in this file where the current configuration (as dict)
+is compared to the provided configuration (as dict) and the command set
+necessary to bring the current configuration to its desired end-state is
+created.
+"""
+
+import importlib
+
+from copy import deepcopy
+
+from ansible.module_utils.six import iteritems
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
+ ResourceModule,
+)
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.bgp_global.bgp_global import (
+ Bgp_global,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.vrf import (
+ VrfTemplate,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import combine
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import (
+ LooseVersion,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import get_os_version
+
+
+# from ansible.plugins.filter.core import combine
+
+
+class Vrf(ResourceModule):
+ """
+ The vyos_vrf config class
+ """
+
+ def __init__(self, module):
+ super(Vrf, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="vrf",
+ tmplt=VrfTemplate(),
+ )
+ self.parsers = [
+ "bind_to_all",
+ ]
+ self.bgp = Bgp_global(module)
+
+ def _validate_template(self):
+ version = get_os_version(self._module)
+ if LooseVersion(version) >= LooseVersion("1.4"):
+ self._tmplt = VrfTemplate()
+ else:
+ self._module.fail_json(msg="VRF is not supported in this version of VyOS")
+
+ def parse(self):
+ """override parse to check template"""
+ self._validate_template()
+ return super().parse()
+
+ def get_parser(self, name):
+ """get_parsers"""
+ self._validate_template()
+ return super().get_parser(name)
+
+ def execute_module(self):
+ """Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ if self.state not in ["parsed", "gathered"]:
+ self.generate_commands()
+ self.run_commands()
+
+ return self.result
+
+ def generate_commands(self):
+ """Generate configuration commands to send based on
+ want, have and desired state.
+ """
+ wantd = {}
+ haved = {}
+ wantd = deepcopy(self.want)
+ haved = deepcopy(self.have)
+
+ # self._module.fail_json(msg="WanT: " + str(self.want) + "**** H: " + str(self.have))
+
+ # if state is merged, merge want onto have and then compare
+ if self.state in ["merged", "replaced"]:
+ # wantd = dict_merge(wantd, haved)
+ # wantd = haved | combine(wantd, recursive=True)
+ wantd = combine(haved, wantd, recursive=True)
+ # self._module.fail_json(msg="Want: " + str(wantd) + "**** H: " + str(haved))
+
+ # if state is deleted, delete and empty out wantd
+ if self.state == "deleted":
+ w = deepcopy(wantd)
+ if w == {} and haved != {}:
+ self.commands = ["delete vrf"]
+ return
+ for k, want in iteritems(w):
+ if not (k in haved and haved[k]):
+ del wantd[k]
+ else:
+ if isinstance(want, list):
+ for entry in want:
+ wname = entry.get("name")
+ haved["instances"] = [
+ i for i in haved.get("instances", []) if i.get("name") != wname
+ ]
+ self.commands.append("delete vrf name {}".format(wname))
+ else:
+ self.commands.append("delete vrf {}".format(k.replace("_", "-")))
+ del wantd[k]
+
+ if self.state == "overridden":
+ w = deepcopy(wantd)
+ h = deepcopy(haved)
+ for k, want in iteritems(w):
+ if k in haved and haved[k] != want:
+ if isinstance(want, list):
+ for entry in want:
+ wname = entry.get("name")
+ hdict = next(
+ (inst for inst in haved["instances"] if inst["name"] == wname),
+ None,
+ )
+ if entry != hdict:
+ # self._module.fail_json(msg="Want: " + str(entry) + "**** H: " + str(hdict))
+ haved["instances"] = [
+ i for i in haved.get("instances", []) if i.get("name") != wname
+ ]
+ self.commands.append("delete vrf name {}".format(wname))
+ self.commands.append("commit")
+
+ for k, want in iteritems(wantd):
+ if isinstance(want, list):
+ self._compare_instances(want=want, have=haved.pop(k, {}))
+ self.compare(
+ parsers=self.parsers,
+ want={k: want},
+ have={k: haved.pop(k, {})},
+ )
+ self._module.fail_json(msg=self.commands)
+
+ def _compare_instances(self, want, have):
+ """Compare the instances of the VRF"""
+ parsers = [
+ "table_id",
+ "vni",
+ "description",
+ "disable_vrf",
+ ]
+ # self._module.fail_json(msg="want: " + str(want) + "**** have: " + str(have))
+
+ for entry in want:
+ h = {}
+ wname = entry.get("name")
+ # h = next((vrf for vrf in have if vrf["name"] == wname), {})
+ h = {
+ k: v
+ for vrf in have
+ if vrf.get("name") == wname
+ for k, v in vrf.items()
+ if k != "address_family"
+ }
+ self.compare(parsers=parsers, want=entry, have=h)
+
+ if "address_family" in entry:
+ wafi = {"name": wname, "address_family": entry.get("address_family", [])}
+ # hdict = next((item for item in have if item["name"] == wname), None)
+ hdict = next((d for d in have if d.get("name") == wname), None)
+
+ hafi = {
+ "name": (hdict or {"name": wname})["name"],
+ "address_family": hdict.get("address_family", []) if hdict else [],
+ }
+
+ # self._module.fail_json(msg="wafi: " + str(wafi) + "**** hafi: " + str(hafi))
+
+ self._compare_addr_family(wafi, hafi)
+
+ if "protocols" in entry:
+ for protocol_name in entry["protocols"]:
+ protocol_module = self._load_protocol_module(protocol_name)
+ w_p_dict = entry["protocols"][protocol_name]
+ h_p_dict = next(
+ (
+ v.get("protocols", {}).get(protocol_name)
+ for v in have
+ if v.get("name") == wname
+ ),
+ {},
+ )
+ if protocol_name == "bgp":
+ protocol_module._validate_template()
+ protocol_module.want = w_p_dict
+ protocol_module.have = h_p_dict
+ protocol_module.generate_commands()
+ elif protocol_name in [
+ # "ospf",
+ # "ospfv3",
+ "static",
+ ]:
+ self._module.fail_json(msg=str(protocol_module))
+ protocol_module._module.params["config"] = w_p_dict
+ protocol_module.state = self.state
+ self._module.fail_json(msg=str(protocol_module.set_config(h_p_dict)))
+
+ protocol_module.commands = protocol_module.set_config(h_p_dict)
+ self.commands.extend(
+ [
+ cmd.replace("protocols", "vrf name " + wname + " protocols", 1)
+ for cmd in protocol_module.commands
+ ],
+ )
+ protocol_module = None # Clear the module to free resources
+
+ def _compare_addr_family(self, want, have):
+ """Compare the address families of the VRF"""
+ afi_parsers = [
+ # "address_family",
+ "disable_forwarding",
+ "disable_nht",
+ ]
+ # self._module.fail_json(msg="wAfi: " + str(want) + "**** hAfi: " + str(have))
+
+ wafi = self.afi_to_list(want)
+ hafi = self.afi_to_list(have)
+
+ lookup = {(d["name"], d["afi"]): d for d in hafi}
+ pairs = [(d1, lookup.get((d1["name"], d1["afi"]), {})) for d1 in wafi]
+
+ for wafd, hafd in pairs:
+ # self._module.fail_json(msg="wAfd: " + str(wafd) + "**** hAfd: " + str(hafd))
+ if "route_maps" in wafd:
+ self._compare_route_maps(wafd, hafd)
+ self.compare(parsers=afi_parsers, want=wafd, have=hafd)
+ # self.compare(parsers=afi_parsers, want=wafi, have=hafi)
+
+ def afi_to_list(self, data):
+ """Convert address family dict to list"""
+
+ return [
+ {"name": data["name"], **{**af, "afi": "ip" if af["afi"] == "ipv4" else af["afi"]}}
+ for af in data["address_family"]
+ ]
+
+ def _compare_route_maps(self, wafd, hafd):
+ want_rms = wafd.get("route_maps", [])
+ have_rms = hafd.get("route_maps", [])
+
+ for want in want_rms:
+ match = next(
+ (
+ h
+ for h in have_rms
+ if h["rm_name"] == want["rm_name"] and h["protocol"] == want["protocol"]
+ ),
+ {},
+ )
+ base = {"name": wafd["name"], "afi": wafd["afi"]}
+
+ self.compare(
+ parsers="route_maps",
+ want={**base, "route_maps": want},
+ have={**base, "route_maps": match},
+ )
+
+ def _load_protocol_module(self, protocol_name):
+ if protocol_name == "bgp":
+ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.bgp_global.bgp_global import (
+ Bgp_global,
+ )
+
+ return Bgp_global(self._module)
+ elif protocol_name == "ospf":
+ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv2.ospfv2 import (
+ Ospfv2,
+ )
+
+ return Ospfv2(self._module)
+ elif protocol_name == "ospfv3":
+ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv3.ospfv3 import (
+ Ospfv3,
+ )
+
+ return Ospfv3(self._module)
+ elif protocol_name == "static":
+ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.static_routes.static_routes import (
+ Static_routes,
+ )
+
+ return Static_routes(self._module)
+ else:
+ self._module.fail_json(msg="The protocol is not supported")
diff --git a/plugins/module_utils/network/vyos/config/vrf/vrf.py b/plugins/module_utils/network/vyos/config/vrf/vrf.py
new file mode 100644
index 00000000..aa4329d9
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/vrf/vrf.py
@@ -0,0 +1,308 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+#
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+"""
+The vyos_vrf config file.
+It is in this file where the current configuration (as dict)
+is compared to the provided configuration (as dict) and the command set
+necessary to bring the current configuration to its desired end-state is
+created.
+"""
+
+from copy import deepcopy
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
+ ResourceModule,
+)
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.bgp_global.bgp_global import (
+ Bgp_global,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv2.ospfv2 import (
+ Ospfv2,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv3.ospfv3 import (
+ Ospfv3,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.static_routes.static_routes import (
+ Static_routes,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.vrf import (
+ VrfTemplate,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import combine
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import (
+ LooseVersion,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import get_os_version
+
+
+class Vrf(ResourceModule):
+ """
+ The vyos_vrf config class
+ """
+
+ def __init__(self, module):
+ super(Vrf, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="vrf",
+ tmplt=VrfTemplate(),
+ )
+ self.parsers = [
+ "bind_to_all",
+ ]
+
+ def _validate_template(self):
+ version = get_os_version(self._module)
+ if LooseVersion(version) >= LooseVersion("1.4"):
+ self._tmplt = VrfTemplate()
+ else:
+ self._module.fail_json(msg="VRF is not supported in this version of VyOS")
+
+ def parse(self):
+ """override parse to check template"""
+ self._validate_template()
+ return super().parse()
+
+ def get_parser(self, name):
+ """get_parsers"""
+ self._validate_template()
+ return super().get_parser(name)
+
+ def execute_module(self):
+ """Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ if self.state not in ["parsed", "gathered"]:
+ self.generate_commands()
+ self.run_commands()
+
+ return self.result
+
+ def generate_commands(self):
+ """Generate configuration commands to send based on
+ want, have and desired state.
+ """
+ wantd = {}
+ haved = {}
+ wantd = deepcopy(self.want)
+ haved = deepcopy(self.have)
+
+ # if state is merged, merge want onto have and then compare
+ if self.state in ["merged", "replaced"]:
+
+ wantd = combine(haved, wantd, recursive=True)
+
+ # if state is deleted, delete and empty out wantd
+ if self.state == "deleted":
+ w = deepcopy(wantd)
+ if w == {} and haved != {}:
+ self.commands = ["delete vrf"]
+ return
+ for k, want in w.items():
+ if not (k in haved and haved[k]):
+ del wantd[k]
+ else:
+ if isinstance(want, list):
+ for entry in want:
+ wname = entry.get("name")
+ haved["instances"] = [
+ i for i in haved.get("instances", []) if i.get("name") != wname
+ ]
+ self.commands.append("delete vrf name {}".format(wname))
+ else:
+ self.commands.append("delete vrf {}".format(k.replace("_", "-")))
+ del wantd[k]
+
+ if self.state == "overridden":
+ w = deepcopy(wantd)
+ h = deepcopy(haved)
+ for k, want in w.items():
+ if k in haved and haved[k] != want:
+ if isinstance(want, list):
+ for entry in want:
+ wname = entry.get("name")
+ hdict = next(
+ (inst for inst in haved["instances"] if inst["name"] == wname),
+ None,
+ )
+ wantc = self._canonicalise(entry)
+ havec = self._canonicalise(hdict or {})
+
+ if wantc != havec:
+ haved["instances"] = [
+ i for i in haved.get("instances", []) if i.get("name") != wname
+ ]
+ self.commands.append("delete vrf name {}".format(wname))
+ self.commands.append("commit")
+
+ for k, want in wantd.items():
+ if isinstance(want, list):
+ self._compare_instances(want=want, have=haved.pop(k, {}))
+ self.compare(
+ parsers=self.parsers,
+ want={k: want},
+ have={k: haved.pop(k, {})},
+ )
+
+ def _compare_instances(self, want, have):
+ """Compare the instances of the VRF"""
+ parsers = [
+ "table_id",
+ "vni",
+ "description",
+ "disable_vrf",
+ ]
+
+ for entry in want:
+ h = {}
+ wname = entry.get("name")
+ h = {
+ k: v
+ for vrf in have
+ if vrf.get("name") == wname
+ for k, v in vrf.items()
+ if k != "address_family"
+ }
+ self.compare(parsers=parsers, want=entry, have=h)
+
+ if "address_family" in entry:
+ wafi = {"name": wname, "address_family": entry.get("address_family", [])}
+ hdict = next((d for d in have if d.get("name") == wname), None)
+
+ hafi = {
+ "name": (hdict or {"name": wname})["name"],
+ "address_family": hdict.get("address_family", []) if hdict else [],
+ }
+
+ self._compare_addr_family(wafi, hafi)
+
+ if "protocols" in entry:
+ for protocol_name in entry["protocols"]:
+
+ w_p_dict = entry["protocols"][protocol_name]
+
+ h_p_dict = next(
+ (
+ v.get("protocols", {}).get(protocol_name, {})
+ for v in have
+ if v.get("name") == wname
+ ),
+ {},
+ )
+ if protocol_name == "bgp":
+ bgp_module = Bgp_global(self._module)
+ bgp_module._validate_template()
+ bgp_module.want = w_p_dict
+ bgp_module.have = h_p_dict
+ bgp_module.generate_commands()
+ protocol_commands = bgp_module.commands
+ elif protocol_name == "ospf":
+ ospfv2_module = Ospfv2(self._module)
+ ospfv2_module._module.params["config"] = w_p_dict
+ ospfv2_module.state = self.state
+ protocol_commands = ospfv2_module.set_config(h_p_dict)
+ elif protocol_name == "ospfv3":
+ ospfv3_module = Ospfv3(self._module)
+ ospfv3_module._module.params["config"] = w_p_dict
+ ospfv3_module.state = self.state
+ protocol_commands = ospfv3_module.set_config(h_p_dict)
+ elif protocol_name == "static":
+ static_routes_module = Static_routes(self._module)
+ static_routes_module._module.params["config"] = w_p_dict
+ static_routes_module.state = self.state
+ protocol_commands = static_routes_module.set_config(h_p_dict)
+ else:
+ self._module.fail_json(
+ msg="The protocol {} is not supported".format(protocol_name),
+ )
+ self.commands.extend(
+ [
+ cmd.replace("protocols", "vrf name " + wname + " protocols", 1)
+ for cmd in protocol_commands
+ ],
+ )
+
+ def _compare_addr_family(self, want, have):
+ """Compare the address families of the VRF"""
+ afi_parsers = [
+ "disable_forwarding",
+ "disable_nht",
+ ]
+
+ wafi = self.afi_to_list(want)
+ hafi = self.afi_to_list(have)
+
+ lookup = {(d["name"], d["afi"]): d for d in hafi}
+ pairs = [(d1, lookup.get((d1["name"], d1["afi"]), {})) for d1 in wafi]
+
+ for wafd, hafd in pairs:
+ if "route_maps" in wafd:
+ self._compare_route_maps(wafd, hafd)
+ self.compare(parsers=afi_parsers, want=wafd, have=hafd)
+
+ def afi_to_list(self, data):
+ """Convert address family dict to list"""
+
+ return [
+ {"name": data["name"], **{**af, "afi": "ip" if af["afi"] == "ipv4" else af["afi"]}}
+ for af in data["address_family"]
+ ]
+
+ def _compare_route_maps(self, wafd, hafd):
+ want_rms = wafd.get("route_maps", [])
+ have_rms = hafd.get("route_maps", [])
+
+ for want in want_rms:
+ match = next(
+ (
+ h
+ for h in have_rms
+ if h["rm_name"] == want["rm_name"] and h["protocol"] == want["protocol"]
+ ),
+ {},
+ )
+ base = {"name": wafd["name"], "afi": wafd["afi"]}
+
+ self.compare(
+ parsers="route_maps",
+ want={**base, "route_maps": want},
+ have={**base, "route_maps": match},
+ )
+
+ def _canonicalise(self, obj):
+ if isinstance(obj, dict):
+ return {k: self._canonicalise(v) for k, v in obj.items()}
+
+ if isinstance(obj, list):
+ if not obj:
+ return obj
+
+ if not isinstance(obj[0], dict):
+ return sorted(obj)
+
+ canon = [self._canonicalise(i) for i in obj]
+
+ def sort_key(d):
+ for k in ("name", "address", "afi", "area_id", "neighbor_id", "dest"):
+ if k in d:
+ return d[k]
+ return tuple(sorted(d.items()))
+
+ return sorted(canon, key=sort_key)
+
+ return obj
diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py
index 74bbda74..24c444dd 100644
--- a/plugins/module_utils/network/vyos/facts/facts.py
+++ b/plugins/module_utils/network/vyos/facts/facts.py
@@ -80,6 +80,7 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.snmp_
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.static_routes.static_routes import (
Static_routesFacts,
)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.vrf.vrf import VrfFacts
FACT_LEGACY_SUBSETS = dict(default=Default, neighbors=Neighbors, config=Config)
@@ -104,6 +105,7 @@ FACT_RESOURCE_SUBSETS = dict(
ntp_global=Ntp_globalFacts,
snmp_server=Snmp_serverFacts,
hostname=HostnameFacts,
+ vrf=VrfFacts,
)
diff --git a/plugins/module_utils/network/vyos/facts/vrf/__init__.py b/plugins/module_utils/network/vyos/facts/vrf/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/vrf/__init__.py
diff --git a/plugins/module_utils/network/vyos/facts/vrf/vrf.py b/plugins/module_utils/network/vyos/facts/vrf/vrf.py
new file mode 100644
index 00000000..6c7b8918
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/vrf/vrf.py
@@ -0,0 +1,227 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+"""
+The vyos vrf fact class
+It is in this file the configuration is collected from the device
+for a given resource, parsed, and the facts tree is populated
+based on the configuration.
+"""
+
+import re
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.vrf.vrf import VrfArgs
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.bgp_global.bgp_global import (
+ Bgp_globalFacts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv2.ospfv2 import (
+ Ospfv2Facts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv3.ospfv3 import (
+ Ospfv3Facts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.static_routes.static_routes import (
+ Static_routesFacts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.vrf import (
+ VrfTemplate,
+)
+
+
+class VrfFacts(object):
+ """The vyos vrf facts class"""
+
+ def __init__(self, module, subspec="config", options="options"):
+ self._module = module
+ self.argument_spec = VrfArgs.argument_spec
+
+ def get_config(self, connection):
+ return connection.get("show configuration commands | match 'set vrf'")
+
+ def get_config_set(self, data, connection):
+ """To classify the configurations beased on vrf"""
+ config_dict = {}
+ for config_line in data.splitlines():
+ vrf_inst = re.search(r"set vrf name (\S+).*", config_line)
+ vrf_bta = re.search(r"set vrf bind-to-all", config_line)
+ if vrf_bta:
+ config_dict["bind_to_all"] = config_dict.get("bind_to_all", "") + config_line + "\n"
+ if vrf_inst:
+ config_dict[vrf_inst.group(1)] = (
+ config_dict.get(vrf_inst.group(1), "") + config_line + "\n"
+ )
+ return list(config_dict.values())
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """Populate the facts for Vrf network resource
+
+ :param connection: the device connection
+ :param ansible_facts: Facts dictionary
+ :param data: previously collected conf
+
+ :rtype: dictionary
+ :returns: facts
+ """
+ facts = {}
+ objs = []
+
+ if not data:
+ data = self.get_config(connection)
+
+ vrf_facts = {}
+ instances = []
+ vrf_parser = VrfTemplate(lines=[], module=self._module)
+ resources = self.get_config_set(data, connection)
+
+ for resource in resources:
+ vrf_parser = VrfTemplate(
+ lines=resource.split("\n"),
+ module=self._module,
+ )
+ objs = vrf_parser.parse()
+
+ if objs and "protocols" in resource:
+
+ protocol_lines = []
+ for line in resource.strip().split("\n"):
+ if "protocols" in line:
+ idx = line.index("protocols")
+ protocol_lines.append("set " + line[idx:])
+ objs["protocols"] = self._parse_protocols("\n".join(protocol_lines))
+
+ if objs:
+ if "bind_to_all" in objs:
+ vrf_facts.update(objs)
+ if "name" in objs:
+ instances.append(self._normalise_instance(objs))
+
+ if instances:
+ vrf_facts.update({"instances": instances})
+
+ ansible_facts["ansible_network_resources"].pop("vrf_facts", None)
+ facts = {"vrf": []}
+
+ params = utils.remove_empties(
+ vrf_parser.validate_config(
+ self.argument_spec,
+ {"config": vrf_facts},
+ redact=True,
+ ),
+ )
+
+ if not resources:
+ params["config"].pop("bind_to_all", None)
+
+ if params.get("config"):
+ facts["vrf"] = params["config"]
+ ansible_facts["ansible_network_resources"].update(facts)
+ return ansible_facts
+
+ def _normalise_instance(self, instance):
+ n_inst = instance.copy()
+ af_map = {}
+
+ for af in instance.get("address_family", []):
+ afi = af.get("afi")
+ if not afi:
+ continue
+
+ if afi not in af_map:
+ af_map[afi] = {"afi": afi}
+
+ for k, v in af.items():
+ if k == "afi":
+ continue
+ elif k == "route_maps":
+ if "route_maps" not in af_map[afi]:
+ af_map[afi]["route_maps"] = []
+ af_map[afi]["route_maps"].extend(v)
+ else:
+ af_map[afi][k] = v
+
+ for afi_data in af_map.values():
+ if "route_maps" in afi_data:
+ seen = []
+ deduped = []
+ for item in afi_data["route_maps"]:
+ if item not in seen:
+ seen.append(item)
+ deduped.append(item)
+ afi_data["route_maps"] = deduped
+
+ n_inst["address_family"] = list(af_map.values())
+ return n_inst
+
+ def _parse_protocols(self, protocols):
+ """Parse protocols and return a dictionary"""
+
+ protocol_chunks = {}
+ parsed_protocols = {}
+
+ for line in protocols.split("\n"):
+ parts = line.split()
+ if len(parts) > 2 and parts[0] == "set" and parts[1] == "protocols":
+ protocol = parts[2]
+ protocol_chunks.setdefault(protocol, []).append(line)
+
+ protocol_strings = {proto: "\n".join(lines) for proto, lines in protocol_chunks.items()}
+
+ for protocol_name, protocol_string in protocol_strings.items():
+ protocol_dict = {}
+
+ if protocol_name == "bgp":
+ bgp_module = Bgp_globalFacts(self._module)
+ protocol_dict = bgp_module.populate_facts(
+ connection=self._module._connection,
+ ansible_facts={"ansible_network_resources": {}},
+ data=protocol_string,
+ )
+ parsed_protocols[protocol_name] = list(
+ protocol_dict.get("ansible_network_resources").values(),
+ )[0]
+
+ elif protocol_name == "ospf":
+ ospf_module = Ospfv2Facts(self._module)
+ protocol_dict = ospf_module.populate_facts(
+ connection=self._module._connection,
+ ansible_facts={"ansible_network_resources": {}},
+ data=protocol_string,
+ )
+ parsed_protocols[protocol_name] = list(
+ protocol_dict.get("ansible_network_resources").values(),
+ )[0]
+
+ elif protocol_name == "ospfv3":
+ ospfv3_module = Ospfv3Facts(self._module)
+ protocol_dict = ospfv3_module.populate_facts(
+ connection=self._module._connection,
+ ansible_facts={"ansible_network_resources": {}},
+ data=protocol_string,
+ )
+ parsed_protocols[protocol_name] = list(
+ protocol_dict.get("ansible_network_resources").values(),
+ )[0]
+
+ elif protocol_name == "static":
+ static_routes_module = Static_routesFacts(self._module)
+ protocol_dict = static_routes_module.populate_facts(
+ connection=self._module._connection,
+ ansible_facts={"ansible_network_resources": {}},
+ data=protocol_string,
+ )
+ parsed_protocols[protocol_name] = list(
+ protocol_dict.get("ansible_network_resources").values(),
+ )[0]
+ else:
+ self._module.fail_json(msg="The protocol is not supported" + protocol_name)
+
+ return parsed_protocols
diff --git a/plugins/module_utils/network/vyos/rm_templates/vrf.py b/plugins/module_utils/network/vyos/rm_templates/vrf.py
new file mode 100644
index 00000000..5171404e
--- /dev/null
+++ b/plugins/module_utils/network/vyos/rm_templates/vrf.py
@@ -0,0 +1,249 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+"""
+The VRF parser templates file. This contains
+a list of parser definitions and associated functions that
+facilitates both facts gathering and native command generation for
+the given network resource.
+"""
+
+import re
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
+ NetworkTemplate,
+)
+
+
+class VrfTemplate(NetworkTemplate):
+ def __init__(self, lines=None, module=None):
+ prefix = {"set": "set", "remove": "delete"}
+ super(VrfTemplate, self).__init__(lines=lines, tmplt=self, prefix=prefix, module=module)
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "table_id",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+vrf
+ \s+name
+ \s+(?P<name>\S+)
+ \s+table
+ \s+'(?P<tid>\S+)'
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{ name }} table {{ table_id }}",
+ "result": {
+ "name": "{{ name }}",
+ "table_id": "{{ tid }}",
+ },
+ },
+ {
+ "name": "bind_to_all",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \s(?P<bta>bind-to-all)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf bind-to-all",
+ "result": {
+ "bind_to_all": "{{ True if bta is defined }}",
+ },
+ },
+ {
+ "name": "vni",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+vrf
+ \s+name
+ \s+(?P<name>\S+)
+ \s+vni
+ \s'(?P<vni>\S+)'
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} vni {{vni}}",
+ "result": {
+ "name": "{{ name }}",
+ "vni": "{{ vni }}",
+ },
+ },
+ {
+ "name": "description",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \sdescription
+ \s(?P<desc>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} description {{description}}",
+ "result": {
+ "name": "{{ name }}",
+ "description": "{{ desc }}",
+ },
+ },
+ {
+ "name": "disable_vrf",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \s(?P<disable>disable)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} disable",
+ "compval": "disable",
+ "result": {
+ "name": "{{ name }}",
+ "disable": "{{ True if disable is defined }}",
+ },
+ },
+ # {
+ # "name": "address_family",
+ # "getval": re.compile(
+ # r"""
+ # ^set
+ # \svrf
+ # \sname
+ # \s(?P<name>\S+)
+ # \s(?P<af>ip|ipv6)
+ # $""",
+ # re.VERBOSE,
+ # ),
+ # "setval": "vrf name {{name}} {{ af }}",
+ # 'compval': "address_family",
+ # "result": {
+ # "name": "{{ name }}",
+ # "address_family": {
+ # '{{ "ipv4" if af == "ip" else "ipv6" }}': {
+ # "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ # },
+ # },
+ # },
+ # },
+ # {
+ # "name": "address_family.disable_forwarding",
+ # "getval": re.compile(
+ # r"""
+ # ^set
+ # \svrf
+ # \sname
+ # \s(?P<name>\S+)
+ # \s(?P<af>ip|ipv6)
+ # \s(?P<df>disable-forwarding)
+ # $""",
+ # re.VERBOSE,
+ # ),
+ # "setval": "vrf name {{name}} {{ afi }} disable-forwarding",
+ # # "compval": "address_family.ipv6.disable_forwarding",
+ # "result": {
+ # "name": "{{ name }}",
+ # "address_family": {
+ # '{{ "ipv4" if af == "ip" else "ipv6" }}': {
+ # "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ # "disable_forwarding": "{{ True if df is defined }}",
+ # },
+ # },
+ # },
+ # },
+ {
+ "name": "disable_forwarding",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \s(?P<af>ip|ipv6)
+ \s(?P<df>disable-forwarding)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} {{ afi }} disable-forwarding",
+ "compval": "disable_forwarding",
+ "result": {
+ "name": "{{ name }}",
+ 'address_family': [{
+ "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ "disable_forwarding": "{{ True if df is defined }}",
+ }],
+ },
+ },
+ {
+ "name": "disable_nht",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \s(?P<af>ip|ipv6)
+ \snht
+ \s(?P<nht>no-resolve-via-default)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} {{ afi }} nht no-resolve-via-default",
+ "compval": "nht_no_resolve_via_default",
+ "result": {
+ "name": "{{ name }}",
+ "address_family": [{
+ "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ "nht_no_resolve_via_default": "{{ True if nht is defined }}",
+ }],
+ },
+ },
+ {
+ "name": "route_maps",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \s(?P<af>ip|ipv6)
+ \sprotocol
+ \s(?P<proto>\S+)
+ \sroute-map
+ \s'(?P<rm>\S+)'
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} {{ afi }} protocol {{ route_maps.protocol }} route-map {{ route_maps.rm_name }}",
+ "compval": "route_maps",
+ "remval": "vrf name {{name}} {{ afi }} protocol {{ route_maps.protocol }}",
+ "result": {
+ "name": "{{ name }}",
+ "address_family": [{
+ "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ "route_maps": [{
+ "rm_name": "{{ rm }}",
+ "protocol": "{{ proto }}",
+ }],
+ }],
+ },
+ },
+ ]
+ # fmt: on
diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py
index 6957f6cb..78445c02 100644
--- a/plugins/module_utils/network/vyos/utils/utils.py
+++ b/plugins/module_utils/network/vyos/utils/utils.py
@@ -285,3 +285,25 @@ def in_target_not_none(h, key):
:return: True/False.
"""
return True if h and key in h and h[key] is not None else False
+
+
+def combine(a, b, recursive=False, list_merge="replace"):
+ """
+ Merge two dictionaries (shallow or deep).
+ :param a: dict
+ :param b: dict
+ :param recursive: bool, deep merge
+ :param list_merge: str, only 'replace' is supported (default Ansible behavior)
+ """
+ if not isinstance(a, dict) or not isinstance(b, dict):
+ raise ValueError("combine expects two dictionaries")
+
+ result = a.copy()
+
+ for k, v in b.items():
+ if recursive and k in result and isinstance(result[k], dict) and isinstance(v, dict):
+ result[k] = combine(result[k], v, recursive=True, list_merge=list_merge)
+ else:
+ result[k] = v
+
+ return result
diff --git a/plugins/modules/vyos_vrf.py b/plugins/modules/vyos_vrf.py
new file mode 100644
index 00000000..395a152b
--- /dev/null
+++ b/plugins/modules/vyos_vrf.py
@@ -0,0 +1,1545 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2024 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+The module file for vyos_vrf
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: vyos_vrf
+version_added: 1.0.0
+short_description: VRF resource module
+description:
+- This module manages vrf configuration on devices running Vyos
+author:
+- Evgeny Molotkov (@omnom62)
+notes:
+- Tested against vyos 1.4.2 and 1.5-stream-2025-Q1
+- This module works with connection C(network_cli).
+options:
+ config:
+ description: List of vrf configuration.
+ type: dict
+ suboptions:
+ bind_to_all:
+ default: false
+ description: Enable binding services to all VRFs
+ type: bool
+ instances:
+ description: Virtual Routing and Forwarding instance
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: VRF instance name
+ required: true
+ type: str
+ description:
+ description: Description
+ type: str
+ disable:
+ default: false
+ description: Administratively disable interface
+ type: bool
+ aliases: ['disabled']
+ table_id:
+ description: Routing table associated with this instance
+ type: int
+ vni:
+ description: Virtual Network Identifier
+ type: int
+ address_family:
+ type: list
+ elements: dict
+ description: Address family configuration
+ suboptions:
+ afi:
+ description: Address family identifier
+ type: str
+ choices: ['ipv4', 'ipv6']
+ disable_forwarding:
+ default: False
+ description: Disable forwarding for this address family
+ type: bool
+ nht_no_resolve_via_default:
+ default: False
+ description: Disable next-hop resolution via default route
+ type: bool
+ route_maps:
+ description: List of route maps for this address family
+ type: list
+ elements: dict
+ suboptions:
+ rm_name:
+ description: Route map name
+ type: str
+ required: true
+ protocol:
+ description: Protocol to which the route map applies
+ type: str
+ choices:
+ - any
+ - babel
+ - bgp
+ - eigrp
+ - isis
+ - ospf
+ - rip
+ - static
+ protocols:
+ # type: list # sanity
+ # elements: dict
+ type: dict
+ description: Protocol configuration
+ suboptions:
+ bgp:
+ type: dict
+ description: BGP configuration
+ suboptions:
+ as_number:
+ description:
+ - AS number.
+ type: int
+ #maximum_paths: --> moved to address-family before 1.3
+ neighbor:
+ description: BGP neighbor
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description:
+ - BGP neighbor address (v4/v6).
+ type: str
+ advertisement_interval:
+ description:
+ - Minimum interval for sending routing updates.
+ type: int
+ capability:
+ description:
+ - Advertise capabilities to this neighbor.
+ type: dict
+ suboptions:
+ dynamic:
+ description:
+ - Advertise dynamic capability to this neighbor.
+ type: bool
+ extended_nexthop:
+ description:
+ - Advertise extended nexthop capability to this neighbor.
+ type: bool
+ default_originate:
+ description:
+ - Send default route to this neighbor
+ type: str
+ description:
+ description:
+ - Description of the neighbor
+ type: str
+ disable_capability_negotiation:
+ description:
+ - Disbale capability negotiation with the neighbor
+ type: bool
+ disable_connected_check:
+ description:
+ - Disable check to see if EBGP peer's address is a connected route.
+ type: bool
+ disable_send_community:
+ description:
+ - Disable sending community attributes to this neighbor.
+ type: str
+ choices: ['extended', 'standard']
+ ebgp_multihop:
+ description:
+ - Allow this EBGP neighbor to not be on a directly connected network. Specify
+ the number hops.
+ type: int
+ local_as:
+ description: local as number not to be prepended to updates from EBGP peers
+ type: int
+ override_capability:
+ description: Ignore capability negotiation with specified neighbor.
+ type: bool
+ passive:
+ description: Do not initiate a session with this neighbor
+ type: bool
+ password:
+ description: BGP MD5 password
+ type: str
+ peer_group_name:
+ description: IPv4 peer group for this peer
+ type: str
+ peer_group:
+ description: True if all the configs under this neighbor key is for peer group template.
+ type: bool
+ port:
+ description: Neighbor's BGP port
+ type: int
+ remote_as:
+ description: Neighbor BGP AS number
+ type: int
+ shutdown:
+ description: Administratively shut down neighbor
+ type: bool
+ solo: # <-- added in 1.3
+ description: Do not send back prefixes learned from the neighbor
+ type: bool
+ strict_capability_match:
+ description: Enable strict capability negotiation
+ type: bool
+ timers:
+ description: Neighbor timers
+ type: dict
+ suboptions:
+ connect:
+ description: BGP connect timer for this neighbor.
+ type: int
+ holdtime:
+ description: BGP hold timer for this neighbor
+ type: int
+ keepalive:
+ description: BGP keepalive interval for this neighbor
+ type: int
+ ttl_security:
+ description: Number of the maximum number of hops to the BGP peer
+ type: int
+ update_source:
+ description: Source IP of routing updates
+ type: str
+ timers:
+ description: BGP protocol timers
+ type: dict
+ suboptions:
+ keepalive:
+ description: Keepalive interval
+ type: int
+ holdtime:
+ description: Hold time interval
+ type: int
+ bgp_params:
+ description: BGP parameters
+ type: dict
+ suboptions:
+ always_compare_med:
+ description: Always compare MEDs from different neighbors
+ type: bool
+ bestpath:
+ description: Default bestpath selection mechanism
+ type: dict
+ suboptions:
+ as_path:
+ description: AS-path attribute comparison parameters
+ type: str
+ choices: ['confed', 'ignore']
+ compare_routerid:
+ description: Compare the router-id for identical EBGP paths
+ type: bool
+ med:
+ description: MED attribute comparison parameters
+ type: str
+ choices: ['confed', 'missing-as-worst']
+ cluster_id:
+ description: Route-reflector cluster-id
+ type: str
+ confederation:
+ description: AS confederation parameters
+ type: list
+ elements: dict
+ suboptions:
+ identifier:
+ description: Confederation AS identifier
+ type: int
+ peers:
+ description: Peer ASs in the BGP confederation
+ type: int
+ dampening:
+ description: Enable route-flap dampening
+ type: dict
+ suboptions:
+ half_life:
+ description: Half-life penalty in seconds
+ type: int
+ max_suppress_time:
+ description: Maximum duration to suppress a stable route
+ type: int
+ re_use:
+ description: Time to start reusing a route
+ type: int
+ start_suppress_time:
+ description: When to start suppressing a route
+ type: int
+ default:
+ description: BGP defaults
+ type: dict
+ suboptions:
+ local_pref:
+ description: Default local preference
+ type: int
+ no_ipv4_unicast:
+ description: |
+ Deactivate IPv4 unicast for a peer by default
+ Deprecated: Unavailable after 1.4
+ type: bool
+ deterministic_med:
+ description: Compare MEDs between different peers in the same AS
+ type: bool
+ disable_network_import_check:
+ description: Disable IGP route check for network statements
+ type: bool
+ distance:
+ description: Administrative distances for BGP routes
+ type: list
+ elements: dict
+ suboptions:
+ type:
+ description: Type of route
+ type: str
+ choices: ['external', 'internal', 'local']
+ value:
+ description: distance
+ type: int
+ prefix:
+ description: Administrative distance for a specific BGP prefix
+ type: int
+ enforce_first_as:
+ description: Require first AS in the path to match peer's AS
+ type: bool
+ graceful_restart:
+ description: Maximum time to hold onto restarting peer's stale paths
+ type: int
+ log_neighbor_changes:
+ description: Log neighbor up/down changes and reset reason
+ type: bool
+ no_client_to_client_reflection:
+ description: Disable client to client route reflection
+ type: bool
+ no_fast_external_failover:
+ description: Disable immediate session reset if peer's connected link goes down
+ type: bool
+ router_id:
+ description: BGP router-id
+ type: str
+ scan_time:
+ description: BGP route scanner interval
+ type: int
+ ospf:
+ type: dict
+ description: OSPFv2 configuration
+ suboptions:
+ areas:
+ description: OSPFv2 area.
+ type: list
+ elements: dict
+ suboptions:
+ area_id:
+ description: OSPFv2 area identity.
+ type: str
+ area_type:
+ description: Area type.
+ type: dict
+ suboptions:
+ normal:
+ description: Normal OSPFv2 area.
+ type: bool
+ nssa:
+ description: NSSA OSPFv2 area.
+ type: dict
+ suboptions:
+ set:
+ description: Enabling NSSA.
+ type: bool
+ default_cost:
+ description: Summary-default cost of NSSA area.
+ type: int
+ no_summary:
+ description: Do not inject inter-area routes into stub.
+ type: bool
+ translate:
+ description: NSSA-ABR.
+ type: str
+ choices: [always, candidate, never]
+ stub:
+ description: Stub OSPFv2 area.
+ type: dict
+ suboptions:
+ set:
+ description: Enabling stub.
+ type: bool
+ default_cost:
+ description: Summary-default cost of stub area.
+ type: int
+ no_summary:
+ description: Do not inject inter-area routes into stub.
+ type: bool
+ authentication:
+ description: OSPFv2 area authentication type.
+ type: str
+ choices: [plaintext-password, md5]
+ network:
+ description: OSPFv2 network.
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ required: true
+ description: OSPFv2 IPv4 network address.
+ type: str
+ range:
+ description: Summarize routes matching prefix (border routers only).
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: border router IPv4 address.
+ type: str
+ cost:
+ description: Metric for this range.
+ type: int
+ not_advertise:
+ description: Don't advertise this range.
+ type: bool
+ substitute:
+ description: Announce area range (IPv4 address) as another prefix.
+ type: str
+ shortcut:
+ description: Area's shortcut mode.
+ type: str
+ choices: [default, disable, enable]
+ virtual_link:
+ description: Virtual link address.
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: virtual link address.
+ type: str
+ authentication:
+ description: OSPFv2 area authentication type.
+ type: dict
+ suboptions:
+ md5:
+ description: MD5 key id based authentication.
+ type: list
+ elements: dict
+ suboptions:
+ key_id:
+ description: MD5 key id.
+ type: int
+ md5_key:
+ description: MD5 key.
+ type: str
+ plaintext_password:
+ description: Plain text password.
+ type: str
+ dead_interval:
+ description: Interval after which a neighbor is declared dead.
+ type: int
+ hello_interval:
+ description: Interval between hello packets.
+ type: int
+ retransmit_interval:
+ description: Interval between retransmitting lost link state advertisements.
+ type: int
+ transmit_delay:
+ description: Link state transmit delay.
+ type: int
+ log_adjacency_changes:
+ description: Log changes in adjacency state.
+ type: str
+ choices: [detail]
+ max_metric:
+ description: OSPFv2 maximum/infinite-distance metric.
+ type: dict
+ suboptions:
+ router_lsa:
+ description: Advertise own Router-LSA with infinite distance (stub router).
+ type: dict
+ suboptions:
+ administrative:
+ description: Administratively apply, for an indefinite period.
+ type: bool
+ on_shutdown:
+ description: Time to advertise self as stub-router.
+ type: int
+ on_startup:
+ description: Time to advertise self as stub-router
+ type: int
+ auto_cost:
+ description: Calculate OSPFv2 interface cost according to bandwidth.
+ type: dict
+ suboptions:
+ reference_bandwidth:
+ description: Reference bandwidth cost in Mbits/sec.
+ type: int
+ default_information:
+ description: Control distribution of default information.
+ type: dict
+ suboptions:
+ originate:
+ description: Distribute a default route.
+ type: dict
+ suboptions:
+ always:
+ description: Always advertise default route.
+ type: bool
+ metric:
+ description: OSPFv2 default metric.
+ type: int
+ metric_type:
+ description: OSPFv2 Metric types for default routes.
+ type: int
+ route_map:
+ description: Route map references.
+ type: str
+ default_metric:
+ description: Metric of redistributed routes
+ type: int
+ distance:
+ description: Administrative distance.
+ type: dict
+ suboptions:
+ global:
+ description: Global OSPFv2 administrative distance.
+ type: int
+ ospf:
+ description: OSPFv2 administrative distance.
+ type: dict
+ suboptions:
+ external:
+ description: Distance for external routes.
+ type: int
+ inter_area:
+ description: Distance for inter-area routes.
+ type: int
+ intra_area:
+ description: Distance for intra-area routes.
+ type: int
+ mpls_te:
+ description: MultiProtocol Label Switching-Traffic Engineering (MPLS-TE) parameters.
+ type: dict
+ suboptions:
+ enabled:
+ description: Enable MPLS-TE functionality.
+ type: bool
+ router_address:
+ description: Stable IP address of the advertising router.
+ type: str
+ neighbor:
+ description: Neighbor IP address.
+ type: list
+ elements: dict
+ suboptions:
+ neighbor_id:
+ description: Identity (number/IP address) of neighbor.
+ type: str
+ poll_interval:
+ description: Seconds between dead neighbor polling interval.
+ type: int
+ priority:
+ description: Neighbor priority.
+ type: int
+ parameters:
+ description: OSPFv2 specific parameters.
+ type: dict
+ suboptions:
+ abr_type:
+ description: OSPFv2 ABR Type.
+ type: str
+ choices: [cisco, ibm, shortcut, standard]
+ opaque_lsa:
+ description: Enable the Opaque-LSA capability (rfc2370).
+ type: bool
+ rfc1583_compatibility:
+ description: Enable rfc1583 criteria for handling AS external routes.
+ type: bool
+ router_id:
+ description: Override the default router identifier.
+ type: str
+ passive_interface:
+ description: Suppress routing updates on an interface.
+ type: list
+ elements: str
+ passive_interface_exclude:
+ description: Interface to exclude when using passive-interface default.
+ type: list
+ elements: str
+ redistribute:
+ description: Redistribute information from another routing protocol.
+ type: list
+ elements: dict
+ suboptions:
+ route_type:
+ description: Route type to redistribute.
+ type: str
+ choices: [bgp, connected, kernel, rip, static]
+ metric:
+ description: Metric for redistribution routes.
+ type: int
+ metric_type:
+ description: OSPFv2 Metric types.
+ type: int
+ route_map:
+ description: Route map references.
+ type: str
+ route_map:
+ description: Filter routes installed in local route map.
+ type: list
+ elements: str
+ timers:
+ description: Adjust routing timers.
+ type: dict
+ suboptions:
+ refresh:
+ description: Adjust refresh parameters.
+ type: dict
+ suboptions:
+ timers:
+ description: refresh timer.
+ type: int
+ throttle:
+ description: Throttling adaptive timers.
+ type: dict
+ suboptions:
+ spf:
+ description: OSPFv2 SPF timers.
+ type: dict
+ suboptions:
+ delay:
+ description: Delay (msec) from first change received till SPF
+ calculation.
+ type: int
+ initial_holdtime:
+ description: Initial hold time(msec) between consecutive SPF calculations.
+ type: int
+ max_holdtime:
+ description: maximum hold time (sec).
+ type: int
+ ospfv3:
+ type: dict
+ description: OSPFv3 configuration
+ suboptions:
+ areas:
+ description: OSPFv3 area.
+ type: list
+ elements: dict
+ suboptions:
+ area_id:
+ description: OSPFv3 Area name/identity.
+ type: str
+ export_list:
+ description: Name of export-list.
+ type: str
+ import_list:
+ description: Name of import-list.
+ type: str
+ interface:
+ description: Enable OSPVv3 on an interface for this area.
+ aliases: ['interfaces']
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: Interface name.
+ type: str
+ range:
+ description: Summarize routes matching prefix (border routers only).
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: border router IPv4 address.
+ type: str
+ advertise:
+ description: Advertise this range.
+ type: bool
+ not_advertise:
+ description: Don't advertise this range.
+ type: bool
+ parameters:
+ description: OSPFv3 specific parameters.
+ type: dict
+ suboptions:
+ router_id:
+ description: Override the default router identifier.
+ type: str
+ redistribute:
+ description: Redistribute information from another routing protocol.
+ type: list
+ elements: dict
+ suboptions:
+ route_type:
+ description: Route type to redistribute.
+ type: str
+ choices:
+ - bgp
+ - connected
+ - kernel
+ - ripng
+ - static
+ route_map:
+ description: Route map references.
+ type: str
+ static:
+ type: list
+ description: Static routes configuration
+ elements: dict
+ suboptions:
+ address_families:
+ description: A dictionary specifying the address family to which the static
+ route(s) belong.
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description:
+ - Specifies the type of route.
+ type: str
+ choices:
+ - ipv4
+ - ipv6
+ required: true
+ routes:
+ description: A dictionary that specify the static route configurations.
+ type: list
+ elements: dict
+ suboptions:
+ dest:
+ description:
+ - An IPv4/v6 address in CIDR notation that specifies the destination
+ network for the static route.
+ type: str
+ required: true
+ blackhole_config:
+ description:
+ - Configured to silently discard packets.
+ type: dict
+ suboptions:
+ type:
+ description:
+ - This is to configure only blackhole.
+ type: str
+ distance:
+ description:
+ - Distance for the route.
+ type: int
+ next_hops:
+ description:
+ - Next hops to the specified destination.
+ type: list
+ elements: dict
+ suboptions:
+ forward_router_address:
+ description:
+ - The IP address of the next hop that can be used to reach the
+ destination network.
+ type: str
+ enabled:
+ description:
+ - Disable IPv4/v6 next-hop static route.
+ type: bool
+ admin_distance:
+ description:
+ - Distance value for the route.
+ type: int
+ interface:
+ description:
+ - Name of the outgoing interface.
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the VYOS device by
+ executing the command B(show configuration commands | match "set vrf").
+ - The states I(replaced) and I(overridden) have identical
+ behaviour for this module.
+ - The state I(parsed) reads the configuration from C(show configuration commands | match "set vrf") option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+"""
+
+EXAMPLES = """
+# # -------------------
+# # 1. Using merged
+# # -------------------
+
+# # Before state:
+# # -------------
+# vyos@vyos:~$ show configuration commands | match 'set vrf'
+# set vrf name vrf-blue description 'blue-vrf'
+# set vrf name vrf-blue disable
+# set vrf name vrf-blue table '100'
+# set vrf name vrf-blue vni '1000'
+# vyos@vyos:~$
+
+# # Task
+# # -------------
+ # - name: Merge provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # instances:
+ # - name: "vrf-green"
+ # description: "green-vrf"
+ # table_id: 110
+ # vni: 1010
+
+# Task output:
+# -------------
+ # "after": {
+ # "bind_to_all": false,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": true,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "description": "green-vrf",
+ # "disable": false,
+ # "name": "vrf-green",
+ # "table_id": 110,
+ # "vni": 1010
+ # }
+ # ]
+ # },
+ # "before": {
+ # "bind_to_all": false,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": true,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # }
+ # ]
+ # },
+ # "changed": true,
+ # "commands": [
+ # "set vrf name vrf-green table 110",
+ # "set vrf name vrf-green vni 1010",
+ # "set vrf name vrf-green description green-vrf"
+ # ]
+
+# After state:
+# # -------------
+# vyos@vyos:~$ show configuration commands | match 'set vrf'
+# set vrf name vrf-blue description 'blue-vrf'
+# set vrf name vrf-blue disable
+# set vrf name vrf-blue table '100'
+# set vrf name vrf-blue vni '1000'
+# set vrf name vrf-green description 'green-vrf'
+# set vrf name vrf-green table '110'
+# set vrf name vrf-green vni '1010'
+# vyos@vyos:~$
+
+# # -------------------
+# # 2. Using replaced
+# # -------------------
+
+# # Before state:
+# # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+
+# # Task
+# # -------------
+ # - name: Merge provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # bind_to_all: true
+ # instances:
+ # - name: "vrf-blue"
+ # description: "blue-vrf"
+ # disable: false
+ # table_id: 100
+ # vni: 1002
+ # - name: "vrf-red"
+ # description: "red-vrf"
+ # disable: false
+ # table_id: 101
+ # vni: 1001
+ # address_family:
+ # - afi: "ipv4"
+ # disable_forwarding: false
+ # route_maps:
+ # - rm_name: "rm1"
+ # protocol: "ospf"
+ # - afi: "ipv6"
+ # nht_no_resolve_via_default: true
+ # state: replaced
+
+# # Task output:
+# # -------------
+ # "after": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1002
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": false,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "ospf",
+ # "rm_name": "rm1"
+ # },
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # },
+ # {
+ # "afi": "ipv6",
+ # "disable_forwarding": false,
+ # "nht_no_resolve_via_default": true
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": false,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "before": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "changed": true,
+ # "commands": [
+ # "set vrf name vrf-blue vni 1002",
+ # "delete vrf name vrf-red disable",
+ # "set vrf name vrf-red ip protocol ospf route-map rm1",
+ # "delete vrf name vrf-red ip disable-forwarding",
+ # "set vrf name vrf-red ipv6 nht no-resolve-via-default"
+ # ]
+
+# After state:
+# # -------------
+ # vyos@vyos:~$
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1002'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red ip protocol ospf route-map 'rm1'
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red ipv6 nht no-resolve-via-default
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+
+# # -------------------
+# # 3. Using overridden
+# # -------------------
+
+# # Before state:
+# # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+# Task
+# -------------
+ # - name: Overridden provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # bind_to_all: true
+ # instances:
+ # - name: "vrf-blue"
+ # description: "blue-vrf"
+ # disable: true
+ # table_id: 100
+ # vni: 1000
+ # - name: "vrf-red"
+ # description: "red-vrf"
+ # disable: true
+ # table_id: 101
+ # vni: 1001
+ # address_family:
+ # - afi: "ipv4"
+ # disable_forwarding: false
+ # route_maps:
+ # - rm_name: "rm1"
+ # protocol: "rip"
+ # - afi: "ipv6"
+ # nht_no_resolve_via_default: false
+ # state: overridden
+
+# # Task output:
+# # -------------
+ # "after": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": true,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": false,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "before": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "changed": true,
+ # "commands": [
+ # "delete vrf name vrf-blue",
+ # "commit",
+ # "delete vrf name vrf-red",
+ # "commit",
+ # "set vrf name vrf-blue table 100",
+ # "set vrf name vrf-blue vni 1000",
+ # "set vrf name vrf-blue description blue-vrf",
+ # "set vrf name vrf-blue disable",
+ # "set vrf name vrf-red table 101",
+ # "set vrf name vrf-red vni 1001",
+ # "set vrf name vrf-red description red-vrf",
+ # "set vrf name vrf-red disable",
+ # "set vrf name vrf-red ip protocol rip route-map rm1"
+ # ]
+
+# After state:
+# # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue disable
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+# 4. Using gathered
+# -------------------
+
+# # Before state:
+# # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+# Task
+# -------------
+# - name: Gather provided configuration with device configuration
+# vyos.vyos.vyos_vrf:
+# config:
+# state: gathered
+
+# # Task output:
+# # -------------
+ # "gathered": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # }
+
+# After state:
+# # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+
+# # -------------------
+# # 5. Using deleted
+# # -------------------
+
+# # Before state:
+# # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf bind-to-all
+ # set vrf name vrf-blue description 'blue-vrf'
+ # set vrf name vrf-blue table '100'
+ # set vrf name vrf-blue vni '1000'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+# # Task
+# # -------------
+# - name: Replace provided configuration with device configuration
+# vyos.vyos.vyos_vrf:
+# config:
+# bind_to_all: false
+# instances:
+# - name: "vrf-blue"
+# state: deleted
+
+
+# # Task output:
+# # -------------
+ # "after": {
+ # "bind_to_all": false,
+ # "instances": [
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "before": {
+ # "bind_to_all": true,
+ # "instances": [
+ # {
+ # "description": "blue-vrf",
+ # "disable": false,
+ # "name": "vrf-blue",
+ # "table_id": 100,
+ # "vni": 1000
+ # },
+ # {
+ # "address_family": [
+ # {
+ # "afi": "ipv4",
+ # "disable_forwarding": true,
+ # "nht_no_resolve_via_default": false,
+ # "route_maps": [
+ # {
+ # "protocol": "rip",
+ # "rm_name": "rm1"
+ # }
+ # ]
+ # }
+ # ],
+ # "description": "red-vrf",
+ # "disable": true,
+ # "name": "vrf-red",
+ # "table_id": 101,
+ # "vni": 1001
+ # }
+ # ]
+ # },
+ # "changed": true,
+ # "commands": [
+ # "delete vrf bind-to-all",
+ # "delete vrf name vrf-blue"
+ # ]
+
+# After state:
+# # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+# # -------------------
+# # 6. Using rendered
+# # -------------------
+
+# # Before state:
+# # -------------
+ # vyos@vyos:~$ show configuration commands | match 'set vrf'
+ # set vrf name vrf-red description 'red-vrf'
+ # set vrf name vrf-red disable
+ # set vrf name vrf-red ip disable-forwarding
+ # set vrf name vrf-red ip protocol rip route-map 'rm1'
+ # set vrf name vrf-red table '101'
+ # set vrf name vrf-red vni '1001'
+ # vyos@vyos:~$
+
+# Task
+# -------------
+ # - name: Render provided configuration with device configuration
+ # vyos.vyos.vyos_vrf:
+ # config:
+ # bind_to_all: true
+ # instances:
+ # - name: "vrf-green"
+ # description: "green-vrf"
+ # disabled: true
+ # table_id: 105
+ # vni: 1000
+ # - name: "vrf-amber"
+ # description: "amber-vrf"
+ # disable: false
+ # table_id: 111
+ # vni: 1001
+ # address_family:
+ # - afi: "ipv4"
+ # disable_forwarding: true
+ # route_maps:
+ # - rm_name: "rm1"
+ # protocol: "ospf"
+ # - afi: "ipv6"
+ # nht_no_resolve_via_default: false
+ # state: rendered
+
+# # Task output:
+# # -------------
+ # "rendered": [
+ # "set vrf bind-to-all",
+ # "set vrf name vrf-green table 105",
+ # "set vrf name vrf-green vni 1000",
+ # "set vrf name vrf-green description green-vrf",
+ # "set vrf name vrf-green disable",
+ # "set vrf name vrf-amber table 111",
+ # "set vrf name vrf-amber vni 1001",
+ # "set vrf name vrf-amber description amber-vrf",
+ # "set vrf name vrf-amber ip protocol ospf route-map rm1",
+ # "set vrf name vrf-amber ip disable-forwarding"
+ # ]
+
+# # -------------------
+# # 7. Using parsed
+# # -------------------
+
+# # vrf_parsed.cfg:
+# # -------------
+# set vrf bind-to-all
+# set vrf name vrf1 description 'red'
+# set vrf name vrf1 disable
+# set vrf name vrf1 table 101
+# set vrf name vrf1 vni 501
+# set vrf name vrf2 description 'blah2'
+# set vrf name vrf2 disable
+# set vrf name vrf2 table 102
+# set vrf name vrf2 vni 102
+# set vrf name vrf1 ip disable-forwarding
+# set vrf name vrf1 ip nht no-resolve-via-default
+# set vrf name vrf-red ip protocol ospf route-map 'rm1'
+# set vrf name vrf-red ipv6 nht no-resolve-via-default
+
+# Task:
+# -------------
+# - name: Parse provided configuration with device configuration
+# vyos.vyos.vyos_vrf:
+# running_config: "{{ lookup('file', './vrf_parsed.cfg') }}"
+# state: parsed
+
+
+# # Task output:
+# # -------------
+# "parsed": {
+# "bind_to_all": true,
+# "instances": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "disable_forwarding": true,
+# "nht_no_resolve_via_default": true
+# }
+# ],
+# "description": "red",
+# "disable": true,
+# "name": "vrf1"
+# },
+# {
+# "description": "blah2",
+# "disable": true,
+# "name": "vrf2"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "disable_forwarding": false,
+# "nht_no_resolve_via_default": false,
+# "route_maps": [
+# {
+# "protocol": "ospf",
+# "rm_name": "rm1"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "disable_forwarding": false,
+# "nht_no_resolve_via_default": true
+# }
+# ],
+# "disable": false,
+# "name": "vrf-red"
+# }
+# ]
+# }
+"""
+
+RETURN = """
+before:
+ description: The configuration prior to the module execution.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+after:
+ description: The resulting configuration after module execution.
+ returned: when changed
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: list
+ sample:
+ - set system ntp server server1 dynamic
+ - set system ntp server server1 prefer
+ - set system ntp server server2 noselect
+ - set system ntp server server2 preempt
+ - set system ntp server server_add preempt
+rendered:
+ description: The provided configuration in the task rendered in device-native format (offline).
+ returned: when I(state) is C(rendered)
+ type: list
+ sample:
+ - set system ntp server server1 dynamic
+ - set system ntp server server1 prefer
+ - set system ntp server server2 noselect
+ - set system ntp server server2 preempt
+ - set system ntp server server_add preempt
+gathered:
+ description: Facts about the network resource gathered from the remote device as structured data.
+ returned: when I(state) is C(gathered)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+parsed:
+ description: The device native config provided in I(running_config) option parsed into structured data as per module argspec.
+ returned: when I(state) is C(parsed)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.vrf.vrf import VrfArgs
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.vrf.vrf import Vrf
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=VrfArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Vrf(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/pr408-diagram.png b/pr408-diagram.png
new file mode 100644
index 00000000..029208e0
--- /dev/null
+++ b/pr408-diagram.png
Binary files differ
diff --git a/tests/integration/targets/vyos_vrf/defaults/main.yaml b/tests/integration/targets/vyos_vrf/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/tests/integration/targets/vyos_vrf/tasks/cli.yaml b/tests/integration/targets/vyos_vrf/tasks/cli.yaml
new file mode 100644
index 00000000..daccf720
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tasks/cli.yaml
@@ -0,0 +1,20 @@
+---
+- name: Collect all cli test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ use_regex: true
+ register: test_cases
+ delegate_to: localhost
+
+- name: Set test_items
+ ansible.builtin.set_fact:
+ test_items: "{{ test_cases.files | map(attribute='path') | list }}"
+
+- name: Run test case (connection=ansible.netcommon.network_cli)
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
diff --git a/tests/integration/targets/vyos_vrf/tasks/main.yaml b/tests/integration/targets/vyos_vrf/tasks/main.yaml
new file mode 100644
index 00000000..e6378581
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Run CLI tests
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/_add_rm.yaml b/tests/integration/targets/vyos_vrf/tests/cli/_add_rm.yaml
new file mode 100644
index 00000000..ddbed78e
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/_add_rm.yaml
@@ -0,0 +1,12 @@
+---
+- ansible.builtin.include_tasks: _remove_rm.yaml
+
+- name: Add Route Map
+ ansible.netcommon.cli_config:
+ config: |-
+ set policy route-map rm1 rule 10 action 'permit'
+ set policy route-map rm1 rule 10 match peer '192.0.2.32'
+ set policy route-map rm1 rule 10 set aggregator as '100'
+ set policy route-map rm1 rule 10 set as-path exclude '111'
+ set policy route-map rm1 rule 10 set large-community none
+ set policy route-map rm1 rule 10 set metric '5'
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/_parsed.cfg b/tests/integration/targets/vyos_vrf/tests/cli/_parsed.cfg
new file mode 100644
index 00000000..5fb7c6da
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/_parsed.cfg
@@ -0,0 +1,34 @@
+set vrf bind-to-all
+set vrf name vrf1 description 'Parser Test VRF 1'
+set vrf name vrf1 disable
+set vrf name vrf1 table 101
+set vrf name vrf1 vni 501
+set vrf name vrf2 description 'Parser Test VRF 2'
+set vrf name vrf2 disable
+set vrf name vrf2 table 102
+set vrf name vrf2 vni 102
+set vrf name vrf1 ip disable-forwarding
+set vrf name vrf1 ip nht no-resolve-via-default
+# set vrf name vrf-red ip protocol kernel route-map 'rm1'
+set vrf name vrf-red ip protocol ospf route-map 'rm1'
+set vrf name vrf-red ipv6 nht no-resolve-via-default
+set vrf name vrf-green protocols ospf area '4'
+set vrf name vrf-green protocols ospf area 4 area-type stub default-cost 20
+set vrf name vrf-green protocols ospf area 4 network 192.0.2.0/24
+set vrf name vrf-green protocols ospf area 4 range 192.0.3.0/24
+set vrf name vrf-green protocols ospf area 4 range 192.0.3.0/24 cost 10
+set vrf name vrf-green protocols ospf area 4 range 192.0.4.0/24
+set vrf name vrf-green protocols ospf area 4 range 192.0.4.0/24 cost 12
+set vrf name vrf-green protocols ospfv3 area '2'
+set vrf name vrf-green protocols ospfv3 area 2 export-list export1
+set vrf name vrf-green protocols ospfv3 area 2 import-list import1
+set vrf name vrf-green protocols ospfv3 area 2 range 2001:db10::/32
+set vrf name vrf-green protocols ospfv3 area 2 range 2001:db20::/32
+set vrf name vrf-green protocols ospfv3 area 2 range 2001:db30::/32
+set vrf name vrf-green protocols static route 192.0.2.0/24
+set vrf name vrf-green protocols static route 192.0.2.0/24 blackhole distance '10'
+set vrf name vrf-green protocols static route 192.0.2.0/24 next-hop '203.0.113.1'
+set vrf name vrf-green protocols static route 192.0.2.0/24 next-hop '203.0.113.2'
+set vrf name vrf-green protocols static route6 2001:db8::/32
+set vrf name vrf-green protocols static route6 2001:db8::/32 blackhole distance '20'
+set vrf name vrf-green protocols static route6 2001:db8::/32 next-hop '2001:db8::1'"
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/_populate.yaml b/tests/integration/targets/vyos_vrf/tests/cli/_populate.yaml
new file mode 100644
index 00000000..9e6253ee
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/_populate.yaml
@@ -0,0 +1,10 @@
+---
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _add_rm.yaml
+
+- name: Setup
+ vyos.vyos.vyos_config:
+ lines: "{{ populate_config }}"
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_vrf/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..d909adfd
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/_remove_config.yaml
@@ -0,0 +1,9 @@
+---
+- name: Remove route-maps and VRF configuration
+ vyos.vyos.vyos_config:
+ lines:
+ - delete policy route-map rm1
+ - delete vrf
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/_remove_rm.yaml b/tests/integration/targets/vyos_vrf/tests/cli/_remove_rm.yaml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/_remove_rm.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/deleted.yaml b/tests/integration/targets/vyos_vrf/tests/cli/deleted.yaml
new file mode 100644
index 00000000..b6a28d0a
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/deleted.yaml
@@ -0,0 +1,34 @@
+---
+- debug:
+ msg: START vyos_vrf deleted integration tests on connection={{ ansible_connection }}
+
+- include_tasks: _populate.yaml
+
+- block:
+ - name: Delete the provided configuration
+ register: result
+ vyos.vyos.vyos_vrf: &id001
+ config:
+ state: deleted
+
+ - assert:
+ that:
+ - result.changed == true
+ - result.commands|symmetric_difference(deleted.commands) == []
+
+ - name: Assert that the after dicts were correctly generated
+ assert:
+ that:
+ - result.after|symmetric_difference(deleted.after) == []
+
+ - name: Delete the existing configuration with the provided running configuration (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_vrf: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_vrf/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..ba1dab0d
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/empty_config.yaml
@@ -0,0 +1,60 @@
+---
+- debug:
+ msg: START vyos_vrf empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_vrf:
+ config:
+ state: merged
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_vrf:
+ config:
+ state: replaced
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_vrf:
+ config:
+ state: overridden
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Parsed with empty running_config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_vrf:
+ running_config:
+ state: parsed
+
+- assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- name: Rendered with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_vrf:
+ config:
+ state: rendered
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/gathered.yaml b/tests/integration/targets/vyos_vrf/tests/cli/gathered.yaml
new file mode 100644
index 00000000..7ea7b286
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/gathered.yaml
@@ -0,0 +1,22 @@
+---
+- debug:
+ msg: START vyos_vrf gathered integration tests on connection={{ ansible_connection }}
+
+- include_tasks: _populate.yaml
+
+- block:
+ - name: Gather config from the device in structured format.
+ register: result
+ vyos.vyos.vyos_vrf:
+ state: gathered
+
+ - vyos.vyos.vyos_facts:
+ gather_network_resources: vrf
+
+ - assert:
+ that:
+ - result.changed == false
+ - result.gathered|symmetric_difference(ansible_facts['network_resources']['vrf']) == []
+
+ always:
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/merged.yaml b/tests/integration/targets/vyos_vrf/tests/cli/merged.yaml
new file mode 100644
index 00000000..0a93ae02
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/merged.yaml
@@ -0,0 +1,54 @@
+---
+- debug:
+ msg: START vyos_vrf merged integration tests on connection={{ ansible_connection }}
+
+- include_tasks: _populate.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ vyos.vyos.vyos_vrf: &id001
+ config:
+ bind_to_all: true
+ instances:
+ - name: "vrf-green"
+ description: "green-vrf"
+ table_id: 110
+ vni: 1010
+ - name: "vrf-pink"
+ description: "pink-vrf"
+ table_id: 111
+ vni: 1111
+ protocols:
+ bgp:
+ as_number: 65005
+ neighbor:
+ - address: 192.0.5.1
+ remote_as: 65012
+ state: merged
+
+ - vyos.vyos.vyos_facts:
+ gather_network_resources: vrf
+
+ - assert:
+ that:
+ - result.changed == true
+ - result.commands|symmetric_difference(merged.commands) == []
+ - result.after|symmetric_difference(ansible_facts['network_resources']['vrf']) == []
+
+ - name: Assert that before dicts were correctly generated
+ assert:
+ that:
+ - "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_vrf: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/overridden.yaml b/tests/integration/targets/vyos_vrf/tests/cli/overridden.yaml
new file mode 100644
index 00000000..e21ae185
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/overridden.yaml
@@ -0,0 +1,49 @@
+---
+- debug:
+ msg: START vyos_vrf overridden integration tests on connection={{ ansible_connection }}
+
+- include_tasks: _populate.yaml
+
+- block:
+ - name: Override the existing configuration with the provided running configuration
+ register: result
+ vyos.vyos.vyos_vrf: &id001
+ config:
+ instances:
+ - name: "vrf-blue"
+ description: "blue-vrf"
+ disable: true
+ table_id: 103
+ vni: 1002
+ - name: "vrf-pink"
+ description: "pink-vrf"
+ table_id: 111
+ vni: 1111
+ protocols:
+ bgp:
+ as_number: 65005
+ neighbor:
+ - address: 192.0.2.1
+ remote_as: 65002
+ state: overridden
+
+ - vyos.vyos.vyos_facts:
+ gather_network_resources: vrf
+
+ - assert:
+ that:
+ - result.changed == true
+ - result.commands|symmetric_difference(overridden.commands) == []
+ - result.after|symmetric_difference(ansible_facts['network_resources']['vrf']) == []
+
+ - name: Override the existing configuration with the provided running configuration (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_vrf: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/parsed.yaml b/tests/integration/targets/vyos_vrf/tests/cli/parsed.yaml
new file mode 100644
index 00000000..7f6a4b3d
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/parsed.yaml
@@ -0,0 +1,16 @@
+---
+- debug:
+ msg: START vyos_vrf parsed integration tests on connection={{ ansible_connection }}
+
+- name: Provide the running configuration for parsing (config to be parsed)
+ register: result
+ vyos.vyos.vyos_vrf:
+ running_config: "{{ lookup('file', '_parsed.cfg') }}"
+ state: parsed
+
+- assert:
+ that:
+ - result.changed == false
+ - result.parsed|symmetric_difference(merged.before) == []
+
+- include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/rendered.yaml b/tests/integration/targets/vyos_vrf/tests/cli/rendered.yaml
new file mode 100644
index 00000000..b8b26d12
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/rendered.yaml
@@ -0,0 +1,133 @@
+---
+- debug:
+ msg: START vyos_route_maps rendered integration tests on connection={{ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- block:
+ - name: Structure provided configuration into device specific commands
+ register: result
+ vyos.vyos.vyos_vrf:
+ config:
+ bind_to_all: true
+ instances:
+ - name: vrf-green
+ description: green-vrf
+ disabled: true
+ table_id: 105
+ vni: 1000
+ protocols:
+ bgp:
+ as_number: 65000
+ neighbor:
+ - address: 192.0.2.1
+ remote_as: 65002
+ - address: "1.1.1.3"
+ passive: true
+ remote_as: 400
+ ospf:
+ log_adjacency_changes: detail
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ mpls_te:
+ router_address: 192.0.11.12
+ auto_cost:
+ reference_bandwidth: 2
+ neighbor:
+ - neighbor_id: 192.0.11.12
+ poll_interval: 10
+ priority: 2
+ redistribute:
+ - route_type: bgp
+ metric: 10
+ metric_type: 2
+ parameters:
+ router_id: 192.0.1.1
+ rfc1583_compatibility: true
+ abr_type: cisco
+ areas:
+ - area_id: "2"
+ area_type:
+ normal: true
+ authentication: plaintext-password
+ shortcut: enable
+ - area_id: "3"
+ area_type:
+ nssa:
+ set: true
+ - area_id: "4"
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: 192.0.2.0/24
+ range:
+ - address: 192.0.3.0/24
+ cost: 10
+ - address: 192.0.4.0/24
+ cost: 12
+ ospfv3:
+ areas:
+ - area_id: "2"
+ export_list: export1
+ import_list: import1
+ range:
+ - address: 2001:db10::/32
+ - address: 2001:db20::/32
+ - address: 2001:db30::/32
+ - area_id: "3"
+ range:
+ - address: 2001:db40::/32
+ parameters:
+ router_id: 192.0.2.10
+ redistribute:
+ - route_type: bgp
+ static:
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: "192.0.2.0/24"
+ blackhole_config:
+ distance: 10
+ next_hops:
+ - forward_router_address: "203.0.113.1"
+ - forward_router_address: "203.0.113.2"
+ - afi: ipv6
+ routes:
+ - dest: "2001:db8::/32"
+ blackhole_config:
+ distance: 20
+ next_hops:
+ - forward_router_address: "2001:db8::1"
+ - name: vrf-amber
+ description: amber-vrf
+ disable: false
+ table_id: 111
+ vni: 1001
+ address_family:
+ - afi: ipv4
+ disable_forwarding: true
+ route_maps:
+ # - rm_name: rm1
+ # protocol: kernel
+ - rm_name: rm1
+ protocol: ospf
+ - afi: ipv6
+ nht_no_resolve_via_default: false
+ state: rendered
+
+ - assert:
+ that:
+ - result.changed == false
+ - result.rendered|symmetric_difference(rendered.commands) == []
+
+ always:
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/replaced.yaml b/tests/integration/targets/vyos_vrf/tests/cli/replaced.yaml
new file mode 100644
index 00000000..68d3e450
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/replaced.yaml
@@ -0,0 +1,56 @@
+---
+- debug:
+ msg: START vyos_vrf replaced integration tests on connection={{ ansible_connection }}
+
+- include_tasks: _populate.yaml
+
+- block:
+ - name: Replace the provided configuration with the existing running configuration
+ register: result
+ vyos.vyos.vyos_vrf: &id001
+ config:
+ instances:
+ - name: "vrf-blue"
+ description: "blue-vrf"
+ disable: true
+ table_id: 100
+ vni: 1000
+ - name: "vrf-red"
+ description: "Vermillion_VRF"
+ disable: false
+ table_id: 101
+ vni: 1011
+ address_family:
+ - afi: "ipv6"
+ nht_no_resolve_via_default: false
+ - name: "vrf-pink"
+ table_id: 111
+ protocols:
+ ospf:
+ default_information:
+ originate:
+ always: true
+ metric: 20
+ metric_type: 1
+ state: replaced
+
+ - vyos.vyos.vyos_facts:
+ gather_network_resources: vrf
+
+ - assert:
+ that:
+ - result.changed == true
+ - result.commands|symmetric_difference(replaced.commands) == []
+ - result.after|symmetric_difference(ansible_facts['network_resources']['vrf']) == []
+
+ - name: Replace the provided configuration with the existing running configuration (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_vrf: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/tests/cli/rtt.yaml b/tests/integration/targets/vyos_vrf/tests/cli/rtt.yaml
new file mode 100644
index 00000000..e8e9ea2c
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/tests/cli/rtt.yaml
@@ -0,0 +1,69 @@
+---
+- debug:
+ msg: START vyos_vrf merged integration tests on connection={{ ansible_connection }}
+
+- include_tasks: _populate.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: baseconfig
+ vyos.vyos.vyos_vrf:
+ config:
+ bind_to_all: true
+ instances:
+ - name: "vrf-green"
+ description: "green-vrf"
+ table_id: 110
+ vni: 1010
+ - name: "vrf-pink"
+ description: "pink-vrf"
+ table_id: 111
+ vni: 1111
+ protocols:
+ bgp:
+ as_number: 65005
+ neighbor:
+ - address: 192.0.5.1
+ remote_as: 65012
+ state: merged
+
+ - vyos.vyos.vyos_facts:
+ gather_network_resources: vrf
+
+ - assert:
+ that:
+ - baseconfig.changed == true
+ - baseconfig.commands|symmetric_difference(merged.commands) == []
+ - baseconfig.after|symmetric_difference(ansible_facts['network_resources']['vrf']) == []
+
+ - name: Merge the existing configuration with the provided running configuration
+ register: result
+ vyos.vyos.vyos_vrf:
+ config:
+ instances:
+ - name: "vrf-blue"
+ description: "blue-vrf"
+ disable: true
+ table_id: 100
+ vni: 1000
+ - name: "vrf-green"
+ description: "green-vrf"
+ table_id: 110
+ vni: 1010
+ address_family:
+ - afi: "ipv4"
+ disable_forwarding: true
+ state: merged
+
+ - name: Revert back to base config using facts round trip
+ register: revert
+ vyos.vyos.vyos_vrf:
+ config: "{{ ansible_facts['network_resources']['vrf'] }}"
+ state: overridden
+
+ - name: Assert that config was reverted
+ assert:
+ that: baseconfig.after == revert.after
+
+ always:
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_vrf/vars/main.yaml b/tests/integration/targets/vyos_vrf/vars/main.yaml
new file mode 100644
index 00000000..9620cf32
--- /dev/null
+++ b/tests/integration/targets/vyos_vrf/vars/main.yaml
@@ -0,0 +1,278 @@
+---
+merged:
+ before:
+ bind_to_all: true
+ instances:
+ - name: "vrf-blue"
+ description: "blue-vrf"
+ disable: false
+ table_id: 100
+ vni: 1000
+ - name: "vrf-red"
+ description: "red-vrf"
+ disable: true
+ table_id: 101
+ vni: 1001
+ address_family:
+ - afi: "ipv4"
+ disable_forwarding: true
+ route_maps:
+ - rm_name: "rm1"
+ protocol: "rip"
+ - afi: "ipv6"
+ nht_no_resolve_via_default: true
+ - name: "vrf-green"
+ description: "green-vrf"
+ table_id: 110
+ vni: 1010
+ protocols:
+ ospf:
+ areas:
+ - area_id: "4"
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: 192.0.2.0/24
+ range:
+ - address: 192.0.3.0/24
+ cost: 10
+ - address: 192.0.4.0/24
+ cost: 12
+ ospfv3:
+ areas:
+ - area_id: "2"
+ export_list: export1
+ import_list: import1
+ range:
+ - address: 2001:db10::/32
+ - address: 2001:db20::/32
+ - address: 2001:db30::/32
+ static:
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: "192.0.2.0/24"
+ blackhole_config:
+ distance: 10
+ next_hops:
+ - forward_router_address: "203.0.113.1"
+ - forward_router_address: "203.0.113.2"
+ - afi: ipv6
+ routes:
+ - dest: "2001:db8::/32"
+ blackhole_config:
+ distance: 20
+ next_hops:
+ - forward_router_address: "2001:db8::1"
+ commands:
+ - set vrf name vrf-green table 110
+ - set vrf name vrf-green vni 1010
+ - set vrf name vrf-green description green-vrf
+ - set vrf name vrf-pink protocols bgp system-as 65005
+ - set vrf name vrf-pink protocols bgp neighbor 192.0.5.1 remote-as 65012
+ after:
+ bind_to_all: true
+ instances:
+ - name: "vrf-blue"
+ description: "blue-vrf"
+ disable: false
+ table_id: 100
+ vni: 1000
+ - name: "vrf-red"
+ description: "red-vrf"
+ disable: true
+ table_id: 101
+ vni: 1001
+ address_family:
+ - afi: "ipv4"
+ disable_forwarding: true
+ route_maps:
+ - rm_name: "rm1"
+ protocol: "rip"
+ - afi: "ipv6"
+ nht_no_resolve_via_default: true
+ - name: "vrf-green"
+ description: "green-vrf"
+ table_id: 110
+ vni: 1010
+
+replaced:
+ commands:
+ - delete vrf bind-to-all
+ - set vrf name vrf-blue disable
+ - set vrf name vrf-red vni 1011
+ - set vrf name vrf-red description Vermillion_VRF
+ - delete vrf name vrf-red disable
+ - delete vrf name vrf-red ipv6 nht no-resolve-via-default
+ - delete vrf name vrf-pink vni 1111
+ - delete vrf name vrf-pink description pink-vrf
+ - delete vrf name vrf-pink protocols ospf log-adjacency-changes 'detail'
+ - delete vrf name vrf-pink protocols ospf auto-cost
+ - delete vrf name vrf-pink protocols ospf max-metric
+ - delete vrf name vrf-pink protocols ospf mpls-te
+ - delete vrf name vrf-pink protocols ospf area
+ - delete vrf name vrf-pink protocols ospf parameters
+ - delete vrf name vrf-pink protocols ospf neighbor
+ - delete vrf name vrf-pink protocols ospf redistribute
+ - set vrf name vrf-pink protocols ospf default-information originate metric 20
+ - set vrf name vrf-pink protocols ospf default-information originate metric-type 1
+ after: []
+
+overridden:
+ commands:
+ - delete vrf name vrf-blue
+ - commit
+ - delete vrf name vrf-pink
+ - commit
+ - set vrf name vrf-blue table 103
+ - set vrf name vrf-blue vni 1002
+ - set vrf name vrf-blue description blue-vrf
+ - set vrf name vrf-blue disable
+ - set vrf name vrf-pink table 111
+ - set vrf name vrf-pink vni 1111
+ - set vrf name vrf-pink description pink-vrf
+ - set vrf name vrf-pink protocols bgp system-as 65005
+ - set vrf name vrf-pink protocols bgp neighbor 192.0.2.1 remote-as 65002
+ - delete vrf bind-to-all
+ after: []
+
+deleted:
+ commands:
+ - delete vrf
+ after: []
+
+rendered:
+ commands:
+ - set vrf bind-to-all
+ - set vrf name vrf-green table 105
+ - set vrf name vrf-green vni 1000
+ - set vrf name vrf-green description green-vrf
+ - set vrf name vrf-green disable
+ - set vrf name vrf-green protocols bgp system-as 65000
+ - set vrf name vrf-green protocols bgp neighbor 192.0.2.1 remote-as 65002
+ - set vrf name vrf-green protocols bgp neighbor 1.1.1.3 passive
+ - set vrf name vrf-green protocols bgp neighbor 1.1.1.3 remote-as 400
+ - set vrf name vrf-green protocols ospf log-adjacency-changes 'detail'
+ - set vrf name vrf-green protocols ospf max-metric router-lsa administrative
+ - set vrf name vrf-green protocols ospf max-metric router-lsa on-shutdown 10
+ - set vrf name vrf-green protocols ospf max-metric router-lsa on-startup 10
+ - set vrf name vrf-green protocols ospf default-information originate always
+ - set vrf name vrf-green protocols ospf default-information originate metric 10
+ - set vrf name vrf-green protocols ospf default-information originate metric-type 2
+ - set vrf name vrf-green protocols ospf mpls-te router-address '192.0.11.12'
+ - set vrf name vrf-green protocols ospf auto-cost reference-bandwidth '2'
+ - set vrf name vrf-green protocols ospf neighbor 192.0.11.12
+ - set vrf name vrf-green protocols ospf neighbor 192.0.11.12 poll-interval 10
+ - set vrf name vrf-green protocols ospf neighbor 192.0.11.12 priority 2
+ - set vrf name vrf-green protocols ospf redistribute bgp
+ - set vrf name vrf-green protocols ospf redistribute bgp metric 10
+ - set vrf name vrf-green protocols ospf redistribute bgp metric-type 2
+ - set vrf name vrf-green protocols ospf parameters router-id '192.0.1.1'
+ - set vrf name vrf-green protocols ospf parameters rfc1583-compatibility
+ - set vrf name vrf-green protocols ospf parameters abr-type 'cisco'
+ - set vrf name vrf-green protocols ospf area '2'
+ - set vrf name vrf-green protocols ospf area 2 area-type normal
+ - set vrf name vrf-green protocols ospf area 2 authentication plaintext-password
+ - set vrf name vrf-green protocols ospf area 2 shortcut enable
+ - set vrf name vrf-green protocols ospf area '3'
+ - set vrf name vrf-green protocols ospf area 3 area-type nssa
+ - set vrf name vrf-green protocols ospf area '4'
+ - set vrf name vrf-green protocols ospf area 4 area-type stub default-cost 20
+ - set vrf name vrf-green protocols ospf area 4 network 192.0.2.0/24
+ - set vrf name vrf-green protocols ospf area 4 range 192.0.3.0/24
+ - set vrf name vrf-green protocols ospf area 4 range 192.0.3.0/24 cost 10
+ - set vrf name vrf-green protocols ospf area 4 range 192.0.4.0/24
+ - set vrf name vrf-green protocols ospf area 4 range 192.0.4.0/24 cost 12
+ - set vrf name vrf-green protocols ospfv3 area '2'
+ - set vrf name vrf-green protocols ospfv3 area 2 export-list export1
+ - set vrf name vrf-green protocols ospfv3 area 2 import-list import1
+ - set vrf name vrf-green protocols ospfv3 area 2 range 2001:db10::/32
+ - set vrf name vrf-green protocols ospfv3 area 2 range 2001:db20::/32
+ - set vrf name vrf-green protocols ospfv3 area 2 range 2001:db30::/32
+ - set vrf name vrf-green protocols ospfv3 area '3'
+ - set vrf name vrf-green protocols ospfv3 area 3 range 2001:db40::/32
+ - set vrf name vrf-green protocols ospfv3 parameters router-id '192.0.2.10'
+ - set vrf name vrf-green protocols ospfv3 redistribute bgp
+ - set vrf name vrf-green protocols static route 192.0.2.0/24
+ - set vrf name vrf-green protocols static route 192.0.2.0/24 blackhole distance '10'
+ - set vrf name vrf-green protocols static route 192.0.2.0/24 next-hop '203.0.113.1'
+ - set vrf name vrf-green protocols static route 192.0.2.0/24 next-hop '203.0.113.2'
+ - set vrf name vrf-green protocols static route6 2001:db8::/32
+ - set vrf name vrf-green protocols static route6 2001:db8::/32 blackhole distance '20'
+ - set vrf name vrf-green protocols static route6 2001:db8::/32 next-hop '2001:db8::1'
+ - set vrf name vrf-amber table 111
+ - set vrf name vrf-amber vni 1001
+ - set vrf name vrf-amber description amber-vrf
+ # - set vrf name vrf-amber ip protocol kernel route-map rm1
+ - set vrf name vrf-amber ip protocol ospf route-map rm1
+ - set vrf name vrf-amber ip disable-forwarding
+
+populate_config:
+ - set vrf bind-to-all
+ - set vrf name vrf-blue description 'blue-vrf'
+ - set vrf name vrf-blue table '100'
+ - set vrf name vrf-blue vni '1000'
+ - set vrf name vrf-red description 'red-vrf'
+ - set vrf name vrf-red disable
+ - set vrf name vrf-red ip disable-forwarding
+ # - set vrf name vrf-red ip protocol kernel route-map 'rm1'
+ - set vrf name vrf-red ip protocol rip route-map 'rm1'
+ - set vrf name vrf-red ipv6 nht no-resolve-via-default
+ - set vrf name vrf-red table '101'
+ - set vrf name vrf-red vni '1001'
+ - set vrf name vrf-pink table 111
+ - set vrf name vrf-pink vni 1111
+ - set vrf name vrf-pink description pink-vrf
+ - set vrf name vrf-pink protocols bgp system-as 65000
+ - set vrf name vrf-pink protocols bgp neighbor 192.0.2.1 remote-as 65002
+ - set vrf name vrf-pink protocols bgp neighbor 1.1.1.3 passive
+ - set vrf name vrf-pink protocols bgp neighbor 1.1.1.3 remote-as 400
+ - set vrf name vrf-pink protocols ospf log-adjacency-changes 'detail'
+ - set vrf name vrf-pink protocols ospf max-metric router-lsa administrative
+ - set vrf name vrf-pink protocols ospf max-metric router-lsa on-shutdown 10
+ - set vrf name vrf-pink protocols ospf max-metric router-lsa on-startup 10
+ - set vrf name vrf-pink protocols ospf default-information originate always
+ - set vrf name vrf-pink protocols ospf default-information originate metric 10
+ - set vrf name vrf-pink protocols ospf default-information originate metric-type 2
+ - set vrf name vrf-pink protocols ospf mpls-te router-address '192.0.11.12'
+ - set vrf name vrf-pink protocols ospf auto-cost reference-bandwidth '2'
+ - set vrf name vrf-pink protocols ospf neighbor 192.0.11.12
+ - set vrf name vrf-pink protocols ospf neighbor 192.0.11.12 poll-interval 10
+ - set vrf name vrf-pink protocols ospf neighbor 192.0.11.12 priority 2
+ - set vrf name vrf-pink protocols ospf redistribute bgp
+ - set vrf name vrf-pink protocols ospf redistribute bgp metric 10
+ - set vrf name vrf-pink protocols ospf redistribute bgp metric-type 2
+ - set vrf name vrf-pink protocols ospf parameters router-id '192.0.1.1'
+ - set vrf name vrf-pink protocols ospf parameters rfc1583-compatibility
+ - set vrf name vrf-pink protocols ospf parameters abr-type 'cisco'
+ - set vrf name vrf-pink protocols ospf area '2'
+ - set vrf name vrf-pink protocols ospf area 2 area-type normal
+ - set vrf name vrf-pink protocols ospf area 2 authentication plaintext-password
+ - set vrf name vrf-pink protocols ospf area 2 shortcut enable
+ - set vrf name vrf-pink protocols ospf area '3'
+ - set vrf name vrf-pink protocols ospf area 3 area-type nssa
+ - set vrf name vrf-pink protocols ospf area '4'
+ - set vrf name vrf-pink protocols ospf area 4 area-type stub default-cost 20
+ - set vrf name vrf-pink protocols ospf area 4 network 192.0.2.0/24
+ - set vrf name vrf-pink protocols ospf area 4 range 192.0.3.0/24
+ - set vrf name vrf-pink protocols ospf area 4 range 192.0.3.0/24 cost 10
+ - set vrf name vrf-pink protocols ospf area 4 range 192.0.4.0/24
+ - set vrf name vrf-pink protocols ospf area 4 range 192.0.4.0/24 cost 12
+ - set vrf name vrf-pink protocols ospfv3 area '2'
+ - set vrf name vrf-pink protocols ospfv3 area 2 export-list export1
+ - set vrf name vrf-pink protocols ospfv3 area 2 import-list import1
+ - set vrf name vrf-pink protocols ospfv3 area 2 range 2001:db10::/32
+ - set vrf name vrf-pink protocols ospfv3 area 2 range 2001:db20::/32
+ - set vrf name vrf-pink protocols ospfv3 area 2 range 2001:db30::/32
+ - set vrf name vrf-pink protocols ospfv3 area '3'
+ - set vrf name vrf-pink protocols ospfv3 area 3 range 2001:db40::/32
+ - set vrf name vrf-pink protocols ospfv3 parameters router-id '192.0.2.10'
+ - set vrf name vrf-pink protocols ospfv3 redistribute bgp
+ - set vrf name vrf-pink protocols static route 192.0.2.0/24
+ - set vrf name vrf-pink protocols static route 192.0.2.0/24 blackhole distance '10'
+ - set vrf name vrf-pink protocols static route 192.0.2.0/24 next-hop '203.0.113.1'
+ - set vrf name vrf-pink protocols static route 192.0.2.0/24 next-hop '203.0.113.2'
+ - set vrf name vrf-pink protocols static route6 2001:db8::/32
+ - set vrf name vrf-pink protocols static route6 2001:db8::/32 blackhole distance '20'
+ - set vrf name vrf-pink protocols static route6 2001:db8::/32 next-hop '2001:db8::1'
diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_vrf_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_vrf_config.cfg
new file mode 100644
index 00000000..094b7cf3
--- /dev/null
+++ b/tests/unit/modules/network/vyos/fixtures/vyos_vrf_config.cfg
@@ -0,0 +1,15 @@
+set vrf bind-to-all
+set vrf name vrf-blue description 'blue-vrf'
+set vrf name vrf-blue table '100'
+set vrf name vrf-blue vni '1000'
+set vrf name vrf-red description 'red-vrf'
+set vrf name vrf-red disable
+set vrf name vrf-red ip disable-forwarding
+set vrf name vrf-red ip protocol rip route-map 'rm1'
+set vrf name vrf-red ipv6 nht no-resolve-via-default
+set vrf name vrf-red table '101'
+set vrf name vrf-red vni '1001'
+set vrf name vrf-red protocols bgp system-as 65000
+set vrf name vrf-red protocols bgp neighbor 192.0.2.1 remote-as 65002
+set vrf name vrf-red protocols bgp neighbor 1.1.1.3 passive
+set vrf name vrf-red protocols bgp neighbor 1.1.1.3 remote-as 400
diff --git a/tests/unit/modules/network/vyos/test_vyos_vrf.py b/tests/unit/modules/network/vyos/test_vyos_vrf.py
new file mode 100644
index 00000000..e86227a9
--- /dev/null
+++ b/tests/unit/modules/network/vyos/test_vyos_vrf.py
@@ -0,0 +1,689 @@
+# (c) 2021 Red Hat Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from unittest.mock import MagicMock, patch
+
+from ansible_collections.vyos.vyos.plugins.modules import vyos_vrf
+from ansible_collections.vyos.vyos.tests.unit.modules.utils import set_module_args
+
+from .vyos_module import TestVyosModule, load_fixture
+
+
+class TestVyosVrfModule(TestVyosModule):
+ module = vyos_vrf
+
+ def setUp(self):
+ super(TestVyosVrfModule, self).setUp()
+
+ self.fake_connection = MagicMock()
+ self.fake_connection.get.return_value = "{}"
+
+ self.fake_connection.get_device_info.return_value = {
+ "version": "1.5",
+ }
+
+ self.fake_connection.get_device_info.return_value = {
+ "network_os_major_version": "1.5",
+ }
+ patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos.get_connection",
+ return_value=self.fake_connection,
+ ).start()
+
+ def _get_resource_connection_side_effect(module, *args, **kwargs):
+ module._connection = self.fake_connection
+ return self.fake_connection
+
+ patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection",
+ side_effect=_get_resource_connection_side_effect,
+ ).start()
+
+ patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ side_effect=_get_resource_connection_side_effect,
+ ).start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.vrf.vrf.VrfFacts.get_config",
+ ).start()
+
+ patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.vrf.vrf.get_os_version",
+ return_value="1.5",
+ ).start()
+
+ patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.bgp_global.bgp_global.get_os_version",
+ return_value="1.5",
+ ).start()
+
+ self.maxDiff = None
+
+ def tearDown(self):
+ super(TestVyosVrfModule, self).tearDown()
+ patch.stopall()
+
+ def load_fixtures(self, commands=None, filename=None):
+ if filename is None:
+ filename = "vyos_vrf_config.cfg"
+
+ def load_from_file(*args, **kwargs):
+ return load_fixture(filename)
+
+ self.mock_execute_show_command.side_effect = load_from_file
+
+ def test_vrf_merged_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf",
+ disable=False,
+ table_id=100,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=True,
+ route_maps=[
+ dict(rm_name="rm1", protocol="rip"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ nht_no_resolve_via_default=True,
+ ),
+ ],
+ protocols=dict(
+ bgp=dict(
+ as_number=65000,
+ neighbor=[
+ dict(
+ address="192.0.2.1",
+ remote_as=65002,
+ ),
+ dict(
+ address="1.1.1.3",
+ remote_as=400,
+ passive=True,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+
+ self.execute_module(changed=False, commands=[])
+
+ def test_vrf_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=False,
+ instances=[
+ dict(
+ name="vrf-green",
+ description="green-vrf",
+ table_id=110,
+ vni=1010,
+ protocols=dict(
+ ospf=dict(
+ log_adjacency_changes="detail",
+ max_metric=dict(
+ router_lsa=dict(
+ administrative=True,
+ on_shutdown=10,
+ on_startup=10,
+ ),
+ ),
+ default_information=dict(
+ originate=dict(
+ always=True,
+ metric=10,
+ metric_type=2,
+ ),
+ ),
+ auto_cost=dict(
+ reference_bandwidth=2,
+ ),
+ neighbor=[
+ dict(
+ neighbor_id="192.0.11.12",
+ poll_interval=10,
+ priority=2,
+ ),
+ ],
+ redistribute=[
+ dict(
+ route_type="bgp",
+ metric=10,
+ metric_type=2,
+ ),
+ ],
+ parameters=dict(
+ router_id="192.0.1.1",
+ rfc1583_compatibility=True,
+ abr_type="cisco",
+ ),
+ areas=[
+ dict(
+ area_id="2",
+ area_type=dict(
+ normal=True,
+ ),
+ authentication="plaintext-password",
+ shortcut="enable",
+ ),
+ dict(
+ area_id="3",
+ area_type=dict(
+ nssa=dict(
+ set=True,
+ ),
+ ),
+ ),
+ dict(
+ area_id="4",
+ area_type=dict(
+ stub=dict(
+ default_cost=20,
+ ),
+ ),
+ network=[
+ dict(
+ address="192.0.2.0/24",
+ ),
+ ],
+ range=[
+ dict(
+ address="192.0.3.0/24",
+ cost=10,
+ ),
+ dict(
+ address="192.0.4.0/24",
+ cost=12,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+
+ commands = [
+ "delete vrf bind-to-all",
+ "set vrf name vrf-green table 110",
+ "set vrf name vrf-green vni 1010",
+ "set vrf name vrf-green description green-vrf",
+ "set vrf name vrf-green protocols ospf log-adjacency-changes 'detail'",
+ "set vrf name vrf-green protocols ospf max-metric router-lsa administrative",
+ "set vrf name vrf-green protocols ospf max-metric router-lsa on-shutdown 10",
+ "set vrf name vrf-green protocols ospf max-metric router-lsa on-startup 10",
+ "set vrf name vrf-green protocols ospf default-information originate always",
+ "set vrf name vrf-green protocols ospf default-information originate metric 10",
+ "set vrf name vrf-green protocols ospf default-information originate metric-type 2",
+ "set vrf name vrf-green protocols ospf auto-cost reference-bandwidth '2'",
+ "set vrf name vrf-green protocols ospf neighbor 192.0.11.12",
+ "set vrf name vrf-green protocols ospf neighbor 192.0.11.12 poll-interval 10",
+ "set vrf name vrf-green protocols ospf neighbor 192.0.11.12 priority 2",
+ "set vrf name vrf-green protocols ospf redistribute bgp",
+ "set vrf name vrf-green protocols ospf redistribute bgp metric 10",
+ "set vrf name vrf-green protocols ospf redistribute bgp metric-type 2",
+ "set vrf name vrf-green protocols ospf parameters router-id '192.0.1.1'",
+ "set vrf name vrf-green protocols ospf parameters rfc1583-compatibility",
+ "set vrf name vrf-green protocols ospf parameters abr-type 'cisco'",
+ "set vrf name vrf-green protocols ospf area '2'",
+ "set vrf name vrf-green protocols ospf area 2 area-type normal",
+ "set vrf name vrf-green protocols ospf area 2 authentication plaintext-password",
+ "set vrf name vrf-green protocols ospf area 2 shortcut enable",
+ "set vrf name vrf-green protocols ospf area '3'",
+ "set vrf name vrf-green protocols ospf area 3 area-type nssa",
+ "set vrf name vrf-green protocols ospf area '4'",
+ "set vrf name vrf-green protocols ospf area 4 area-type stub default-cost 20",
+ "set vrf name vrf-green protocols ospf area 4 network 192.0.2.0/24",
+ "set vrf name vrf-green protocols ospf area 4 range 192.0.3.0/24",
+ "set vrf name vrf-green protocols ospf area 4 range 192.0.3.0/24 cost 10",
+ "set vrf name vrf-green protocols ospf area 4 range 192.0.4.0/24",
+ "set vrf name vrf-green protocols ospf area 4 range 192.0.4.0/24 cost 12",
+ ]
+
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vrf_replaced(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf-replaced",
+ disable=True,
+ table_id=100,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=False,
+ route_maps=[
+ dict(rm_name="rm1", protocol="rip"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ nht_no_resolve_via_default=False,
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "set vrf name vrf-blue description blue-vrf-replaced",
+ "set vrf name vrf-blue disable",
+ "delete vrf name vrf-red ip disable-forwarding",
+ "delete vrf name vrf-red ipv6 nht no-resolve-via-default",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vrf_replaced_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf",
+ disable=False,
+ table_id=100,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=True,
+ route_maps=[
+ dict(rm_name="rm1", protocol="rip"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ nht_no_resolve_via_default=True,
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vrf_overridden(self):
+ set_module_args(
+ dict(
+ config=dict(
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf",
+ disable=True,
+ table_id=103,
+ vni=1002,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ protocols=dict(
+ bgp=dict(
+ as_number=65000,
+ neighbor=[
+ dict(
+ address="192.0.2.1",
+ remote_as=65003,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+ commands = [
+ "delete vrf name vrf-blue",
+ "commit",
+ "delete vrf name vrf-red",
+ "commit",
+ "set vrf name vrf-blue table 103",
+ "set vrf name vrf-blue vni 1002",
+ "set vrf name vrf-blue description blue-vrf",
+ "set vrf name vrf-blue disable",
+ "set vrf name vrf-red table 101",
+ "set vrf name vrf-red vni 1001",
+ "set vrf name vrf-red description red-vrf",
+ "set vrf name vrf-red disable",
+ "set vrf name vrf-red protocols bgp system-as 65000",
+ "set vrf name vrf-red protocols bgp neighbor 192.0.2.1 remote-as 65003",
+ "delete vrf bind-to-all",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vrf_overridden_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf",
+ disable=False,
+ table_id=100,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=True,
+ nht_no_resolve_via_default=False,
+ route_maps=[
+ dict(rm_name="rm1", protocol="rip"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ disable_forwarding=False,
+ nht_no_resolve_via_default=True,
+ ),
+ ],
+ protocols=dict(
+ bgp=dict(
+ as_number=65000,
+ neighbor=[
+ dict(
+ address="192.0.2.1",
+ remote_as=65002,
+ ),
+ dict(
+ address="1.1.1.3",
+ remote_as=400,
+ passive=True,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vrf_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-green",
+ description="green-vrf",
+ disabled=True,
+ table_id=105,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-amber",
+ description="amber-vrf",
+ disable=False,
+ table_id=111,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=True,
+ route_maps=[
+ dict(rm_name="rm1", protocol="ospf"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ nht_no_resolve_via_default=False,
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="rendered",
+ ),
+ )
+ rendered_commands = [
+ "set vrf bind-to-all",
+ "set vrf name vrf-green table 105",
+ "set vrf name vrf-green vni 1000",
+ "set vrf name vrf-green description green-vrf",
+ "set vrf name vrf-green disable",
+ "set vrf name vrf-amber table 111",
+ "set vrf name vrf-amber vni 1001",
+ "set vrf name vrf-amber description amber-vrf",
+ "set vrf name vrf-amber ip protocol ospf route-map rm1",
+ "set vrf name vrf-amber ip disable-forwarding",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(
+ sorted(result["rendered"]),
+ sorted(rendered_commands),
+ result["rendered"],
+ )
+
+ def test_vrf_parsed(self):
+ commands = (
+ "set vrf bind-to-all",
+ "set vrf name vrf1 description 'red'",
+ "set vrf name vrf1 disable",
+ "set vrf name vrf1 table 101",
+ "set vrf name vrf1 vni 501",
+ "set vrf name vrf2 description 'green'",
+ "set vrf name vrf2 disable",
+ "set vrf name vrf2 table 102",
+ "set vrf name vrf2 vni 102",
+ "set vrf name vrf1 ip disable-forwarding",
+ "set vrf name vrf1 ip nht no-resolve-via-default",
+ "set vrf name vrf-red ip protocol ospf route-map 'rm1'",
+ "set vrf name vrf-red ipv6 nht no-resolve-via-default",
+ )
+ parsed_str = "\n".join(commands)
+ set_module_args(dict(running_config=parsed_str, state="parsed"))
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "bind_to_all": True,
+ "instances": [
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "disable_forwarding": True,
+ "nht_no_resolve_via_default": True,
+ },
+ ],
+ "description": "red",
+ "disable": True,
+ "name": "vrf1",
+ },
+ {
+ "description": "green",
+ "disable": True,
+ "name": "vrf2",
+ },
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "disable_forwarding": False,
+ "nht_no_resolve_via_default": False,
+ "route_maps": [
+ {
+ "protocol": "ospf",
+ "rm_name": "rm1",
+ },
+ ],
+ },
+ {
+ "afi": "ipv6",
+ "disable_forwarding": False,
+ "nht_no_resolve_via_default": True,
+ },
+ ],
+ "disable": False,
+ "name": "vrf-red",
+ },
+ ],
+ }
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_vrf_gathered(self):
+ set_module_args(dict(state="gathered"))
+ result = self.execute_module(changed=False)
+ gathered_list = {
+ "bind_to_all": True,
+ "instances": [
+ {
+ "description": "blue-vrf",
+ "disable": False,
+ "name": "vrf-blue",
+ "table_id": 100,
+ "vni": 1000,
+ },
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "disable_forwarding": True,
+ "nht_no_resolve_via_default": False,
+ "route_maps": [
+ {"protocol": "rip", "rm_name": "rm1"},
+ ],
+ },
+ {
+ "afi": "ipv6",
+ "disable_forwarding": False,
+ "nht_no_resolve_via_default": True,
+ },
+ ],
+ "description": "red-vrf",
+ "disable": True,
+ "name": "vrf-red",
+ "protocols": {
+ "bgp": {
+ "as_number": 65000,
+ "neighbor": [
+ {"address": "1.1.1.3", "passive": True, "remote_as": 400},
+ {"address": "192.0.2.1", "remote_as": 65002},
+ ],
+ },
+ },
+ "table_id": 101,
+ "vni": 1001,
+ },
+ ],
+ }
+ self.assertEqual(gathered_list, result["gathered"])
+
+ def test_vrf_deleted(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ ),
+ ],
+ ),
+ state="deleted",
+ ),
+ )
+ commands = [
+ "delete vrf bind-to-all",
+ "delete vrf name vrf-blue",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vrf_all_deleted(self):
+ set_module_args(
+ dict(
+ state="deleted",
+ ),
+ )
+ commands = [
+ "delete vrf",
+ ]
+ self.execute_module(changed=True, commands=commands)